// enable-notifications.test.mjs — Tests for the enableNotifications subscription flow. // // Run with: node --test web/test/enable-notifications.test.mjs import { describe, it, beforeEach } from 'node:test'; import assert from 'node:assert/strict'; // ── Logic under test ────────────────────────────────────────────────────────── // // When subscribing to push notifications, any existing stale subscription // (e.g. from before a VAPID key rotation) must be unsubscribed first. // Otherwise the browser rejects subscribe() with "applicationServerKey is not valid". /** * Extracted subscription logic (mirrors enableNotifications in app.js). * Returns the new subscription endpoint, or throws on error. */ async function subscribeWithUnsubscribeStale(pushManager, applicationServerKey) { // Clear any stale existing subscription. const existing = await pushManager.getSubscription(); if (existing) { await existing.unsubscribe(); } const sub = await pushManager.subscribe({ userVisibleOnly: true, applicationServerKey }); return sub; } describe('subscribeWithUnsubscribeStale', () => { it('unsubscribes existing subscription before subscribing', async () => { let unsubscribeCalled = false; const existingSub = { unsubscribe: async () => { unsubscribeCalled = true; }, }; let subscribeCalled = false; const pushManager = { getSubscription: async () => existingSub, subscribe: async (opts) => { subscribeCalled = true; return { endpoint: 'https://push.example.com/sub/new', toJSON: () => ({}) }; }, }; await subscribeWithUnsubscribeStale(pushManager, new Uint8Array([4, 1, 2])); assert.equal(unsubscribeCalled, true, 'existing subscription should have been unsubscribed'); assert.equal(subscribeCalled, true, 'new subscription should have been created'); }); it('subscribes normally when no existing subscription', async () => { let subscribeCalled = false; const pushManager = { getSubscription: async () => null, subscribe: async (opts) => { subscribeCalled = true; return { endpoint: 'https://push.example.com/sub/new', toJSON: () => ({}) }; }, }; const sub = await subscribeWithUnsubscribeStale(pushManager, new Uint8Array([4, 1, 2])); assert.equal(subscribeCalled, true, 'subscribe should have been called'); assert.ok(sub, 'subscription object should be returned'); }); });