118 lines
4.6 KiB
Go
118 lines
4.6 KiB
Go
package test
|
|
|
|
import (
|
|
domainArticle "RenewCMS/internal/domain/article"
|
|
"encoding/json"
|
|
"net/http"
|
|
"testing"
|
|
)
|
|
|
|
const (
|
|
localizedArticleID = 12
|
|
localizedArticleStory = 5
|
|
)
|
|
|
|
var legacyListItemKeys = []string{"id", "title", "body", "body_format", "is_online", "site_id", "authors", "created_at", "updated_at", "excerpt", "slug", "seo_status", "seo_suggestions"}
|
|
|
|
var legacyArticleKeys = []string{"id", "title", "body", "is_online", "site_id", "authors", "slug", "excerpt", "seo_title", "seo_description", "cover_image_id", "cover_image_alt", "social_title", "social_description", "social_image_id", "canonical_url", "noindex", "seo_dismissed", "created_at", "updated_at"}
|
|
|
|
func localizedArticle(lang string, online bool) domainArticle.Article {
|
|
return domainArticle.Article{ID: localizedArticleID, Title: "Bonjour le monde", IsOnline: online, CreatedBy: createdByWriterID, Lang: lang, StoryID: localizedArticleStory}
|
|
}
|
|
|
|
func TestArticleLocalizationStorageHTTP(t *testing.T) {
|
|
assertFields := func(t *testing.T, fields map[string]string, lang string, legacyKeys []string) {
|
|
t.Helper()
|
|
if fields["lang"] != `"`+lang+`"` || fields["story_id"] != "5" {
|
|
t.Errorf(`expected lang %q and story_id 5, got lang=%s story_id=%s`, lang, fields["lang"], fields["story_id"])
|
|
}
|
|
for _, key := range legacyKeys {
|
|
if _, present := fields[key]; !present {
|
|
t.Errorf("legacy key %q is missing", key)
|
|
}
|
|
}
|
|
}
|
|
readers := []struct {
|
|
name string
|
|
lang string
|
|
path string
|
|
auth bool
|
|
list bool
|
|
on bool
|
|
}{
|
|
{"GET /v1/article/12 with a valid jwt", "fr-CA", "/v1/article/12", true, false, false},
|
|
{"GET /v1/article/12 with a valid jwt and no language", "", "/v1/article/12", true, false, false},
|
|
{"GET /v1/article/ list item", "fr-CA", "/v1/article/", true, true, false},
|
|
{"public article read of an online article", "fr-CA", "/v1/article/12", false, false, true},
|
|
}
|
|
for _, reader := range readers {
|
|
t.Run("Article reads expose lang and story_id "+reader.name, func(t *testing.T) {
|
|
e, router := newCreatedByEnv(t)
|
|
e.articles.articles[localizedArticleID] = localizedArticle(reader.lang, reader.on)
|
|
var options []activityRequest
|
|
if reader.auth {
|
|
options = append(options, asUser(e, activityOwnerID))
|
|
}
|
|
rec := sendCreatedBy(router, http.MethodGet, reader.path, "", options...)
|
|
if rec.Code != http.StatusOK {
|
|
t.Fatalf("status %d: %s", rec.Code, rec.Body)
|
|
}
|
|
var fields map[string]string
|
|
if reader.list {
|
|
for _, item := range decodeArticleItems(t, rec.Body.Bytes()) {
|
|
if string(item["id"]) == "12" {
|
|
fields = rawFields(item)
|
|
}
|
|
}
|
|
} else {
|
|
fields = rawFields(decodeArticleFields(t, rec.Body.Bytes()))
|
|
}
|
|
if fields == nil {
|
|
t.Fatalf("article 12 not found in %s", rec.Body)
|
|
}
|
|
legacyKeys := legacyArticleKeys
|
|
if reader.list {
|
|
legacyKeys = legacyListItemKeys
|
|
}
|
|
assertFields(t, fields, reader.lang, legacyKeys)
|
|
})
|
|
}
|
|
|
|
t.Run("PATCH ignores lang and story_id", func(t *testing.T) {
|
|
e, router := newCreatedByEnv(t)
|
|
e.articles.articles[localizedArticleID] = localizedArticle("fr-CA", false)
|
|
|
|
patched := sendCreatedBy(router, http.MethodPatch, "/v1/article/12", `{"excerpt":"Short","lang":"en","story_id":99}`, asUser(e, activityOwnerID))
|
|
|
|
if patched.Code != http.StatusOK {
|
|
t.Fatalf("status %d: %s", patched.Code, patched.Body)
|
|
}
|
|
assertFields(t, rawFields(decodeArticleFields(t, patched.Body.Bytes())), "fr-CA", legacyArticleKeys)
|
|
if stored := e.articles.articles[localizedArticleID]; stored.Lang != "fr-CA" || stored.StoryID != localizedArticleStory {
|
|
t.Errorf("the stored language or story changed: %+v", stored)
|
|
}
|
|
})
|
|
t.Run("A patch carrying only lang and story_id is refused like a patch with no updatable field", func(t *testing.T) {
|
|
e, router := newCreatedByEnv(t)
|
|
e.articles.articles[localizedArticleID] = localizedArticle("fr-CA", false)
|
|
|
|
empty := sendCreatedBy(router, http.MethodPatch, "/v1/article/12", `{}`, asUser(e, activityOwnerID))
|
|
localizationOnly := sendCreatedBy(router, http.MethodPatch, "/v1/article/12", `{"lang":"en","story_id":99}`, asUser(e, activityOwnerID))
|
|
|
|
if empty.Code != http.StatusBadRequest || localizationOnly.Code != empty.Code {
|
|
t.Fatalf("expected both to be refused with 400, got %d and %d", empty.Code, localizationOnly.Code)
|
|
}
|
|
if stored := e.articles.articles[localizedArticleID]; stored.Lang != "fr-CA" || stored.StoryID != localizedArticleStory {
|
|
t.Errorf("the stored language or story changed: %+v", stored)
|
|
}
|
|
})
|
|
}
|
|
|
|
func rawFields(object map[string]json.RawMessage) map[string]string {
|
|
flat := make(map[string]string, len(object))
|
|
for key, value := range object {
|
|
flat[key] = string(value)
|
|
}
|
|
return flat
|
|
}
|