Files
xuanzhi-service/server/service/book/validation_test.go
2026-04-27 10:12:21 +08:00

127 lines
4.7 KiB
Go

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)
}
}