package test import ( "RenewCMS/internal/domain/article" "RenewCMS/internal/domain/localization" "RenewCMS/internal/domain/site" "RenewCMS/internal/infrastructure/useCases" "errors" "math" "slices" "strings" "testing" ) func TestLocalizationDomainRules(t *testing.T) { t.Run("A site has exactly one default language", func(t *testing.T) { cases := []struct { name string rows []localization.Row err error }{ {"none", []localization.Row{{Tag: "en"}}, localization.ErrSingleDefault}, {"one", []localization.Row{{Tag: "en", IsDefault: true}, {Tag: "fr"}}, nil}, {"two", []localization.Row{{Tag: "en", IsDefault: true}, {Tag: "fr", IsDefault: true}}, localization.ErrSingleDefault}, } for _, c := range cases { if err := localization.RequireSingleDefault(c.rows); !errors.Is(err, c.err) { t.Errorf("%s: %v, want %v", c.name, err, c.err) } } }) t.Run("Only an enabled assigned language takes part in the public surfaces", func(t *testing.T) { rows := []localization.Row{{Tag: "en", IsDefault: true, Enabled: true, Confirmed: true}, {Tag: "es"}} if !localization.PublicTag(rows, "en") || localization.PublicTag(rows, "es") || localization.PublicTag(rows, "") || localization.PublicTag(rows, "de") { t.Error("public languages are the enabled rows only") } }) t.Run("The site text belongs to the default language and to unassigned versions", func(t *testing.T) { if !localization.SiteTextAllowed("en", "en") || !localization.SiteTextAllowed("en", "") || localization.SiteTextAllowed("en", "fr") { t.Error("site text rule") } if localization.ConfirmedDefaultTag([]localization.Row{{Tag: "en", IsDefault: true}}) != "" { t.Error("an unconfirmed default is no default") } }) t.Run("The title template placeholders have one source", func(t *testing.T) { if site.DefaultTitleTemplate != site.TitlePlaceholder+" | "+site.SitePlaceholder { t.Errorf("default template %q", site.DefaultTitleTemplate) } }) t.Run("A page window never overflows", func(t *testing.T) { cases := []struct { page, size, offset, limit int }{ {1, 25, 0, 25}, {3, 5, 10, 5}, {0, 5, 0, 5}, {math.MinInt, 5, 0, 5}, {math.MaxInt, 25, math.MaxInt, 25}, {2, -1, 0, 0}, } for _, c := range cases { offset, limit := article.Filters{Page: c.page, Size: c.size}.Window() if offset != c.offset || limit != c.limit { t.Errorf("page %d size %d: %d %d", c.page, c.size, offset, limit) } } }) } func TestCheckArticleSEOIsLanguageAware(t *testing.T) { repo := newMockArticleRepo() sites := newMockSiteRepo(repo) journal := sites.seed(1, "Journal", "journal", true) journal.DefaultDescription = strings.Repeat("Renovation notes. ", 6) sites.sites[1] = journal rows := newFakeLocalizationStore(repo) rows.rows[1] = []localization.Row{{Tag: "en", IsDefault: true, Enabled: true, Confirmed: true}, {Tag: "fr", Enabled: true}} repo.articles[1] = article.Article{ID: 1, Title: "Harbour", SiteID: 1, Lang: "en", SEODismissed: []string{}} repo.articles[2] = article.Article{ID: 2, Title: "Port", SiteID: 1, Lang: "fr", SEODismissed: []string{}} check := useCases.NewCheckArticleSEOUseCase(repo, sites, newMockImageRepo(), rows) codes := func(id uint32) []string { result, err := check.Check(id, ownerCaller(1), useCases.CheckArticleSEOCommand{}) if err != nil { t.Fatal(err) } found := []string{} for _, suggestion := range result.Suggestions { found = append(found, suggestion.Code) } return found } if slices.Contains(codes(1), article.DismissDescShort) { t.Error("the default language uses the site description") } if !slices.Contains(codes(2), article.DismissDescShort) { t.Error("another language never uses the site description") } }