import { describe, it, expect, beforeEach, vi } from 'vitest' import './test-utils' import { NO_PERMISSIONS_REQUIRED, PERMISSION_NAMES, getPermissionStatus, updatePermission, removePermissions, showNotification, getPosition } from './common' describe('common.js', () => { beforeEach(() => { browser.storage.local._reset() browser.notifications._reset() vi.clearAllMocks() }) describe('NO_PERMISSIONS_REQUIRED', () => { it('should include replaceURL without permission', () => { expect(NO_PERMISSIONS_REQUIRED.replaceURL).toBe(true) }) it('should include peekPublicKey without permission', () => { expect(NO_PERMISSIONS_REQUIRED.peekPublicKey).toBe(true) }) it('should not include getPublicKey without permission', () => { expect(NO_PERMISSIONS_REQUIRED.getPublicKey).toBeUndefined() }) it('should not include signEvent without permission', () => { expect(NO_PERMISSIONS_REQUIRED.signEvent).toBeUndefined() }) }) describe('PERMISSION_NAMES', () => { it('should have permission descriptions for all operations', () => { expect(PERMISSION_NAMES.getPublicKey).toBe('read your public key') expect(PERMISSION_NAMES.signEvent).toBe( 'sign events using your private key' ) expect(PERMISSION_NAMES['nip04.encrypt']).toBe( 'encrypt messages to peers' ) expect(PERMISSION_NAMES['nip04.decrypt']).toBe( 'decrypt messages from peers' ) expect(PERMISSION_NAMES['nip44.encrypt']).toBe( 'encrypt messages to peers' ) expect(PERMISSION_NAMES['nip44.decrypt']).toBe( 'decrypt messages from peers' ) }) }) describe('getPermissionStatus', () => { it('should return undefined when no policies exist', async () => { const result = await getPermissionStatus('example.com', 'getPublicKey') expect(result).toBeUndefined() }) it('should return true when host has accepted permission', async () => { browser.storage.local.set({ policies: { 'example.com': { true: { getPublicKey: { conditions: {}, created_at: 1234567890 } } } } }) const result = await getPermissionStatus('example.com', 'getPublicKey') expect(result).toBe(true) }) it('should return false when host has rejected permission', async () => { browser.storage.local.set({ policies: { 'example.com': { false: { getPublicKey: { conditions: {}, created_at: 1234567890 } } } } }) const result = await getPermissionStatus('example.com', 'getPublicKey') expect(result).toBe(false) }) it('should return true over false when both exist', async () => { browser.storage.local.set({ policies: { 'example.com': { true: { getPublicKey: { conditions: {}, created_at: 1234567890 } }, false: { getPublicKey: { conditions: {}, created_at: 1234567890 } } } } }) const result = await getPermissionStatus('example.com', 'getPublicKey') expect(result).toBe(true) }) it('should check kind conditions for signEvent', async () => { browser.storage.local.set({ policies: { 'example.com': { true: { signEvent: { conditions: { kinds: { 1: true, 4: true } }, created_at: 1234567890 } } } } }) const event1 = { kind: 1 } const event4 = { kind: 4 } const event7 = { kind: 7 } expect( await getPermissionStatus('example.com', 'signEvent', event1) ).toBe(true) expect( await getPermissionStatus('example.com', 'signEvent', event4) ).toBe(true) expect( await getPermissionStatus('example.com', 'signEvent', event7) ).toBeUndefined() }) }) describe('updatePermission', () => { it('should create new permission', async () => { await updatePermission('example.com', 'getPublicKey', true, {}) const { policies } = await browser.storage.local.get('policies') expect(policies['example.com'].true.getPublicKey).toBeDefined() expect(policies['example.com'].true.getPublicKey.conditions).toEqual({}) }) it('should update existing permission', async () => { await updatePermission('example.com', 'getPublicKey', true, {}) await updatePermission('example.com', 'getPublicKey', true, {}) const { policies } = await browser.storage.local.get('policies') expect(policies['example.com'].true.getPublicKey).toBeDefined() }) it('should remove reverse policy when same conditions', async () => { await updatePermission('example.com', 'getPublicKey', false, {}) await updatePermission('example.com', 'getPublicKey', true, {}) const { policies } = await browser.storage.local.get('policies') expect(policies['example.com']?.false?.getPublicKey).toBeUndefined() expect(policies['example.com'].true.getPublicKey).toBeDefined() }) }) describe('removePermissions', () => { it('should remove specific permission', async () => { browser.storage.local.set({ policies: { 'example.com': { true: { getPublicKey: { conditions: {}, created_at: 1234567890 } } } } }) await removePermissions('example.com', true, 'getPublicKey') const { policies } = await browser.storage.local.get('policies') expect(policies['example.com'].true.getPublicKey).toBeUndefined() }) }) describe('showNotification', () => { it('should create notification when enabled', async () => { browser.storage.local.set({ notifications: true }) await showNotification('example.com', true, 'getPublicKey', {}) expect(browser.notifications.create).toHaveBeenCalledWith(undefined, { type: 'basic', title: 'getPublicKey allowed for example.com', message: expect.any(String), iconUrl: 'icons/48x48.png' }) }) it('should not create notification when disabled', async () => { browser.storage.local.set({ notifications: false }) await showNotification('example.com', true, 'getPublicKey', {}) expect(browser.notifications.create).not.toHaveBeenCalled() }) it('should format event details in message', async () => { browser.storage.local.set({ notifications: true }) await showNotification('example.com', true, 'signEvent', { event: { kind: 1, content: 'Hello', tags: [] } }) expect(browser.notifications.create).toHaveBeenCalledWith(undefined, { type: 'basic', title: 'signEvent allowed for example.com', message: expect.stringContaining('1'), iconUrl: 'icons/48x48.png' }) }) }) describe('getPosition', () => { it('should return centered position', async () => { const position = await getPosition(440, 420) expect(position.top).toBe(430) // Math.round(100 + (1080 - 420) / 2) expect(position.left).toBe(840) // Math.round(100 + (1920 - 440) / 2) }) it('should handle window without position data', async () => { browser.windows.getLastFocused.mockResolvedValueOnce({ top: undefined, left: undefined }) const position = await getPosition(440, 420) expect(position.top).toBe(0) expect(position.left).toBe(0) }) }) })