145 lines
4.9 KiB
Go
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}
|
|
}
|