mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-08 20:42:43 +00:00
Merge pull request #1003 from MBombeck/fix/cycle-symptom-severity-null
fix(cycle): accept a symptom logged without an intensity
This commit is contained in:
3 files changed
+92
-11
No files matched your search
+15
-9
@@ -20721,9 +20721,11 @@ components:
|
||||
minLength: 1
|
||||
maxLength: 80
|
||||
severity:
|
||||
type: integer
|
||||
minimum: 1
|
||||
maximum: 4
|
||||
anyOf:
|
||||
- type: integer
|
||||
minimum: 1
|
||||
maximum: 4
|
||||
- type: "null"
|
||||
required:
|
||||
- key
|
||||
note:
|
||||
@@ -20859,9 +20861,11 @@ components:
|
||||
minLength: 1
|
||||
maxLength: 80
|
||||
severity:
|
||||
type: integer
|
||||
minimum: 1
|
||||
maximum: 4
|
||||
anyOf:
|
||||
- type: integer
|
||||
minimum: 1
|
||||
maximum: 4
|
||||
- type: "null"
|
||||
required:
|
||||
- key
|
||||
note:
|
||||
@@ -20975,9 +20979,11 @@ components:
|
||||
minLength: 1
|
||||
maxLength: 80
|
||||
severity:
|
||||
type: integer
|
||||
minimum: 1
|
||||
maximum: 4
|
||||
anyOf:
|
||||
- type: integer
|
||||
minimum: 1
|
||||
maximum: 4
|
||||
- type: "null"
|
||||
required:
|
||||
- key
|
||||
note:
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
|
||||
import {
|
||||
cycleDayLogInputSchema,
|
||||
cycleDayLogPatchSchema,
|
||||
} from "@/lib/validations/cycle";
|
||||
|
||||
/**
|
||||
* A symptom picked without an intensity is the ordinary way to log one.
|
||||
*
|
||||
* The sheet holds the picker as key to intensity and sends `severity: null`
|
||||
* for every symptom the user did not rate, which is most of them. The schema
|
||||
* took a number or nothing at all, so those entries came back 422 and the
|
||||
* sheet showed "Could not save. Try again." with no way to tell why. The link
|
||||
* row has always stored an unrated symptom as a plain presence; only the
|
||||
* gate at the door disagreed, and nothing tested it.
|
||||
*/
|
||||
const BASE_INPUT = {
|
||||
date: "2026-09-17",
|
||||
loggedAt: new Date().toISOString(),
|
||||
} as const;
|
||||
|
||||
describe("cycle day-log symptoms accept an unrated selection", () => {
|
||||
for (const [name, schema] of [
|
||||
["create", cycleDayLogInputSchema],
|
||||
["patch", cycleDayLogPatchSchema],
|
||||
] as const) {
|
||||
it(`${name}: takes a symptom with no intensity at all`, () => {
|
||||
const parsed = schema.safeParse({
|
||||
...BASE_INPUT,
|
||||
symptoms: [{ key: "cramps" }],
|
||||
});
|
||||
expect(parsed.success, JSON.stringify(parsed.error?.issues)).toBe(true);
|
||||
});
|
||||
|
||||
it(`${name}: takes an explicit null intensity, which is what the sheet sends`, () => {
|
||||
const parsed = schema.safeParse({
|
||||
...BASE_INPUT,
|
||||
symptoms: [
|
||||
{ key: "cramps", severity: null },
|
||||
{ key: "back_pain", severity: null },
|
||||
],
|
||||
});
|
||||
expect(parsed.success, JSON.stringify(parsed.error?.issues)).toBe(true);
|
||||
});
|
||||
|
||||
it(`${name}: still takes a rated symptom`, () => {
|
||||
const parsed = schema.safeParse({
|
||||
...BASE_INPUT,
|
||||
symptoms: [{ key: "cramps", severity: 3 }],
|
||||
});
|
||||
expect(parsed.success).toBe(true);
|
||||
});
|
||||
|
||||
it(`${name}: still refuses an intensity outside 1 to 4`, () => {
|
||||
for (const severity of [0, 5, 2.5]) {
|
||||
const parsed = schema.safeParse({
|
||||
...BASE_INPUT,
|
||||
symptoms: [{ key: "cramps", severity }],
|
||||
});
|
||||
expect(parsed.success, `severity ${severity}`).toBe(false);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
@@ -131,7 +131,12 @@ export const cycleDayLogInputSchema = z.object({
|
||||
.array(
|
||||
z.object({
|
||||
key: z.string().min(1).max(80),
|
||||
severity: z.number().int().min(1).max(4).optional(),
|
||||
// NULL is the ordinary case, not an edge: picking a symptom without
|
||||
// tapping an intensity is how most entries are logged, and the link
|
||||
// row stores that as a plain presence. Rejecting it refused every
|
||||
// unrated symptom with a 422 the sheet could only show as
|
||||
// "Could not save".
|
||||
severity: z.number().int().min(1).max(4).nullable().optional(),
|
||||
}),
|
||||
)
|
||||
.max(40)
|
||||
@@ -181,7 +186,12 @@ export const cycleDayLogPatchSchema = z.object({
|
||||
.array(
|
||||
z.object({
|
||||
key: z.string().min(1).max(80),
|
||||
severity: z.number().int().min(1).max(4).optional(),
|
||||
// NULL is the ordinary case, not an edge: picking a symptom without
|
||||
// tapping an intensity is how most entries are logged, and the link
|
||||
// row stores that as a plain presence. Rejecting it refused every
|
||||
// unrated symptom with a 422 the sheet could only show as
|
||||
// "Could not save".
|
||||
severity: z.number().int().min(1).max(4).nullable().optional(),
|
||||
}),
|
||||
)
|
||||
.max(40)
|
||||
|
||||
Reference in new issue
Block a user