From 75f9ef150764f8965b57ffcc83ade8c73c6f300b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Bombeck?= Date: Thu, 22 Oct 2026 01:15:01 +0200 Subject: [PATCH] test(workouts): opt the account in before expecting a stored track GPS tracks are kept only after the account turns storeWorkoutRoutes on. The two route-storing cases opt in first, and a new case proves that an account which has not opted in keeps the workout, answers it as inserted, and stores no track. --- .../integration/workout-batch-create.test.ts | 65 +++++++++++++++++++ 1 file changed, 65 insertions(+) diff --git a/tests/integration/workout-batch-create.test.ts b/tests/integration/workout-batch-create.test.ts index 190fa34ef..00e431dfd 100644 --- a/tests/integration/workout-batch-create.test.ts +++ b/tests/integration/workout-batch-create.test.ts @@ -137,6 +137,17 @@ function makeRequest( }); } +/** + * GPS tracks are kept only after the account opts in (v1.44, + * `storeWorkoutRoutes`, off by default). The route-storing cases turn it on. + */ +async function keepWorkoutRoutes(): Promise { + await getPrismaClient().user.update({ + where: { id: TEST_USER_ID }, + data: { storeWorkoutRoutes: true }, + }); +} + function baseWorkout( externalId: string, overrides: WorkoutFixture = {}, @@ -154,6 +165,7 @@ function baseWorkout( describe("POST /api/workouts/batch (real Postgres)", () => { it("inserts a single workout with a nested route", async () => { const { POST } = await import("@/app/api/workouts/batch/route"); + await keepWorkoutRoutes(); const body = { workouts: [ @@ -216,6 +228,58 @@ describe("POST /api/workouts/batch (real Postgres)", () => { ).toEqual(body.workouts[0]!.route!.geometry); }); + it("keeps the workout and drops its track for an account that has not opted in", async () => { + const { POST } = await import("@/app/api/workouts/batch/route"); + const before = await getPrismaClient().user.findUniqueOrThrow({ + where: { id: TEST_USER_ID }, + select: { storeWorkoutRoutes: true }, + }); + expect(before.storeWorkoutRoutes).toBe(false); + + const body = { + workouts: [ + baseWorkout("hk-uuid-no-optin-001", { + totalDistanceM: 5200, + route: { + geometry: { + type: "LineString", + coordinates: [ + [11.077, 49.452], + [11.078, 49.453], + ], + }, + }, + }), + ], + }; + + const res = await POST(makeRequest(body)); + expect(res.status).toBe(200); + const json = (await res.json()) as { + data: { + inserted: number; + entries: Array<{ index: number; status: string }>; + }; + }; + // The entry status speaks for the workout, which was stored; the track + // follows the account's own setting, which the client reads separately. + expect(json.data.inserted).toBe(1); + expect(json.data.entries).toEqual([{ index: 0, status: "inserted" }]); + + const workouts = await getPrismaClient().workout.findMany({ + where: { userId: TEST_USER_ID }, + include: { route: true }, + }); + expect(workouts).toHaveLength(1); + expect(workouts[0]?.totalDistanceM).toBe(5200); + expect(workouts[0]?.route).toBeNull(); + expect( + await getPrismaClient().workoutRoute.count({ + where: { workout: { userId: TEST_USER_ID } }, + }), + ).toBe(0); + }); + it("persists a route-independent HR series for an indoor workout (v1.10.0)", async () => { const { POST } = await import("@/app/api/workouts/batch/route"); @@ -254,6 +318,7 @@ describe("POST /api/workouts/batch (real Postgres)", () => { it("inserts a 100-workout batch with a mix of routed and routeless entries", async () => { const { POST } = await import("@/app/api/workouts/batch/route"); + await keepWorkoutRoutes(); const workouts: WorkoutFixture[] = Array.from({ length: 100 }, (_, i) => { const offsetMin = i * 60;