mirror of
https://github.com/Sea-Haven-Industries/seahaven-ap.git
synced 2026-10-07 16:18:53 +00:00
102 lines
3.7 KiB
TypeScript
102 lines
3.7 KiB
TypeScript
import { describe, expect, it } from "vitest";
|
|
import { createApp } from "../app.js";
|
|
import { loadEnv } from "../env.js";
|
|
import type { ErrorEnvelope } from "../http.js";
|
|
import { createFakeDb, emptyStore, SEED } from "../test/fake-db.js";
|
|
|
|
function expectEnvelope(body: unknown, code: string) {
|
|
const envelope = body as ErrorEnvelope;
|
|
expect(envelope.error.code).toBe(code);
|
|
}
|
|
|
|
function adminEnv() {
|
|
return loadEnv({
|
|
NODE_ENV: "test",
|
|
DEV_AUTH_BYPASS: "true",
|
|
DEV_AUTH_SUB: SEED.user.cognitoSub,
|
|
DEV_AUTH_EMAIL: SEED.user.email,
|
|
DEV_AUTH_NAME: SEED.user.name,
|
|
DEV_AUTH_ROLE: "admin",
|
|
});
|
|
}
|
|
|
|
function viewerEnv() {
|
|
return loadEnv({
|
|
NODE_ENV: "test",
|
|
DEV_AUTH_BYPASS: "true",
|
|
DEV_AUTH_SUB: SEED.user.cognitoSub,
|
|
DEV_AUTH_EMAIL: SEED.user.email,
|
|
DEV_AUTH_NAME: SEED.user.name,
|
|
DEV_AUTH_ROLE: "viewer",
|
|
});
|
|
}
|
|
|
|
describe("master data stubs", () => {
|
|
it("lists and gets seeded vendors", async () => {
|
|
const app = createApp(adminEnv(), createFakeDb());
|
|
const list = await app.request("/api/vendors");
|
|
expect(list.status).toBe(200);
|
|
const listed = (await list.json()) as { items: Array<{ id: string; name: string }> };
|
|
expect(listed.items[0]?.id).toBe(SEED.vendor.id);
|
|
const get = await app.request(`/api/vendors/${SEED.vendor.id}`);
|
|
expect(get.status).toBe(200);
|
|
await expect(get.json()).resolves.toMatchObject({ id: SEED.vendor.id, name: SEED.vendor.name });
|
|
});
|
|
|
|
it("creates a vendor and returns 201", async () => {
|
|
const app = createApp(adminEnv(), createFakeDb());
|
|
const response = await app.request("/api/vendors", {
|
|
method: "POST",
|
|
headers: { "content-type": "application/json", origin: "http://127.0.0.1:3000" },
|
|
body: JSON.stringify({ name: "Harbor Maintenance", defaultPaymentMethod: "ach" }),
|
|
});
|
|
expect(response.status).toBe(201);
|
|
await expect(response.json()).resolves.toMatchObject({
|
|
name: "Harbor Maintenance",
|
|
defaultPaymentMethod: "ach",
|
|
});
|
|
});
|
|
|
|
it("returns 404 for a missing vendor", async () => {
|
|
const store = emptyStore();
|
|
store.vendors = [];
|
|
const app = createApp(adminEnv(), createFakeDb(store));
|
|
const response = await app.request(`/api/vendors/${SEED.vendor.id}`);
|
|
expect(response.status).toBe(404);
|
|
expectEnvelope(await response.json(), "NOT_FOUND");
|
|
});
|
|
|
|
it("returns 403 when a non-admin writes vendors", async () => {
|
|
const app = createApp(viewerEnv(), createFakeDb());
|
|
const response = await app.request("/api/vendors", {
|
|
method: "POST",
|
|
headers: { "content-type": "application/json", origin: "http://127.0.0.1:3000" },
|
|
body: JSON.stringify({ name: "Nope" }),
|
|
});
|
|
expect(response.status).toBe(403);
|
|
expectEnvelope(await response.json(), "FORBIDDEN");
|
|
});
|
|
|
|
it("lists GL accounts and departments", async () => {
|
|
const app = createApp(adminEnv(), createFakeDb());
|
|
const gl = await app.request("/api/gl-accounts");
|
|
expect(gl.status).toBe(200);
|
|
const glBody = (await gl.json()) as { items: Array<{ code: string }> };
|
|
expect(glBody.items[0]?.code).toBe("6100");
|
|
const departments = await app.request("/api/departments");
|
|
expect(departments.status).toBe(200);
|
|
const deptBody = (await departments.json()) as { items: Array<{ code: string }> };
|
|
expect(deptBody.items[0]?.code).toBe("OPS");
|
|
});
|
|
|
|
it("updates a user role", async () => {
|
|
const app = createApp(adminEnv(), createFakeDb());
|
|
const response = await app.request(`/api/users/${SEED.user.id}`, {
|
|
method: "PATCH",
|
|
headers: { "content-type": "application/json", origin: "http://127.0.0.1:3000" },
|
|
body: JSON.stringify({ role: "approver" }),
|
|
});
|
|
expect(response.status).toBe(200);
|
|
await expect(response.json()).resolves.toMatchObject({ role: "approver" });
|
|
});
|
|
});
|