Skip to content

Commit 17d6585

Browse files
committed
cleanup
1 parent ab9a3c8 commit 17d6585

34 files changed

+244
-323
lines changed

README.md

Lines changed: 30 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -11,91 +11,67 @@
1111
<a href="https://github.com/launchql/supabase-test/blob/main/LICENSE"><img height="20" src="https://img.shields.io/badge/license-MIT-blue.svg"/></a>
1212
</p>
1313

14+
A friendly playground for building and validating Supabase Row-Level Security (RLS) using LaunchQL. It includes real-world examples, migrations, and a comprehensive test suite you can run locally.
1415

15-
A friendly playground for building and validating Supabase Row‑Level Security (RLS) using LaunchQL. It includes real‑world examples, migrations, and a comprehensive test suite you can run locally.
16-
17-
Built with [supabase-test](https://www.npmjs.com/package/supabase-test) — a Supabase‑optimized version of `pgsql-test` for instant, isolated Postgres test databases with automatic rollbacks and Supabase defaults. See the package for install and features.
16+
Built with [supabase-test](https://www.npmjs.com/package/supabase-test) — a Supabase-optimized version of `pgsql-test` for instant, isolated Postgres test databases with automatic rollbacks and Supabase defaults.
1817

1918
## Features
2019

21-
- 🔐 RLS policy‑driven example tests with example product database using Supabase users
22-
- 🧪 Comprehensive end‑to‑end test suite against native Supabase schemas/tables (auth, storage, functions, realtime, and more)
23-
- 🐘 Supabase CLI local stack for zero‑setup Postgres
24-
- 🧪 Jest‑based tests that exercise RLS behavior end‑to‑end
25-
- 🚀 GitHub Actions workflows to run integration/e2e tests in CI/CD
26-
- 🧩 Modular schema packages you can reuse and extend
20+
- 🔐 **RLS Policy Testing** - Real-world examples with users and products tables
21+
- 🧪 **Comprehensive Test Suite** - End-to-end tests against native Supabase schemas
22+
- 🐘 **Zero-Setup Postgres** - Supabase CLI local stack for instant development
23+
- **Jest Integration** - Fast, isolated tests with automatic rollbacks
24+
- 🚀 **CI/CD Ready** - GitHub Actions workflows for automated testing
25+
- 🧩 **Modular Architecture** - Reusable schema packages you can extend
2726

28-
## Quick start (tl;dr)
27+
## Quick Start
2928

3029
```bash
31-
# bring up a local supabase stack
30+
# Initialize and start local Supabase stack
3231
npx supabase init
3332
npx supabase start
3433

35-
# install deps and run all package tests
34+
# Install dependencies
3635
pnpm install
3736

38-
# rls-demo: run tests in watch mode
37+
# Run tests in watch mode
3938
cd packages/rls-demo
4039
pnpm test:watch
4140
```
4241

43-
## getting started (step by step)
44-
45-
this section will walk through everything slowly, from installing tools to running focused tests and exploring the schemas.
46-
47-
1. install prerequisites (node, pnpm, supabase cli)
48-
2. initialize supabase and confirm services are healthy
49-
3. configure pg env vars if your shell needs them
50-
4. run migrations or package deploys as needed
51-
5. run tests (full suite and targeted)
52-
6. inspect policies and iterate
53-
54-
for the expanded guide with screenshots and copy‑paste commands, see `docs/img/USAGE.md` (coming soon).
42+
## Repository Structure
5543

56-
## repository layout
44+
This is a LaunchQL workspace combining `pnpm` and `lql` for modular Postgres packages:
5745

58-
The repository is a launchql workspace, which is a hybrid `pnpm`/`lql` workspace, which allows for modular postgres packages, that can be easily tested via `pgsql-test`, or in the case of this repository, `supabase-test`. Here are the packages of interest:
46+
- **`packages/supabase`** - Supabase-focused SQL, tests, and helpers
47+
- **`packages/rls-demo`** - Demo extension showcasing RLS with users/products
5948

60-
- `packages/supabase`: supabase‑focused sql, tests, and helpers
61-
- `packages/rls-demo`: demo extension showcasing rls with users/products
49+
## Testing
6250

63-
## testing
64-
65-
If you want to see how to run tests in each of the relevant packages, here are handy snippets you may want to learn:
51+
Run tests in different modes:
6652

6753
```bash
68-
# rls-demo: run tests in watch mode
54+
# Run all tests from root
55+
pnpm test
56+
57+
# Watch mode for specific package
6958
cd packages/rls-demo
7059
pnpm test:watch
7160

72-
# edit tests in packages/rls-demo/__tests__/... and Jest will re-run
73-
```
74-
75-
```bash
76-
# supabase: run tests in watch mode
61+
# Run Supabase package tests
7762
cd packages/supabase
7863
pnpm test:watch
7964
```
8065

81-
```bash
82-
# run all packages’ tests from the repo root
83-
pnpm test
84-
```
85-
86-
## Adding a package using `lql`
87-
88-
- [ ] TODO
89-
9066
## Requirements
9167

9268
- Node.js 20+
9369
- pnpm 10+
9470
- Supabase CLI 2+
9571

96-
## troubleshooting
72+
## Troubleshooting
9773

98-
- if your environment needs explicit pg variables, export and retry:
74+
If you encounter connection issues, set your environment variables:
9975

10076
```bash
10177
export PGPORT=54322
@@ -104,9 +80,10 @@ export PGUSER=postgres
10480
export PGPASSWORD=postgres
10581
```
10682

107-
- if `pnpm test` can’t reach postgres, confirm supabase services are running and the `PG*` env vars match the port printed by `npx supabase start`
108-
- if ports are busy, stop old containers or pass a different port to supabase
109-
- node version mismatches can cause odd errors; use node 20+
83+
Common issues:
84+
- Ensure Supabase services are running (`npx supabase status`)
85+
- Check that ports match those shown by `npx supabase start`
86+
- Use Node.js 20+ to avoid compatibility issues
11087

11188
## Related LaunchQL Tooling
11289

@@ -117,4 +94,4 @@ export PGPASSWORD=postgres
11794

11895
AS DESCRIBED IN THE LICENSES, THE SOFTWARE IS PROVIDED "AS IS", AT YOUR OWN RISK, AND WITHOUT WARRANTIES OF ANY KIND.
11996

120-
No developer or entity involved in creating this software will be liable for any claims or damages whatsoever associated with your use, inability to use, or your interaction with other users of the code, including any direct, indirect, incidental, special, exemplary, punitive or consequential damages, or loss of profits, cryptocurrencies, tokens, or anything else of value.
97+
No developer or entity involved in creating this software will be liable for any claims or damages whatsoever associated with your use, inability to use, or your interaction with other users of the code, including any direct, indirect, incidental, special, exemplary, punitive or consequential damages, or loss of profits, cryptocurrencies, tokens, or anything else of value.

packages/rls-demo/README.md

Lines changed: 31 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,43 @@
1-
# @lql-pg/rls-demo
1+
# Supabase RLS Demo
22

3-
RLS (Row Level Security) demo extension for PostgreSQL.
3+
<p align="center" width="100%">
4+
<img height="250" src="https://raw.githubusercontent.com/launchql/supabase-test/refs/heads/main/docs/img/logos.svg" />
5+
</p>
46

5-
Provides a demonstration of Row Level Security implementation with users and products tables, including:
6-
- `rls_test` schema with proper RLS policies
7-
- `users` table with RLS policies for user data access
8-
- `products` table with RLS policies for product ownership
9-
- Foreign key relationships and proper indexing
10-
- Automatic `updated_at` timestamp triggers
7+
<p align="center" width="100%">
8+
<a href="https://github.com/launchql/supabase-test/actions/workflows/ci.yml">
9+
<img height="20" src="https://github.com/launchql/supabase-test/actions/workflows/ci.yml/badge.svg" />
10+
</a>
11+
<a href="https://github.com/launchql/supabase-test/blob/main/LICENSE"><img height="20" src="https://img.shields.io/badge/license-MIT-blue.svg"/></a>
12+
</p>
1113

12-
## Sample Data
14+
Supabase RLS (Row Level Security) demo, showcasing best practices for implementing secure, multi-tenant applications.
1315

14-
This package includes sample data to demonstrate RLS functionality:
16+
## Features
1517

16-
### Users
17-
- Alice Johnson ([email protected])
18-
- Bob Smith ([email protected])
19-
- Charlie Brown ([email protected])
20-
- Diana Prince ([email protected])
18+
- 🔐 Complete RLS implementation with users and products tables
19+
- 👥 Multi-tenant data isolation using Supabase auth
20+
- 🧪 Comprehensive test suite with real-world scenarios
2121

22-
### Products
23-
- Alice owns: Laptop Pro ($1299.99), Wireless Mouse ($49.99)
24-
- Bob owns: Mechanical Keyboard ($149.99), Monitor 4K ($399.99)
25-
- Charlie owns: Webcam HD ($89.99), Headphones ($199.99)
26-
- Diana owns: Standing Desk ($599.99), Desk Lamp ($79.99)
22+
## Schema Overview
2723

28-
## Data Insertion
24+
The `rls_test` schema includes:
25+
- **user_profiles** table with RLS policies for user data access
26+
- **products** table with RLS policies for product ownership
27+
- Proper foreign key constraints and indexes
2928

30-
### Using SQL File
31-
```bash
32-
psql -d your_database -f seed-data.sql
33-
```
29+
## Quick Start
3430

35-
### Using Node.js Script
3631
```bash
37-
node insert-data.js
32+
# Run tests
33+
pnpm test
34+
35+
# Watch mode for development
36+
pnpm test:watch
3837
```
3938

40-
### Using pgsql-test
41-
The test suite includes comprehensive data insertion and RLS testing examples.
39+
## Disclaimer
40+
41+
AS DESCRIBED IN THE LICENSES, THE SOFTWARE IS PROVIDED "AS IS", AT YOUR OWN RISK, AND WITHOUT WARRANTIES OF ANY KIND.
42+
43+
No developer or entity involved in creating this software will be liable for any claims or damages whatsoever associated with your use, inability to use, or your interaction with other users of the code, including any direct, indirect, incidental, special, exemplary, punitive or consequential damages, or loss of profits, cryptocurrencies, tokens, or anything else of value.

packages/rls-demo/__tests__/rls-test-products.test.ts

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,10 @@
11
import { getConnections, PgTestClient } from 'supabase-test';
22

3-
let pg: PgTestClient;
43
let db: PgTestClient;
54
let teardown: () => Promise<void>;
65

76
beforeAll(async () => {
8-
9-
10-
({ pg, db, teardown } = await getConnections());
7+
({ db, teardown } = await getConnections());
118
});
129

1310
afterAll(async () => {

packages/rls-demo/__tests__/rls-test-users.test.ts

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,10 @@
11
import { getConnections, PgTestClient } from 'supabase-test';
22

3-
let pg: PgTestClient;
43
let db: PgTestClient;
54
let teardown: () => Promise<void>;
65

76
beforeAll(async () => {
8-
9-
10-
({ pg, db, teardown } = await getConnections());
7+
({ db, teardown } = await getConnections());
118
});
129

1310
afterAll(async () => {

packages/rls-demo/__tests__/rls/rls.advanced.test.ts

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ describe('tutorial: advanced rls edge cases and scenarios', () => {
2424
db.setContext({ role: 'service_role' });
2525

2626
const user = await db.one(
27-
`INSERT INTO rls_test.users (email, name)
27+
`INSERT INTO rls_test.user_profiles (email, name)
2828
VALUES ($1, $2)
2929
RETURNING id`,
3030
['[email protected]', 'Advanced User 1']
@@ -43,7 +43,7 @@ describe('tutorial: advanced rls edge cases and scenarios', () => {
4343
);
4444

4545
const verifiedUsers = await db.any(
46-
`SELECT id FROM rls_test.users WHERE id = $1`,
46+
`SELECT id FROM rls_test.user_profiles WHERE id = $1`,
4747
[user.id]
4848
);
4949
expect(verifiedUsers.length).toBe(1);
@@ -57,7 +57,7 @@ describe('tutorial: advanced rls edge cases and scenarios', () => {
5757
db.clearContext();
5858

5959
const anonUsers = await db.any(
60-
`SELECT id FROM rls_test.users WHERE id = $1`,
60+
`SELECT id FROM rls_test.user_profiles WHERE id = $1`,
6161
[user.id]
6262
);
6363
expect(anonUsers.length).toBe(0);
@@ -76,7 +76,7 @@ describe('tutorial: advanced rls edge cases and scenarios', () => {
7676

7777
// create user as admin
7878
const user = await db.one(
79-
`INSERT INTO rls_test.users (email, name)
79+
`INSERT INTO rls_test.user_profiles (email, name)
8080
VALUES ($1, $2)
8181
RETURNING id`,
8282
['[email protected]', 'Advanced User 2']
@@ -104,14 +104,14 @@ describe('tutorial: advanced rls edge cases and scenarios', () => {
104104

105105
// create two users as admin
106106
const user1 = await db.one(
107-
`INSERT INTO rls_test.users (email, name)
107+
`INSERT INTO rls_test.user_profiles (email, name)
108108
VALUES ($1, $2)
109109
RETURNING id`,
110110
['[email protected]', 'Advanced User 3']
111111
);
112112

113113
const user2 = await db.one(
114-
`INSERT INTO rls_test.users (email, name)
114+
`INSERT INTO rls_test.user_profiles (email, name)
115115
VALUES ($1, $2)
116116
RETURNING id`,
117117
['[email protected]', 'Advanced User 4']
@@ -154,14 +154,14 @@ describe('tutorial: advanced rls edge cases and scenarios', () => {
154154

155155
// create multiple users as admin
156156
const user1 = await db.one(
157-
`INSERT INTO rls_test.users (email, name)
157+
`INSERT INTO rls_test.user_profiles (email, name)
158158
VALUES ($1, $2)
159159
RETURNING id`,
160160
['[email protected]', 'Advanced User 5']
161161
);
162162

163163
const user2 = await db.one(
164-
`INSERT INTO rls_test.users (email, name)
164+
`INSERT INTO rls_test.user_profiles (email, name)
165165
VALUES ($1, $2)
166166
RETURNING id`,
167167
['[email protected]', 'Advanced User 6']
@@ -213,7 +213,7 @@ describe('tutorial: advanced rls edge cases and scenarios', () => {
213213

214214
// create user as admin
215215
const user = await db.one(
216-
`INSERT INTO rls_test.users (email, name)
216+
`INSERT INTO rls_test.user_profiles (email, name)
217217
VALUES ($1, $2)
218218
RETURNING id`,
219219
['[email protected]', 'Advanced User 7']
@@ -245,7 +245,7 @@ describe('tutorial: advanced rls edge cases and scenarios', () => {
245245

246246
// user deletes themselves - products should cascade delete
247247
await db.any(
248-
`DELETE FROM rls_test.users WHERE id = $1`,
248+
`DELETE FROM rls_test.user_profiles WHERE id = $1`,
249249
[user.id]
250250
);
251251

@@ -264,21 +264,21 @@ describe('tutorial: advanced rls edge cases and scenarios', () => {
264264

265265
// create three users as admin
266266
const user1 = await db.one(
267-
`INSERT INTO rls_test.users (email, name)
267+
`INSERT INTO rls_test.user_profiles (email, name)
268268
VALUES ($1, $2)
269269
RETURNING id`,
270270
['[email protected]', 'Advanced User 8']
271271
);
272272

273273
const user2 = await db.one(
274-
`INSERT INTO rls_test.users (email, name)
274+
`INSERT INTO rls_test.user_profiles (email, name)
275275
VALUES ($1, $2)
276276
RETURNING id`,
277277
['[email protected]', 'Advanced User 9']
278278
);
279279

280280
const user3 = await db.one(
281-
`INSERT INTO rls_test.users (email, name)
281+
`INSERT INTO rls_test.user_profiles (email, name)
282282
VALUES ($1, $2)
283283
RETURNING id`,
284284
['[email protected]', 'Advanced User 10']
@@ -332,7 +332,7 @@ describe('tutorial: advanced rls edge cases and scenarios', () => {
332332

333333
// create user as admin
334334
const user = await db.one(
335-
`INSERT INTO rls_test.users (email, name)
335+
`INSERT INTO rls_test.user_profiles (email, name)
336336
VALUES ($1, $2)
337337
RETURNING id`,
338338
['[email protected]', 'Advanced User 11']
@@ -346,7 +346,7 @@ describe('tutorial: advanced rls edge cases and scenarios', () => {
346346

347347
// should not be able to access user data with null user_id
348348
await expect(
349-
db.one(`SELECT id FROM rls_test.users WHERE id = $1`, [user.id])
349+
db.one(`SELECT id FROM rls_test.user_profiles WHERE id = $1`, [user.id])
350350
).rejects.toThrow();
351351
});
352352

@@ -356,14 +356,14 @@ describe('tutorial: advanced rls edge cases and scenarios', () => {
356356

357357
// create two users as admin
358358
const user1 = await db.one(
359-
`INSERT INTO rls_test.users (email, name)
359+
`INSERT INTO rls_test.user_profiles (email, name)
360360
VALUES ($1, $2)
361361
RETURNING id`,
362362
['[email protected]', 'Advanced User 12']
363363
);
364364

365365
const user2 = await db.one(
366-
`INSERT INTO rls_test.users (email, name)
366+
`INSERT INTO rls_test.user_profiles (email, name)
367367
VALUES ($1, $2)
368368
RETURNING id`,
369369
['[email protected]', 'Advanced User 13']

0 commit comments

Comments
 (0)