Files
dbx/apps/desktop/src/lib/__tests__/table/batchTableDrop.spec.ts
T

76 lines
2.9 KiB
TypeScript
Vendored

import { describe, expect, it, vi } from "vitest";
import { runBatchTableDrop } from "@/lib/table/batchTableDrop";
import type { QueryResult } from "@/types/database";
function queryResult(overrides: Partial<QueryResult> = {}): QueryResult {
return { columns: [], rows: [], affected_rows: 0, execution_time_ms: 1, ...overrides };
}
const plan = [
{ target: "orders", sql: "DROP TABLE orders" },
{ target: "customers", sql: "DROP TABLE customers" },
{ target: "events", sql: "DROP TABLE events" },
];
describe("batch table drop", () => {
it("keeps SQL Server sequential so progress and partial failure stay attributable", async () => {
const executeStatement = vi.fn(async (sql: string) => {
if (sql.includes("customers")) throw new Error("permission denied");
});
const executeBatch = vi.fn();
const onProgress = vi.fn();
const result = await runBatchTableDrop({ databaseType: "sqlserver", plan, executeStatement, executeBatch, onProgress });
expect(executeStatement.mock.calls.map(([sql]) => sql)).toEqual(["DROP TABLE orders", "DROP TABLE customers"]);
expect(executeBatch).not.toHaveBeenCalled();
expect(result.succeeded).toEqual(["orders"]);
expect(result.failed?.message).toBe("permission denied");
expect(onProgress.mock.calls.map(([progress]) => progress)).toEqual([
{ completed: 1, total: 3, success: true },
{ completed: 2, total: 3, success: false },
]);
});
it("maps indexed batch results back to their exact targets", async () => {
const result = await runBatchTableDrop({
databaseType: "mysql",
plan,
executeStatement: vi.fn(),
executeBatch: async () => [queryResult({ statement_index: 0 }), queryResult({ statement_index: 1, execution_error: true, columns: ["Error"], rows: [["locked"]] })],
onProgress: vi.fn(),
});
expect(result.succeeded).toEqual(["orders"]);
expect(result.failed?.message).toBe("locked");
});
it("treats a successful atomic HTTP SQLite batch as all-or-nothing", async () => {
const onProgress = vi.fn();
const result = await runBatchTableDrop({
databaseType: "turso",
plan,
executeStatement: vi.fn(),
executeBatch: async () => [queryResult()],
onProgress,
});
expect(result.succeeded).toEqual(["orders", "customers", "events"]);
expect(result.failed).toBeUndefined();
expect(onProgress).toHaveBeenLastCalledWith({ completed: 3, total: 3, success: true });
});
it("fails closed when a non-atomic batch omits statement indexes", async () => {
const result = await runBatchTableDrop({
databaseType: "postgres",
plan,
executeStatement: vi.fn(),
executeBatch: async () => [queryResult()],
onProgress: vi.fn(),
});
expect(result.succeeded).toEqual([]);
expect(result.failed?.message).toBe("Batch drop did not report a result for every statement");
});
});