feat(db): mesh data model — meshes, members, invites, audit log
- pgSchema "mesh" with 4 tables isolating the peer mesh domain - Enums: visibility, transport, tier, role - audit_log is metadata-only (E2E encryption enforced at broker/client) - Cascade on mesh delete, soft-delete via archivedAt/revokedAt Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
134
packages/api/src/utils/test/index.test.ts
Normal file
134
packages/api/src/utils/test/index.test.ts
Normal file
@@ -0,0 +1,134 @@
|
||||
import { describe, expect, it, vi } from "vitest";
|
||||
import { z } from "zod";
|
||||
|
||||
import { handle, isAPIError, withTimeout } from "../index";
|
||||
|
||||
describe("isAPIError", () => {
|
||||
it("should return true for valid API error object", () => {
|
||||
const error = {
|
||||
code: "ERROR_CODE",
|
||||
message: "Something went wrong",
|
||||
timestamp: new Date().toISOString(),
|
||||
path: "/api/test",
|
||||
};
|
||||
expect(isAPIError(error)).toBe(true);
|
||||
});
|
||||
|
||||
it.each([
|
||||
[{}],
|
||||
[{ code: "ERROR_CODE" }],
|
||||
[{ message: "Something went wrong" }],
|
||||
[{ timestamp: new Date().toISOString() }],
|
||||
[{ path: "/api/test" }],
|
||||
])("should return false for invalid object", (input) => {
|
||||
expect(isAPIError(input)).toBe(false);
|
||||
});
|
||||
|
||||
it.each([[null], [undefined]])("should return false for %s", (input) => {
|
||||
expect(isAPIError(input)).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe("handle", () => {
|
||||
it("should return data on success", async () => {
|
||||
const mockFn = vi.fn().mockResolvedValue({
|
||||
ok: true,
|
||||
json: () => Promise.resolve({ success: true }),
|
||||
});
|
||||
|
||||
const handler = handle(mockFn);
|
||||
const result = await handler({});
|
||||
|
||||
expect(result).toEqual({ success: true });
|
||||
});
|
||||
|
||||
it("should throw error on failure if throwOnError is true (default)", async () => {
|
||||
const mockFn = vi.fn().mockResolvedValue({
|
||||
ok: false,
|
||||
json: () => Promise.resolve({ message: "Failed" }),
|
||||
});
|
||||
|
||||
const handler = handle(mockFn);
|
||||
await expect(handler({})).rejects.toThrow(Error);
|
||||
});
|
||||
|
||||
it("should return null on failure if throwOnError is false", async () => {
|
||||
const mockFn = vi.fn().mockResolvedValue({
|
||||
ok: false,
|
||||
json: () => Promise.resolve({ message: "Failed" }),
|
||||
});
|
||||
|
||||
const handler = handle(mockFn, { throwOnError: false });
|
||||
const result = await handler({});
|
||||
|
||||
expect(result).toBeNull();
|
||||
});
|
||||
|
||||
it("should throw error if fetch throws and throwOnError is true", async () => {
|
||||
const mockFn = vi.fn().mockRejectedValue(new Error("Network Error"));
|
||||
const handler = handle(mockFn);
|
||||
await expect(handler({})).rejects.toThrow("Network Error");
|
||||
});
|
||||
|
||||
it("should allow error propagation if fetch throws and throwOnError is false", async () => {
|
||||
const mockFn = vi.fn().mockRejectedValue(new Error("Network Error"));
|
||||
const handler = handle(mockFn, { throwOnError: false });
|
||||
|
||||
// Expect it to throw because handle doesn't catch fn() errors
|
||||
await expect(handler({})).rejects.toThrow("Network Error");
|
||||
});
|
||||
|
||||
it("should validate data with schema if provided", async () => {
|
||||
const schema = z.object({ id: z.number() });
|
||||
const mockFn = vi.fn().mockResolvedValue({
|
||||
ok: true,
|
||||
json: () => Promise.resolve({ id: 123 }),
|
||||
});
|
||||
|
||||
const handler = handle(mockFn, { schema });
|
||||
const result = await handler({});
|
||||
|
||||
expect(result).toEqual({ id: 123 });
|
||||
});
|
||||
|
||||
it("should throw error if schema validation fails and throwOnError is true", async () => {
|
||||
const schema = z.object({ id: z.number() });
|
||||
const mockFn = vi.fn().mockResolvedValue({
|
||||
ok: true,
|
||||
json: () => Promise.resolve({ id: "invalid" }),
|
||||
});
|
||||
|
||||
const handler = handle(mockFn, { schema });
|
||||
await expect(handler({})).rejects.toThrow();
|
||||
});
|
||||
|
||||
it("should return null if schema validation fails and throwOnError is false", async () => {
|
||||
const schema = z.object({ id: z.number() });
|
||||
const mockFn = vi.fn().mockResolvedValue({
|
||||
ok: true,
|
||||
json: () => Promise.resolve({ id: "invalid" }),
|
||||
});
|
||||
|
||||
const handler = handle(mockFn, { schema, throwOnError: false });
|
||||
const result = await handler({});
|
||||
|
||||
expect(result).toBeNull();
|
||||
});
|
||||
});
|
||||
|
||||
describe("withTimeout", () => {
|
||||
it("should resolve if promise finishes before timeout", async () => {
|
||||
const promise = new Promise((resolve) =>
|
||||
setTimeout(() => resolve("done"), 10),
|
||||
);
|
||||
const result = await withTimeout(promise, 100);
|
||||
expect(result).toBe("done");
|
||||
});
|
||||
|
||||
it("should reject if timeout is reached", async () => {
|
||||
const promise = new Promise((resolve) =>
|
||||
setTimeout(() => resolve("done"), 100),
|
||||
);
|
||||
await expect(withTimeout(promise, 10)).rejects.toThrow(Error);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user