Files
2026-08-09 14:30:42 -04:00

131 lines
4.6 KiB
JavaScript

import test from "node:test";
import assert from "node:assert/strict";
import request from "supertest";
import { setup, signup, password } from "./helpers.js";
async function bootstrapAdmin(agent) {
const response = await agent.post("/api/auth/bootstrap").send({
email: "[email protected]",
password,
setupToken: "a-secure-bootstrap-token",
});
assert.equal(response.status, 201);
return response.body.csrfToken;
}
test("plans: custom name is created, listed, and defaults to blank", async () => {
const { agent } = await setup();
const { csrf } = await signup(agent, "[email protected]");
const unnamed = await agent
.post("/api/plans")
.set("x-csrf-token", csrf)
.send({ plan: { fields: { 0.1: "House blend" } } });
assert.equal(unnamed.status, 201);
assert.equal(unnamed.body.plan.name, "");
const named = await agent
.post("/api/plans")
.set("x-csrf-token", csrf)
.send({ plan: { fields: { 0.1: "House blend" } }, name: " Winter batch " });
assert.equal(named.status, 201);
assert.equal(named.body.plan.name, "Winter batch", "name is trimmed");
const list = (await agent.get("/api/plans")).body.plans;
assert.equal(list.find((p) => p.id === named.body.plan.id).name, "Winter batch");
assert.equal(list.find((p) => p.id === unnamed.body.plan.id).name, "");
});
test("plans: PUT name-only preserves the plan JSONB, and PUT plan-only preserves the name", async () => {
const { agent } = await setup();
const { csrf } = await signup(agent, "[email protected]");
const created = await agent
.post("/api/plans")
.set("x-csrf-token", csrf)
.send({ plan: { fields: { 0.1: "Original title", "0.4": "300" } }, name: "First name" });
const planId = created.body.plan.id;
// Name-only update: the plan JSONB is untouched.
const renamed = await agent
.put(`/api/plans/${planId}`)
.set("x-csrf-token", csrf)
.send({ name: "Second name" });
assert.equal(renamed.status, 200);
assert.equal(renamed.body.plan.name, "Second name");
assert.equal(renamed.body.plan.plan.fields["0.1"], "Original title");
assert.equal(renamed.body.plan.plan.fields["0.4"], "300");
// Plan-only update: the name is untouched.
const replanned = await agent
.put(`/api/plans/${planId}`)
.set("x-csrf-token", csrf)
.send({ plan: { fields: { 0.1: "New title", "0.4": "350" } } });
assert.equal(replanned.status, 200);
assert.equal(replanned.body.plan.name, "Second name");
assert.equal(replanned.body.plan.plan.fields["0.1"], "New title");
// Both at once.
const both = await agent
.put(`/api/plans/${planId}`)
.set("x-csrf-token", csrf)
.send({ plan: { fields: { 0.1: "Third title" } }, name: "Third name" });
assert.equal(both.body.plan.name, "Third name");
assert.equal(both.body.plan.plan.fields["0.1"], "Third title");
// Neither field present: bad request, same as the pre-existing plan-required behavior.
assert.equal(
(await agent.put(`/api/plans/${planId}`).set("x-csrf-token", csrf).send({})).status,
400,
);
});
test("plans: ownership — a stranger cannot rename another user's plan", async () => {
const { app } = await setup();
const owner = request.agent(app);
const stranger = request.agent(app);
const { csrf: ownerCsrf } = await signup(owner, "[email protected]");
const { csrf: strangerCsrf } = await signup(stranger, "[email protected]");
const created = await owner
.post("/api/plans")
.set("x-csrf-token", ownerCsrf)
.send({ plan: { fields: { 0.1: "Owner's plan" } } });
const planId = created.body.plan.id;
const hijack = await stranger
.put(`/api/plans/${planId}`)
.set("x-csrf-token", strangerCsrf)
.send({ name: "Hijacked" });
assert.equal(hijack.status, 404);
// The plan is unaffected.
const stillOwners = (await owner.get("/api/plans")).body.plans;
assert.equal(stillOwners.find((p) => p.id === planId).name, "");
});
test("plans: admin plan list title falls back to worksheet field 0.1 when no custom name is set", async () => {
const { app } = await setup();
const admin = request.agent(app);
await bootstrapAdmin(admin);
const user = request.agent(app);
const { csrf: userCsrf } = await signup(user, "[email protected]");
const named = await user
.post("/api/plans")
.set("x-csrf-token", userCsrf)
.send({ plan: { fields: { 0.1: "Worksheet title" } }, name: "Custom title" });
const unnamed = await user
.post("/api/plans")
.set("x-csrf-token", userCsrf)
.send({ plan: { fields: { 0.1: "Worksheet title only" } } });
const list = (await admin.get("/api/admin/plans")).body.plans;
assert.equal(list.find((p) => p.id === named.body.plan.id).title, "Custom title");
assert.equal(
list.find((p) => p.id === unnamed.body.plan.id).title,
"Worksheet title only",
);
});