refac: missing mutation tests, spa specs, checks shown to pass, touch targets, catalogue entry, production code
This commit is contained in:
1 parent
7c15206170
commit
3e02e14da4
48 files changed
+2173
-83
No files matched your search
+63
-5
@@ -10,6 +10,7 @@ import (
|
||||
"slices"
|
||||
"sort"
|
||||
"strings"
|
||||
"sync"
|
||||
"testing"
|
||||
"unicode"
|
||||
|
||||
@@ -19,6 +20,7 @@ import (
|
||||
)
|
||||
|
||||
type mockArticleRepo struct {
|
||||
mu sync.Mutex
|
||||
articles map[uint32]article.Article
|
||||
failUpdateBodyFor map[uint32]error
|
||||
nextID uint32
|
||||
@@ -64,6 +66,8 @@ func (m *mockArticleRepo) withAuthors(a article.Article) article.Article {
|
||||
}
|
||||
|
||||
func (m *mockArticleRepo) ListForAccount(creatorID uint32, authorID *uint32) ([]article.Article, error) {
|
||||
m.mu.Lock()
|
||||
defer m.mu.Unlock()
|
||||
if err := m.fail.trigger("ListForAccount"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -91,6 +95,8 @@ func (m *mockArticleRepo) sortedIds() []uint32 {
|
||||
}
|
||||
|
||||
func (m *mockArticleRepo) FindByFilters(filters article.Filters) ([]article.Article, error) {
|
||||
m.mu.Lock()
|
||||
defer m.mu.Unlock()
|
||||
if err := m.fail.trigger("FindByFilters"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -106,6 +112,8 @@ func (m *mockArticleRepo) FindByFilters(filters article.Filters) ([]article.Arti
|
||||
}
|
||||
|
||||
func (m *mockArticleRepo) FindPage(filters article.Filters) (article.PageResult, error) {
|
||||
m.mu.Lock()
|
||||
defer m.mu.Unlock()
|
||||
m.listCalls++
|
||||
if err := m.fail.trigger("FindPage"); err != nil {
|
||||
return article.PageResult{}, err
|
||||
@@ -159,6 +167,8 @@ func (m *mockArticleRepo) FindPage(filters article.Filters) (article.PageResult,
|
||||
}
|
||||
|
||||
func (m *mockArticleRepo) CountByVisibility(onlineOnly bool) (article.Counts, error) {
|
||||
m.mu.Lock()
|
||||
defer m.mu.Unlock()
|
||||
if err := m.fail.trigger("CountByVisibility"); err != nil {
|
||||
return article.Counts{}, err
|
||||
}
|
||||
@@ -175,6 +185,8 @@ func (m *mockArticleRepo) CountByVisibility(onlineOnly bool) (article.Counts, er
|
||||
}
|
||||
|
||||
func (m *mockArticleRepo) CountVersions(filters article.Filters) (article.Counts, error) {
|
||||
m.mu.Lock()
|
||||
defer m.mu.Unlock()
|
||||
m.listCalls++
|
||||
if err := m.fail.trigger("CountVersions"); err != nil {
|
||||
return article.Counts{}, err
|
||||
@@ -195,26 +207,36 @@ func (m *mockArticleRepo) CountVersions(filters article.Filters) (article.Counts
|
||||
}
|
||||
|
||||
func (m *mockArticleRepo) FindStoryPage(filters article.StoryFilters) (article.StoryPage, error) {
|
||||
m.mu.Lock()
|
||||
defer m.mu.Unlock()
|
||||
m.listCalls++
|
||||
return article.StoryPage{Refs: []article.StoryRef{}}, m.fail.trigger("FindStoryPage")
|
||||
}
|
||||
|
||||
func (m *mockArticleRepo) CountStories(filters article.StoryFilters) (article.StoryCounts, error) {
|
||||
m.mu.Lock()
|
||||
defer m.mu.Unlock()
|
||||
m.listCalls++
|
||||
return article.StoryCounts{}, m.fail.trigger("CountStories")
|
||||
}
|
||||
|
||||
func (m *mockArticleRepo) ListByStories(storyIDs []uint32, readable article.StoryFilters) ([]article.Article, error) {
|
||||
m.mu.Lock()
|
||||
defer m.mu.Unlock()
|
||||
m.listCalls++
|
||||
return []article.Article{}, m.fail.trigger("ListByStories")
|
||||
}
|
||||
|
||||
func (m *mockArticleRepo) FindTitleMatches(q string, readable article.StoryFilters) ([]uint32, error) {
|
||||
m.mu.Lock()
|
||||
defer m.mu.Unlock()
|
||||
m.listCalls++
|
||||
return []uint32{}, m.fail.trigger("FindTitleMatches")
|
||||
}
|
||||
|
||||
func (m *mockArticleRepo) CountVisibleTo(userID uint32) (article.Counts, error) {
|
||||
m.mu.Lock()
|
||||
defer m.mu.Unlock()
|
||||
if err := m.fail.trigger("CountVisibleTo"); err != nil {
|
||||
return article.Counts{}, err
|
||||
}
|
||||
@@ -270,11 +292,13 @@ func foldArticleSearch(value string) string {
|
||||
}
|
||||
|
||||
func (m *mockArticleRepo) Get(id uint32) (article.Article, error) {
|
||||
m.mu.Lock()
|
||||
defer m.mu.Unlock()
|
||||
if err := m.fail.trigger("Get"); err != nil {
|
||||
return article.Article{}, err
|
||||
}
|
||||
if m.onGet != nil {
|
||||
if err := m.onGet(id); err != nil {
|
||||
if err := outsideLockErr(&m.mu, func() error { return m.onGet(id) }); err != nil {
|
||||
return article.Article{}, err
|
||||
}
|
||||
}
|
||||
@@ -286,6 +310,8 @@ func (m *mockArticleRepo) Get(id uint32) (article.Article, error) {
|
||||
}
|
||||
|
||||
func (m *mockArticleRepo) GetByName(name string) (article.Article, error) {
|
||||
m.mu.Lock()
|
||||
defer m.mu.Unlock()
|
||||
if err := m.fail.trigger("GetByName"); err != nil {
|
||||
return article.Article{}, err
|
||||
}
|
||||
@@ -299,6 +325,8 @@ func (m *mockArticleRepo) GetByName(name string) (article.Article, error) {
|
||||
}
|
||||
|
||||
func (m *mockArticleRepo) GetAll() ([]article.Article, error) {
|
||||
m.mu.Lock()
|
||||
defer m.mu.Unlock()
|
||||
result := make([]article.Article, 0)
|
||||
for _, id := range m.sortedIds() {
|
||||
result = append(result, m.articles[id])
|
||||
@@ -319,6 +347,8 @@ func (m *mockArticleRepo) slugUsedOn(siteID uint32, lang string, slug string, ex
|
||||
}
|
||||
|
||||
func (m *mockArticleRepo) SlugTaken(siteID uint32, lang string, slug string, exceptID uint32) (bool, error) {
|
||||
m.mu.Lock()
|
||||
defer m.mu.Unlock()
|
||||
if err := m.fail.trigger("SlugTaken"); err != nil {
|
||||
return false, err
|
||||
}
|
||||
@@ -326,6 +356,8 @@ func (m *mockArticleRepo) SlugTaken(siteID uint32, lang string, slug string, exc
|
||||
}
|
||||
|
||||
func (m *mockArticleRepo) FindByImage(imageID uint32) ([]article.Article, error) {
|
||||
m.mu.Lock()
|
||||
defer m.mu.Unlock()
|
||||
if err := m.fail.trigger("FindByImage"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -339,6 +371,8 @@ func (m *mockArticleRepo) FindByImage(imageID uint32) ([]article.Article, error)
|
||||
}
|
||||
|
||||
func (m *mockArticleRepo) ClearImage(imageID uint32) (article.ImageReferences, error) {
|
||||
m.mu.Lock()
|
||||
defer m.mu.Unlock()
|
||||
if err := m.fail.trigger("ClearImage"); err != nil {
|
||||
return article.ImageReferences{}, err
|
||||
}
|
||||
@@ -359,6 +393,8 @@ func (m *mockArticleRepo) ClearImage(imageID uint32) (article.ImageReferences, e
|
||||
}
|
||||
|
||||
func (m *mockArticleRepo) RestoreImage(references article.ImageReferences, imageID uint32) error {
|
||||
m.mu.Lock()
|
||||
defer m.mu.Unlock()
|
||||
for _, id := range references.Cover {
|
||||
a := m.articles[id]
|
||||
a.CoverImageID = idPointer(imageID)
|
||||
@@ -373,6 +409,8 @@ func (m *mockArticleRepo) RestoreImage(references article.ImageReferences, image
|
||||
}
|
||||
|
||||
func (m *mockArticleRepo) RepointImage(fromImageIDs []uint32, toImageID uint32) ([]uint32, error) {
|
||||
m.mu.Lock()
|
||||
defer m.mu.Unlock()
|
||||
if err := m.fail.trigger("RepointImage"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -397,10 +435,12 @@ func (m *mockArticleRepo) RepointImage(fromImageIDs []uint32, toImageID uint32)
|
||||
}
|
||||
|
||||
func (m *mockArticleRepo) Create(a article.Article) (article.Article, error) {
|
||||
m.mu.Lock()
|
||||
defer m.mu.Unlock()
|
||||
m.createCalled = true
|
||||
if hook := m.beforeCreate; hook != nil {
|
||||
m.beforeCreate = nil
|
||||
hook()
|
||||
outsideLock(&m.mu, hook)
|
||||
}
|
||||
if err := m.fail.trigger("Create"); err != nil {
|
||||
return article.Article{}, err
|
||||
@@ -439,6 +479,8 @@ func (m *mockArticleRepo) Create(a article.Article) (article.Article, error) {
|
||||
}
|
||||
|
||||
func (m *mockArticleRepo) UpdateBody(id uint32, body string) (article.Article, error) {
|
||||
m.mu.Lock()
|
||||
defer m.mu.Unlock()
|
||||
m.updateBodyIDs = append(m.updateBodyIDs, id)
|
||||
if err := m.fail.trigger("UpdateBody"); err != nil {
|
||||
return article.Article{}, err
|
||||
@@ -474,6 +516,8 @@ func (m *mockArticleRepo) storyHasLanguage(storyID uint32, lang string) bool {
|
||||
}
|
||||
|
||||
func (m *mockArticleRepo) GetByLangSlug(siteID uint32, lang string, slug string) (article.Article, error) {
|
||||
m.mu.Lock()
|
||||
defer m.mu.Unlock()
|
||||
if err := m.fail.trigger("GetByLangSlug"); err != nil {
|
||||
return article.Article{}, err
|
||||
}
|
||||
@@ -486,6 +530,8 @@ func (m *mockArticleRepo) GetByLangSlug(siteID uint32, lang string, slug string)
|
||||
}
|
||||
|
||||
func (m *mockArticleRepo) ListByStory(storyID uint32) ([]article.Article, error) {
|
||||
m.mu.Lock()
|
||||
defer m.mu.Unlock()
|
||||
if err := m.fail.trigger("ListByStory"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -502,12 +548,14 @@ func (m *mockArticleRepo) ListByStory(storyID uint32) ([]article.Article, error)
|
||||
}
|
||||
|
||||
func (m *mockArticleRepo) MoveToSite(ids []uint32, siteID uint32) error {
|
||||
m.mu.Lock()
|
||||
defer m.mu.Unlock()
|
||||
if err := m.fail.trigger("MoveToSite"); err != nil {
|
||||
return err
|
||||
}
|
||||
if hook := m.beforeMove; hook != nil {
|
||||
m.beforeMove = nil
|
||||
hook()
|
||||
outsideLock(&m.mu, hook)
|
||||
}
|
||||
snapshot := maps.Clone(m.articles)
|
||||
for position, id := range ids {
|
||||
@@ -532,6 +580,8 @@ func (m *mockArticleRepo) MoveToSite(ids []uint32, siteID uint32) error {
|
||||
}
|
||||
|
||||
func (m *mockArticleRepo) Update(id uint32, update article.Update) (article.Article, error) {
|
||||
m.mu.Lock()
|
||||
defer m.mu.Unlock()
|
||||
if err := m.fail.trigger("Update"); err != nil {
|
||||
return article.Article{}, err
|
||||
}
|
||||
@@ -541,7 +591,7 @@ func (m *mockArticleRepo) Update(id uint32, update article.Update) (article.Arti
|
||||
}
|
||||
if hook := m.beforeUpdate; hook != nil {
|
||||
m.beforeUpdate = nil
|
||||
hook()
|
||||
outsideLock(&m.mu, hook)
|
||||
a = m.articles[id]
|
||||
}
|
||||
if update.IfRevision != nil && a.EditRevision != *update.IfRevision {
|
||||
@@ -609,6 +659,8 @@ func applySeoUpdate(a *article.Article, update article.Update) {
|
||||
}
|
||||
|
||||
func (m *mockArticleRepo) UpdateIsOnline(id uint32, isOnline bool) (article.Article, error) {
|
||||
m.mu.Lock()
|
||||
defer m.mu.Unlock()
|
||||
if err := m.fail.trigger("UpdateIsOnline"); err != nil {
|
||||
return article.Article{}, err
|
||||
}
|
||||
@@ -622,6 +674,8 @@ func (m *mockArticleRepo) UpdateIsOnline(id uint32, isOnline bool) (article.Arti
|
||||
}
|
||||
|
||||
func (m *mockArticleRepo) Delete(id uint32) error {
|
||||
m.mu.Lock()
|
||||
defer m.mu.Unlock()
|
||||
if err := m.fail.trigger("Delete"); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -634,6 +688,8 @@ func (m *mockArticleRepo) Delete(id uint32) error {
|
||||
}
|
||||
|
||||
func (m *mockArticleRepo) FindByBodyContaining(filename string) ([]article.Article, error) {
|
||||
m.mu.Lock()
|
||||
defer m.mu.Unlock()
|
||||
if err := m.fail.trigger("FindByBodyContaining"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -645,12 +701,14 @@ func (m *mockArticleRepo) FindByBodyContaining(filename string) ([]article.Artic
|
||||
}
|
||||
}
|
||||
if m.afterFindByBody != nil {
|
||||
defer m.afterFindByBody()
|
||||
defer outsideLock(&m.mu, m.afterFindByBody)
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (m *mockArticleRepo) AssignUnassignedLanguage(siteID uint32, lang string) (int, error) {
|
||||
m.mu.Lock()
|
||||
defer m.mu.Unlock()
|
||||
if err := m.fail.trigger("AssignUnassignedLanguage"); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user