/ clis / notebooklm / source-fulltext.test.js
source-fulltext.test.js
  1  import { beforeEach, describe, expect, it, vi } from 'vitest';
  2  const { mockListNotebooklmSourcesViaRpc, mockListNotebooklmSourcesFromPage, mockGetNotebooklmSourceFulltextViaRpc, mockGetNotebooklmPageState, mockRequireNotebooklmSession, } = vi.hoisted(() => ({
  3      mockListNotebooklmSourcesViaRpc: vi.fn(),
  4      mockListNotebooklmSourcesFromPage: vi.fn(),
  5      mockGetNotebooklmSourceFulltextViaRpc: vi.fn(),
  6      mockGetNotebooklmPageState: vi.fn(),
  7      mockRequireNotebooklmSession: vi.fn(),
  8  }));
  9  vi.mock('./utils.js', async () => {
 10      const actual = await vi.importActual('./utils.js');
 11      return {
 12          ...actual,
 13          listNotebooklmSourcesViaRpc: mockListNotebooklmSourcesViaRpc,
 14          listNotebooklmSourcesFromPage: mockListNotebooklmSourcesFromPage,
 15          getNotebooklmSourceFulltextViaRpc: mockGetNotebooklmSourceFulltextViaRpc,
 16          getNotebooklmPageState: mockGetNotebooklmPageState,
 17          requireNotebooklmSession: mockRequireNotebooklmSession,
 18      };
 19  });
 20  import { getRegistry } from '@jackwener/opencli/registry';
 21  import './source-fulltext.js';
 22  describe('notebooklm source-fulltext', () => {
 23      const command = getRegistry().get('notebooklm/source-fulltext');
 24      beforeEach(() => {
 25          mockListNotebooklmSourcesViaRpc.mockReset();
 26          mockListNotebooklmSourcesFromPage.mockReset();
 27          mockGetNotebooklmSourceFulltextViaRpc.mockReset();
 28          mockGetNotebooklmPageState.mockReset();
 29          mockRequireNotebooklmSession.mockReset();
 30          mockRequireNotebooklmSession.mockResolvedValue(undefined);
 31          mockGetNotebooklmPageState.mockResolvedValue({
 32              url: 'https://notebooklm.google.com/notebook/nb-demo',
 33              title: 'Browser Automation',
 34              hostname: 'notebooklm.google.com',
 35              kind: 'notebook',
 36              notebookId: 'nb-demo',
 37              loginRequired: false,
 38              notebookCount: 1,
 39          });
 40      });
 41      it('returns fulltext for a source matched from rpc source rows', async () => {
 42          mockListNotebooklmSourcesViaRpc.mockResolvedValue([
 43              {
 44                  id: 'src-1',
 45                  notebook_id: 'nb-demo',
 46                  title: '粘贴的文字',
 47                  url: 'https://notebooklm.google.com/notebook/nb-demo',
 48                  source: 'rpc',
 49                  type: 'pasted-text',
 50              },
 51          ]);
 52          mockGetNotebooklmSourceFulltextViaRpc.mockResolvedValue({
 53              source_id: 'src-1',
 54              notebook_id: 'nb-demo',
 55              title: '粘贴的文字',
 56              kind: 'generated-text',
 57              content: '第一段\n第二段',
 58              char_count: 7,
 59              url: 'https://example.com/source',
 60              source: 'rpc',
 61          });
 62          const result = await command.func({}, { source: 'src-1' });
 63          expect(result).toEqual([
 64              {
 65                  source_id: 'src-1',
 66                  notebook_id: 'nb-demo',
 67                  title: '粘贴的文字',
 68                  kind: 'generated-text',
 69                  content: '第一段\n第二段',
 70                  char_count: 7,
 71                  url: 'https://example.com/source',
 72                  source: 'rpc',
 73              },
 74          ]);
 75      });
 76      it('matches by title from dom rows when rpc source list is unavailable', async () => {
 77          mockListNotebooklmSourcesViaRpc.mockResolvedValue([]);
 78          mockListNotebooklmSourcesFromPage.mockResolvedValue([
 79              {
 80                  id: 'src-1',
 81                  notebook_id: 'nb-demo',
 82                  title: '粘贴的文字',
 83                  url: 'https://notebooklm.google.com/notebook/nb-demo',
 84                  source: 'current-page',
 85              },
 86          ]);
 87          mockGetNotebooklmSourceFulltextViaRpc.mockResolvedValue({
 88              source_id: 'src-1',
 89              notebook_id: 'nb-demo',
 90              title: '粘贴的文字',
 91              kind: 'generated-text',
 92              content: '第一段\n第二段',
 93              char_count: 7,
 94              url: 'https://example.com/source',
 95              source: 'rpc',
 96          });
 97          const result = await command.func({}, { source: '粘贴的文字' });
 98          expect(result).toEqual([
 99              expect.objectContaining({
100                  source_id: 'src-1',
101                  title: '粘贴的文字',
102                  content: '第一段\n第二段',
103              }),
104          ]);
105      });
106  });