import { test } from 'node:test'; import assert from 'node:assert/strict'; import { createStore } from 'jotai'; import { ImportRoomKeyProgressData, ImportRoomKeyStage } from 'matrix-js-sdk/lib/crypto-api'; import { backupRestoreProgressAtom, BackupProgressStatus } from './backupRestore'; // backupRestoreProgressAtom maps ImportRoomKeyProgressData stages onto an // IBackupProgress status held in an unexported baseAtom: // Fetch -> Fetching // LoadKeys with successes+failures === total -> Done // LoadKeys otherwise -> Loading{ downloaded = successes+failures } // We drive the write atom through a jotai store and read back the getter. const load = (successes: number, failures: number, total: number): ImportRoomKeyProgressData => ({ stage: ImportRoomKeyStage.LoadKeys, successes, failures, total, }); test('starts Idle', () => { const store = createStore(); assert.deepEqual(store.get(backupRestoreProgressAtom), { status: BackupProgressStatus.Idle, }); }); test('Fetch stage -> Fetching', () => { const store = createStore(); store.set(backupRestoreProgressAtom, { stage: ImportRoomKeyStage.Fetch }); assert.deepEqual(store.get(backupRestoreProgressAtom), { status: BackupProgressStatus.Fetching, }); }); test('LoadKeys with downloaded === total -> Done', () => { const store = createStore(); store.set(backupRestoreProgressAtom, load(8, 2, 10)); assert.deepEqual(store.get(backupRestoreProgressAtom), { status: BackupProgressStatus.Done, }); }); test('LoadKeys mid-progress -> Loading with downloaded = successes + failures', () => { const store = createStore(); store.set(backupRestoreProgressAtom, load(3, 1, 10)); assert.deepEqual(store.get(backupRestoreProgressAtom), { status: BackupProgressStatus.Loading, data: { downloaded: 4, successes: 3, failures: 1, total: 10 }, }); }); test('LoadKeys at zero progress -> Loading with downloaded 0', () => { const store = createStore(); store.set(backupRestoreProgressAtom, load(0, 0, 5)); assert.deepEqual(store.get(backupRestoreProgressAtom), { status: BackupProgressStatus.Loading, data: { downloaded: 0, successes: 0, failures: 0, total: 5 }, }); }); test('Fetch then LoadKeys completion transitions Fetching -> Done', () => { const store = createStore(); store.set(backupRestoreProgressAtom, { stage: ImportRoomKeyStage.Fetch }); assert.equal(store.get(backupRestoreProgressAtom).status, BackupProgressStatus.Fetching); store.set(backupRestoreProgressAtom, load(5, 0, 5)); assert.equal(store.get(backupRestoreProgressAtom).status, BackupProgressStatus.Done); });