package quizzes_test import ( "net/http/httptest" "slices" "strings" "testing" quizzes "git.golem15.com/golem15/sm-quizzes-plugin" "git.golem15.com/golem15/sm-quizzes-plugin/controllers/api" "git.golem15.com/golem15/summercms/modules/bouncer" "git.golem15.com/golem15/summercms/modules/pact" "git.golem15.com/golem15/summercms/modules/party" "git.golem15.com/golem15/summercms/modules/phrasebook" "git.golem15.com/golem15/summercms/modules/surf" "git.golem15.com/golem15/summercms/modules/towel" ) func quizzesPlugin(t *testing.T, plugins []party.Plugin) party.Plugin { t.Helper() for _, p := range plugins { if p.ID() == "golem15.quizzes" { return p } } t.Fatal("golem15.quizzes was not activated") return nil } func TestPluginActivates(t *testing.T) { app, plugins := activate(t, nil, nil) p := quizzesPlugin(t, plugins) if _, ok := p.(*quizzes.Plugin); !ok { t.Fatalf("activated plugin is %T", p) } if got := p.Requires(); !slices.Equal(got, []string{"golem15.user"}) { t.Errorf("Requires = %v, want golem15.user", got) } if got := len(p.(pact.HasModels).Models()); got != 5 { t.Errorf("Models = %d, want 5", got) } if len(p.(pact.HasMigrations).Migrations()) == 0 { t.Error("no migrations") } if app.Config.Bool("golem15.quizzes.scoring.multiple_partial") { t.Error("scoring.multiple_partial defaults to true, want false") } if !app.Config.Has("golem15.quizzes.scoring.penalty_wrong") { t.Error("scoring.penalty_wrong has no default") } } func TestRoutesRegistered(t *testing.T) { app, plugins := activate(t, nil, nil) router, err := surf.BuildRouter(app, plugins) if err != nil { t.Fatalf("BuildRouter: %v", err) } want := []string{ "GET /_quizzes/api/v1/quizzes", "GET /_quizzes/api/v1/quizzes/{slug}", "POST /_quizzes/api/v1/quizzes/{slug}/attempts", "GET /_quizzes/api/v1/attempts", "GET /_quizzes/api/v1/attempts/{id}", "POST /_quizzes/api/v1/attempts/{id}/answers", "POST /_quizzes/api/v1/attempts/{id}/finish", "POST /api/v1/quizzes/import", } var got []string for _, r := range router.Routes() { if r.PluginID != "golem15.quizzes" { continue } got = append(got, r.Method+" "+r.Pattern) if r.Pattern == "/api/v1/quizzes/import" { for _, mw := range []string{"user.api_token", "user.scope:write", "user.permission:golem15.quizzes.access_quizzes"} { if !slices.Contains(r.Middleware, mw) { t.Errorf("%s %s is not behind %s: %v", r.Method, r.Pattern, mw, r.Middleware) } } continue } if !slices.Contains(r.Middleware, "jwt.auth") { t.Errorf("%s %s is not behind jwt.auth: %v", r.Method, r.Pattern, r.Middleware) } } if !slices.Equal(got, want) { t.Errorf("routes = %v\nwant %v", got, want) } } func TestAPIMessagesAreTranslated(t *testing.T) { // party.Activate loads the plugins' lang trees into the translator. app, _ := activate(t, nil, nil) if _, ok := app.Lookup[*phrasebook.Translator](); !ok { t.Fatal("no translator after activation") } h := api.New(app) for locale, want := range map[string]string{"pl": "Nie znaleziono podejścia", "en": "Attempt not found"} { req := httptest.NewRequest("GET", "/", nil) req = req.WithContext(towel.WithLocale(bouncer.WithUser(req.Context(), &bouncer.Principal{ID: 1}), locale)) rec := httptest.NewRecorder() h.ShowAttempt(rec, req) // no {id}: 404 if rec.Code != 404 || !strings.Contains(rec.Body.String(), want) { t.Errorf("%s: %d %s, want 404 with %q", locale, rec.Code, rec.Body.String(), want) } } }