package app import ( "context" "encoding/json" "io" "log/slog" "net/http" "net/http/httptest" "net/url" "strings" "testing" ) func testHandler(t *testing.T) http.Handler { t.Helper() return testHandlerConfig(t, Config{ListenAddress: ":0", BaseURL: "https://example.org", PublicName: "Test", DefaultLanguage: "de"}) } func testHandlerConfig(t *testing.T, cfg Config) http.Handler { t.Helper() h, err := New(context.Background(), cfg, slog.New(slog.NewTextHandler(io.Discard, nil))) if err != nil { t.Fatal(err) } return h } func TestPresetBadgeFrench(t *testing.T) { r := httptest.NewRequest(http.MethodGet, "/badge/research.svg?lang=fr", nil) w := httptest.NewRecorder() testHandler(t).ServeHTTP(w, r) if w.Code != http.StatusOK { t.Fatalf("status %d: %s", w.Code, w.Body.String()) } if ct := w.Header().Get("Content-Type"); !strings.Contains(ct, "image/svg+xml") { t.Fatalf("content type %q", ct) } if !strings.Contains(w.Body.String(), "AI ASSISTED") { t.Fatal("missing localized preset") } } func TestValidate(t *testing.T) { body := `{"@context":"https://example.org/context/v1","@type":"AIUsageDeclaration","schemaVersion":"1.1","language":"de","components":{"text":{"aiExtent":"assisted","activities":["research"],"humanReview":"editorial"}},"assurance":"selfDeclared"}` r := httptest.NewRequest(http.MethodPost, "/v1/validate", strings.NewReader(body)) w := httptest.NewRecorder() testHandler(t).ServeHTTP(w, r) if w.Code != http.StatusOK { t.Fatalf("status %d: %s", w.Code, w.Body.String()) } var result map[string]any if err := json.Unmarshal(w.Body.Bytes(), &result); err != nil { t.Fatal(err) } if result["valid"] != true { t.Fatalf("unexpected response: %#v", result) } } func TestCommunityRejectsCustomBadge(t *testing.T) { r := httptest.NewRequest(http.MethodGet, "/v1/badge.svg?lang=en&badgeMessage=Custom", nil) w := httptest.NewRecorder() testHandler(t).ServeHTTP(w, r) if w.Code != http.StatusForbidden { t.Fatalf("status %d: %s", w.Code, w.Body.String()) } if !strings.Contains(w.Body.String(), "licensed_feature_required") { t.Fatalf("unexpected response: %s", w.Body.String()) } } func TestCapabilities(t *testing.T) { r := httptest.NewRequest(http.MethodGet, "/v1/capabilities", nil) w := httptest.NewRecorder() testHandler(t).ServeHTTP(w, r) if w.Code != http.StatusOK { t.Fatalf("status %d", w.Code) } if !strings.Contains(w.Body.String(), `"edition":"community"`) { t.Fatalf("unexpected response: %s", w.Body.String()) } } func TestMarketingPageGerman(t *testing.T) { r := httptest.NewRequest(http.MethodGet, "/product?lang=de", nil) w := httptest.NewRecorder() testHandler(t).ServeHTTP(w, r) if w.Code != http.StatusOK { t.Fatalf("status %d: %s", w.Code, w.Body.String()) } body := w.Body.String() for _, expected := range []string{"Declare how content was made.", "Docker Compose", "JSON-LD"} { if !strings.Contains(body, expected) { t.Fatalf("marketing page missing %q", expected) } } } func TestMarketingPageLanguageNegotiation(t *testing.T) { r := httptest.NewRequest(http.MethodGet, "/product", nil) r.Header.Set("Accept-Language", "fr-FR,fr;q=0.9,en;q=0.8") w := httptest.NewRecorder() testHandler(t).ServeHTTP(w, r) if w.Code != http.StatusOK { t.Fatalf("status %d: %s", w.Code, w.Body.String()) } if !strings.Contains(w.Body.String(), "Declare how content was made.") { t.Fatal("missing French marketing content") } } func TestInstallAlias(t *testing.T) { r := httptest.NewRequest(http.MethodGet, "/install?lang=en", nil) w := httptest.NewRecorder() testHandler(t).ServeHTTP(w, r) if w.Code != http.StatusTemporaryRedirect { t.Fatalf("status %d", w.Code) } if location := w.Header().Get("Location"); location != "/product?lang=en#install" { t.Fatalf("unexpected redirect %q", location) } } func TestPricingRouteRemoved(t *testing.T) { r := httptest.NewRequest(http.MethodGet, "/pricing", nil) w := httptest.NewRecorder() testHandler(t).ServeHTTP(w, r) if w.Code != http.StatusNotFound { t.Fatalf("status %d", w.Code) } } func TestDeclarationLanguageSwitcherPreservesQuery(t *testing.T) { r := httptest.NewRequest(http.MethodGet, "/declaration?mode=article&textExtent=partial&textReview=expert&coverImageExtent=partial&coverImageReview=editorial&lang=de&assurance=selfDeclared", nil) w := httptest.NewRecorder() testHandler(t).ServeHTTP(w, r) if w.Code != http.StatusOK { t.Fatalf("status %d: %s", w.Code, w.Body.String()) } body := w.Body.String() for _, expected := range []string{ `id="declaration-language"`, `lang=en`, `textExtent=partial`, `textReview=expert`, `coverImageExtent=partial`, `hreflang="en"`, `hreflang="x-default"`, } { if !strings.Contains(body, expected) { t.Fatalf("language switcher missing %q", expected) } } if !strings.Contains(body, `