refac: missing mutation tests, spa specs, checks shown to pass, touch targets, catalogue entry, production code

This commit is contained in:
Florian Sylvain committed 2026-11-04 03:04:35 +01:00
1 parent 7c15206170
commit 3e02e14da4
48 files changed
+2173 -83

No files matched your search

+49 -5
View File
@@ -14,6 +14,7 @@ import (
"sort"
"strconv"
"strings"
"sync"
"testing"
"time"
@@ -21,6 +22,7 @@ import (
)
type mockSiteRepo struct {
mu sync.Mutex
sites map[uint32]site.Site
articles *mockArticleRepo
nextID uint32
@@ -36,7 +38,12 @@ type mockSiteRepo struct {
}
func (m *mockSiteRepo) LockSite(id uint32) error {
m.mu.Lock()
defer m.mu.Unlock()
m.lockedSites = append(m.lockedSites, id)
if len(m.lockedSites) > runawayLockCalls {
return errRunawayLocking
}
if m.busy {
return transaction.ErrLockContention
}
@@ -44,13 +51,18 @@ func (m *mockSiteRepo) LockSite(id uint32) error {
}
func (m *mockSiteRepo) TryLockSites(ids []uint32) error {
m.mu.Lock()
defer m.mu.Unlock()
m.tryLocked = append(m.tryLocked, slices.Clone(ids))
if len(m.tryLocked) > runawayLockCalls {
return errRunawayLocking
}
if m.busy {
return transaction.ErrLockContention
}
if hook := m.afterTryLock; hook != nil {
m.afterTryLock = nil
hook()
outsideLock(&m.mu, hook)
}
return nil
}
@@ -98,9 +110,15 @@ func (m *mockSiteRepo) defaults() []uint32 {
}
func (m *mockSiteRepo) List() ([]site.Site, error) {
m.mu.Lock()
defer m.mu.Unlock()
if err := m.fail.trigger("List"); err != nil {
return nil, err
}
return m.sortedSites(), nil
}
func (m *mockSiteRepo) sortedSites() []site.Site {
result := make([]site.Site, 0, len(m.sites))
for _, s := range m.sites {
result = append(result, m.withCount(s))
@@ -115,17 +133,19 @@ func (m *mockSiteRepo) List() ([]site.Site, error) {
}
return result[i].ID < result[j].ID
})
return result, nil
return result
}
func (m *mockSiteRepo) Find(query site.ListQuery) (site.Page, error) {
m.mu.Lock()
defer m.mu.Unlock()
if err := m.fail.trigger("Find"); err != nil {
return site.Page{}, err
}
all, err := m.List()
if err != nil {
if err := m.fail.trigger("List"); err != nil {
return site.Page{}, err
}
all := m.sortedSites()
needle := foldArticleSearch(strings.TrimSpace(query.Q))
matching := []site.Site{}
for _, s := range all {
@@ -142,6 +162,8 @@ func (m *mockSiteRepo) Find(query site.ListQuery) (site.Page, error) {
}
func (m *mockSiteRepo) Get(id uint32) (site.Site, error) {
m.mu.Lock()
defer m.mu.Unlock()
if err := m.fail.trigger("Get"); err != nil {
return site.Site{}, err
}
@@ -153,6 +175,8 @@ func (m *mockSiteRepo) Get(id uint32) (site.Site, error) {
}
func (m *mockSiteRepo) GetByKey(key string) (site.Site, error) {
m.mu.Lock()
defer m.mu.Unlock()
if err := m.fail.trigger("GetByKey"); err != nil {
return site.Site{}, err
}
@@ -165,6 +189,8 @@ func (m *mockSiteRepo) GetByKey(key string) (site.Site, error) {
}
func (m *mockSiteRepo) GetDefault() (site.Site, error) {
m.mu.Lock()
defer m.mu.Unlock()
if err := m.fail.trigger("GetDefault"); err != nil {
return site.Site{}, err
}
@@ -175,6 +201,8 @@ func (m *mockSiteRepo) GetDefault() (site.Site, error) {
}
func (m *mockSiteRepo) Create(s site.Site) (site.Site, error) {
m.mu.Lock()
defer m.mu.Unlock()
m.createCalls++
if err := m.fail.trigger("Create"); err != nil {
return site.Site{}, err
@@ -192,6 +220,8 @@ func (m *mockSiteRepo) Create(s site.Site) (site.Site, error) {
}
func (m *mockSiteRepo) Update(s site.Site) (site.Site, error) {
m.mu.Lock()
defer m.mu.Unlock()
if err := m.fail.trigger("Update"); err != nil {
return site.Site{}, err
}
@@ -207,6 +237,8 @@ func (m *mockSiteRepo) Update(s site.Site) (site.Site, error) {
}
func (m *mockSiteRepo) SetDefault(id uint32) (site.Site, error) {
m.mu.Lock()
defer m.mu.Unlock()
m.setDefaultCalls++
if _, ok := m.sites[id]; !ok {
return site.Site{}, site.ErrSiteNotFound
@@ -227,6 +259,8 @@ func (m *mockSiteRepo) SetDefault(id uint32) (site.Site, error) {
}
func (m *mockSiteRepo) DeleteMovingArticles(id uint32, reassignTo *uint32) error {
m.mu.Lock()
defer m.mu.Unlock()
m.deleteCalls++
m.deleteReassignments = append(m.deleteReassignments, reassignTo)
if err := m.fail.trigger("DeleteMovingArticles"); err != nil {
@@ -258,6 +292,8 @@ func (m *mockSiteRepo) DeleteMovingArticles(id uint32, reassignTo *uint32) error
}
func (m *mockSiteRepo) ClearImage(imageID uint32) ([]uint32, error) {
m.mu.Lock()
defer m.mu.Unlock()
if err := m.fail.trigger("ClearImage"); err != nil {
return nil, err
}
@@ -274,6 +310,8 @@ func (m *mockSiteRepo) ClearImage(imageID uint32) ([]uint32, error) {
}
func (m *mockSiteRepo) AssignImage(siteIDs []uint32, imageID uint32) error {
m.mu.Lock()
defer m.mu.Unlock()
for _, id := range siteIDs {
s := m.sites[id]
assigned := imageID
@@ -284,6 +322,8 @@ func (m *mockSiteRepo) AssignImage(siteIDs []uint32, imageID uint32) error {
}
func (m *mockSiteRepo) RepointImage(fromImageIDs []uint32, toImageID uint32) (int, error) {
m.mu.Lock()
defer m.mu.Unlock()
if err := m.fail.trigger("RepointImage"); err != nil {
return 0, err
}
@@ -338,7 +378,7 @@ func newSiteEnv(t *testing.T) *siteEnv {
c.RunPurgeUseCase = useCases.NewRunPurgeUseCase(p.images, p.articles, mergeMedia, newMockPurgeSettingsRepo(), func() time.Time { return p.now }, log.New(io.Discard, "", 0), recorder, sites, plainAuthors())
c.ListSitesUseCase = useCases.NewListSitesUseCase(sites)
c.CreateSiteUseCase = useCases.NewCreateSiteUseCase(sites, p.images, recorder)
c.UpdateSiteUseCase = useCases.NewUpdateSiteUseCase(sites, p.images, recorder, p.articles)
c.UpdateSiteUseCase = useCases.NewUpdateSiteUseCase(sites, p.images, recorder, siteWriteTransactor(sites, p.articles))
c.SetDefaultSiteUseCase = useCases.NewSetDefaultSiteUseCase(sites, recorder)
c.DeleteSiteUseCase = useCases.NewDeleteSiteUseCase(sites, recorder)
router := chi.NewRouter()
@@ -427,3 +467,7 @@ func plainSites() *mockSiteRepo {
sites.seed(1, "Default", "default", true)
return sites
}
func siteWriteTransactor(sites site.Repository, seo article.SEOIndex) transaction.Transactor {
return repositoriesTransactor{transaction.Repositories{Sites: sites, ArticleSEO: seo}}
}