fix: technical debts left by the Sites, Authors and SEO slices, plus backend support for the new Sites and Authors pagination
This commit is contained in:
1 parent
9f4ce426a8
commit
daf3594316
86 files changed
+4223
-1485
No files matched your search
@@ -0,0 +1,123 @@
|
||||
package test
|
||||
|
||||
import (
|
||||
"RenewCMS/api/pkg/apperr"
|
||||
"RenewCMS/internal/domain/user"
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"reflect"
|
||||
"testing"
|
||||
)
|
||||
|
||||
const mediaGetEditorID = 9
|
||||
|
||||
func newMediaGetEnv(t *testing.T) *siteEnv {
|
||||
t.Helper()
|
||||
e := newSiteEnvWithMain(t)
|
||||
e.users.users[mediaGetEditorID] = user.User{ID: mediaGetEditorID, Username: "editor", Email: "editor@example.com", IsVerified: true, Role: user.Role("editor")}
|
||||
e.seedImageRecord(5)
|
||||
return e
|
||||
}
|
||||
|
||||
func (e *siteEnv) seedImageRecord(id uint32) {
|
||||
e.seedImage(id)
|
||||
img := e.images.images[id]
|
||||
img.Size, img.Width, img.Height, img.SHA256 = 2048, 800, 600, hashA
|
||||
e.images.images[id] = img
|
||||
e.seedSpring(1, `<img src="`+img.Path+`">`, true)
|
||||
}
|
||||
|
||||
func TestMediaGetOne(t *testing.T) {
|
||||
t.Run("Who can read one image", func(t *testing.T) {
|
||||
cases := []struct {
|
||||
credentials string
|
||||
send func(e *siteEnv) *httptest.ResponseRecorder
|
||||
status int
|
||||
}{
|
||||
{"the owner's jwt cookie", func(e *siteEnv) *httptest.ResponseRecorder {
|
||||
return e.as(t, apiKeyOwnerId, http.MethodGet, "/v1/media/5", "")
|
||||
}, http.StatusOK},
|
||||
{"a verified admin's jwt cookie", func(e *siteEnv) *httptest.ResponseRecorder {
|
||||
return e.as(t, apiKeyDevId, http.MethodGet, "/v1/media/5", "")
|
||||
}, http.StatusOK},
|
||||
{"a verified account with another role", func(e *siteEnv) *httptest.ResponseRecorder {
|
||||
return e.as(t, mediaGetEditorID, http.MethodGet, "/v1/media/5", "")
|
||||
}, http.StatusOK},
|
||||
{"a valid API key", func(e *siteEnv) *httptest.ResponseRecorder {
|
||||
raw, _ := e.issueKey(apiKeyDevId, "Deploy bot")
|
||||
return e.asKey(t, raw, http.MethodGet, "/v1/media/5", "")
|
||||
}, http.StatusOK},
|
||||
{"an unverified account's jwt cookie", func(e *siteEnv) *httptest.ResponseRecorder {
|
||||
return e.as(t, apiKeyQuinnId, http.MethodGet, "/v1/media/5", "")
|
||||
}, http.StatusForbidden},
|
||||
{"no credentials", func(e *siteEnv) *httptest.ResponseRecorder {
|
||||
return e.anonymous(t, http.MethodGet, "/v1/media/5", "")
|
||||
}, http.StatusUnauthorized},
|
||||
}
|
||||
for _, c := range cases {
|
||||
t.Run(c.credentials, func(t *testing.T) {
|
||||
e := newMediaGetEnv(t)
|
||||
if rec := c.send(e); rec.Code != c.status {
|
||||
t.Errorf("status = %d, expected %d", rec.Code, c.status)
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("The item has the shape of the list", func(t *testing.T) {
|
||||
e := newMediaGetEnv(t)
|
||||
single := e.owner(t, http.MethodGet, "/v1/media/5", "")
|
||||
listed := e.owner(t, http.MethodGet, "/v1/media/", "")
|
||||
var one map[string]any
|
||||
var page struct {
|
||||
Items []map[string]any `json:"items"`
|
||||
}
|
||||
if err := json.Unmarshal(single.Body.Bytes(), &one); err != nil {
|
||||
t.Fatalf("decode item: %v", err)
|
||||
}
|
||||
if err := json.Unmarshal(listed.Body.Bytes(), &page); err != nil {
|
||||
t.Fatalf("decode list: %v", err)
|
||||
}
|
||||
var expected map[string]any
|
||||
for _, item := range page.Items {
|
||||
if item["id"] == 5.0 {
|
||||
expected = item
|
||||
}
|
||||
}
|
||||
if expected == nil || !reflect.DeepEqual(one, expected) {
|
||||
t.Fatalf("item %v, list element %v", one, expected)
|
||||
}
|
||||
if one["used_in"] != 1.0 || one["size"] != 2048.0 {
|
||||
t.Errorf("item = %v", one)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("A missing image is not found", func(t *testing.T) {
|
||||
e := newMediaGetEnv(t)
|
||||
rec := e.owner(t, http.MethodGet, "/v1/media/999", "")
|
||||
expectSiteStatusAndBody(t, rec, http.StatusNotFound, apperr.ImageNotFoundErrorMessage)
|
||||
})
|
||||
|
||||
t.Run("A malformed id is refused", func(t *testing.T) {
|
||||
for _, id := range []string{"abc", "-1", "4294967296", "1.5"} {
|
||||
e := newMediaGetEnv(t)
|
||||
rec := e.owner(t, http.MethodGet, "/v1/media/"+id, "")
|
||||
expectSiteStatusAndBody(t, rec, http.StatusBadRequest, apperr.IdUint32ErrorMessage)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("Reading one image records nothing", func(t *testing.T) {
|
||||
e := newMediaGetEnv(t)
|
||||
e.owner(t, http.MethodGet, "/v1/media/5", "")
|
||||
e.noEvent(t)
|
||||
})
|
||||
|
||||
t.Run("The route does not shadow the usage route", func(t *testing.T) {
|
||||
e := newMediaGetEnv(t)
|
||||
rec := e.owner(t, http.MethodGet, "/v1/media/5/usage", "")
|
||||
if rec.Code != http.StatusOK || rec.Body.String() == "" {
|
||||
t.Fatalf("status %d", rec.Code)
|
||||
}
|
||||
})
|
||||
}
|
||||
Reference in new issue
Block a user