import { beforeEach, describe, expect, it, jest } from '@jest/globals'; import handler from '~background/messages/extension/updateIcon'; import { validateSupport } from '~utils/domain'; describe('background/messages/extension/updateIcon.ts', () => { const req = { name: 'extension/updateIcon' as const }; const res = { send: jest.fn() }; beforeEach(() => { jest.clearAllMocks(); (validateSupport as jest.Mock).mockReturnValue(true); }); it('should set warnIcon when config is on, tab.url is valid, and issue URL exists', async () => { const body = { domain: 'example.com' }; const sender = { frameId: 0, tab: { id: 123, url: 'https://example.com/page', }, } as chrome.runtime.MessageSender; await chrome.storage.local.set({ 'example.com': { on: true, issue: { expiresAt: Date.now() + 8 * 60 * 60 * 1000, flags: ['jest'], url: 'https://example.com/issue', }, }, }); await handler({ ...req, body, sender }, res); expect(chrome.action.setIcon).toHaveBeenCalledWith({ path: 'warn-icon', tabId: 123 }); expect(res.send).toHaveBeenCalledWith({ success: true }); }); it('should set onIcon when config is on, tab.url is valid, and no issue URL exists', async () => { const body = { domain: 'example.com' }; const sender = { frameId: 0, tab: { id: 123, url: 'https://example.com/page', }, } as chrome.runtime.MessageSender; await chrome.storage.local.set({ 'example.com': { on: true, issue: { expiresAt: Date.now() + 24 * 60 * 60 * 1000, }, }, }); await handler({ ...req, body, sender }, res); expect(chrome.action.setIcon).toHaveBeenCalledWith({ path: 'on-icon', tabId: 123 }); expect(res.send).toHaveBeenCalledWith({ success: true }); }); it('should set offIcon when config is off or tab.url is not valid', async () => { const body = { domain: 'example.com' }; const sender = { frameId: 0, tab: { id: 123, url: 'https://example.com/page', }, } as chrome.runtime.MessageSender; await chrome.storage.local.set({ 'example.com': { on: false, issue: { expiresAt: Date.now() + 24 * 60 * 60 * 1000, }, }, }); await handler({ ...req, body, sender }, res); expect(chrome.action.setIcon).toHaveBeenCalledWith({ path: 'off-icon', tabId: 123 }); expect(res.send).toHaveBeenCalledWith({ success: true }); }); it('should set offIcon when config is on but validateSupport is false', async () => { const body = { domain: 'example.com' }; const sender = { frameId: 0, tab: { id: 123, url: 'https://example.com/page', }, } as chrome.runtime.MessageSender; (validateSupport as jest.Mock).mockReturnValue(false); await chrome.storage.local.set({ 'example.com': { on: true, issue: { expiresAt: Date.now() + 24 * 60 * 60 * 1000, }, }, }); await handler({ ...req, body, sender }, res); expect(chrome.action.setIcon).toHaveBeenCalledWith({ path: 'off-icon', tabId: 123 }); expect(res.send).toHaveBeenCalledWith({ success: true }); }); it('should return success: false when frameId is not 0', async () => { const body = { domain: 'example.com' }; const sender = { frameId: 1, tab: { id: 123, url: 'https://example.com/page', }, } as chrome.runtime.MessageSender; await chrome.storage.local.set({ 'example.com': { on: false, issue: { expiresAt: Date.now() + 24 * 60 * 60 * 1000, }, }, }); await handler({ ...req, body, sender }, res); expect(chrome.action.setIcon).not.toHaveBeenCalled(); expect(res.send).toHaveBeenCalledWith({ success: false }); }); it('should return success: false when tab.id is undefined', async () => { const body = { domain: 'example.com' }; const sender = { frameId: 0, tab: undefined } as chrome.runtime.MessageSender; await chrome.storage.local.set({ 'example.com': { on: false, issue: { expiresAt: Date.now() + 24 * 60 * 60 * 1000, }, }, }); await handler({ ...req, body, sender }, res); expect(chrome.action.setIcon).not.toHaveBeenCalled(); expect(res.send).toHaveBeenCalledWith({ success: false }); }); });