package book import ( "strings" "testing" "github.com/flipped-aurora/gin-vue-admin/server/model/book" commonModel "github.com/flipped-aurora/gin-vue-admin/server/model/common" ) func TestValidateBookRejectsOutOfRangeAggregates(t *testing.T) { tests := []struct { name string item book.Book want string }{ {name: "negative hot score", item: book.Book{HotScore: -1}, want: "hotScore"}, {name: "rating below zero", item: book.Book{Rating: -0.1}, want: "rating"}, {name: "rating above ten", item: book.Book{Rating: 10.1}, want: "rating"}, {name: "negative comment count", item: book.Book{CommentCount: -1}, want: "commentCount"}, {name: "negative word count", item: book.Book{WordCount: -1}, want: "wordCount"}, {name: "negative series sort", item: book.Book{SeriesSort: -1}, want: "seriesSort"}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { assertValidationErrorContains(t, validateBook(tt.item), tt.want) }) } } func TestValidateBookRejectsInvalidFixedDictionaryValues(t *testing.T) { tests := []struct { name string item book.Book want string }{ {name: "invalid era tag", item: book.Book{EraTag: "bad", CompletionStatus: book.BookCompletionStatusSerializing, PublishStatus: book.BookPublishStatusDraft}, want: "eraTag"}, {name: "invalid completion status", item: book.Book{EraTag: book.BookEraTagUnknown, CompletionStatus: "bad", PublishStatus: book.BookPublishStatusDraft}, want: "completionStatus"}, {name: "invalid publish status", item: book.Book{EraTag: book.BookEraTagUnknown, CompletionStatus: book.BookCompletionStatusSerializing, PublishStatus: "bad"}, want: "publishStatus"}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { assertValidationErrorContains(t, validateBook(tt.item), tt.want) }) } } func TestValidateBookAuthorRejectsInvalidStatus(t *testing.T) { err := validateBookAuthor(book.BookAuthor{AuthorStatus: "bad"}) assertValidationErrorContains(t, err, "authorStatus") } func TestValidateBookAuthorAcceptsCommonEnabledStatus(t *testing.T) { if err := validateBookAuthor(book.BookAuthor{AuthorStatus: commonModel.CommonEnabledStatusEnabled}); err != nil { t.Fatalf("validateBookAuthor enabled error = %v", err) } if err := validateBookAuthor(book.BookAuthor{AuthorStatus: commonModel.CommonEnabledStatusDisabled}); err != nil { t.Fatalf("validateBookAuthor disabled error = %v", err) } } func TestApplyBookAuthorRelationDefaults(t *testing.T) { item := applyBookAuthorRelationDefaults(book.BookAuthorRelation{}) if item.AuthorSort != 1 { t.Fatalf("AuthorSort = %d, want 1", item.AuthorSort) } } func TestValidateBookChapterRejectsReadableWithoutLines(t *testing.T) { err := validateBookChapter(book.BookChapter{ChapterNo: 1, IsReadable: true, TotalLines: 0}) assertValidationErrorContains(t, err, "totalLines") } func TestValidateBookAuthorRelationRejectsInvalidSort(t *testing.T) { err := validateBookAuthorRelation(book.BookAuthorRelation{AuthorSort: 0}) assertValidationErrorContains(t, err, "authorSort") } func TestValidateBookCommentRejectsInvalidAnchorLikeCountAndStatus(t *testing.T) { tests := []struct { name string item book.BookComment want string }{ {name: "book comment with line", item: book.BookComment{ChapterID: 0, LineIndex: 1}, want: "lineIndex"}, {name: "negative like count", item: book.BookComment{LikeCount: -1}, want: "likeCount"}, {name: "invalid comment status", item: book.BookComment{CommentStatus: "bad"}, want: "commentStatus"}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { assertValidationErrorContains(t, validateBookComment(tt.item), tt.want) }) } } func TestValidateBookReadRecordRejectsInvalidProgressAndAnchor(t *testing.T) { tests := []struct { name string item book.BookReadRecord want string }{ {name: "progress below zero", item: book.BookReadRecord{ReadProgress: -0.1, ChapterID: 1, LineIndex: 1}, want: "readProgress"}, {name: "progress above one hundred", item: book.BookReadRecord{ReadProgress: 100.1, ChapterID: 1, LineIndex: 1}, want: "readProgress"}, {name: "missing chapter", item: book.BookReadRecord{ReadProgress: 10, ChapterID: 0, LineIndex: 1}, want: "chapterId"}, {name: "missing line", item: book.BookReadRecord{ReadProgress: 10, ChapterID: 1, LineIndex: 0}, want: "lineIndex"}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { assertValidationErrorContains(t, validateBookReadRecord(tt.item), tt.want) }) } } func assertValidationErrorContains(t *testing.T, err error, want string) { t.Helper() if err == nil { t.Fatalf("validation error = nil, want %q", want) } if !strings.Contains(err.Error(), want) { t.Fatalf("validation error = %q, want contains %q", err.Error(), want) } }