test(uninstall): cover backups that fail verification after copying

Add cases where the backup copy reports success but leaves the recovery
file missing or holding other bytes; uninstall must fail before writing.
Narrow the installation guide so it promises a backup path only for the
failures that report one.
This commit is contained in:
Adolanium committed 2026-10-16 23:46:40 +03:00
1 parent 2dfc2d0f7c
commit 70bff72403
2 files changed
+35 -3

No files matched your search

+4 -3
View File
@@ -61,9 +61,10 @@ create backups, use atomic replacement, and verify their result. Setup and
uninstall retain an existing `.rea.backup` rather than replacing the first snapshot.
If that snapshot differs from the current configuration, setup and uninstall
preserve a verified `.rea.backup.<sha256>.recovery` copy of the current bytes
before editing; setup also previews it. Both snapshots remain available; a
failed update, readback, or rollback names the backup path that holds the bytes
from just before that edit.
before editing; setup also previews it. Both snapshots remain available.
When an edit made a backup, a failed uninstall update or restore, and a failed
setup readback or rollback, name the backup path that holds the bytes from just
before that edit.
Setup also retains valid environment overrides in REA's existing server entry,
such as `REA_MCP_INPUT_SCHEMA_PROFILE`, `REA_MCP_OUTPUT_SCHEMA_PROFILE`, and
`REA_MCP_MAX_RESPONSE_BYTES`.
@@ -138,6 +138,37 @@ describe("uninstall backups after edits made since setup", () => {
expect(await readFile(configPath, "utf8")).toBe(beforeUninstall);
expect(await readFile(recoveryPath, "utf8")).toBe("occupied by other data");
});
it.each([
["missing", async () => undefined],
[
"wrong",
(_source: string, destination: string) =>
writeFile(destination, "not the current configuration", {
flag: "wx",
}),
],
] as const)(
"blocks removal when the reported copy leaves %s backup bytes",
async (_label, copy) => {
const { root, configPath, client, beforeUninstall } =
await editedSinceSetup("rea-uninstall-current-backup-unverified-");
let writes = 0;
const result = await systemUninstallHost(root, {
...fileSystem("update"),
copy,
writeText: async () => {
writes += 1;
},
}).removeClient(client);
expect(result.status).toBe("failed");
expect(result.detail).toMatch(
/^Configuration could not be backed up, so no change was made\. /,
);
expect(writes).toBe(0);
expect(await readFile(configPath, "utf8")).toBe(beforeUninstall);
},
);
});
it("accepts a literal UTF-8 replacement character without changing its value", async () => {