Files
kuber/tests/lib/database.test.ts
T

98 lines
2.8 KiB
TypeScript

import { describe, expect, test } from "bun:test";
import type { ComposeSpecification, Service } from "../../schema/docker.d";
import {
buildDatabaseUrl,
getComposePostgresClaims,
getServicePostgresClaim,
isPostgresVolumeEntry,
} from "../../lib/database";
describe("managed PostgreSQL claims", () => {
test("supports short and explicit syntax", () => {
expect(
getServicePostgresClaim("app", {
volumes: ["postgresql:app"],
} as Service),
).toEqual({
service: "app",
username: "app",
database: "app",
secretName: "postgres-app",
});
expect(
getServicePostgresClaim("app", {
volumes: ["postgresql:user/database"],
} as Service),
).toEqual({
service: "app",
username: "user",
database: "database",
secretName: "postgres-user",
});
});
test.each([
"postgresql:",
"postgresql:user/",
"postgresql:/database",
"postgresql:user/database/extra",
"postgresql:user:database",
])("rejects malformed declaration %s", (entry) => {
expect(() =>
getServicePostgresClaim("app", { volumes: [entry] } as Service),
).toThrow("Use postgresql:<name> or postgresql:<user>/<database>");
});
test("ignores unrelated entries and rejects duplicate declarations", () => {
expect(
getServicePostgresClaim("app", {
volumes: ["cache:/cache"],
} as Service),
).toBeUndefined();
expect(isPostgresVolumeEntry("cache:/cache")).toBe(false);
expect(() =>
getServicePostgresClaim("app", {
volumes: ["postgresql:one", "postgresql:two"],
} as Service),
).toThrow("declares multiple postgres volumes");
});
test("allows one owner to share a database", () => {
const compose = {
services: {
app: { volumes: ["postgresql:user/database"] },
worker: { volumes: ["postgresql:user/database"] },
},
} as ComposeSpecification;
expect(getComposePostgresClaims(compose)).toHaveLength(2);
});
test("rejects conflicting database owners", () => {
const compose = {
services: {
app: { volumes: ["postgresql:one/shared"] },
worker: { volumes: ["postgresql:two/shared"] },
},
} as ComposeSpecification;
expect(() => getComposePostgresClaims(compose)).toThrow(
"Database shared is claimed by both one and two",
);
});
test("escapes every connection URL component", () => {
expect(
buildDatabaseUrl(
{
service: "app",
username: "user@host",
database: "my/database",
secretName: "postgres-user",
},
{ username: "user@host", password: "p:a/ss?#" },
),
).toBe(
"postgresql://user%40host:p%3Aa%2Fss%3F%[email protected]:5432/my%2Fdatabase",
);
});
});