identifier.test.ts
1 /** 2 * Tests for dashboard tab identifier module 3 */ 4 import { describe, it, expect, vi, beforeEach } from 'vitest'; 5 import { 6 createDashboardUrl, 7 parseDashboardUrl, 8 isDashboardUrl, 9 } from '../../../src/lib/window/identifier'; 10 import type { ParentWorkspace, ChildWorkspace, StandaloneWorkspace } from '../../../src/lib/types'; 11 12 // Mock browser API 13 const mockGetURL = vi.fn((path: string) => `chrome-extension://test-id${path}`); 14 15 vi.stubGlobal('browser', { 16 runtime: { 17 getURL: mockGetURL, 18 }, 19 }); 20 21 describe('createDashboardUrl', () => { 22 const baseWorkspace = { 23 metadata: { 24 created: new Date().toISOString(), 25 lastModified: new Date().toISOString(), 26 lastAccessed: new Date().toISOString(), 27 switchCount: 0, 28 totalTimeActive: 0, 29 }, 30 }; 31 32 it('creates URL for parent workspace', () => { 33 const workspace: ParentWorkspace = { 34 ...baseWorkspace, 35 id: 'parent-123', 36 name: 'Test Parent', 37 type: 'parent', 38 parentId: null, 39 isTranscendent: false, 40 children: [], 41 }; 42 43 const url = createDashboardUrl(workspace); 44 45 expect(url).toContain('workspace-dashboard.html'); 46 expect(url).toContain('workspaceId=parent-123'); 47 expect(url).toContain('type=parent'); 48 expect(url).toContain('transcendent=0'); 49 expect(url).not.toContain('parentId='); 50 }); 51 52 it('creates URL for child workspace with parentId', () => { 53 const workspace: ChildWorkspace = { 54 ...baseWorkspace, 55 id: 'child-456', 56 name: 'Test Child', 57 type: 'child', 58 parentId: 'parent-123', 59 isTranscendent: false, 60 tabs: [], 61 }; 62 63 const url = createDashboardUrl(workspace); 64 65 expect(url).toContain('workspaceId=child-456'); 66 expect(url).toContain('type=child'); 67 expect(url).toContain('parentId=parent-123'); 68 }); 69 70 it('creates URL with transcendent flag', () => { 71 const workspace: StandaloneWorkspace = { 72 ...baseWorkspace, 73 id: 'standalone-789', 74 name: 'Transcendent', 75 type: 'standalone', 76 parentId: null, 77 isTranscendent: true, 78 tabs: [], 79 }; 80 81 const url = createDashboardUrl(workspace); 82 83 expect(url).toContain('transcendent=1'); 84 }); 85 }); 86 87 describe('parseDashboardUrl', () => { 88 beforeEach(() => { 89 mockGetURL.mockImplementation((path: string) => `chrome-extension://test-id${path}`); 90 }); 91 92 it('parses valid dashboard URL', () => { 93 const url = 'chrome-extension://test-id/workspace-dashboard.html?workspaceId=ws-123&type=parent&transcendent=0'; 94 const params = parseDashboardUrl(url); 95 96 expect(params).not.toBeNull(); 97 expect(params?.workspaceId).toBe('ws-123'); 98 expect(params?.type).toBe('parent'); 99 expect(params?.isTranscendent).toBe(false); 100 expect(params?.parentId).toBeNull(); 101 }); 102 103 it('parses URL with parentId', () => { 104 const url = 'chrome-extension://test-id/workspace-dashboard.html?workspaceId=child-1&type=child&transcendent=0&parentId=parent-1'; 105 const params = parseDashboardUrl(url); 106 107 expect(params?.parentId).toBe('parent-1'); 108 }); 109 110 it('parses transcendent flag correctly', () => { 111 const url = 'chrome-extension://test-id/workspace-dashboard.html?workspaceId=ws-1&type=standalone&transcendent=1'; 112 const params = parseDashboardUrl(url); 113 114 expect(params?.isTranscendent).toBe(true); 115 }); 116 117 it('returns null for non-extension URL', () => { 118 const url = 'https://example.com/workspace-dashboard.html?workspaceId=ws-1&type=parent'; 119 const params = parseDashboardUrl(url); 120 121 expect(params).toBeNull(); 122 }); 123 124 it('returns null for non-dashboard URL', () => { 125 const url = 'chrome-extension://test-id/popup.html?workspaceId=ws-1'; 126 const params = parseDashboardUrl(url); 127 128 expect(params).toBeNull(); 129 }); 130 131 it('returns null for missing workspaceId', () => { 132 const url = 'chrome-extension://test-id/workspace-dashboard.html?type=parent'; 133 const params = parseDashboardUrl(url); 134 135 expect(params).toBeNull(); 136 }); 137 138 it('returns null for missing type', () => { 139 const url = 'chrome-extension://test-id/workspace-dashboard.html?workspaceId=ws-1'; 140 const params = parseDashboardUrl(url); 141 142 expect(params).toBeNull(); 143 }); 144 145 it('returns null for invalid type', () => { 146 const url = 'chrome-extension://test-id/workspace-dashboard.html?workspaceId=ws-1&type=invalid'; 147 const params = parseDashboardUrl(url); 148 149 expect(params).toBeNull(); 150 }); 151 152 it('returns null for invalid URL', () => { 153 expect(parseDashboardUrl('not-a-url')).toBeNull(); 154 expect(parseDashboardUrl('')).toBeNull(); 155 }); 156 }); 157 158 describe('isDashboardUrl', () => { 159 it('returns true for valid dashboard URL', () => { 160 const url = 'chrome-extension://test-id/workspace-dashboard.html?workspaceId=ws-1&type=parent&transcendent=0'; 161 expect(isDashboardUrl(url)).toBe(true); 162 }); 163 164 it('returns false for non-dashboard URL', () => { 165 expect(isDashboardUrl('https://example.com')).toBe(false); 166 expect(isDashboardUrl('chrome-extension://test-id/popup.html')).toBe(false); 167 expect(isDashboardUrl('')).toBe(false); 168 }); 169 });