note.test.js
1 import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; 2 import { ArgumentError } from '@jackwener/opencli/errors'; 3 import { getRegistry } from '@jackwener/opencli/registry'; 4 import './note.js'; 5 function createPageMock() { 6 return { 7 goto: vi.fn().mockResolvedValue(undefined), 8 evaluate: vi.fn().mockResolvedValue(undefined), 9 getCookies: vi.fn().mockResolvedValue([]), 10 snapshot: vi.fn().mockResolvedValue(undefined), 11 click: vi.fn().mockResolvedValue(undefined), 12 typeText: vi.fn().mockResolvedValue(undefined), 13 pressKey: vi.fn().mockResolvedValue(undefined), 14 scrollTo: vi.fn().mockResolvedValue(undefined), 15 getFormState: vi.fn().mockResolvedValue({ forms: [], orphanFields: [] }), 16 wait: vi.fn().mockResolvedValue(undefined), 17 tabs: vi.fn().mockResolvedValue([]), 18 closeTab: vi.fn().mockResolvedValue(undefined), 19 newTab: vi.fn().mockResolvedValue(undefined), 20 selectTab: vi.fn().mockResolvedValue(undefined), 21 networkRequests: vi.fn().mockResolvedValue([]), 22 consoleMessages: vi.fn().mockResolvedValue([]), 23 scroll: vi.fn().mockResolvedValue(undefined), 24 autoScroll: vi.fn().mockResolvedValue(undefined), 25 installInterceptor: vi.fn().mockResolvedValue(undefined), 26 getInterceptedRequests: vi.fn().mockResolvedValue([]), 27 waitForCapture: vi.fn().mockResolvedValue(undefined), 28 screenshot: vi.fn().mockResolvedValue(''), 29 setFileInput: vi.fn().mockResolvedValue(undefined), 30 insertText: vi.fn().mockResolvedValue(undefined), 31 getCurrentUrl: vi.fn().mockResolvedValue(null), 32 }; 33 } 34 describe('instagram note registration', () => { 35 beforeEach(() => { 36 vi.restoreAllMocks(); 37 }); 38 afterEach(() => { 39 vi.restoreAllMocks(); 40 }); 41 it('registers the note command with a required positional content arg', () => { 42 const cmd = getRegistry().get('instagram/note'); 43 expect(cmd).toBeDefined(); 44 expect(cmd?.browser).toBe(true); 45 expect(cmd?.args.some((arg) => arg.name === 'content' && arg.positional && arg.required)).toBe(true); 46 }); 47 it('rejects missing note content before browser work', async () => { 48 const page = createPageMock(); 49 const cmd = getRegistry().get('instagram/note'); 50 await expect(cmd.func(page, {})).rejects.toThrow(ArgumentError); 51 expect(page.goto).not.toHaveBeenCalled(); 52 }); 53 it('rejects blank note content before browser work', async () => { 54 const page = createPageMock(); 55 const cmd = getRegistry().get('instagram/note'); 56 await expect(cmd.func(page, { content: ' ' })).rejects.toThrow(ArgumentError); 57 expect(page.goto).not.toHaveBeenCalled(); 58 }); 59 it('rejects note content longer than 60 characters before browser work', async () => { 60 const page = createPageMock(); 61 const cmd = getRegistry().get('instagram/note'); 62 await expect(cmd.func(page, { content: 'x'.repeat(61) })).rejects.toThrow(ArgumentError); 63 expect(page.goto).not.toHaveBeenCalled(); 64 }); 65 it('publishes a note through the web inbox mutation', async () => { 66 const page = createPageMock(); 67 const cmd = getRegistry().get('instagram/note'); 68 vi.mocked(page.evaluate).mockResolvedValue({ 69 ok: true, 70 noteId: '17849203563031468', 71 }); 72 const rows = await cmd.func(page, { content: 'hello note' }); 73 expect(page.goto).toHaveBeenCalledWith('https://www.instagram.com/direct/inbox/'); 74 expect(page.evaluate).toHaveBeenCalledTimes(1); 75 expect(rows).toEqual([{ 76 status: '✅ Posted', 77 detail: 'Instagram note published successfully', 78 noteId: '17849203563031468', 79 }]); 80 }); 81 });