fix(records): give the visit, vaccination and workout refusals a sentence

The visit, vaccination, allergy, address-book and workout forms read a
refusal's code through the catalogue, but nineteen of the codes their
routes send had no sentence: a stale doctor or check-up, a planned visit
that would close a check-up, a dose without a name, a booster that
cannot be planned, an invalid body, a workout batch that is too large.
Each of them read as the form's generic "could not be saved", which
hides what the person can change. They now have their own sentence in
all ten languages.
This commit is contained in:
Marc-André Bombeck committed 2026-11-11 21:32:23 +01:00
1 parent 0b7afd8460
commit 85240ab858
11 files changed
+364

No files matched your search

@@ -7,7 +7,11 @@ import en from "../../../../messages/en.json";
import es from "../../../../messages/es.json";
import fr from "../../../../messages/fr.json";
import itCatalog from "../../../../messages/it.json";
import ko from "../../../../messages/ko.json";
import nl from "../../../../messages/nl.json";
import pl from "../../../../messages/pl.json";
import ptBR from "../../../../messages/pt-BR.json";
import ru from "../../../../messages/ru.json";
type Catalog = Record<string, unknown>;
@@ -160,4 +164,54 @@ describe("localizedApiError", () => {
}
});
});
describe("the refusals of the visit, vaccination, allergy, address-book and workout saves", () => {
// Each of these is a code the route sends to a form that reads it through
// `localizedApiError`; without a sentence the form says only "could not
// save", which hides a fix the person can make.
const codes = [
"encounter.invalid",
"encounter.practitioner-not-found",
"encounter.reminder-not-found",
"encounter.reminder-conflict",
"vaccination.invalid",
"vaccination.not-found",
"vaccination.identity-required",
"vaccination.practitioner-not-found",
"vaccination.encounter-not-found",
"vaccination.custom-vaccine-not-found",
"vaccination.booster-invalid",
"vaccination.booster-no-antigen",
"vaccination.booster-out-of-scope",
"allergy.invalid",
"practitioner.invalid",
"workout.batch.invalid",
"workout.batch.too_large",
"workout.batch.payload_too_large",
"workout.batch.source_not_permitted",
];
it.each([
["de", de],
["en", en],
["es", es],
["fr", fr],
["it", itCatalog],
["ko", ko],
["nl", nl],
["pl", pl],
["pt-BR", ptBR],
["ru", ru],
])("has a sentence of its own for each in %s", (_, locale) => {
const localT = translator(locale as Catalog);
for (const code of codes) {
const error = new ApiError("raw English server prose", 422, {
errorCode: code,
});
expect(localizedApiError(error, localT, "common.error"), code).not.toBe(
localT("common.error"),
);
}
});
});
});