forked from BasedHardware/omi
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathfirebaseSwRouting.test.ts
More file actions
90 lines (79 loc) · 2.59 KB
/
Copy pathfirebaseSwRouting.test.ts
File metadata and controls
90 lines (79 loc) · 2.59 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
import { readFileSync } from 'node:fs';
import path from 'node:path';
import { describe, expect, it } from 'vitest';
/**
* The background half of notification routing.
*
* A recap notification clicked while the app is backgrounded is handled by the
* service worker, not by `useNotifications`. `/recaps` was removed and not
* redirected, so a worker still pointing there lands the click on a 404 even
* though the in-app mapping is correct.
*/
const templatePath = path.join(
import.meta.dirname,
'..',
'..',
'..',
'public',
'firebase-messaging-sw.js.template',
);
type ClickHandler = (event: {
notification: { data: Record<string, string>; close: () => void };
waitUntil: (value: unknown) => void;
}) => void;
const ORIGIN = 'https://app.omi.me';
function notificationClickHandler(): { run: ClickHandler; openedUrls: string[] } {
const listeners = new Map<string, ClickHandler>();
const openedUrls: string[] = [];
const self = {
location: { origin: ORIGIN },
registration: { showNotification: () => {} },
skipWaiting: () => {},
addEventListener: (type: string, handler: ClickHandler) =>
listeners.set(type, handler),
};
const clients = {
matchAll: async () => [],
openWindow: async (url: string) => {
openedUrls.push(url);
},
claim: async () => {},
};
const firebase = {
initializeApp: () => {},
messaging: () => ({ onBackgroundMessage: () => {} }),
};
const source = readFileSync(templatePath, 'utf8');
new Function('self', 'clients', 'firebase', 'importScripts', 'console', source)(
self,
clients,
firebase,
() => {},
{ log: () => {} },
);
const handler = listeners.get('notificationclick');
if (!handler) throw new Error('service worker registered no notificationclick');
return { run: handler, openedUrls };
}
async function clickTarget(navigateTo: string): Promise<string> {
const { run, openedUrls } = notificationClickHandler();
const waited: unknown[] = [];
run({
notification: { data: { navigate_to: navigateTo }, close: () => {} },
waitUntil: (value) => waited.push(value),
});
await Promise.all(waited);
return openedUrls[0] ?? '';
}
describe('firebase messaging service worker routing', () => {
it('opens a backgrounded recap notification on the timeline', async () => {
expect(await clickTarget('/daily-summary/recap-7')).toBe(
`${ORIGIN}/conversations?recap=recap-7`,
);
});
it('opens the legacy /recaps payload on the timeline too', async () => {
expect(await clickTarget('/recaps/recap-7')).toBe(
`${ORIGIN}/conversations?recap=recap-7`,
);
});
});