Test and deploy / test-and-deploy (push) Successful in 59s
Co-Authored-By: Claude Fable 5 <[email protected]>
131 lines
4.6 KiB
JavaScript
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",
|
|
);
|
|
});
|