also looking at this
feat(ios): tell the page about a notification that arrives while the app is open
#259
11 files
+410
-58
| @@ -94,6 +94,8 @@ function loadPage(beforeInject?: (page: Record<string, any>) => void, seed = SEE | ||
| 94 | 94 | // What CraftEventManager.handleNotificationResponse evaluates. |
| 95 | 95 | tap: (detail: unknown) => |
| 96 | 96 | page.dispatchEvent(new CustomEvent('craftNotificationResponse', { detail })), |
| 97 | receive: (detail: unknown) => | |
| 98 | page.dispatchEvent(new CustomEvent('craftNotificationReceived', { detail })), | |
| 97 | 99 | } |
| 98 | 100 | } |
| 99 | 101 | |
| @@ -253,6 +255,48 @@ describe('the injected iOS page script', () => { | ||
| 253 | 255 | expect(seen).toEqual([]) |
| 254 | 256 | }) |
| 255 | 257 | |
| 258 | // #256: a notification that arrives while the page is open reaches it, | |
| 259 | // live, on the notifications object the page ends up with. | |
| 260 | it('hands a notification that arrived while the page was open to onReceive', () => { | |
| 261 | const page = loadPage() | |
| 262 | expect(typeof page.craft.notifications.onReceive).toBe('function') | |
| 263 | ||
| 264 | const seen: unknown[] = [] | |
| 265 | const unsubscribe = page.craft.notifications.onReceive((detail: unknown) => seen.push(detail)) | |
| 266 | page.receive({ screen: 'recap' }) | |
| 267 | expect(seen).toEqual([{ screen: 'recap' }]) | |
| 268 | ||
| 269 | unsubscribe() | |
| 270 | page.receive({ screen: 'plant-id' }) | |
| 271 | expect(seen).toEqual([{ screen: 'recap' }]) | |
| 272 | }) | |
| 273 | ||
| 274 | it('keeps arrivals and taps apart', async () => { | |
| 275 | const page = loadPage() | |
| 276 | const taps: unknown[] = [] | |
| 277 | const arrivals: unknown[] = [] | |
| 278 | page.craft.notifications.onTap((detail: unknown) => taps.push(detail)) | |
| 279 | page.craft.notifications.onReceive((detail: unknown) => arrivals.push(detail)) | |
| 280 | await tick() | |
| 281 | ||
| 282 | page.receive({ screen: 'recap' }) | |
| 283 | page.tap({ screen: 'plant-id' }) | |
| 284 | expect(arrivals).toEqual([{ screen: 'recap' }]) | |
| 285 | expect(taps).toEqual([{ screen: 'plant-id' }]) | |
| 286 | }) | |
| 287 | ||
| 288 | // Held taps are for a launch the page was not there for. An arrival is | |
| 289 | // news only to a page that is running, so nothing is held for later. | |
| 290 | it('does not hold an arrival for a page that subscribes afterwards', async () => { | |
| 291 | const page = loadPage() | |
| 292 | page.receive({ screen: 'recap' }) | |
| 293 | ||
| 294 | const seen: unknown[] = [] | |
| 295 | page.craft.notifications.onReceive((detail: unknown) => seen.push(detail)) | |
| 296 | await tick() | |
| 297 | expect(seen).toEqual([]) | |
| 298 | }) | |
| 299 | ||
| 256 | 300 | // #198 and #215. The Android page script runs the same block; its own test |
| 257 | 301 | // covers the rest of the contract. |
| 258 | 302 | const tick = () => new Promise(resolve => setTimeout(resolve, 5)) |