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
@@ -0,0 +1,102 @@
|
||||
package test
|
||||
|
||||
import (
|
||||
"RenewCMS/internal/domain/article"
|
||||
"RenewCMS/internal/domain/author"
|
||||
"errors"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestArticleTitleLengthBounds(t *testing.T) {
|
||||
cases := []struct {
|
||||
runes int
|
||||
valid bool
|
||||
}{
|
||||
{article.MinTitleRunes - 1, false},
|
||||
{article.MinTitleRunes, true},
|
||||
{article.MaxTitleRunes, true},
|
||||
{article.MaxTitleRunes + 1, false},
|
||||
}
|
||||
for _, c := range cases {
|
||||
err := article.ValidateTitle(strings.Repeat("é", c.runes))
|
||||
if (err == nil) != c.valid || (err != nil && !errors.Is(err, article.ErrInvalidTitle)) {
|
||||
t.Errorf("%d runes: err = %v", c.runes, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestArticleDetailedErrorsMatchTheirSentinel(t *testing.T) {
|
||||
cases := []struct {
|
||||
err error
|
||||
sentinel error
|
||||
}{
|
||||
{&article.RevisionConflictError{Current: 4}, article.ErrRevisionConflict},
|
||||
{&article.LanguageExistsError{ArticleID: 9}, article.ErrLanguageExists},
|
||||
{&article.LanguageNotEnabledError{Missing: []string{"de"}}, article.ErrLanguageNotEnabled},
|
||||
{&article.SlugConflictError{ArticleIDs: []uint32{3}}, article.ErrSlugConflict},
|
||||
}
|
||||
for _, c := range cases {
|
||||
if !errors.Is(c.err, c.sentinel) || c.err.Error() != c.sentinel.Error() {
|
||||
t.Errorf("%T does not match %v", c.err, c.sentinel)
|
||||
}
|
||||
if errors.Is(c.err, article.ErrArticleNotFound) {
|
||||
t.Errorf("%T matches an unrelated sentinel", c.err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestArticleRevisionsMoveByOne(t *testing.T) {
|
||||
opened := article.Article{}.Opened()
|
||||
cases := []struct {
|
||||
impact article.Impact
|
||||
edit, content uint32
|
||||
}{
|
||||
{article.Impact{}, 1, 1},
|
||||
{article.Impact{Edited: true}, 2, 1},
|
||||
{article.Impact{Edited: true, Content: true}, 2, 2},
|
||||
}
|
||||
for _, c := range cases {
|
||||
revised := opened.Revised(c.impact)
|
||||
if revised.EditRevision != c.edit || revised.ContentRevision != c.content {
|
||||
t.Errorf("%+v: edit %d content %d", c.impact, revised.EditRevision, revised.ContentRevision)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestArticleCopiedIntoKeepsAnAuthorList(t *testing.T) {
|
||||
source := article.Article{ID: 7, Body: "<p>Body</p>", ContentRevision: 3}
|
||||
copied := source.CopiedInto(article.Article{Lang: "fr"})
|
||||
if copied.Authors == nil || len(copied.Authors) != 0 {
|
||||
t.Fatalf("authors = %#v", copied.Authors)
|
||||
}
|
||||
if *copied.SourceArticleID != 7 || copied.SourceRevision != 3 || copied.Body != "<p>Body</p>" {
|
||||
t.Fatalf("copied = %+v", copied)
|
||||
}
|
||||
credited := article.Article{Authors: []author.Byline{{}}}.CopiedInto(article.Article{})
|
||||
if len(credited.Authors) != 1 {
|
||||
t.Fatalf("credited authors = %#v", credited.Authors)
|
||||
}
|
||||
}
|
||||
|
||||
func TestArticleStoryFiltersPerLanguage(t *testing.T) {
|
||||
cases := []struct {
|
||||
filters article.StoryFilters
|
||||
want bool
|
||||
}{
|
||||
{article.StoryFilters{Lang: "fr"}, true},
|
||||
{article.StoryFilters{Lang: "fr", Missing: true}, false},
|
||||
{article.StoryFilters{}, false},
|
||||
}
|
||||
for _, c := range cases {
|
||||
if got := c.filters.PerLanguage(); got != c.want {
|
||||
t.Errorf("%+v: PerLanguage = %v", c.filters, got)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestArticleSEOSummaryStale(t *testing.T) {
|
||||
if !(article.SEOSummary{}).Stale() || (article.SEOSummary{Status: article.SEOStatusReady}).Stale() {
|
||||
t.Fatal("only a summary without status is stale")
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user