mirror of
https://github.com/better-auth/better-auth.git
synced 2026-10-19 11:24:57 -05:00
131 lines
3.9 KiB
TypeScript
131 lines
3.9 KiB
TypeScript
import fs from "node:fs/promises";
|
|
import os from "node:os";
|
|
import path from "node:path";
|
|
import { expect, it } from "vitest";
|
|
import type { MigrationDecisions } from "../src/commands/migration-decisions";
|
|
import {
|
|
loadMigrationDecisions,
|
|
writeMigrationDecisions,
|
|
} from "../src/commands/migration-decisions";
|
|
|
|
it("rejects decisions that do not identify the release migration", async () => {
|
|
const directory = await fs.mkdtemp(
|
|
path.join(os.tmpdir(), "better-auth-migration-decisions-"),
|
|
);
|
|
const filePath = path.join(directory, "better-auth-migration.json");
|
|
await fs.writeFile(filePath, JSON.stringify({ formatVersion: 1 }), "utf8");
|
|
|
|
try {
|
|
await expect(loadMigrationDecisions(filePath)).rejects.toThrow("migration");
|
|
} finally {
|
|
await fs.rm(directory, { recursive: true });
|
|
}
|
|
});
|
|
|
|
it("rejects decisions for a different release migration", async () => {
|
|
const directory = await fs.mkdtemp(
|
|
path.join(os.tmpdir(), "better-auth-migration-decisions-"),
|
|
);
|
|
const filePath = path.join(directory, "better-auth-migration.json");
|
|
await fs.writeFile(
|
|
filePath,
|
|
JSON.stringify({ formatVersion: 1, migration: "1.7-to-1.8" }),
|
|
"utf8",
|
|
);
|
|
|
|
try {
|
|
await expect(loadMigrationDecisions(filePath)).rejects.toThrow("migration");
|
|
} finally {
|
|
await fs.rm(directory, { recursive: true });
|
|
}
|
|
});
|
|
|
|
it("preserves an existing migration decisions file with different content", async () => {
|
|
const directory = await fs.mkdtemp(
|
|
path.join(os.tmpdir(), "better-auth-migration-decisions-"),
|
|
);
|
|
const filePath = path.join(directory, "better-auth-migration.json");
|
|
const existing = `${JSON.stringify(
|
|
{
|
|
formatVersion: 1,
|
|
legacyTableNames: { oauthConsent: "oauthConsent" },
|
|
migration: "1.6-to-1.7",
|
|
},
|
|
null,
|
|
2,
|
|
)}\n`;
|
|
await fs.writeFile(filePath, existing, "utf8");
|
|
|
|
try {
|
|
await expect(
|
|
writeMigrationDecisions(filePath, {
|
|
formatVersion: 1,
|
|
legacyTableNames: { oauthConsent: "legacyOAuthConsent" },
|
|
migration: "1.6-to-1.7",
|
|
} satisfies MigrationDecisions),
|
|
).rejects.toThrow(
|
|
"already exists with different decisions and was not changed",
|
|
);
|
|
await expect(fs.readFile(filePath, "utf8")).resolves.toBe(existing);
|
|
} finally {
|
|
await fs.rm(directory, { recursive: true });
|
|
}
|
|
});
|
|
|
|
it("reuses an identical migration decisions file", async () => {
|
|
const directory = await fs.mkdtemp(
|
|
path.join(os.tmpdir(), "better-auth-migration-decisions-"),
|
|
);
|
|
const filePath = path.join(directory, "better-auth-migration.json");
|
|
const decisions = {
|
|
formatVersion: 1,
|
|
legacyTableNames: { oauthConsent: "oauthConsent" },
|
|
migration: "1.6-to-1.7",
|
|
} satisfies MigrationDecisions;
|
|
|
|
try {
|
|
await expect(writeMigrationDecisions(filePath, decisions)).resolves.toBe(
|
|
"created",
|
|
);
|
|
await expect(writeMigrationDecisions(filePath, decisions)).resolves.toBe(
|
|
"reused",
|
|
);
|
|
} finally {
|
|
await fs.rm(directory, { recursive: true });
|
|
}
|
|
});
|
|
|
|
it("allows only one of two different concurrent decisions to claim a path", async () => {
|
|
const directory = await fs.mkdtemp(
|
|
path.join(os.tmpdir(), "better-auth-migration-decisions-"),
|
|
);
|
|
const filePath = path.join(directory, "better-auth-migration.json");
|
|
const left = {
|
|
formatVersion: 1,
|
|
legacyTableNames: { oauthConsent: "oauthConsent" },
|
|
migration: "1.6-to-1.7",
|
|
} satisfies MigrationDecisions;
|
|
const right = {
|
|
formatVersion: 1,
|
|
legacyTableNames: { oauthConsent: "legacyOAuthConsent" },
|
|
migration: "1.6-to-1.7",
|
|
} satisfies MigrationDecisions;
|
|
|
|
try {
|
|
const results = await Promise.allSettled([
|
|
writeMigrationDecisions(filePath, left),
|
|
writeMigrationDecisions(filePath, right),
|
|
]);
|
|
expect(results.filter(({ status }) => status === "fulfilled")).toHaveLength(
|
|
1,
|
|
);
|
|
expect(results.filter(({ status }) => status === "rejected")).toHaveLength(
|
|
1,
|
|
);
|
|
const saved = JSON.parse(await fs.readFile(filePath, "utf8")) as unknown;
|
|
expect([left, right]).toContainEqual(saved);
|
|
} finally {
|
|
await fs.rm(directory, { recursive: true });
|
|
}
|
|
});
|