Skip to content

Commit daa4923

Browse files
committed
frontend: fix tests
1 parent cddefb9 commit daa4923

File tree

2 files changed

+44
-9
lines changed

2 files changed

+44
-9
lines changed

frontend/src/__tests__/utils.test.ts

Lines changed: 43 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,18 @@ function withServiceWorker(controller: Partial<ServiceWorker> & { postMessage: (
2828
swListener = undefined;
2929
});
3030

31+
// Mock getRegistration to return an active service worker
32+
// The active property should have the postMessage method
33+
const getRegistration = vi.fn(async () => ({
34+
active: controller as ServiceWorker,
35+
}));
36+
3137
Object.defineProperty(navigator, 'serviceWorker', {
3238
value: {
3339
controller,
3440
addEventListener,
3541
removeEventListener,
42+
getRegistration,
3643
},
3744
configurable: true,
3845
});
@@ -97,13 +104,28 @@ describe('utils', () => {
97104
});
98105

99106
it('does nothing when no service worker controller (store)', async () => {
100-
Object.defineProperty(navigator, 'serviceWorker', { value: { controller: null }, configurable: true });
107+
Object.defineProperty(navigator, 'serviceWorker', {
108+
value: {
109+
controller: null,
110+
getRegistration: vi.fn(async () => null),
111+
},
112+
configurable: true
113+
});
101114
await utils.storeSecretKeyInServiceWorker('abc');
102115
// no error thrown
103116
});
104117

105118
it('requests secret and resolves with response (getSecretKeyFromServiceWorker)', async () => {
106-
const postMessage = vi.fn();
119+
const postMessage = vi.fn((msg: any) => {
120+
// When the service worker receives a RequestSecret message,
121+
// simulate it responding with the secret
122+
if (msg.type === MessageType.RequestSecret) {
123+
// Use queueMicrotask to ensure the message handler is set up first
124+
queueMicrotask(() => {
125+
triggerSWMessage({ type: MessageType.StoreSecret, data: 'encoded' });
126+
});
127+
}
128+
});
107129
withServiceWorker({ postMessage } as any);
108130

109131
const promise = utils.getSecretKeyFromServiceWorker();
@@ -115,14 +137,18 @@ describe('utils', () => {
115137
});
116138

117139
it('returns null when no service worker controller available', async () => {
118-
// Setup no controller scenario which should return null immediately
140+
// Setup no controller scenario - will retry 3 times with 500ms delays each = 1500ms total
119141
Object.defineProperty(navigator, 'serviceWorker', {
120-
value: { controller: null },
142+
value: {
143+
controller: null,
144+
getRegistration: vi.fn(async () => null),
145+
},
121146
configurable: true,
122147
});
148+
123149
const result = await utils.getSecretKeyFromServiceWorker();
124150
expect(result).toBeNull();
125-
});
151+
}, 10000); // Generous timeout to allow for multiple retries
126152

127153
it('clears secret key via service worker', async () => {
128154
const postMessage = vi.fn();
@@ -160,6 +186,7 @@ describe('utils', () => {
160186
Object.defineProperty(navigator, 'serviceWorker', {
161187
value: {
162188
controller: { postMessage },
189+
getRegistration: vi.fn(async () => ({ active: { postMessage } })),
163190
},
164191
configurable: true,
165192
});
@@ -249,6 +276,7 @@ describe('utils', () => {
249276
}
250277
return { error: null, response: { status: 200 } };
251278
});
279+
252280
await utils.refresh_access_token();
253281
expect(utils.loggedIn.value).toBe(utils.AppState.LoggedIn);
254282
});
@@ -262,14 +290,21 @@ describe('utils', () => {
262290
}
263291
return { error: null, response: { status: 200 } };
264292
});
293+
265294
await utils.refresh_access_token();
266295
expect(utils.loggedIn.value).toBe(utils.AppState.LoggedIn);
267296
});
268297

269298
it('catch block resets secret if tokens missing', async () => {
270299
(window.localStorage.getItem as any).mockImplementation(() => null);
271-
// Ensure no service worker controller so helper returns fast null
272-
Object.defineProperty(navigator, 'serviceWorker', { value: { controller: null }, configurable: true });
300+
// Ensure no service worker controller - will retry 3 times with 500ms delays each
301+
Object.defineProperty(navigator, 'serviceWorker', {
302+
value: {
303+
controller: null,
304+
getRegistration: vi.fn(async () => null),
305+
},
306+
configurable: true
307+
});
273308
// Start from LoggedOut so we can ensure it does not become LoggedIn
274309
utils.loggedIn.value = utils.AppState.LoggedOut;
275310
(utils.fetchClient as any).GET = vi.fn(async (path: string) => {
@@ -278,6 +313,7 @@ describe('utils', () => {
278313
}
279314
return { error: null, response: { status: 200 } };
280315
});
316+
281317
await utils.refresh_access_token();
282318
// Should not have transitioned to LoggedIn
283319
expect(utils.loggedIn.value).not.toBe(utils.AppState.LoggedIn);

frontend/src/utils.tsx

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -155,8 +155,6 @@ export async function getSecretKeyFromServiceWorker(): Promise<string | null> {
155155
}
156156

157157
secretKeyPromise = new Promise(async (resolve) => {
158-
gettingSecretInProgress = true;
159-
160158
// We dont use navigator.serviceWorker.controller here since it can be, for whatever reason,
161159
// null for an entire browser session
162160
const controller = await navigator.serviceWorker.getRegistration(location.origin);
@@ -174,6 +172,7 @@ export async function getSecretKeyFromServiceWorker(): Promise<string | null> {
174172
console.error("Max retries reached for getting secretKey from service worker");
175173
return resolve(null);
176174
}
175+
gettingSecretInProgress = true;
177176

178177
const timeout = setTimeout(async () => {
179178
console.error("Service Worker: Failed to get secretKey within timeout. Retrying...");

0 commit comments

Comments
 (0)