package book import ( "encoding/json" "testing" "time" "github.com/flipped-aurora/gin-vue-admin/server/global" "github.com/flipped-aurora/gin-vue-admin/server/model/book" bookReq "github.com/flipped-aurora/gin-vue-admin/server/model/book/request" commonReq "github.com/flipped-aurora/gin-vue-admin/server/model/common/request" "github.com/glebarez/sqlite" "github.com/stretchr/testify/require" "gorm.io/gorm" ) func setupBookDisplayTestDB(t *testing.T) { t.Helper() db, err := gorm.Open(sqlite.Open(":memory:"), &gorm.Config{}) require.NoError(t, err) require.NoError(t, db.AutoMigrate( &book.Book{}, &book.BookChapter{}, &book.BookComment{}, &book.BookCommentLikeRecord{}, &book.BookFavoriteRecord{}, &book.BookReadRecord{}, )) global.GVA_DB = db t.Cleanup(func() { global.GVA_DB = nil }) } func createBookDisplayFixture(t *testing.T) (book.Book, book.BookChapter, book.BookComment) { t.Helper() bookItem := book.Book{ Title: "边城", BookType: "novel", EraTag: book.BookEraTagModern, CompletionStatus: book.BookCompletionStatusCompleted, PublishStatus: book.BookPublishStatusOnShelf, } require.NoError(t, global.GVA_DB.Create(&bookItem).Error) chapter := book.BookChapter{ BookID: bookItem.ID, Title: "第一章 茶峒", ChapterNo: 1, ContentFileUrl: "chapters/biancheng-1.txt", IsEnabled: true, } require.NoError(t, global.GVA_DB.Create(&chapter).Error) comment := book.BookComment{ MemberUserID: 7, BookID: bookItem.ID, ChapterID: chapter.ID, Content: "这段很有画面感", CommentStatus: book.BookCommentStatusNormal, } require.NoError(t, global.GVA_DB.Create(&comment).Error) return bookItem, chapter, comment } func requireJSONField(t *testing.T, value any, key string, expected any) { t.Helper() payload, err := json.Marshal(value) require.NoError(t, err) var got map[string]any require.NoError(t, json.Unmarshal(payload, &got)) require.Equal(t, expected, got[key]) } func TestBookChapterServiceReturnsBookTitle(t *testing.T) { setupBookDisplayTestDB(t) bookItem, chapter, _ := createBookDisplayFixture(t) list, total, err := (&BookChapterService{}).GetBookChapterInfoList(bookReq.BookChapterSearch{ PageInfo: commonReq.PageInfo{Page: 1, PageSize: 10}, BookID: uintPtr(bookItem.ID), }) require.NoError(t, err) require.EqualValues(t, 1, total) require.Len(t, list, 1) require.Equal(t, chapter.ID, list[0].ID) requireJSONField(t, list[0], "bookTitle", "边城") detail, err := (&BookChapterService{}).GetBookChapter(chapter.ID) require.NoError(t, err) requireJSONField(t, detail, "bookTitle", "边城") } func TestBookCommentServiceReturnsBookAndChapterTitles(t *testing.T) { setupBookDisplayTestDB(t) bookItem, _, comment := createBookDisplayFixture(t) list, total, err := (&BookCommentService{}).GetBookCommentInfoList(bookReq.BookCommentSearch{ PageInfo: commonReq.PageInfo{Page: 1, PageSize: 10}, BookID: uintPtr(bookItem.ID), }) require.NoError(t, err) require.EqualValues(t, 1, total) require.Len(t, list, 1) require.Equal(t, comment.ID, list[0].ID) requireJSONField(t, list[0], "bookTitle", "边城") requireJSONField(t, list[0], "chapterTitle", "第一章 茶峒") detail, err := (&BookCommentService{}).GetBookComment(comment.ID) require.NoError(t, err) requireJSONField(t, detail, "bookTitle", "边城") requireJSONField(t, detail, "chapterTitle", "第一章 茶峒") } func TestBookCommentLikeRecordServiceReturnsCommentDisplayFields(t *testing.T) { setupBookDisplayTestDB(t) _, _, comment := createBookDisplayFixture(t) record := book.BookCommentLikeRecord{ CommentID: comment.ID, MemberUserID: 8, LikedAt: time.Now(), } require.NoError(t, global.GVA_DB.Create(&record).Error) list, total, err := (&BookCommentLikeRecordService{}).GetBookCommentLikeRecordInfoList(bookReq.BookCommentLikeRecordSearch{ PageInfo: commonReq.PageInfo{Page: 1, PageSize: 10}, CommentID: uintPtr(comment.ID), }) require.NoError(t, err) require.EqualValues(t, 1, total) require.Len(t, list, 1) require.Equal(t, record.ID, list[0].ID) requireJSONField(t, list[0], "bookTitle", "边城") requireJSONField(t, list[0], "commentContent", "这段很有画面感") detail, err := (&BookCommentLikeRecordService{}).GetBookCommentLikeRecord(record.ID) require.NoError(t, err) requireJSONField(t, detail, "bookTitle", "边城") requireJSONField(t, detail, "commentContent", "这段很有画面感") } func TestBookFavoriteRecordServiceReturnsBookTitle(t *testing.T) { setupBookDisplayTestDB(t) bookItem, _, _ := createBookDisplayFixture(t) record := book.BookFavoriteRecord{ MemberUserID: 9, BookID: bookItem.ID, FavoritedAt: time.Now(), } require.NoError(t, global.GVA_DB.Create(&record).Error) list, total, err := (&BookFavoriteRecordService{}).GetBookFavoriteRecordInfoList(bookReq.BookFavoriteRecordSearch{ PageInfo: commonReq.PageInfo{Page: 1, PageSize: 10}, BookID: uintPtr(bookItem.ID), }) require.NoError(t, err) require.EqualValues(t, 1, total) require.Len(t, list, 1) require.Equal(t, record.ID, list[0].ID) requireJSONField(t, list[0], "bookTitle", "边城") detail, err := (&BookFavoriteRecordService{}).GetBookFavoriteRecord(record.ID) require.NoError(t, err) requireJSONField(t, detail, "bookTitle", "边城") } func TestBookReadRecordServiceReturnsChapterTitle(t *testing.T) { setupBookDisplayTestDB(t) bookItem, chapter, _ := createBookDisplayFixture(t) record := book.BookReadRecord{ MemberUserID: 10, BookID: bookItem.ID, BookTitleSnapshot: bookItem.Title, ReadProgress: 12.5, ChapterID: chapter.ID, LineIndex: 3, LastReadAt: time.Now(), } require.NoError(t, global.GVA_DB.Create(&record).Error) list, total, err := (&BookReadRecordService{}).GetBookReadRecordInfoList(bookReq.BookReadRecordSearch{ PageInfo: commonReq.PageInfo{Page: 1, PageSize: 10}, BookID: uintPtr(bookItem.ID), }) require.NoError(t, err) require.EqualValues(t, 1, total) require.Len(t, list, 1) require.Equal(t, record.ID, list[0].ID) requireJSONField(t, list[0], "chapterTitle", "第一章 茶峒") detail, err := (&BookReadRecordService{}).GetBookReadRecord(record.ID) require.NoError(t, err) requireJSONField(t, detail, "chapterTitle", "第一章 茶峒") }