/**
* postgres-mcp - Prompts Unit Tests
*
* Tests for PostgreSQL prompts verifying structure, handlers,
* and proper argument handling.
*/
import { describe, it, expect, vi, beforeEach } from "vitest";
import { getPostgresPrompts } from "../index.js";
import type { PostgresAdapter } from "../../PostgresAdapter.js";
import {
createMockPostgresAdapter,
createMockRequestContext,
} from "../../../../__tests__/mocks/index.js";
describe("getPostgresPrompts", () => {
let mockAdapter: ReturnType<typeof createMockPostgresAdapter>;
let prompts: ReturnType<typeof getPostgresPrompts>;
beforeEach(() => {
vi.clearAllMocks();
mockAdapter = createMockPostgresAdapter();
// Mock getToolDefinitions to return sample tools for tool index prompt
(
mockAdapter.getToolDefinitions as ReturnType<typeof vi.fn>
).mockReturnValue([
{
name: "pg_read_query",
description: "Execute a read query",
group: "core",
},
{
name: "pg_write_query",
description: "Execute a write query",
group: "core",
},
]);
prompts = getPostgresPrompts(mockAdapter as unknown as PostgresAdapter);
});
it("should return 19 prompts", () => {
expect(prompts).toHaveLength(19);
});
it("should have all expected prompt names", () => {
const promptNames = prompts.map((p) => p.name);
// Original prompts
expect(promptNames).toContain("pg_query_builder");
expect(promptNames).toContain("pg_schema_design");
expect(promptNames).toContain("pg_performance_analysis");
expect(promptNames).toContain("pg_migration");
expect(promptNames).toContain("pg_tool_index");
expect(promptNames).toContain("pg_quick_query");
expect(promptNames).toContain("pg_quick_schema");
// Health and optimization prompts
expect(promptNames).toContain("pg_database_health_check");
expect(promptNames).toContain("pg_backup_strategy");
expect(promptNames).toContain("pg_index_tuning");
expect(promptNames).toContain("pg_extension_setup");
// Extension setup prompts
expect(promptNames).toContain("pg_setup_pgvector");
expect(promptNames).toContain("pg_setup_postgis");
expect(promptNames).toContain("pg_setup_pgcron");
expect(promptNames).toContain("pg_setup_partman");
expect(promptNames).toContain("pg_setup_kcache");
expect(promptNames).toContain("pg_setup_citext");
expect(promptNames).toContain("pg_setup_ltree");
expect(promptNames).toContain("pg_setup_pgcrypto");
});
it("should have handler function for all prompts", () => {
for (const prompt of prompts) {
expect(typeof prompt.handler).toBe("function");
}
});
it("should have required description for all prompts", () => {
for (const prompt of prompts) {
expect(prompt.description).toBeDefined();
expect(prompt.description.length).toBeGreaterThan(0);
}
});
});
describe("pg_query_builder prompt", () => {
let prompts: ReturnType<typeof getPostgresPrompts>;
let mockContext: ReturnType<typeof createMockRequestContext>;
beforeEach(() => {
vi.clearAllMocks();
const mockAdapter = createMockPostgresAdapter();
(
mockAdapter.getToolDefinitions as ReturnType<typeof vi.fn>
).mockReturnValue([]);
prompts = getPostgresPrompts(mockAdapter as unknown as PostgresAdapter);
mockContext = createMockRequestContext();
});
it("should require tables and operation arguments", () => {
const prompt = prompts.find((p) => p.name === "pg_query_builder")!;
expect(prompt.arguments).toHaveLength(2);
expect(prompt.arguments?.find((a) => a.name === "tables")?.required).toBe(
true,
);
expect(
prompt.arguments?.find((a) => a.name === "operation")?.required,
).toBe(true);
});
it("should generate query guidance with tables and operation", async () => {
const prompt = prompts.find((p) => p.name === "pg_query_builder")!;
const result = await prompt.handler(
{ tables: "users,orders", operation: "JOIN" },
mockContext,
);
expect(result).toContain("users,orders");
expect(result).toContain("JOIN");
expect(result).toContain("parameterized queries");
});
});
describe("pg_schema_design prompt", () => {
let prompts: ReturnType<typeof getPostgresPrompts>;
let mockContext: ReturnType<typeof createMockRequestContext>;
beforeEach(() => {
vi.clearAllMocks();
const mockAdapter = createMockPostgresAdapter();
(
mockAdapter.getToolDefinitions as ReturnType<typeof vi.fn>
).mockReturnValue([]);
prompts = getPostgresPrompts(mockAdapter as unknown as PostgresAdapter);
mockContext = createMockRequestContext();
});
it("should accept useCase and optional requirements", () => {
const prompt = prompts.find((p) => p.name === "pg_schema_design")!;
expect(prompt.arguments?.find((a) => a.name === "useCase")?.required).toBe(
true,
);
expect(
prompt.arguments?.find((a) => a.name === "requirements")?.required,
).toBe(false);
});
it("should generate schema design guidance", async () => {
const prompt = prompts.find((p) => p.name === "pg_schema_design")!;
const result = await prompt.handler(
{
useCase: "E-commerce platform",
requirements: "Must support 1M users",
},
mockContext,
);
expect(result).toContain("E-commerce platform");
expect(result).toContain("1M users");
expect(result).toContain("data types");
});
});
describe("pg_performance_analysis prompt", () => {
let prompts: ReturnType<typeof getPostgresPrompts>;
let mockContext: ReturnType<typeof createMockRequestContext>;
beforeEach(() => {
vi.clearAllMocks();
const mockAdapter = createMockPostgresAdapter();
(
mockAdapter.getToolDefinitions as ReturnType<typeof vi.fn>
).mockReturnValue([]);
prompts = getPostgresPrompts(mockAdapter as unknown as PostgresAdapter);
mockContext = createMockRequestContext();
});
it("should accept query and optional context", () => {
const prompt = prompts.find((p) => p.name === "pg_performance_analysis")!;
expect(prompt.arguments?.find((a) => a.name === "query")?.required).toBe(
true,
);
expect(prompt.arguments?.find((a) => a.name === "context")?.required).toBe(
false,
);
});
it("should generate performance analysis guidance", async () => {
const prompt = prompts.find((p) => p.name === "pg_performance_analysis")!;
const result = await prompt.handler(
{
query: "SELECT * FROM users WHERE email LIKE $1",
context: "Table has 10M rows",
},
mockContext,
);
expect(result).toContain("SELECT * FROM users");
expect(result).toContain("10M rows");
expect(result).toContain("pg_explain");
});
});
describe("pg_migration prompt", () => {
let prompts: ReturnType<typeof getPostgresPrompts>;
let mockContext: ReturnType<typeof createMockRequestContext>;
beforeEach(() => {
vi.clearAllMocks();
const mockAdapter = createMockPostgresAdapter();
(
mockAdapter.getToolDefinitions as ReturnType<typeof vi.fn>
).mockReturnValue([]);
prompts = getPostgresPrompts(mockAdapter as unknown as PostgresAdapter);
mockContext = createMockRequestContext();
});
it("should generate migration guidance", async () => {
const prompt = prompts.find((p) => p.name === "pg_migration")!;
const result = await prompt.handler(
{
change: "Add email column",
table: "users",
},
mockContext,
);
expect(result).toContain("Add email column");
expect(result).toContain("users");
expect(result).toContain("Up Migration");
expect(result).toContain("Down Migration");
});
});
describe("pg_tool_index prompt", () => {
let prompts: ReturnType<typeof getPostgresPrompts>;
let mockContext: ReturnType<typeof createMockRequestContext>;
beforeEach(() => {
vi.clearAllMocks();
const mockAdapter = createMockPostgresAdapter();
(
mockAdapter.getToolDefinitions as ReturnType<typeof vi.fn>
).mockReturnValue([
{
name: "pg_read_query",
description: "Execute a read query. Returns rows.",
group: "core",
},
{
name: "pg_write_query",
description: "Execute a write query. Returns affected rows.",
group: "core",
},
{
name: "pg_explain",
description: "Explain a query plan.",
group: "performance",
},
]);
prompts = getPostgresPrompts(mockAdapter as unknown as PostgresAdapter);
mockContext = createMockRequestContext();
});
it("should generate tool index with groups", async () => {
const prompt = prompts.find((p) => p.name === "pg_tool_index")!;
const result = await prompt.handler({}, mockContext);
expect(result).toContain("PostgreSQL MCP Tools");
expect(result).toContain("core");
expect(result).toContain("pg_read_query");
});
});
describe("pg_quick_query prompt", () => {
let prompts: ReturnType<typeof getPostgresPrompts>;
let mockContext: ReturnType<typeof createMockRequestContext>;
beforeEach(() => {
vi.clearAllMocks();
const mockAdapter = createMockPostgresAdapter();
(
mockAdapter.getToolDefinitions as ReturnType<typeof vi.fn>
).mockReturnValue([]);
prompts = getPostgresPrompts(mockAdapter as unknown as PostgresAdapter);
mockContext = createMockRequestContext();
});
it("should generate quick query guidance", async () => {
const prompt = prompts.find((p) => p.name === "pg_quick_query")!;
const result = await prompt.handler(
{
action: "find users by email",
},
mockContext,
);
expect(result).toContain("find users by email");
expect(result).toContain("pg_read_query");
});
});
describe("pg_quick_schema prompt", () => {
let prompts: ReturnType<typeof getPostgresPrompts>;
let mockContext: ReturnType<typeof createMockRequestContext>;
beforeEach(() => {
vi.clearAllMocks();
const mockAdapter = createMockPostgresAdapter();
(
mockAdapter.getToolDefinitions as ReturnType<typeof vi.fn>
).mockReturnValue([]);
prompts = getPostgresPrompts(mockAdapter as unknown as PostgresAdapter);
mockContext = createMockRequestContext();
});
it("should return schema exploration reference", async () => {
const prompt = prompts.find((p) => p.name === "pg_quick_schema")!;
const result = await prompt.handler({}, mockContext);
expect(result).toContain("pg_list_tables");
expect(result).toContain("pg_describe_table");
expect(result).toContain("postgres://schema");
});
});
describe("Extension setup prompts", () => {
let prompts: ReturnType<typeof getPostgresPrompts>;
let mockContext: ReturnType<typeof createMockRequestContext>;
beforeEach(() => {
vi.clearAllMocks();
const mockAdapter = createMockPostgresAdapter();
(
mockAdapter.getToolDefinitions as ReturnType<typeof vi.fn>
).mockReturnValue([]);
prompts = getPostgresPrompts(mockAdapter as unknown as PostgresAdapter);
mockContext = createMockRequestContext();
});
it("pg_setup_pgvector should provide pgvector setup guidance", async () => {
const prompt = prompts.find((p) => p.name === "pg_setup_pgvector")!;
const result = (await prompt.handler({}, mockContext)) as string;
expect(result).toContain("pgvector");
expect(result.toLowerCase()).toContain("vector");
});
it("pg_setup_pgvector should highlight cosine distance metric when selected", async () => {
const prompt = prompts.find((p) => p.name === "pg_setup_pgvector")!;
const result = (await prompt.handler(
{ distanceMetric: "cosine" },
mockContext,
)) as string;
expect(result).toContain("✓ Selected");
expect(result).toContain("cosine");
});
it("pg_setup_pgvector should highlight l2 distance metric when selected", async () => {
const prompt = prompts.find((p) => p.name === "pg_setup_pgvector")!;
const result = (await prompt.handler(
{ distanceMetric: "l2" },
mockContext,
)) as string;
expect(result).toContain("L2/Euclidean (✓ Selected)");
expect(result).toContain("vector_l2_ops");
});
it("pg_setup_pgvector should highlight inner_product distance metric when selected", async () => {
const prompt = prompts.find((p) => p.name === "pg_setup_pgvector")!;
const result = (await prompt.handler(
{ distanceMetric: "inner_product" },
mockContext,
)) as string;
expect(result).toContain("Inner Product (✓ Selected)");
expect(result).toContain("vector_inner_product_ops");
});
it("pg_setup_pgvector should use custom content type and dimensions", async () => {
const prompt = prompts.find((p) => p.name === "pg_setup_pgvector")!;
const result = (await prompt.handler(
{
contentType: "products",
dimensions: "768",
},
mockContext,
)) as string;
expect(result).toContain("Products");
expect(result).toContain("768");
expect(result).toContain("CREATE TABLE products");
});
it("pg_setup_postgis should provide PostGIS setup guidance", async () => {
const prompt = prompts.find((p) => p.name === "pg_setup_postgis")!;
const result = await prompt.handler({}, mockContext);
expect(result).toContain("PostGIS");
});
it("pg_setup_pgcron should provide pg_cron setup guidance", async () => {
const prompt = prompts.find((p) => p.name === "pg_setup_pgcron")!;
const result = await prompt.handler({}, mockContext);
expect(result).toContain("pg_cron");
});
it("pg_setup_partman should provide pg_partman setup guidance", async () => {
const prompt = prompts.find((p) => p.name === "pg_setup_partman")!;
const result = await prompt.handler({}, mockContext);
expect(result).toContain("pg_partman");
});
it("pg_setup_kcache should provide pg_stat_kcache setup guidance", async () => {
const prompt = prompts.find((p) => p.name === "pg_setup_kcache")!;
const result = (await prompt.handler({}, mockContext)) as string;
expect(result.toLowerCase()).toContain("kcache");
});
it("pg_setup_citext should provide citext setup guidance", async () => {
const prompt = prompts.find((p) => p.name === "pg_setup_citext")!;
const result = await prompt.handler({}, mockContext);
expect(result).toContain("citext");
});
it("pg_setup_ltree should provide ltree setup guidance", async () => {
const prompt = prompts.find((p) => p.name === "pg_setup_ltree")!;
const result = await prompt.handler({}, mockContext);
expect(result).toContain("ltree");
});
it("pg_setup_pgcrypto should provide pgcrypto setup guidance", async () => {
const prompt = prompts.find((p) => p.name === "pg_setup_pgcrypto")!;
const result = await prompt.handler({}, mockContext);
expect(result).toContain("pgcrypto");
});
});
describe("Health and optimization prompts", () => {
let prompts: ReturnType<typeof getPostgresPrompts>;
let mockContext: ReturnType<typeof createMockRequestContext>;
beforeEach(() => {
vi.clearAllMocks();
const mockAdapter = createMockPostgresAdapter();
(
mockAdapter.getToolDefinitions as ReturnType<typeof vi.fn>
).mockReturnValue([]);
prompts = getPostgresPrompts(mockAdapter as unknown as PostgresAdapter);
mockContext = createMockRequestContext();
});
it("pg_database_health_check should provide health check guidance", async () => {
const prompt = prompts.find((p) => p.name === "pg_database_health_check")!;
const result = (await prompt.handler({}, mockContext)) as string;
expect(result.toLowerCase()).toContain("health");
});
it("pg_backup_strategy should provide backup guidance", async () => {
const prompt = prompts.find((p) => p.name === "pg_backup_strategy")!;
const result = (await prompt.handler({}, mockContext)) as string;
expect(result.toLowerCase()).toContain("backup");
});
it("pg_index_tuning should provide index optimization guidance", async () => {
const prompt = prompts.find((p) => p.name === "pg_index_tuning")!;
const result = (await prompt.handler({}, mockContext)) as string;
expect(result.toLowerCase()).toContain("index");
});
it("pg_extension_setup should provide extension guidance", async () => {
const prompt = prompts.find((p) => p.name === "pg_extension_setup")!;
const result = (await prompt.handler({}, mockContext)) as string;
expect(result.toLowerCase()).toContain("extension");
});
});
// =============================================================================
// Prompt UseCase Branch Coverage Tests
// =============================================================================
describe("pg_setup_ltree useCase branches", () => {
let prompts: ReturnType<typeof getPostgresPrompts>;
let mockContext: ReturnType<typeof createMockRequestContext>;
beforeEach(() => {
vi.clearAllMocks();
const mockAdapter = createMockPostgresAdapter();
(
mockAdapter.getToolDefinitions as ReturnType<typeof vi.fn>
).mockReturnValue([]);
prompts = getPostgresPrompts(mockAdapter as unknown as PostgresAdapter);
mockContext = createMockRequestContext();
});
it("should handle categories useCase (default)", async () => {
const prompt = prompts.find((p) => p.name === "pg_setup_ltree")!;
const result = (await prompt.handler({}, mockContext)) as string;
expect(result).toContain("categories");
expect(result).toContain("CREATE TABLE categories");
expect(result).toContain("Electronics");
});
it("should handle org_chart useCase", async () => {
const prompt = prompts.find((p) => p.name === "pg_setup_ltree")!;
const result = (await prompt.handler(
{ useCase: "org_chart" },
mockContext,
)) as string;
expect(result).toContain("Org Chart");
expect(result).toContain("CREATE TABLE employees");
expect(result).toContain("CEO");
expect(result).toContain("org_path");
});
it("should handle file_paths useCase", async () => {
const prompt = prompts.find((p) => p.name === "pg_setup_ltree")!;
const result = (await prompt.handler(
{ useCase: "file_paths" },
mockContext,
)) as string;
expect(result).toContain("File Paths");
expect(result).toContain("CREATE TABLE files");
expect(result).toContain("home.user1.documents");
});
it("should handle taxonomy useCase (default branch)", async () => {
const prompt = prompts.find((p) => p.name === "pg_setup_ltree")!;
const result = (await prompt.handler(
{ useCase: "taxonomy" },
mockContext,
)) as string;
expect(result).toContain("Taxonomy");
expect(result).toContain("CREATE TABLE species");
expect(result).toContain("Homo sapiens");
});
});
describe("pg_setup_pgcron useCase branches", () => {
let prompts: ReturnType<typeof getPostgresPrompts>;
let mockContext: ReturnType<typeof createMockRequestContext>;
beforeEach(() => {
vi.clearAllMocks();
const mockAdapter = createMockPostgresAdapter();
(
mockAdapter.getToolDefinitions as ReturnType<typeof vi.fn>
).mockReturnValue([]);
prompts = getPostgresPrompts(mockAdapter as unknown as PostgresAdapter);
mockContext = createMockRequestContext();
});
it("should handle maintenance useCase (default)", async () => {
const prompt = prompts.find((p) => p.name === "pg_setup_pgcron")!;
const result = (await prompt.handler({}, mockContext)) as string;
expect(result).toContain("Maintenance");
expect(result).toContain("VACUUM ANALYZE");
expect(result).toContain("REINDEX");
});
it("should handle cleanup useCase", async () => {
const prompt = prompts.find((p) => p.name === "pg_setup_pgcron")!;
const result = (await prompt.handler(
{ useCase: "cleanup" },
mockContext,
)) as string;
expect(result).toContain("Cleanup");
expect(result).toContain("DELETE FROM logs");
expect(result).toContain("purge-sessions");
});
it("should handle reporting useCase", async () => {
const prompt = prompts.find((p) => p.name === "pg_setup_pgcron")!;
const result = (await prompt.handler(
{ useCase: "reporting" },
mockContext,
)) as string;
expect(result).toContain("Reporting");
expect(result).toContain("daily-summary");
expect(result).toContain("MATERIALIZED VIEW");
});
it("should handle etl useCase", async () => {
const prompt = prompts.find((p) => p.name === "pg_setup_pgcron")!;
const result = (await prompt.handler(
{ useCase: "etl" },
mockContext,
)) as string;
expect(result).toContain("Etl");
expect(result).toContain("incremental-load");
expect(result).toContain("full-sync");
});
it("should handle backup useCase (default branch)", async () => {
const prompt = prompts.find((p) => p.name === "pg_setup_pgcron")!;
const result = (await prompt.handler(
{ useCase: "backup" },
mockContext,
)) as string;
expect(result).toContain("Backup");
expect(result).toContain("CHECKPOINT");
expect(result).toContain("pg_switch_wal");
});
});
describe("pg_setup_postgis useCase branches", () => {
let prompts: ReturnType<typeof getPostgresPrompts>;
let mockContext: ReturnType<typeof createMockRequestContext>;
beforeEach(() => {
vi.clearAllMocks();
const mockAdapter = createMockPostgresAdapter();
(
mockAdapter.getToolDefinitions as ReturnType<typeof vi.fn>
).mockReturnValue([]);
prompts = getPostgresPrompts(mockAdapter as unknown as PostgresAdapter);
mockContext = createMockRequestContext();
});
it("should handle mapping useCase (default)", async () => {
const prompt = prompts.find((p) => p.name === "pg_setup_postgis")!;
const result = (await prompt.handler({}, mockContext)) as string;
expect(result).toContain("Mapping");
expect(result).toContain("CREATE TABLE locations");
expect(result).toContain("GEOGRAPHY(POINT, 4326)");
});
it("should handle distance_calc useCase", async () => {
const prompt = prompts.find((p) => p.name === "pg_setup_postgis")!;
const result = (await prompt.handler(
{ useCase: "distance_calc" },
mockContext,
)) as string;
expect(result).toContain("Distance Calc");
expect(result).toContain("CREATE TABLE points_of_interest");
expect(result).toContain("ST_Distance");
});
it("should handle spatial_analysis useCase", async () => {
const prompt = prompts.find((p) => p.name === "pg_setup_postgis")!;
const result = (await prompt.handler(
{ useCase: "spatial_analysis" },
mockContext,
)) as string;
expect(result).toContain("Spatial Analysis");
expect(result).toContain("CREATE TABLE regions");
expect(result).toContain("POLYGON");
expect(result).toContain("ST_Contains");
});
it("should handle routing useCase (default branch)", async () => {
const prompt = prompts.find((p) => p.name === "pg_setup_postgis")!;
const result = (await prompt.handler(
{ useCase: "routing" },
mockContext,
)) as string;
expect(result).toContain("Routing");
expect(result).toContain("CREATE TABLE roads");
expect(result).toContain("LINESTRING");
expect(result).toContain("ST_DWithin");
});
});
describe("pg_backup_strategy backupType branches", () => {
let prompts: ReturnType<typeof getPostgresPrompts>;
let mockContext: ReturnType<typeof createMockRequestContext>;
beforeEach(() => {
vi.clearAllMocks();
const mockAdapter = createMockPostgresAdapter();
(
mockAdapter.getToolDefinitions as ReturnType<typeof vi.fn>
).mockReturnValue([]);
prompts = getPostgresPrompts(mockAdapter as unknown as PostgresAdapter);
mockContext = createMockRequestContext();
});
it("should handle logical backupType (default)", async () => {
const prompt = prompts.find((p) => p.name === "pg_backup_strategy")!;
const result = (await prompt.handler({}, mockContext)) as string;
expect(result).toContain("Logical Backup");
expect(result).toContain("pg_dump");
expect(result).toContain("Full Backup");
expect(result).toContain("Schema-Only Backup");
});
it("should handle explicit logical backupType", async () => {
const prompt = prompts.find((p) => p.name === "pg_backup_strategy")!;
const result = (await prompt.handler(
{ backupType: "logical" },
mockContext,
)) as string;
expect(result).toContain("Logical Backup");
expect(result).toContain("pg_dump -Fc -Z9");
expect(result).toContain("--schema-only");
});
it("should handle physical backupType", async () => {
const prompt = prompts.find((p) => p.name === "pg_backup_strategy")!;
const result = (await prompt.handler(
{ backupType: "physical" },
mockContext,
)) as string;
expect(result).toContain("Physical Backup");
expect(result).toContain("pg_basebackup");
expect(result).toContain("Base Backup");
expect(result).toContain("WAL Archiving");
expect(result).toContain("archive_mode");
expect(result).toContain("archive_command");
});
it("should handle continuous backupType", async () => {
const prompt = prompts.find((p) => p.name === "pg_backup_strategy")!;
const result = (await prompt.handler(
{ backupType: "continuous" },
mockContext,
)) as string;
expect(result).toContain("Continuous Archiving");
expect(result).toContain("PITR");
expect(result).toContain("point in time");
});
it("should include custom retention period", async () => {
const prompt = prompts.find((p) => p.name === "pg_backup_strategy")!;
const result = (await prompt.handler(
{
backupType: "physical",
retentionDays: "60",
},
mockContext,
)) as string;
expect(result).toContain("60 days");
});
});
describe("pg_setup_partman useCase branches", () => {
let prompts: ReturnType<typeof getPostgresPrompts>;
let mockContext: ReturnType<typeof createMockRequestContext>;
beforeEach(() => {
vi.clearAllMocks();
const mockAdapter = createMockPostgresAdapter();
(
mockAdapter.getToolDefinitions as ReturnType<typeof vi.fn>
).mockReturnValue([]);
prompts = getPostgresPrompts(mockAdapter as unknown as PostgresAdapter);
mockContext = createMockRequestContext();
});
it("should handle time-series partitionType (default)", async () => {
const prompt = prompts.find((p) => p.name === "pg_setup_partman")!;
const result = (await prompt.handler({}, mockContext)) as string;
expect(result).toContain("pg_partman");
expect(result).toContain("Time Partitioning");
expect(result).toContain("event_time");
});
it("should handle serial partitionType", async () => {
const prompt = prompts.find((p) => p.name === "pg_setup_partman")!;
const result = (await prompt.handler(
{ partitionType: "serial" },
mockContext,
)) as string;
// This triggers the serial/id branch in the partman prompt
expect(result).toContain("Serial Partitioning");
expect(result).toContain("orders");
expect(result).toContain("1000000");
});
it("should handle id partitionType", async () => {
const prompt = prompts.find((p) => p.name === "pg_setup_partman")!;
const result = (await prompt.handler(
{ partitionType: "id" },
mockContext,
)) as string;
expect(result).toContain("Id Partitioning");
expect(result).toContain("PARTITION BY RANGE (id)");
});
});
// =============================================================================
// Additional Branch Coverage Tests - Phase 1
// =============================================================================
describe("pg_setup_citext useCase branches", () => {
let prompts: ReturnType<typeof getPostgresPrompts>;
let mockContext: ReturnType<typeof createMockRequestContext>;
beforeEach(() => {
vi.clearAllMocks();
const mockAdapter = createMockPostgresAdapter();
(
mockAdapter.getToolDefinitions as ReturnType<typeof vi.fn>
).mockReturnValue([]);
prompts = getPostgresPrompts(mockAdapter as unknown as PostgresAdapter);
mockContext = createMockRequestContext();
});
it("should handle email useCase (default)", async () => {
const prompt = prompts.find((p) => p.name === "pg_setup_citext")!;
const result = (await prompt.handler({}, mockContext)) as string;
expect(result).toContain("Emails");
expect(result).toContain("CREATE TABLE users");
expect(result).toContain("email CITEXT UNIQUE");
});
it("should handle username useCase", async () => {
const prompt = prompts.find((p) => p.name === "pg_setup_citext")!;
const result = (await prompt.handler(
{ useCase: "username" },
mockContext,
)) as string;
expect(result).toContain("Usernames");
expect(result).toContain("CREATE TABLE accounts");
expect(result).toContain("username CITEXT UNIQUE");
expect(result).toContain("duplicate usernames");
});
it("should handle tags useCase", async () => {
const prompt = prompts.find((p) => p.name === "pg_setup_citext")!;
const result = (await prompt.handler(
{ useCase: "tags" },
mockContext,
)) as string;
expect(result).toContain("Tagss");
expect(result).toContain("CREATE TABLE tags");
expect(result).toContain("name CITEXT UNIQUE");
expect(result).toContain("post_tags");
});
it("should handle domains useCase (else branch)", async () => {
const prompt = prompts.find((p) => p.name === "pg_setup_citext")!;
const result = (await prompt.handler(
{ useCase: "domains" },
mockContext,
)) as string;
expect(result).toContain("Domainss");
expect(result).toContain("CREATE TABLE websites");
expect(result).toContain("domain CITEXT UNIQUE");
});
});
describe("pg_setup_pgcrypto useCase branches", () => {
let prompts: ReturnType<typeof getPostgresPrompts>;
let mockContext: ReturnType<typeof createMockRequestContext>;
beforeEach(() => {
vi.clearAllMocks();
const mockAdapter = createMockPostgresAdapter();
(
mockAdapter.getToolDefinitions as ReturnType<typeof vi.fn>
).mockReturnValue([]);
prompts = getPostgresPrompts(mockAdapter as unknown as PostgresAdapter);
mockContext = createMockRequestContext();
});
it("should handle password_hashing useCase (default)", async () => {
const prompt = prompts.find((p) => p.name === "pg_setup_pgcrypto")!;
const result = (await prompt.handler({}, mockContext)) as string;
expect(result).toContain("Password Hashing");
expect(result).toContain("crypt");
expect(result).toContain("gen_salt");
expect(result).toContain("bcrypt");
});
it("should handle encryption useCase", async () => {
const prompt = prompts.find((p) => p.name === "pg_setup_pgcrypto")!;
const result = (await prompt.handler(
{ useCase: "encryption" },
mockContext,
)) as string;
expect(result).toContain("Encryption");
expect(result).toContain("pgp_sym_encrypt");
expect(result).toContain("pgp_sym_decrypt");
expect(result).toContain("AES");
});
it("should handle uuid useCase", async () => {
const prompt = prompts.find((p) => p.name === "pg_setup_pgcrypto")!;
const result = (await prompt.handler(
{ useCase: "uuid" },
mockContext,
)) as string;
expect(result).toContain("Uuid");
expect(result).toContain("gen_random_uuid");
expect(result).toContain("UUID PRIMARY KEY");
expect(result).toContain("gen_random_bytes");
});
it("should handle hmac useCase (else branch)", async () => {
const prompt = prompts.find((p) => p.name === "pg_setup_pgcrypto")!;
const result = (await prompt.handler(
{ useCase: "hmac" },
mockContext,
)) as string;
expect(result).toContain("Hmac");
expect(result).toContain("hmac");
expect(result).toContain("sha256");
expect(result).toContain("signature");
});
});
describe("pg_setup_partman interval branches", () => {
let prompts: ReturnType<typeof getPostgresPrompts>;
let mockContext: ReturnType<typeof createMockRequestContext>;
beforeEach(() => {
vi.clearAllMocks();
const mockAdapter = createMockPostgresAdapter();
(
mockAdapter.getToolDefinitions as ReturnType<typeof vi.fn>
).mockReturnValue([]);
prompts = getPostgresPrompts(mockAdapter as unknown as PostgresAdapter);
mockContext = createMockRequestContext();
});
it("should handle daily interval (default)", async () => {
const prompt = prompts.find((p) => p.name === "pg_setup_partman")!;
const result = (await prompt.handler({}, mockContext)) as string;
expect(result).toContain("1 day");
expect(result).toContain("90 days");
});
it("should handle weekly interval", async () => {
const prompt = prompts.find((p) => p.name === "pg_setup_partman")!;
const result = (await prompt.handler(
{ interval: "weekly" },
mockContext,
)) as string;
expect(result).toContain("1 week");
expect(result).toContain("52 weeks");
});
it("should handle monthly interval", async () => {
const prompt = prompts.find((p) => p.name === "pg_setup_partman")!;
const result = (await prompt.handler(
{ interval: "monthly" },
mockContext,
)) as string;
expect(result).toContain("1 month");
expect(result).toContain("24 months");
});
it("should handle yearly interval", async () => {
const prompt = prompts.find((p) => p.name === "pg_setup_partman")!;
const result = (await prompt.handler(
{ interval: "yearly" },
mockContext,
)) as string;
expect(result).toContain("1 year");
expect(result).toContain("5 years");
});
});
describe("pg_setup_kcache focus branches", () => {
let prompts: ReturnType<typeof getPostgresPrompts>;
let mockContext: ReturnType<typeof createMockRequestContext>;
beforeEach(() => {
vi.clearAllMocks();
const mockAdapter = createMockPostgresAdapter();
(
mockAdapter.getToolDefinitions as ReturnType<typeof vi.fn>
).mockReturnValue([]);
prompts = getPostgresPrompts(mockAdapter as unknown as PostgresAdapter);
mockContext = createMockRequestContext();
});
it("should handle all focus (default)", async () => {
const prompt = prompts.find((p) => p.name === "pg_setup_kcache")!;
const result = (await prompt.handler({}, mockContext)) as string;
expect(result).toContain("ALL Analysis");
expect(result).toContain("CPU Analysis");
expect(result).toContain("I/O Analysis");
expect(result).toContain("Memory Analysis");
});
it("should handle cpu focus", async () => {
const prompt = prompts.find((p) => p.name === "pg_setup_kcache")!;
const result = (await prompt.handler(
{ focus: "cpu" },
mockContext,
)) as string;
expect(result).toContain("CPU Analysis");
expect(result).toContain("user_time");
expect(result).toContain("system_time");
expect(result).not.toContain("I/O Analysis");
expect(result).not.toContain("Memory Analysis");
});
it("should handle io focus", async () => {
const prompt = prompts.find((p) => p.name === "pg_setup_kcache")!;
const result = (await prompt.handler(
{ focus: "io" },
mockContext,
)) as string;
expect(result).toContain("I/O Analysis");
expect(result).toContain("reads");
expect(result).toContain("writes");
expect(result).not.toContain("CPU Analysis");
expect(result).not.toContain("Memory Analysis");
});
it("should handle memory focus", async () => {
const prompt = prompts.find((p) => p.name === "pg_setup_kcache")!;
const result = (await prompt.handler(
{ focus: "memory" },
mockContext,
)) as string;
expect(result).toContain("Memory Analysis");
expect(result).toContain("page_faults");
expect(result).toContain("majflts");
expect(result).not.toContain("CPU Analysis");
expect(result).not.toContain("I/O Analysis");
});
});
describe("pg_database_health_check focus branches", () => {
let prompts: ReturnType<typeof getPostgresPrompts>;
let mockContext: ReturnType<typeof createMockRequestContext>;
beforeEach(() => {
vi.clearAllMocks();
const mockAdapter = createMockPostgresAdapter();
(
mockAdapter.getToolDefinitions as ReturnType<typeof vi.fn>
).mockReturnValue([]);
prompts = getPostgresPrompts(mockAdapter as unknown as PostgresAdapter);
mockContext = createMockRequestContext();
});
it("should handle all focus (default)", async () => {
const prompt = prompts.find((p) => p.name === "pg_database_health_check")!;
const result = (await prompt.handler({}, mockContext)) as string;
expect(result).toContain("Index Health");
expect(result).toContain("Connection Health");
expect(result).toContain("Vacuum Health");
expect(result).toContain("Replication Health");
expect(result).toContain("Buffer Cache Health");
});
it("should handle indexes focus", async () => {
const prompt = prompts.find((p) => p.name === "pg_database_health_check")!;
const result = (await prompt.handler(
{ focus: "indexes" },
mockContext,
)) as string;
expect(result).toContain("Index Health");
expect(result).toContain("Invalid indexes");
expect(result).not.toContain("Connection Health");
});
it("should handle connections focus", async () => {
const prompt = prompts.find((p) => p.name === "pg_database_health_check")!;
const result = (await prompt.handler(
{ focus: "connections" },
mockContext,
)) as string;
expect(result).toContain("Connection Health");
expect(result).toContain("max_connections");
expect(result).not.toContain("Index Health");
});
it("should handle vacuum focus", async () => {
const prompt = prompts.find((p) => p.name === "pg_database_health_check")!;
const result = (await prompt.handler(
{ focus: "vacuum" },
mockContext,
)) as string;
expect(result).toContain("Vacuum Health");
expect(result).toContain("wraparound");
expect(result).not.toContain("Index Health");
});
it("should handle replication focus", async () => {
const prompt = prompts.find((p) => p.name === "pg_database_health_check")!;
const result = (await prompt.handler(
{ focus: "replication" },
mockContext,
)) as string;
expect(result).toContain("Replication Health");
expect(result).toContain("Replication lag");
expect(result).not.toContain("Index Health");
});
it("should handle buffer focus", async () => {
const prompt = prompts.find((p) => p.name === "pg_database_health_check")!;
const result = (await prompt.handler(
{ focus: "buffer" },
mockContext,
)) as string;
expect(result).toContain("Buffer Cache Health");
expect(result).toContain("Cache hit ratio");
expect(result).not.toContain("Index Health");
});
});
describe("pg_index_tuning focus branches", () => {
let prompts: ReturnType<typeof getPostgresPrompts>;
let mockContext: ReturnType<typeof createMockRequestContext>;
beforeEach(() => {
vi.clearAllMocks();
const mockAdapter = createMockPostgresAdapter();
(
mockAdapter.getToolDefinitions as ReturnType<typeof vi.fn>
).mockReturnValue([]);
prompts = getPostgresPrompts(mockAdapter as unknown as PostgresAdapter);
mockContext = createMockRequestContext();
});
it("should handle all focus (default)", async () => {
const prompt = prompts.find((p) => p.name === "pg_index_tuning")!;
const result = (await prompt.handler({}, mockContext)) as string;
expect(result).toContain("All");
expect(result).toContain("Unused Indexes");
expect(result).toContain("Missing Indexes");
expect(result).toContain("Duplicate/Redundant Indexes");
});
it("should handle unused focus", async () => {
const prompt = prompts.find((p) => p.name === "pg_index_tuning")!;
const result = (await prompt.handler(
{ focus: "unused" },
mockContext,
)) as string;
expect(result).toContain("Unused Indexes");
expect(result).toContain("idx_scan = 0");
expect(result).not.toContain("Missing Indexes");
});
it("should handle missing focus", async () => {
const prompt = prompts.find((p) => p.name === "pg_index_tuning")!;
const result = (await prompt.handler(
{ focus: "missing" },
mockContext,
)) as string;
expect(result).toContain("Missing Indexes");
expect(result).toContain("pg_analyze_workload");
expect(result).not.toContain("Unused Indexes");
});
it("should handle duplicate focus", async () => {
const prompt = prompts.find((p) => p.name === "pg_index_tuning")!;
const result = (await prompt.handler(
{ focus: "duplicate" },
mockContext,
)) as string;
expect(result).toContain("Duplicate/Redundant Indexes");
expect(result).toContain("Redundant patterns");
expect(result).not.toContain("Unused Indexes");
});
it("should handle custom schema", async () => {
const prompt = prompts.find((p) => p.name === "pg_index_tuning")!;
const result = (await prompt.handler(
{ schema: "custom_schema" },
mockContext,
)) as string;
expect(result).toContain("custom_schema");
});
});
// =============================================================================
// Optional Parameter Empty Value Branch Coverage
// =============================================================================
describe("pg_schema_design optional requirements branch", () => {
let prompts: ReturnType<typeof getPostgresPrompts>;
let mockContext: ReturnType<typeof createMockRequestContext>;
beforeEach(() => {
vi.clearAllMocks();
const mockAdapter = createMockPostgresAdapter();
(
mockAdapter.getToolDefinitions as ReturnType<typeof vi.fn>
).mockReturnValue([]);
prompts = getPostgresPrompts(mockAdapter as unknown as PostgresAdapter);
mockContext = createMockRequestContext();
});
it("should handle empty requirements (empty string branch)", async () => {
const prompt = prompts.find((p) => p.name === "pg_schema_design")!;
const result = (await prompt.handler(
{
useCase: "Blog platform",
requirements: "",
},
mockContext,
)) as string;
// Should not include Requirements section when empty
expect(result).toContain("Blog platform");
expect(result).not.toContain("**Requirements:**");
});
it("should handle undefined requirements (nullish branch)", async () => {
const prompt = prompts.find((p) => p.name === "pg_schema_design")!;
const result = (await prompt.handler(
{
useCase: "E-commerce",
},
mockContext,
)) as string;
expect(result).toContain("E-commerce");
expect(result).not.toContain("**Requirements:**");
});
});
describe("pg_performance_analysis optional context branch", () => {
let prompts: ReturnType<typeof getPostgresPrompts>;
let mockContext: ReturnType<typeof createMockRequestContext>;
beforeEach(() => {
vi.clearAllMocks();
const mockAdapter = createMockPostgresAdapter();
(
mockAdapter.getToolDefinitions as ReturnType<typeof vi.fn>
).mockReturnValue([]);
prompts = getPostgresPrompts(mockAdapter as unknown as PostgresAdapter);
mockContext = createMockRequestContext();
});
it("should handle empty context (empty string branch)", async () => {
const prompt = prompts.find((p) => p.name === "pg_performance_analysis")!;
const result = (await prompt.handler(
{
query: "SELECT * FROM users",
context: "",
},
mockContext,
)) as string;
expect(result).toContain("SELECT * FROM users");
expect(result).not.toContain("**Context:**");
});
it("should handle undefined context (nullish branch)", async () => {
const prompt = prompts.find((p) => p.name === "pg_performance_analysis")!;
const result = (await prompt.handler(
{
query: "SELECT * FROM orders",
},
mockContext,
)) as string;
expect(result).toContain("SELECT * FROM orders");
expect(result).not.toContain("**Context:**");
});
});
describe("pg_migration optional table branch", () => {
let prompts: ReturnType<typeof getPostgresPrompts>;
let mockContext: ReturnType<typeof createMockRequestContext>;
beforeEach(() => {
vi.clearAllMocks();
const mockAdapter = createMockPostgresAdapter();
(
mockAdapter.getToolDefinitions as ReturnType<typeof vi.fn>
).mockReturnValue([]);
prompts = getPostgresPrompts(mockAdapter as unknown as PostgresAdapter);
mockContext = createMockRequestContext();
});
it("should handle empty table (empty string branch)", async () => {
const prompt = prompts.find((p) => p.name === "pg_migration")!;
const result = (await prompt.handler(
{
change: "Add new index",
table: "",
},
mockContext,
)) as string;
expect(result).toContain("Add new index");
expect(result).not.toContain("**Table:**");
});
it("should handle undefined table (nullish branch)", async () => {
const prompt = prompts.find((p) => p.name === "pg_migration")!;
const result = (await prompt.handler(
{
change: "Create sequence",
},
mockContext,
)) as string;
expect(result).toContain("Create sequence");
expect(result).not.toContain("**Table:**");
});
});