test(cli): cover release inspection failure modes

This commit is contained in:
Gustavo Valverde
2026-08-25 07:23:34 -04:00
parent df50ac0511
commit 2df67c244b
2 changed files with 43 additions and 24 deletions
@@ -1494,6 +1494,9 @@ export async function retireScimAccountsFrom16(
DELETE FROM ${sql.table(accountTable)}
WHERE ${sql.ref(idColumn)} IN (${sql.join(accounts.map((account) => account.id))})
`.execute(kysely);
// The upgrade requires a maintenance window with every SCIM and account
// writer stopped. Recheck here so an in-flight write that crossed the
// shutdown boundary blocks the migration before it can continue.
const { accounts: remainingAccounts } = await readScimAccountsFrom16(
config,
state,
+40 -24
View File
@@ -836,40 +836,56 @@ describe("migrate command modes", () => {
/**
* @see https://github.com/better-auth/better-auth/pull/10575#discussion_r3830648963
*/
it("reports release inspection failures as a blocked JSON plan", async () => {
it.each([
"plan",
"apply",
] as const)("reports release inspection failures as a blocked JSON %s result", async (mode) => {
const db = new Database(":memory:");
const auth = betterAuth({ database: db });
vi.spyOn(config, "getConfig").mockImplementation(async () => auth.options);
vi.spyOn(
releaseMigration,
"inspectLegacyReleaseDataFrom16",
).mockRejectedValueOnce(new Error("legacy data is unreadable"));
const inspectLegacyReleaseData = vi
.spyOn(releaseMigration, "inspectLegacyReleaseDataFrom16")
.mockRejectedValueOnce(new Error("legacy data is unreadable"));
const migrationFile = await writeMigrationDecisions({
formatVersion: 1,
migration: "1.6-to-1.7",
});
const consoleLog = vi.spyOn(console, "log").mockImplementation(() => {});
await expect(
migrateAction({
cwd: process.cwd(),
migrationFile,
mode: "plan",
outputFormat: "json",
}),
).resolves.toBeUndefined();
try {
await expect(
migrateAction({
approved: true,
cwd: process.cwd(),
migrationFile,
mode,
outputFormat: "json",
}),
).resolves.toBeUndefined();
expect(process.exitCode).toBe(1);
expect(JSON.parse(String(consoleLog.mock.calls[0]?.[0]))).toMatchObject({
blockers: [
{
code: "release-migration-error",
message: "legacy data is unreadable",
},
],
status: "blocked",
});
process.exitCode = undefined;
expect(inspectLegacyReleaseData).toHaveBeenCalledOnce();
if (mode === "plan") {
expect(process.exitCode).toBe(1);
} else {
expect(process.exit).toHaveBeenCalledWith(1);
}
const output = JSON.parse(String(consoleLog.mock.calls[0]?.[0]));
const plan = mode === "apply" ? output.plan : output;
expect(plan).toMatchObject({
blockers: [
{
code: "release-migration-error",
message: "legacy data is unreadable",
},
],
status: "blocked",
});
if (mode === "apply") {
expect(output).toMatchObject({ status: "blocked" });
}
} finally {
process.exitCode = undefined;
}
});
it("rejects interactive JSON application before inspecting the database", async () => {