fix(10): guard shared-calendar designation against non-existent target (CR-01)

PUT /api/admin/calendars/:id/shared cleared the current shared calendar then
set the target in two non-transactional UPDATEs without checking the target
exists — a bad/stale id wiped the family shared lane and still returned ok.
Verify the target inside a transaction; return 404 when absent. Adds a
regression test (RED→GREEN).
This commit is contained in:
Lucas Berger
2026-06-13 15:38:35 -04:00
parent ebde3e1d08
commit 2f347cbd98
2 changed files with 42 additions and 4 deletions
+21
View File
@@ -456,6 +456,27 @@ describe('PUT /api/admin/calendars/:id/shared', () => {
expect(sharedIds).toContain(calB);
expect(sharedIds).not.toContain(calA);
});
it('returns 404 for a non-existent target and does NOT clear the existing shared calendar (CR-01)', async () => {
const adminId = await seedUser('admin-shared-missing', true);
const calA = await seedCalendar(adminId, 'cal-a-keep', true); // currently the shared family lane
currentDevUserId = adminId;
const app = await getApp();
// PUT a target id that does not exist. The handler must verify the target
// exists BEFORE clearing the current shared lane, so a bad/stale id can
// never silently wipe the family's shared calendar (BLOCKER CR-01).
const res = await app.fetch(jsonRequest('PUT', '/api/admin/calendars/99999999/shared'));
expect(res.status).toBe(404);
// calA must STILL be shared — the no-op target must not have cleared it.
const [rowA] = await db
.select({ isShared: calendars.isShared })
.from(calendars)
.where(eq(calendars.id, calA))
.limit(1);
expect(rowA.isShared).toBe(true);
});
});
// ===========================================================================