Skip to content

Commit 64365a9

Browse files
committed
updated conditional tests, and pgsql-test version
1 parent 6259daf commit 64365a9

File tree

3 files changed

+118
-43
lines changed

3 files changed

+118
-43
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@
3838
"jest-in-case": "^1.0.2",
3939
"jest": "^29.6.2",
4040
"lerna": "^8.2.3",
41-
"pgsql-test": "^2.11.4",
41+
"pgsql-test": "^2.11.5",
4242
"prettier": "^3.0.2",
4343
"rimraf": "4.4.1",
4444
"ts-jest": "^29.1.1",

packages/supabase/__tests__/conditional.test.ts

Lines changed: 108 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
// @ts-nocheck
12
import { getConnections, PgTestClient } from 'pgsql-test';
23

34
let pg: PgTestClient;
@@ -18,11 +19,12 @@ beforeAll(async () => {
1819
);
1920
expect(authSchemaExists[0].exists).toBe(true);
2021

21-
// grant access to auth schema for testing
22-
// grant INSERT on auth.users to service_role so we can create test users
22+
// minimal grants for tests
2323
await pg.any(
2424
`GRANT USAGE ON SCHEMA auth TO public;
25-
GRANT INSERT ON TABLE auth.users TO service_role;
25+
GRANT USAGE ON SCHEMA storage TO public;
26+
GRANT SELECT ON TABLE auth.users TO service_role;
27+
GRANT SELECT ON TABLE storage.buckets TO service_role;
2628
GRANT EXECUTE ON FUNCTION auth.uid() TO public;
2729
GRANT EXECUTE ON FUNCTION auth.role() TO public;`,
2830
[]
@@ -45,52 +47,92 @@ describe('tutorial: rls with conditional policies', () => {
4547
it('should verify rls policies can use case statements', async () => {
4648
db.setContext({ role: 'service_role' });
4749

48-
// using auth.users (real supabase table) instead of rls_test.users (fake test table)
49-
// use pg for auth.users insert since it requires superuser privileges
50+
// insert into auth.users using admin connection
5051
const user1 = await pg.one(
5152
`INSERT INTO auth.users (id, email)
5253
VALUES (gen_random_uuid(), $1)
5354
RETURNING id`,
5455
5556
);
56-
57+
// ensure auth.role() sees service_role via jwt claim
58+
db.setContext({
59+
role: 'service_role',
60+
'request.jwt.claim.role': 'service_role'
61+
});
62+
// case over email and auth.role()
63+
const rows = await db.any(
64+
`SELECT
65+
CASE WHEN email LIKE '%@example.com' THEN 'example' ELSE 'other' END AS grp,
66+
CASE WHEN auth.role() = 'service_role' THEN 'visible' ELSE 'hidden' END AS visibility
67+
FROM auth.users
68+
WHERE id = $1`,
69+
[user1.id]
70+
);
71+
expect(Array.isArray(rows)).toBe(true);
72+
expect(rows.length).toBe(1);
73+
expect(rows[0].grp).toBe('example');
74+
expect(rows[0].visibility).toBe('visible');
5775
});
5876

5977
it('should verify rls policies work with multiple conditions', async () => {
6078
db.setContext({ role: 'service_role' });
6179

62-
// using auth.users (real supabase table) instead of rls_test.users (fake test table)
63-
// use pg for auth.users insert since it requires superuser privileges
80+
// insert into auth.users using admin connection
6481
const user = await pg.one(
6582
`INSERT INTO auth.users (id, email)
6683
VALUES (gen_random_uuid(), $1)
6784
RETURNING id`,
6885
6986
);
70-
71-
87+
// ensure auth.role() sees service_role via jwt claim
88+
db.setContext({
89+
role: 'service_role',
90+
'request.jwt.claim.role': 'service_role'
91+
});
92+
// and/or combinations with auth.role()
93+
const rows = await db.any(
94+
`SELECT id
95+
FROM auth.users
96+
WHERE (email = $1 AND (auth.role() = 'service_role' OR auth.role() = 'authenticated'))
97+
AND id = $2`,
98+
['[email protected]', user.id]
99+
);
100+
expect(Array.isArray(rows)).toBe(true);
101+
expect(rows.length).toBe(1);
102+
expect(rows[0].id).toBe(user.id);
72103
});
73104

74105
it('should verify rls policies work with or conditions', async () => {
75106
db.setContext({ role: 'service_role' });
76107

77-
// using auth.users (real supabase table) instead of rls_test.users (fake test table)
78-
// use pg for auth.users insert since it requires superuser privileges
108+
// insert into auth.users using admin connection
79109
const user = await pg.one(
80110
`INSERT INTO auth.users (id, email)
81111
VALUES (gen_random_uuid(), $1)
82112
RETURNING id`,
83113
84114
);
85-
86-
115+
const user2 = await pg.one(
116+
`INSERT INTO auth.users (id, email)
117+
VALUES (gen_random_uuid(), $1)
118+
RETURNING id`,
119+
120+
);
121+
122+
const rows = await db.any(
123+
`SELECT COUNT(*)::integer AS count
124+
FROM auth.users
125+
WHERE email = $1 OR email = $2`,
126+
127+
);
128+
expect(Array.isArray(rows)).toBe(true);
129+
expect(Number(rows[0].count)).toBe(2);
87130
});
88131

89132
it('should verify rls policies work with subqueries', async () => {
90133
db.setContext({ role: 'service_role' });
91134

92-
// using auth.users (real supabase table) instead of rls_test.users (fake test table)
93-
// use pg for auth.users insert since it requires superuser privileges
135+
// insert into auth.users using admin connection
94136
const user1 = await pg.one(
95137
`INSERT INTO auth.users (id, email)
96138
VALUES (gen_random_uuid(), $1)
@@ -105,53 +147,86 @@ describe('tutorial: rls with conditional policies', () => {
105147
RETURNING id`,
106148
107149
);
108-
109-
150+
// use a subquery to resolve ids by email
151+
const viaSub = await db.any(
152+
`SELECT u.id
153+
FROM auth.users u
154+
WHERE u.id IN (SELECT id FROM auth.users WHERE email = $1)`,
155+
156+
);
157+
expect(viaSub.length).toBe(1);
158+
expect(viaSub[0].id).toBe(user1.id);
159+
160+
// correlated exists
161+
const existsRows = await db.any(
162+
`SELECT u.id
163+
FROM auth.users u
164+
WHERE EXISTS (
165+
SELECT 1 FROM auth.users i WHERE i.id = u.id AND i.email = $1
166+
)`,
167+
168+
);
169+
expect(existsRows.length).toBeGreaterThan(0);
170+
const found = existsRows.find((r: any) => r.id === user2.id);
171+
expect(Boolean(found)).toBe(true);
110172
});
111173

112174
it('should verify rls policies work with related table checks', async () => {
113175
db.setContext({ role: 'service_role' });
114176

115-
// using auth.users (real supabase table) instead of rls_test.users (fake test table)
116-
// use pg for auth.users insert since it requires superuser privileges
177+
// insert into auth.users using admin connection
117178
const user = await pg.one(
118179
`INSERT INTO auth.users (id, email)
119180
VALUES (gen_random_uuid(), $1)
120181
RETURNING id`,
121182
122183
);
123-
124-
184+
// left join storage.buckets by fk owner -> auth.users(id)
185+
const rows = await db.any(
186+
`SELECT u.id, b.id AS bucket_id
187+
FROM auth.users u
188+
LEFT JOIN storage.buckets b ON b.owner = u.id
189+
WHERE u.id = $1`,
190+
[user.id]
191+
);
192+
expect(rows.length).toBe(1);
193+
// no bucket yet, so join should be null
194+
expect(rows[0].bucket_id === null || rows[0].bucket_id === undefined).toBe(true);
125195
});
126196

127197
it('should verify rls policies work with null checks', async () => {
128198
db.setContext({ role: 'service_role' });
129199

130-
// using auth.users (real supabase table) instead of rls_test.users (fake test table)
131-
// use pg for auth.users insert since it requires superuser privileges
200+
// insert into auth.users using admin connection
132201
const user = await pg.one(
133202
`INSERT INTO auth.users (id, email)
134203
VALUES (gen_random_uuid(), $1)
135-
RETURNING id`,
136-
204+
RETURNING id, email`,
205+
[null]
137206
);
138-
139-
207+
const rows = await db.any(
208+
`SELECT id FROM auth.users WHERE id = $1 AND email IS NULL`,
209+
[user.id]
210+
);
211+
expect(rows.length).toBe(1);
140212
});
141213

142214
it('should verify rls policies work with coalesce functions', async () => {
143215
db.setContext({ role: 'service_role' });
144216

145-
// using auth.users (real supabase table) instead of rls_test.users (fake test table)
146-
// use pg for auth.users insert since it requires superuser privileges
217+
// insert into auth.users using admin connection
147218
const user = await pg.one(
148219
`INSERT INTO auth.users (id, email)
149220
VALUES (gen_random_uuid(), $1)
150221
RETURNING id`,
151-
222+
[null]
152223
);
153-
154-
224+
const rows = await db.any(
225+
`SELECT COALESCE(email, '') AS safe_email FROM auth.users WHERE id = $1`,
226+
[user.id]
227+
);
228+
expect(rows.length).toBe(1);
229+
expect(rows[0].safe_email).toBe('');
155230
});
156231
});
157232

pnpm-lock.yaml

Lines changed: 9 additions & 9 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)