- GET/PATCH /house/current — renomme le foyer de l'utilisateur connecté.
PATCH avec houseId null -> 404 HOUSE_NOT_FOUND.
- PATCH /profile/diet { dietId: number | null } — régime du profil ;
null l'efface (étape skippable du parcours). dietId invalide ->
404 DIET_NOT_FOUND.
- GET/PATCH /profile/allergies — allergènes/intolérances, liste d'IDs ;
PATCH remplace l'ensemble complet (pas une fusion, cohérent avec un
multi-select). ID invalide -> 404 ALLERGY_NOT_FOUND.
- 3 nouveaux ErrorCode (4041-4043) + libellés fr.
- Extraction de toSafeProfile() dans src/lib/safe-profile.ts —
auparavant dupliqué dans auth.service.ts et require-auth.ts,
profile.service.ts le réutilise aussi.
- Tests Mocha (28 passing) + Cucumber (15 scenarios) — même convention
que le reste, doc README.
Deuxième commit de la feature profil/foyer/régime/allergènes —
composants front partagés dans le commit suivant.
81 lines
2.6 KiB
TypeScript
81 lines
2.6 KiB
TypeScript
import { ErrorCode, type SignupInput } from "@batch-cooking/shared";
|
|
import { faker } from "@faker-js/faker";
|
|
import { expect } from "chai";
|
|
import request from "supertest";
|
|
import { createApp } from "../src/app.js";
|
|
import { prisma } from "../src/db/prisma.js";
|
|
import { resetDatabase } from "../test-support/reset-db.js";
|
|
|
|
function buildSignupPayload(): SignupInput {
|
|
const firstName = faker.person.firstName();
|
|
const lastName = faker.person.lastName();
|
|
return {
|
|
firstName,
|
|
lastName,
|
|
email: faker.internet.email({ firstName, lastName }).toLowerCase(),
|
|
password: faker.internet.password({ length: 16 }),
|
|
};
|
|
}
|
|
|
|
describe("Household", () => {
|
|
const app = createApp();
|
|
|
|
beforeEach(async () => {
|
|
await resetDatabase();
|
|
});
|
|
|
|
after(async () => {
|
|
await prisma.$disconnect();
|
|
});
|
|
|
|
describe("GET /house/current", () => {
|
|
it("rejects requests without a session cookie with 401 NOT_AUTHENTICATED", async () => {
|
|
const res = await request(app).get("/house/current");
|
|
|
|
expect(res.status).to.equal(401);
|
|
expect(res.body.code).to.equal(ErrorCode.NOT_AUTHENTICATED);
|
|
});
|
|
|
|
it("returns the household created at signup", async () => {
|
|
const agent = request.agent(app);
|
|
const signupRes = await agent.post("/auth/signup").send(buildSignupPayload());
|
|
|
|
const res = await agent.get("/house/current");
|
|
|
|
expect(res.status).to.equal(200);
|
|
expect(res.body).to.deep.equal({ id: signupRes.body.houseId, name: res.body.name });
|
|
});
|
|
});
|
|
|
|
describe("PATCH /house/current", () => {
|
|
it("rejects requests without a session cookie with 401 NOT_AUTHENTICATED", async () => {
|
|
const res = await request(app).patch("/house/current").send({ name: "Chez nous" });
|
|
|
|
expect(res.status).to.equal(401);
|
|
expect(res.body.code).to.equal(ErrorCode.NOT_AUTHENTICATED);
|
|
});
|
|
|
|
it("renames the household", async () => {
|
|
const agent = request.agent(app);
|
|
await agent.post("/auth/signup").send(buildSignupPayload());
|
|
|
|
const res = await agent.patch("/house/current").send({ name: "Chez les Dupont" });
|
|
|
|
expect(res.status).to.equal(200);
|
|
expect(res.body.name).to.equal("Chez les Dupont");
|
|
|
|
const refetch = await agent.get("/house/current");
|
|
expect(refetch.body.name).to.equal("Chez les Dupont");
|
|
});
|
|
|
|
it("rejects an empty name with 400 VALIDATION_ERROR", async () => {
|
|
const agent = request.agent(app);
|
|
await agent.post("/auth/signup").send(buildSignupPayload());
|
|
|
|
const res = await agent.patch("/house/current").send({ name: "" });
|
|
|
|
expect(res.status).to.equal(400);
|
|
expect(res.body.code).to.equal(ErrorCode.VALIDATION_ERROR);
|
|
});
|
|
});
|
|
});
|