fix(workouts): report no route when its track cannot be read

This commit is contained in:
Marc-André Bombeck committed 2026-09-27 15:11:43 +02:00
1 parent f98f8eaa24
commit 833fb0b465
2 files changed
+32 -11

No files matched your search

+16 -11
View File
@@ -259,17 +259,22 @@ export const GET = apiHandler(
null,
)?.id ?? null;
const route = row.route
? {
geometry: routeGeometry,
// `compact=1` drops the (up to 20k-entry) timestamp array; the
// SVG needs geometry, not the per-sample timestamps, and the
// splits above are already derived from them server-side.
sampleTimestamps: compact
? null
: (row.route.sampleTimestamps ?? null),
}
: null;
// A route whose track cannot be read (a sealed value that no longer
// opens, or an old row stored as a JSON null) is reported as no route at
// all: clients decode `route.geometry` as required, so a route object
// with a null geometry would fail the whole workout detail for them.
const route =
row.route && routeGeometry
? {
geometry: routeGeometry,
// `compact=1` drops the (up to 20k-entry) timestamp array; the
// SVG needs geometry, not the per-sample timestamps, and the
// splits above are already derived from them server-side.
sampleTimestamps: compact
? null
: (row.route.sampleTimestamps ?? null),
}
: null;
// v1.10.0 — route-independent per-workout HR series. Present for
// both indoor (no route) and outdoor workouts that shipped a
@@ -23,6 +23,7 @@
* rather than only in a count.
*/
import { NextRequest } from "next/server";
import { Prisma } from "@/generated/prisma/client";
import { beforeEach, describe, expect, it, vi } from "vitest";
import { cookieJar, headerJar } from "./mock-next-headers";
@@ -277,3 +278,18 @@ describe("GET /api/workouts/{id} — reconstructed heart-rate curve", () => {
expect(response.status).toBe(404);
});
});
describe("GET /api/workouts/{id} — a route whose track cannot be read", () => {
it("reports no route at all instead of a route with a null geometry", async () => {
const id = await createWorkout();
// Neither the sealed column nor the legacy readable one holds a track:
// the shape an unreadable or JSON-null row resolves to.
await getPrismaClient().workoutRoute.create({
data: { workoutId: id, geometry: Prisma.JsonNull },
});
const body = (await fetchDetail(id)) as unknown as {
data: { route: unknown };
};
expect(body.data.route).toBeNull();
});
});