47 lines
1.8 KiB
TypeScript
47 lines
1.8 KiB
TypeScript
import { describe, expect, it } from "vitest";
|
|
|
|
import {
|
|
createPostgresPool,
|
|
getScriptDataBackend,
|
|
quotePostgresIdentifier
|
|
} from "../scripts/postgres-client.mjs";
|
|
|
|
describe("PostgreSQL script configuration", () => {
|
|
it("requires an explicit data backend", () => {
|
|
expect(() => getScriptDataBackend({ NODE_ENV: "test" })).toThrow("ZHINIAN_DATA_BACKEND");
|
|
expect(getScriptDataBackend({ NODE_ENV: "test", ZHINIAN_DATA_BACKEND: "postgres" })).toBe("postgres");
|
|
});
|
|
|
|
it("forces plaintext even when DATABASE_URL requests verified TLS", async () => {
|
|
const pool = createPostgresPool({
|
|
env: {
|
|
NODE_ENV: "test",
|
|
ZHINIAN_DATA_BACKEND: "postgres",
|
|
DATABASE_URL: "postgresql://app:secret@rds.example:5432/app?connect_timeout=5&sslmode=verify-full&sslrootcert=/missing/ca.pem"
|
|
}
|
|
});
|
|
|
|
expect(pool.options.ssl).toBe(false);
|
|
expect(pool.options.connectionString).toContain("sslmode=disable");
|
|
expect(pool.options.connectionString).not.toContain("sslrootcert");
|
|
expect(pool.options.connectionString).toContain("connect_timeout=5");
|
|
await pool.end();
|
|
});
|
|
|
|
it("rejects unsupported connection-string SSL options", () => {
|
|
expect(() => createPostgresPool({
|
|
env: {
|
|
NODE_ENV: "test",
|
|
ZHINIAN_DATA_BACKEND: "postgres",
|
|
DATABASE_URL: "postgresql://app:secret@rds.example:5432/app?sslcert=unexpected"
|
|
}
|
|
})).toThrow("unsupported SSL query parameters");
|
|
});
|
|
|
|
it("quotes PostgreSQL role identifiers without allowing SQL syntax injection", () => {
|
|
expect(quotePostgresIdentifier("zhinian_app")).toBe('"zhinian_app"');
|
|
expect(() => quotePostgresIdentifier('app"role')).toThrow("identifier");
|
|
expect(() => quotePostgresIdentifier("bad\0role")).toThrow("identifier");
|
|
});
|
|
});
|