summaryrefslogtreecommitdiff
path: root/web/test/enable-notifications.test.mjs
blob: c8afdd3e2bd5d8ab5612081d53e0a1e1448c62d5 (plain)
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
// 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');
  });
});