Milestone v1.0: FamilySync MVP #1
@@ -448,6 +448,56 @@ describe('PATCH /api/lists/:id (authorized update)', () => {
|
||||
const body = await res.json() as { name: string }
|
||||
expect(body.name).toBe('Sharee Renamed')
|
||||
})
|
||||
|
||||
it('T-04-08: sharee sending { isShared: false } gets 403 and list_shares is unchanged', async () => {
|
||||
const ownerId = await seedUser('t04-08-owner')
|
||||
const shareeId = await seedUser('t04-08-sharee')
|
||||
const listId = await seedList(ownerId, 'T04-08 Shared List', true)
|
||||
await shareList(listId, shareeId)
|
||||
|
||||
// Act as sharee
|
||||
currentDevUserId = shareeId
|
||||
const app = await getApp()
|
||||
|
||||
// Sharee tries to set isShared: false — must be blocked
|
||||
const res = await app.request(jsonRequest('PATCH', `/api/lists/${listId}`, { isShared: false }))
|
||||
expect(res.status).toBe(403)
|
||||
const body = await res.json() as { error: string }
|
||||
// Response should mention owner/sharing
|
||||
expect(body.error).toMatch(/owner|shar/i)
|
||||
|
||||
// Prove list_shares is untouched — sharee row still exists
|
||||
const { and, eq } = await import('drizzle-orm')
|
||||
const shares = await db.select().from(listShares).where(
|
||||
and(eq(listShares.listId, listId), eq(listShares.userId, shareeId)),
|
||||
)
|
||||
expect(shares.length).toBe(1)
|
||||
})
|
||||
|
||||
it('T-04-08: sharee sending { isShared: true } gets 403 and no new shares are inserted', async () => {
|
||||
const ownerId = await seedUser('t04-08-true-owner')
|
||||
const shareeId = await seedUser('t04-08-true-sharee')
|
||||
// Private list (isShared: false) but sharee already has explicit access
|
||||
const listId = await seedList(ownerId, 'T04-08 Private List', false)
|
||||
await shareList(listId, shareeId)
|
||||
|
||||
// Act as sharee
|
||||
currentDevUserId = shareeId
|
||||
const app = await getApp()
|
||||
|
||||
// Record share count before the attempted mutation
|
||||
const { eq } = await import('drizzle-orm')
|
||||
const beforeShares = await db.select().from(listShares).where(eq(listShares.listId, listId))
|
||||
const beforeCount = beforeShares.length
|
||||
|
||||
// Sharee tries to set isShared: true — must be blocked
|
||||
const res = await app.request(jsonRequest('PATCH', `/api/lists/${listId}`, { isShared: true }))
|
||||
expect(res.status).toBe(403)
|
||||
|
||||
// Prove no new shares were inserted
|
||||
const afterShares = await db.select().from(listShares).where(eq(listShares.listId, listId))
|
||||
expect(afterShares.length).toBe(beforeCount)
|
||||
})
|
||||
})
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
Reference in New Issue
Block a user