mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-08 04:32:42 +00:00
test(e2e): follow the restore to its job before reading the record
The restore route answers 202 with a job id and leaves the work to the backup-restore queue. The journey still expected the synchronous 200 and read the record straight after the click. It now asserts the queued answer and its status route, polls that route until the job reports succeeded (a failed job ends the wait with its code), and only then checks what the restore put back and dropped. The job runs on the pg-boss worker inside the server under test, as the manual backup pass earlier in the same file already relies on.
This commit is contained in:
1 parent
a46d0b41c8
commit
42e35ffbf9
1 file changed
+33
-2
@@ -532,7 +532,38 @@ test.describe("Backup and restore, through the settings surfaces", () => {
|
||||
|
||||
await openBackupsConsole(page);
|
||||
const response = await restoreThroughDialog(page, requireSnapshot());
|
||||
expect(response.status()).toBe(200);
|
||||
// The restore runs on the `backup-restore` queue: the request answers 202
|
||||
// with the job and its status route, and the worker inside the server
|
||||
// under test does the work. Nothing below is read until the job says it
|
||||
// is done, so every assertion is about the finished restore rather than
|
||||
// a moment in the middle of it.
|
||||
expect(response.status()).toBe(202);
|
||||
const queued = (await response.json()) as {
|
||||
data: { jobId: string; status: string; statusUrl: string };
|
||||
};
|
||||
expect(queued.data.status).toBe("queued");
|
||||
expect(queued.data.statusUrl).toBe(
|
||||
`/api/admin/backups/restores/${queued.data.jobId}`,
|
||||
);
|
||||
await expect
|
||||
.poll(
|
||||
async () => {
|
||||
const res = await page.request.get(queued.data.statusUrl);
|
||||
const body = (await res.json()) as {
|
||||
data: {
|
||||
status: string;
|
||||
failure: { code: string } | null;
|
||||
} | null;
|
||||
};
|
||||
// A failed job ends the wait with its code in the message instead
|
||||
// of running the clock out on a state that will never change.
|
||||
return body.data?.status === "failed"
|
||||
? `failed: ${body.data.failure?.code ?? "unknown"}`
|
||||
: body.data?.status;
|
||||
},
|
||||
{ timeout: 60_000, intervals: [250, 500, 1_000] },
|
||||
)
|
||||
.toBe("succeeded");
|
||||
|
||||
const afterRestore = await storedMeasurements();
|
||||
|
||||
@@ -564,7 +595,7 @@ test.describe("Backup and restore, through the settings surfaces", () => {
|
||||
|
||||
// And the reading that arrived after the snapshot is gone.
|
||||
// `docs/ops/backup-restore.md` says the restore "replaces the account's
|
||||
// data tables", and the route's own words are "one transaction replaces
|
||||
// data tables", and `restore-backup.ts` puts it as "one transaction replaces
|
||||
// every serialized owner-scoped class". Replacing is not merging: whoever
|
||||
// restores yesterday's copy loses today's readings, and that is the
|
||||
// documented behaviour rather than an accident of the implementation.
|
||||
|
||||
Reference in new issue
Block a user