Files
study-bible-project/server/health.test.js
nmemmertandClaude Sonnet 5.5 bdb04cdedc
Build and Push Docker Image / build-and-push (push) Successful in 10m22s
Add cross-reference map, admin health page, passkeys and device list, settings tabs
- Reader: chapter cross-reference map (M) from IQ Bible's reference graph
- Admin: Health tab with disk use, snapshots (back up, download, restore), failure logs
- Passkey sign-in (WebAuthn), signed-in device list, sign out others, optional sign-in alerts
- Settings split into Account, Preferences, Notifications, Security, Your data tabs
- ntfy server field: catch a topic typed into the server box

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-06 12:52:49 -04:00

51 lines
2.3 KiB
JavaScript

// @vitest-environment node
import { afterEach, beforeEach, expect, test, vi } from 'vitest';
import { mkdtempSync, rmSync } from 'fs';
import { tmpdir } from 'os';
import { join } from 'path';
let dir;
beforeEach(() => { dir = mkdtempSync(join(tmpdir(), 'health-')); process.env.DATA_DIR = dir; vi.resetModules(); });
afterEach(() => { rmSync(dir, { recursive: true, force: true }); delete process.env.DATA_DIR; });
const load = async () => {
const db = await import('./db.js'); db.initDb();
return { db, backups: await import('./backups.js'), health: await import('./health.js') };
};
test('the event log keeps the newest first, filters by kind and is capped', async () => {
const { health } = await load();
health.logEvent('signin', 'a'); health.logEvent('notify', 'b'); health.logEvent('signin', 'c');
expect(health.recentEvents('signin').map((e) => e.detail)).toEqual(['c', 'a']);
for (let i = 0; i < 300; i += 1) health.logEvent('signin', String(i));
expect(health.recentEvents(null, 1000)).toHaveLength(200);
});
test('a snapshot can be restored, and what was there is kept as a safety copy', async () => {
const { db, backups } = await load();
db.createUser({ id: 'u1', email: 'a@x.test', passwordHash: 'h' });
await backups.runBackup(new Date('2026-10-01T10:00:00Z'));
db.createUser({ id: 'u2', email: 'b@x.test', passwordHash: 'h' });
expect(db.countUsers()).toBe(2);
const [snap] = backups.listSnapshots();
const result = await backups.restoreSnapshot(snap.name, new Date('2026-10-02T10:00:00Z'));
expect(db.countUsers()).toBe(1); // back to when the snapshot was taken
expect(backups.listSnapshots().map((s) => s.name)).toContain(result.safetyCopy.split('/').pop());
});
test('only real snapshot names resolve', async () => {
const { backups } = await load();
expect(backups.snapshotPath('../projects.db')).toBeNull();
expect(backups.snapshotPath('projects-2026-01-01-00-00.db')).toBeNull(); // valid name, but no such file
await expect(backups.restoreSnapshot('nope')).rejects.toThrow('No such snapshot');
});
test('disk use reports the database and snapshot sizes', async () => {
const { backups, health } = await load();
await backups.runBackup();
const use = health.diskUse();
expect(use.db).toBeGreaterThan(0);
expect(use.backups).toBeGreaterThan(0);
expect(health.backupStatus().latest).not.toBeNull();
});