Closer/functions/src/backup/onRestoreRequested.test.ts

40 lines
1.7 KiB
TypeScript
Raw Normal View History

import { selfAlertAllowed, isRestoreReadyTransition, SELF_ALERT_DEDUPE_MS } from './onRestoreRequested'
// Both helpers are pure decisions extracted from the restore triggers, so no firebase-admin mock is needed.
describe('selfAlertAllowed (self-alert spam dedupe)', () => {
const now = 1_000_000_000_000
it('allows the alert when no previous alert timestamp exists', () => {
expect(selfAlertAllowed(undefined, now)).toBe(true)
expect(selfAlertAllowed(null, now)).toBe(true)
expect(selfAlertAllowed('not-a-number', now)).toBe(true)
})
it('suppresses a second alert inside the dedupe window', () => {
expect(selfAlertAllowed(now - (SELF_ALERT_DEDUPE_MS - 1), now)).toBe(false)
expect(selfAlertAllowed(now - 1, now)).toBe(false)
})
it('allows again once the window has elapsed', () => {
expect(selfAlertAllowed(now - SELF_ALERT_DEDUPE_MS, now)).toBe(true)
expect(selfAlertAllowed(now - (SELF_ALERT_DEDUPE_MS + 5_000), now)).toBe(true)
})
})
describe('isRestoreReadyTransition (completion-alert guard)', () => {
it('fires only on the REQUESTED→READY edge', () => {
expect(isRestoreReadyTransition('REQUESTED', 'READY')).toBe(true)
})
it('does not fire when already READY (no repeat on unrelated updates)', () => {
expect(isRestoreReadyTransition('READY', 'READY')).toBe(false)
})
it('does not fire for non-READY outcomes', () => {
expect(isRestoreReadyTransition('REQUESTED', 'DECLINED')).toBe(false)
expect(isRestoreReadyTransition('REQUESTED', 'EXPIRED')).toBe(false)
expect(isRestoreReadyTransition('READY', 'RESTORED')).toBe(false)
expect(isRestoreReadyTransition(undefined, undefined)).toBe(false)
})
})