Files
RenewCMS/test/site_media_acceptance_test.go
T

145 lines
4.9 KiB
Go

package test
import (
"RenewCMS/internal/domain/article"
"encoding/json"
"net/http"
"strconv"
"testing"
)
type mediaListBody struct {
Items []struct {
ID uint32 `json:"id"`
UsedIn int `json:"used_in"`
} `json:"items"`
Counts struct {
Unused int `json:"unused"`
} `json:"counts"`
}
func (e *siteEnv) useImageOnSite(siteID uint32, imageID uint32) {
s := e.sites.sites[siteID]
s.DefaultSocialImageID = idPointer(imageID)
e.sites.sites[siteID] = s
}
func (e *siteEnv) seedDuplicates() {
e.seedBanner(5, "banner.png", "samehash")
e.seedBanner(6, "banner-copy.png", "samehash")
}
func TestSitesMediaUsage(t *testing.T) {
t.Run("An image used as a default social image is counted as used", func(t *testing.T) {
e := newSiteEnvWithShop(t)
e.seedBanner(5, "banner.png", "hash")
e.useImageOnSite(siteShopID, 5)
rec := e.owner(t, http.MethodGet, "/v1/media/", "")
unused := e.owner(t, http.MethodGet, "/v1/media/?filter=unused", "")
var list, unusedList mediaListBody
_ = json.Unmarshal(rec.Body.Bytes(), &list)
_ = json.Unmarshal(unused.Body.Bytes(), &unusedList)
if len(list.Items) != 1 || list.Items[0].UsedIn != 1 || list.Counts.Unused != 0 || len(unusedList.Items) != 0 {
t.Errorf("list %s, unused %s", rec.Body.String(), unused.Body.String())
}
})
t.Run("Deleting the image clears the site's field", func(t *testing.T) {
e := newSiteEnvWithShop(t)
e.seedBanner(5, "banner.png", "hash")
e.useImageOnSite(siteShopID, 5)
rec := e.owner(t, http.MethodDelete, "/v1/media/5", "")
if rec.Code != http.StatusNoContent || e.sites.sites[siteShopID].DefaultSocialImageID != nil {
t.Errorf("status %d, image %v", rec.Code, e.sites.sites[siteShopID].DefaultSocialImageID)
}
})
t.Run("A failed image deletion keeps the site's field", func(t *testing.T) {
e := newSiteEnvWithShop(t)
e.seedBanner(5, "banner.png", "hash")
e.useImageOnSite(siteShopID, 5)
e.images.failDeleteFor = map[uint32]error{5: errRepositoryFailure}
rec := e.owner(t, http.MethodDelete, "/v1/media/5", "")
if rec.Code != http.StatusInternalServerError || e.sites.sites[siteShopID].DefaultSocialImageID == nil {
t.Errorf("status %d, image %v", rec.Code, e.sites.sites[siteShopID].DefaultSocialImageID)
}
})
t.Run("Merging copies repoints the site", func(t *testing.T) {
e := newSiteEnvWithShop(t)
e.seedDuplicates()
e.useImageOnSite(siteShopID, 6)
rec := e.owner(t, http.MethodPost, "/v1/media/merge", `{"keep_id": 5, "merge_ids": [6]}`)
var body map[string]int
_ = json.Unmarshal(rec.Body.Bytes(), &body)
kept := e.sites.sites[siteShopID].DefaultSocialImageID
if rec.Code != http.StatusOK || body["sites_updated"] != 1 || kept == nil || *kept != 5 {
t.Errorf("status %d, body %s, image %v", rec.Code, rec.Body.String(), kept)
}
})
t.Run("Purge repoints sites the same way", func(t *testing.T) {
e := newSiteEnvWithShop(t)
e.seedDuplicates()
e.articles.articles[1] = articleUsingImage(5)
e.useImageOnSite(siteShopID, 6)
rec := e.owner(t, http.MethodPost, "/v1/media/purge", "")
var body map[string]int
_ = json.Unmarshal(rec.Body.Bytes(), &body)
kept := e.sites.sites[siteShopID].DefaultSocialImageID
if rec.Code != http.StatusOK || body["sites_updated"] != 1 || kept == nil || *kept != 5 {
t.Errorf("status %d, body %s, image %v", rec.Code, rec.Body.String(), kept)
}
})
t.Run("A failed purge group leaves the site pointing at an existing image", func(t *testing.T) {
e := newSiteEnvWithShop(t)
e.seedDuplicates()
e.articles.articles[1] = articleUsingImage(5)
e.useImageOnSite(siteShopID, 6)
e.images.failDeleteFor = map[uint32]error{6: errRepositoryFailure}
rec := e.owner(t, http.MethodPost, "/v1/media/purge", "")
referenced := e.sites.sites[siteShopID].DefaultSocialImageID
if rec.Code != http.StatusOK || referenced == nil {
t.Fatalf("status %d, image %v", rec.Code, referenced)
}
if _, exists := e.images.images[*referenced]; !exists {
t.Errorf("the site points at the missing image %d", *referenced)
}
})
t.Run("The usage lookup stays an array and later gains additive keys", func(t *testing.T) {
e := newSiteEnvWithShop(t)
e.seedBanner(5, "banner.png", "hash")
e.useImageOnSite(siteShopID, 5)
e.articles.articles[1] = articleUsingImage(5)
rec := e.owner(t, http.MethodGet, "/v1/media/5/usage", "")
var items []map[string]any
if err := json.Unmarshal(rec.Body.Bytes(), &items); err != nil || rec.Code != http.StatusOK || len(items) != 2 {
t.Fatalf("status %d, body %s", rec.Code, rec.Body.String())
}
first := items[0]
if first["id"] != float64(1) || first["title"] != "Spring release" || first["published"] != true || first["type"] != "article" {
t.Errorf("the article item lost a key: %v", first)
}
})
}
func articleUsingImage(imageID uint32) article.Article {
return article.Article{ID: 1, Title: "Spring release", Body: `<img src="` + producersBannerPath + strconv.Itoa(int(imageID)) + `.png">`, IsOnline: true, SiteID: siteMainID}
}