chapter-nav.test.ts 2.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. /**
  2. * chapter-nav 单元测试
  3. *
  4. * 覆盖:
  5. * 1. 第一个章节:无 prev,next 为第二节
  6. * 2. 中间章节:prev/next 都有
  7. * 3. 最后一章:有 prev,无 next
  8. * 4. 章节不在列表中:返 0/nav 全部 null
  9. * 5. bookId=0 边界
  10. * 6. DB 异常:返回零值 nav,不抛
  11. */
  12. import { describe, it, expect, vi, beforeEach } from 'vitest';
  13. const mocks = vi.hoisted(() => ({
  14. findMany: vi.fn(),
  15. }));
  16. vi.mock('@/models', () => ({
  17. prisma: {
  18. bookChapter: {
  19. findMany: mocks.findMany,
  20. },
  21. },
  22. }));
  23. import { getChapterNav } from '@/modules/book-generator/chapter-nav';
  24. describe('chapter-nav', () => {
  25. beforeEach(() => {
  26. vi.clearAllMocks();
  27. });
  28. it('第一章:prev=null, next=2', async () => {
  29. mocks.findMany.mockResolvedValue([{ id: 100 }, { id: 101 }, { id: 102 }]);
  30. const nav = await getChapterNav(1, 100);
  31. expect(nav.chapter_index).toBe(1);
  32. expect(nav.total_chapters).toBe(3);
  33. expect(nav.prev_chapter_id).toBeNull();
  34. expect(nav.next_chapter_id).toBe(101);
  35. });
  36. it('中间章:prev/next 都有', async () => {
  37. mocks.findMany.mockResolvedValue([{ id: 100 }, { id: 101 }, { id: 102 }]);
  38. const nav = await getChapterNav(1, 101);
  39. expect(nav.chapter_index).toBe(2);
  40. expect(nav.prev_chapter_id).toBe(100);
  41. expect(nav.next_chapter_id).toBe(102);
  42. });
  43. it('最后一章:next=null', async () => {
  44. mocks.findMany.mockResolvedValue([{ id: 100 }, { id: 101 }, { id: 102 }]);
  45. const nav = await getChapterNav(1, 102);
  46. expect(nav.chapter_index).toBe(3);
  47. expect(nav.prev_chapter_id).toBe(101);
  48. expect(nav.next_chapter_id).toBeNull();
  49. });
  50. it('章节不在列表中:全部 nav null', async () => {
  51. mocks.findMany.mockResolvedValue([{ id: 100 }, { id: 101 }]);
  52. const nav = await getChapterNav(1, 999);
  53. expect(nav.chapter_index).toBe(0);
  54. expect(nav.total_chapters).toBe(2);
  55. expect(nav.prev_chapter_id).toBeNull();
  56. expect(nav.next_chapter_id).toBeNull();
  57. });
  58. it('bookId/chapterId 非法:返零值', async () => {
  59. const nav1 = await getChapterNav(0, 100);
  60. expect(nav1).toEqual({ chapter_index: 0, total_chapters: 0, prev_chapter_id: null, next_chapter_id: null });
  61. const nav2 = await getChapterNav(1, 0);
  62. expect(nav2).toEqual({ chapter_index: 0, total_chapters: 0, prev_chapter_id: null, next_chapter_id: null });
  63. });
  64. it('DB 异常:返回零值 nav,不抛', async () => {
  65. mocks.findMany.mockRejectedValue(new Error('DB down'));
  66. const nav = await getChapterNav(1, 100);
  67. expect(nav).toEqual({ chapter_index: 0, total_chapters: 0, prev_chapter_id: null, next_chapter_id: null });
  68. });
  69. });