feat: add opt-in daily Discord reminders with quiet hours
This commit is contained in:
@@ -15,6 +15,7 @@ test("WAL snapshots restore committed progress, revoke sessions, replicate, and
|
||||
mkdirSync(config.replica!);
|
||||
const habit = await f.json("/habits", "POST", { name: "Water", method: "count", target: 8, unit: "cups" }, 201);
|
||||
await f.json(`/habits/${habit.id}/days/2026-09-04/progress`, "PUT", { count: 6 });
|
||||
f.sqlite.exec("INSERT INTO reminder_settings (user_id, enabled, time, quiet_start, quiet_end, updated_at) VALUES ('alice', 1, '20:00', '22:00', '08:00', 0)");
|
||||
const first = createBackup(f.sqlite, config);
|
||||
expect(statSync(first).mode & 0o777).toBe(0o600);
|
||||
expect(latestBackupTime(config)).toBeGreaterThan(0);
|
||||
@@ -24,6 +25,7 @@ test("WAL snapshots restore committed progress, revoke sessions, replicate, and
|
||||
try {
|
||||
expect(restored.query("SELECT count FROM habit_days").get()).toEqual({ count: 6 });
|
||||
expect(restored.query("SELECT * FROM sessions").all()).toEqual([]);
|
||||
expect(restored.query("SELECT enabled FROM reminder_settings").get()).toEqual({ enabled: 0 });
|
||||
expect(restored.query("PRAGMA integrity_check").get()).toEqual({ integrity_check: "ok" });
|
||||
} finally { restored.close(); }
|
||||
expect(() => restoreBackup(first, destination)).toThrow("new path");
|
||||
@@ -48,3 +50,24 @@ test("invalid backups and missing replica mounts fail without overwriting data",
|
||||
expect(latestBackupTime(config)).toBe(0);
|
||||
} finally { f.close(); rmSync(directory, { recursive: true, force: true }); }
|
||||
});
|
||||
|
||||
test("backup and restore CLIs work against a live database without overwriting it", async () => {
|
||||
const directory = mkdtempSync(join(tmpdir(), "minabot-backup-cli-"));
|
||||
const path = join(directory, "live.sqlite");
|
||||
const f = fixture(path);
|
||||
try {
|
||||
f.sqlite.exec("PRAGMA journal_mode=WAL");
|
||||
await f.json('/habits', 'POST', { name: 'CLI recovery', method: 'manual' }, 201);
|
||||
const backup = Bun.spawnSync([process.execPath, 'scripts/backup.ts'], {
|
||||
env: { ...process.env, DATABASE_PATH: path, BACKUP_DIR: 'backups', BACKUP_REPLICA_DIR: '', BACKUP_RETAIN: '7', BACKUP_INTERVAL_HOURS: '24' },
|
||||
});
|
||||
expect(backup.exitCode).toBe(0);
|
||||
const snapshot = backup.stdout.toString().trim();
|
||||
const restored = join(directory, 'recovered.sqlite');
|
||||
const result = Bun.spawnSync([process.execPath, 'scripts/restore.ts', snapshot, restored]);
|
||||
expect(result.exitCode).toBe(0);
|
||||
const check = new Database(restored, { readonly: true });
|
||||
try { expect(check.query('SELECT count(*) AS n FROM habits').get()).toEqual({ n: 1 }); } finally { check.close(); }
|
||||
expect(f.sqlite.query('SELECT count(*) AS n FROM sessions').get()).toEqual({ n: 2 });
|
||||
} finally { f.close(); rmSync(directory, { recursive: true, force: true }); }
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user