import test from 'node:test'; import assert from 'node:assert/strict'; import { computeRetryDelayMinutes } from '../src/services/notification-dispatcher.js'; import { createPushSender, classifyMessagingError } from '../src/services/notification-fcm.js'; test('computeRetryDelayMinutes backs off exponentially with a cap', () => { assert.equal(computeRetryDelayMinutes(1), 5); assert.equal(computeRetryDelayMinutes(2), 10); assert.equal(computeRetryDelayMinutes(3), 20); assert.equal(computeRetryDelayMinutes(5), 60); assert.equal(computeRetryDelayMinutes(9), 60); }); test('classifyMessagingError distinguishes invalid and retryable push failures', () => { assert.equal(classifyMessagingError('messaging/registration-token-not-registered'), 'INVALID_TOKEN'); assert.equal(classifyMessagingError('messaging/server-unavailable'), 'RETRYABLE'); assert.equal(classifyMessagingError('messaging/unknown-problem'), 'FAILED'); }); test('createPushSender log-only mode simulates successful delivery results', async () => { const sender = createPushSender({ deliveryMode: 'log-only' }); const results = await sender.send( { id: 'notification-1', notification_type: 'SHIFT_START_REMINDER', priority: 'HIGH', tenant_id: 'tenant-1', payload: { assignmentId: 'assignment-1' }, }, [ { id: 'token-1', provider: 'FCM', pushToken: 'demo-token' }, ] ); assert.equal(results.length, 1); assert.equal(results[0].deliveryStatus, 'SIMULATED'); assert.equal(results[0].transient, false); });