source-guide.test.js
1 import { beforeEach, describe, expect, it, vi } from 'vitest'; 2 const { mockListNotebooklmSourcesViaRpc, mockListNotebooklmSourcesFromPage, mockGetNotebooklmSourceGuideViaRpc, mockGetNotebooklmPageState, mockRequireNotebooklmSession, } = vi.hoisted(() => ({ 3 mockListNotebooklmSourcesViaRpc: vi.fn(), 4 mockListNotebooklmSourcesFromPage: vi.fn(), 5 mockGetNotebooklmSourceGuideViaRpc: 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 getNotebooklmSourceGuideViaRpc: mockGetNotebooklmSourceGuideViaRpc, 16 getNotebooklmPageState: mockGetNotebooklmPageState, 17 requireNotebooklmSession: mockRequireNotebooklmSession, 18 }; 19 }); 20 import { getRegistry } from '@jackwener/opencli/registry'; 21 import './source-guide.js'; 22 describe('notebooklm source-guide', () => { 23 const command = getRegistry().get('notebooklm/source-guide'); 24 beforeEach(() => { 25 mockListNotebooklmSourcesViaRpc.mockReset(); 26 mockListNotebooklmSourcesFromPage.mockReset(); 27 mockGetNotebooklmSourceGuideViaRpc.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 source guide for a source matched from rpc source rows', async () => { 42 mockListNotebooklmSourcesViaRpc.mockResolvedValue([ 43 { 44 id: 'src-yt', 45 notebook_id: 'nb-demo', 46 title: 'Video Source', 47 url: 'https://notebooklm.google.com/notebook/nb-demo', 48 source: 'rpc', 49 type: 'youtube', 50 type_code: 9, 51 }, 52 ]); 53 mockGetNotebooklmSourceGuideViaRpc.mockResolvedValue({ 54 source_id: 'src-yt', 55 notebook_id: 'nb-demo', 56 title: 'Video Source', 57 type: 'youtube', 58 summary: 'Guide summary.', 59 keywords: ['AI', 'agents'], 60 source: 'rpc', 61 }); 62 const result = await command.func({}, { source: 'src-yt' }); 63 expect(result).toEqual([ 64 { 65 source_id: 'src-yt', 66 notebook_id: 'nb-demo', 67 title: 'Video Source', 68 type: 'youtube', 69 summary: 'Guide summary.', 70 keywords: ['AI', 'agents'], 71 source: 'rpc', 72 }, 73 ]); 74 }); 75 it('matches by title from dom rows when rpc source list is unavailable', async () => { 76 mockListNotebooklmSourcesViaRpc.mockResolvedValue([]); 77 mockListNotebooklmSourcesFromPage.mockResolvedValue([ 78 { 79 id: 'src-1', 80 notebook_id: 'nb-demo', 81 title: 'Example Source', 82 url: 'https://notebooklm.google.com/notebook/nb-demo', 83 source: 'current-page', 84 }, 85 ]); 86 mockGetNotebooklmSourceGuideViaRpc.mockResolvedValue({ 87 source_id: 'src-1', 88 notebook_id: 'nb-demo', 89 title: 'Example Source', 90 type: null, 91 summary: 'Guide summary.', 92 keywords: ['topic'], 93 source: 'rpc', 94 }); 95 const result = await command.func({}, { source: 'example source' }); 96 expect(result).toEqual([ 97 expect.objectContaining({ 98 source_id: 'src-1', 99 title: 'Example Source', 100 summary: 'Guide summary.', 101 }), 102 ]); 103 }); 104 });