test(cycle): cover cervix signs + secondary-symptom across the wire

Integration coverage for the new fields: a cervix observation round-trips
POST → GET on the day-log route; the cycle-prefs GET defaults
secondarySymptom to MUCUS and a PATCH to CERVIX persists; and the
backup/restore path preserves both the cervix day-log signs and the
profile's secondary-symptom choice.
This commit is contained in:
Marc-André Bombeck committed 2026-06-14 15:36:14 +02:00
1 parent e832222402
commit fd00eb48d0
2 files changed
+55 -1

No files matched your search

+13 -1
View File
@@ -176,6 +176,9 @@ describe("cycle backup — round-trips through build + restore", () => {
date: "2026-03-02",
flow: "MEDIUM",
cycleId: cycle.id,
cervixPosition: "HIGH",
cervixFirmness: "SOFT",
cervixOpening: "OPEN",
notesEncrypted: "v1:abc123:cipher-envelope",
source: "MANUAL",
},
@@ -187,7 +190,12 @@ describe("cycle backup — round-trips through build + restore", () => {
data: { dayLogId: dayLog.id, symptomId: symptom.id },
});
await prisma.cycleProfile.create({
data: { userId: USER_ID, goal: "TRYING_TO_CONCEIVE", cycleTrackingEnabled: true },
data: {
userId: USER_ID,
goal: "TRYING_TO_CONCEIVE",
cycleTrackingEnabled: true,
secondarySymptom: "CERVIX",
},
});
// Build the backup section, then assert it round-trips through the schema.
@@ -217,6 +225,9 @@ describe("cycle backup — round-trips through build + restore", () => {
});
expect(restored).toHaveLength(1);
expect(restored[0].notesEncrypted).toBe("v1:abc123:cipher-envelope");
expect(restored[0].cervixPosition).toBe("HIGH");
expect(restored[0].cervixFirmness).toBe("SOFT");
expect(restored[0].cervixOpening).toBe("OPEN");
expect(restored[0].cycleId).not.toBeNull();
expect(restored[0].symptomLinks.map((l) => l.symptom.key)).toEqual([
"cramps",
@@ -226,5 +237,6 @@ describe("cycle backup — round-trips through build + restore", () => {
where: { userId: USER_ID },
});
expect(profile.goal).toBe("TRYING_TO_CONCEIVE");
expect(profile.secondarySymptom).toBe("CERVIX");
});
});
+42
View File
@@ -202,6 +202,30 @@ describe("cycle day-logs — single read (GET)", () => {
const res = await GET(jsonRequest("/api/cycle/day-logs?date=nope", "GET"));
expect(res.status).toBe(422);
});
it("round-trips the cervix observation signs through POST → GET", async () => {
await loginAs(FEMALE_USER_ID);
const route = await import("@/app/api/cycle/day-logs/route");
await route.POST(
jsonRequest("/api/cycle/day-logs", "POST", {
date: "2026-05-02",
cervixPosition: "HIGH",
cervixFirmness: "SOFT",
cervixOpening: "OPEN",
loggedAt: "2026-05-02T08:00:00.000Z",
}),
);
const hit = await route.GET(
jsonRequest("/api/cycle/day-logs?date=2026-05-02", "GET"),
);
expect(hit.status).toBe(200);
const { data } = await hit.json();
expect(data.cervixPosition).toBe("HIGH");
expect(data.cervixFirmness).toBe("SOFT");
expect(data.cervixOpening).toBe("OPEN");
});
});
describe("cycle day-logs — symptom severity", () => {
@@ -488,6 +512,24 @@ describe("cycle-prefs gate flip", () => {
);
expect(res.status).toBe(201);
});
it("defaults secondarySymptom to MUCUS and persists a switch to CERVIX", async () => {
await loginAs(FEMALE_USER_ID);
const { GET, PATCH } = await import(
"@/app/api/auth/me/cycle-prefs/route"
);
const initial = await GET();
expect((await initial.json()).data.secondarySymptom).toBe("MUCUS");
const patched = await PATCH(
jsonRequest("/api/auth/me/cycle-prefs", "PATCH", {
secondarySymptom: "CERVIX",
}),
);
expect(patched.status).toBe(200);
expect((await patched.json()).data.secondarySymptom).toBe("CERVIX");
});
});
describe("sync/changes — cycle domains", () => {