Skip to content

Commit 311dfc6

Browse files
committed
test(stack): pin the v3 bulk null-envelope guard
Drives `bulkEncrypt` to return a length-matched response with a null envelope at position 0 and asserts the query fails 500 with "null envelope at position 0" rather than sending the literal "null" as the `in` operand. Sibling to the existing length-mismatch guard test. Claude-Session: https://claude.ai/code/session_01MxTTPaPP16m6br7Hoab94w
1 parent a068a4d commit 311dfc6

1 file changed

Lines changed: 25 additions & 0 deletions

File tree

‎packages/stack/__tests__/supabase-v3-builder.test.ts‎

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1901,4 +1901,29 @@ describe('v3 in-list term encryption batches by column', () => {
19011901
expect(status).toBe(500)
19021902
expect(error?.message).toMatch(/1 term(s)? for 2 value(s)?/)
19031903
})
1904+
1905+
it('rejects a bulk response with a null envelope rather than sending "null"', async () => {
1906+
const supabase = createMockSupabase()
1907+
const encryption = createMockEncryptionClient()
1908+
// A length-matched response, but position 0 is a null envelope. Without the
1909+
// guard, `JSON.stringify(null)` would send the literal `"null"` as the `in`
1910+
// operand — matching whatever `"null"` encodes to instead of failing.
1911+
;(
1912+
encryption as unknown as { bulkEncrypt: (...a: unknown[]) => unknown }
1913+
).bulkEncrypt = () =>
1914+
operation([{ data: null }, { data: fakeEnvelope('grace', 'nickname') }])
1915+
1916+
const { error, status } = await new EncryptedQueryBuilderV3Impl(
1917+
'users',
1918+
users,
1919+
encryption,
1920+
supabase.client,
1921+
USERS_ALL_COLUMNS,
1922+
)
1923+
.select('id')
1924+
.in('nickname', ['ada', 'grace'])
1925+
1926+
expect(status).toBe(500)
1927+
expect(error?.message).toMatch(/null envelope at position 0/)
1928+
})
19041929
})

0 commit comments

Comments
 (0)