refactor(ext/sw): extract storage.ts + move itemToManifestEntry (Plan C Phase 2)
P1.9: loadDeviceSettings / loadBlacklist / saveBlacklist / saveDeviceSettings + itemToManifestEntry were duplicated across popup-only.ts and content-callable.ts. Lifts the four storage helpers into service-worker/ storage.ts and itemToManifestEntry into service-worker/vault.ts. Both router files now import from one home each. Adds storage.test.ts covering round-trips and defaults. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
56
extension/src/service-worker/__tests__/storage.test.ts
Normal file
56
extension/src/service-worker/__tests__/storage.test.ts
Normal file
@@ -0,0 +1,56 @@
|
||||
import { beforeEach, describe, expect, it, vi } from 'vitest';
|
||||
import { loadDeviceSettings, saveDeviceSettings, loadBlacklist, saveBlacklist }
|
||||
from '../storage';
|
||||
|
||||
function mockChromeStorage(initial: Record<string, unknown> = {}) {
|
||||
const store: Record<string, unknown> = { ...initial };
|
||||
(global as { chrome: unknown }).chrome = {
|
||||
storage: {
|
||||
local: {
|
||||
get: vi.fn((keys: string | string[]) => {
|
||||
const arr = Array.isArray(keys) ? keys : [keys];
|
||||
const out: Record<string, unknown> = {};
|
||||
for (const k of arr) if (k in store) out[k] = store[k];
|
||||
return Promise.resolve(out);
|
||||
}),
|
||||
set: vi.fn((kv: Record<string, unknown>) => {
|
||||
Object.assign(store, kv);
|
||||
return Promise.resolve();
|
||||
}),
|
||||
},
|
||||
},
|
||||
} as never;
|
||||
return store;
|
||||
}
|
||||
|
||||
describe('service-worker/storage', () => {
|
||||
beforeEach(() => { mockChromeStorage(); });
|
||||
|
||||
it('loadDeviceSettings returns default when storage is empty', async () => {
|
||||
const s = await loadDeviceSettings();
|
||||
expect(s.captureEnabled).toBe(false);
|
||||
expect(s.captureStyle).toBe('bar');
|
||||
});
|
||||
|
||||
it('loadDeviceSettings returns stored value', async () => {
|
||||
mockChromeStorage({ relicarioSettings: { captureEnabled: true, captureStyle: 'toast' } });
|
||||
const s = await loadDeviceSettings();
|
||||
expect(s.captureEnabled).toBe(true);
|
||||
expect(s.captureStyle).toBe('toast');
|
||||
});
|
||||
|
||||
it('saveDeviceSettings persists', async () => {
|
||||
const store = mockChromeStorage();
|
||||
await saveDeviceSettings({ captureEnabled: true, captureStyle: 'bar' });
|
||||
expect(store.relicarioSettings).toEqual({ captureEnabled: true, captureStyle: 'bar' });
|
||||
});
|
||||
|
||||
it('loadBlacklist returns empty array by default', async () => {
|
||||
expect(await loadBlacklist()).toEqual([]);
|
||||
});
|
||||
|
||||
it('saveBlacklist / loadBlacklist round-trips', async () => {
|
||||
await saveBlacklist(['example.com', 'evil.test']);
|
||||
expect(await loadBlacklist()).toEqual(['example.com', 'evil.test']);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user