Files
HealthLog/tests/integration/pending-migrations-notice.test.ts
T

79 lines
2.8 KiB
TypeScript

/**
* The boot notice `docker-entrypoint.sh` prints before `migrate deploy`
* (`scripts/pending-migrations.mjs`), against the migrated test database.
*
* Every shipped migration is applied here, so the count is zero; a
* migrations directory with one more entry than the database has applied
* stands for a freshly pulled image, and a schema with no migrations table
* for a first boot.
*/
import { cpSync, mkdirSync, mkdtempSync, rmSync, writeFileSync } from "node:fs";
import { tmpdir } from "node:os";
import { join } from "node:path";
import { afterEach, describe, expect, it } from "vitest";
import {
pendingMigrations,
pendingNotice,
shippedMigrations,
} from "../../scripts/pending-migrations.mjs";
const MIGRATIONS = join(process.cwd(), "prisma", "migrations");
const tempDirs: string[] = [];
afterEach(() => {
for (const dir of tempDirs.splice(0)) rmSync(dir, { recursive: true });
});
function connectionString(): string {
const url = process.env.DATABASE_URL;
if (!url) throw new Error("DATABASE_URL is not set for the integration run");
return url;
}
describe("pending-migrations boot notice", () => {
it("counts nothing pending on a database that has applied every migration", async () => {
const pending = await pendingMigrations({
connectionString: connectionString(),
migrationsDir: MIGRATIONS,
});
expect(shippedMigrations(MIGRATIONS).length).toBeGreaterThan(300);
expect(pending).toEqual([]);
expect(pendingNotice(pending.length)).toBe(
"HealthLog: Database schema is up to date.",
);
});
it("counts a migration the image ships and the database has not applied", async () => {
const dir = mkdtempSync(join(tmpdir(), "hl-migrations-"));
tempDirs.push(dir);
cpSync(MIGRATIONS, dir, { recursive: true });
mkdirSync(join(dir, "9999_not_applied_yet"));
writeFileSync(join(dir, "9999_not_applied_yet", "migration.sql"), "");
// A directory without migration.sql is not a migration.
mkdirSync(join(dir, "9998_no_sql"));
const pending = await pendingMigrations({
connectionString: connectionString(),
migrationsDir: dir,
});
expect(pending).toEqual(["9999_not_applied_yet"]);
const notice = pendingNotice(pending.length);
expect(notice).toContain("1 database migration pending");
expect(notice).toContain("pg_dump");
});
it("treats a schema without a migrations table as a first boot", async () => {
const url = new URL(connectionString());
url.searchParams.set("schema", "schema_never_migrated");
const pending = await pendingMigrations({
connectionString: url.toString(),
migrationsDir: MIGRATIONS,
});
expect(pending).toEqual(shippedMigrations(MIGRATIONS));
expect(pendingNotice(pending.length)).toMatch(
/^HealthLog: \d+ database migrations pending\./,
);
});
});