Skip to content

Commit

Permalink
Adding support for authenticate_as_service_role (#13)
Browse files Browse the repository at this point in the history
  • Loading branch information
tiniscule authored Oct 25, 2023
1 parent f23c4d5 commit 4ffec5e
Show file tree
Hide file tree
Showing 10 changed files with 151 additions and 58 deletions.
15 changes: 10 additions & 5 deletions .github/workflows/pg_tap.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,25 @@ jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions-rs/toolchain@v1
with:
toolchain: stable
- uses: actions-rs/cargo@v1
with:
command: install
args: --git https://github.com/supabase/dbdev.git dbdev
- uses: actions/checkout@v3
- uses: supabase/setup-cli@v1
with:
version: 1.50.4
version: latest
- name: Supabase Start
run: supabase init && supabase start
- name: Enable pgtle
run: psql -v ON_ERROR_STOP=1 -U postgres -d postgres -h localhost -p 54322 -c "CREATE EXTENSION pg_tle;"
env:
PGPASSWORD: postgres
- name: Install supabase_test_helpers extension
run: psql -v ON_ERROR_STOP=1 -U postgres -d postgres -h localhost -p 54322 -f ./supabase_test_helpers_pglet.sql
env:
PGPASSWORD: postgres
- name: Install supabase_test_helpers extension using dbdev cli
run: dbdev install --connection postgres://postgres:postgres@localhost:54322/postgres --path .
- name: Move files into supabase tests directory
run: mkdir ./supabase/tests && mv ./tests/* ./supabase/tests/
- name: Run Tests
Expand Down
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
.idea
.idea
.DS_Store
supabase_test_helpers_pglet.sql
2 changes: 1 addition & 1 deletion LICENSE.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
Copyright 2022 usebasejump.com
Copyright 2023 usebasejump.com

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

Expand Down
78 changes: 56 additions & 22 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Supabase Test Helpers
A collection of functions designed to make testing Supabase projects easier. Created as part of our [open source SaaS starter for Supabase](https://usebasejump.com).

## Quick Start
## Quick Start (recommended)
If you're using Supabase:

1) Install dbdev following the instructions here: [github.com/supabase/dbdev](https://github.com/supabase/dbdev)
Expand Down Expand Up @@ -29,39 +29,51 @@ SELECT * FROM finish();
ROLLBACK;
```

For a basic example, check out the [example blog tests](tests/04-blog-example.sql).
For a basic example, check out the [example blog tests](https://github.com/usebasejump/supabase-test-helpers/blob/main/tests/04-blog-example.sql).

## Manual Installation
Copy the contents of `supabase_test_helpers.sql` into the very first alphabetical test in your test suite, such as `00000-supabase_test_helpers.sql`. This will ensure that the test helpers are removed after your tests have run.
## Manual Installation (not recommended)
Copy the contents of the most recent version into the very first alphabetical test in your test suite, such as `00000-supabase_test_helpers.sql`. This will ensure that the test helpers are removed after your tests have run. for it to work, you need to create some fake tests at the bottom of the file for pgtap to not complain. Here's an example:
```sql

## Writing tests
Check out the docs below for available helpers. To view a comprehensive example, check out our [blog tests](tests/04-blog-example.sql).
-- we have to run some tests to get this to pass as the first test file.
-- investigating options to make this better. Maybe a dedicated test harness
-- but we dont' want these functions to always exist on the database.
BEGIN;

## Contributing
Yes, please! Anything you've found helpful for testing Supabase projects is welcome. To contribute:
select plan(7);
select function_returns('tests', 'create_supabase_user', Array['text', 'text', 'text', 'jsonb'], 'uuid');
select function_returns('tests', 'get_supabase_uid', Array['text'], 'uuid');
select function_returns('tests', 'get_supabase_user', Array['text'], 'json');
select function_returns('tests', 'authenticate_as', Array['text'], 'void');
select function_returns('tests', 'clear_authentication', Array[null], 'void');
select function_returns('tests', 'rls_enabled', Array['text', 'text'], 'text');
select function_returns('tests', 'rls_enabled', Array['text'], 'text');
select * from finish();
ROLLBACK;
```

* Add [pgTAP compliant test functions](https://pgtap.org/documentation.html#composeyourself) to `supabase_test_helpers.sql`
* Comments should be added above each function, follow the examples in the file.
* Add tests for your functions in `tests/XX-your-function-name.sql`
* Submit a PR
## Writing tests
Check out the docs below for available helpers. To view a comprehensive example, check out our [blog tests](https://github.com/usebasejump/supabase-test-helpers/blob/main/tests/04-blog-example.sql).

## Test Helpers
The following is auto-generated off of comments in the `supabase_test_helpers.sql` file. Any changes added to the README directly will be overwritten.
The following is auto-generated off of comments in the `supabase_test_helpers--0.0.2.sql` file. Any changes added to the README directly will be overwritten.

<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->

- [tests.create_supabase_user(identifier text, email text, phone text)](#testscreate_supabase_useridentifier-text-email-text-phone-text)
- [tests.get_supabase_user(identifier text)](#testsget_supabase_useridentifier-text)
- [tests.get_supabase_uid(identifier text)](#testsget_supabase_uididentifier-text)
- [tests.authenticate_as(identifier text)](#testsauthenticate_asidentifier-text)
- [tests.clear_authentication()](#testsclear_authentication)
- [tests.rls_enabled(testing_schema text)](#testsrls_enabledtesting_schema-text)
- [tests.rls_enabled(testing_schema text, testing_table text)](#testsrls_enabledtesting_schema-text-testing_table-text)
- [tests.create_supabase_user(identifier text, email text, phone text)](#testscreate_supabase_useridentifier-text-email-text-phone-text)
- [tests.get_supabase_user(identifier text)](#testsget_supabase_useridentifier-text)
- [tests.get_supabase_uid(identifier text)](#testsget_supabase_uididentifier-text)
- [tests.authenticate_as(identifier text)](#testsauthenticate_asidentifier-text)
- [tests.authenticate_as_service_role()](#testsauthenticate_as_service_role)
- [tests.clear_authentication()](#testsclear_authentication)
- [tests.rls_enabled(testing_schema text)](#testsrls_enabledtesting_schema-text)
- [tests.rls_enabled(testing_schema text, testing_table text)](#testsrls_enabledtesting_schema-text-testing_table-text)
- [Contributing](#contributing)

<!-- END doctoc generated TOC please keep comment here to allow auto update -->

<!-- include: supabase_test_helpers.sql -->
<!-- include: supabase_test_helpers--0.0.2.sql -->

### tests.create_supabase_user(identifier text, email text, phone text)

Expand Down Expand Up @@ -129,6 +141,17 @@ Example:
SELECT tests.authenticate_as('test_owner');
```

### tests.authenticate_as_service_role()
Clears authentication object and sets role to service_role.

Returns:
- `void`

Example:
```sql
SELECT tests.authenticate_as_service_role();
```

### tests.clear_authentication()
Clears out the authentication and sets role to anon

Expand Down Expand Up @@ -173,4 +196,15 @@ Example:
ROLLBACK;
```

<!-- /include: supabase_test_helpers.sql -->
<!-- /include: supabase_test_helpers--0.0.2.sql -->

## Contributing
Yes, please! Anything you've found helpful for testing Supabase projects is welcome. To contribute:

* Create a new version of supabase_test_helpers `supabase_test_helpers--{major}-{minor}-{patch}.sql`
* New versions are intended to be a fresh install, so copy the contents of the previous version into the new version.
* Add [pgTAP compliant test functions](https://pgtap.org/documentation.html#composeyourself) to the new version
* Comments should be added above each function, follow the examples in the file.
* Create a migration file `supabase_test_helpers--{oldMajor}-{oldMinor}-{oldPatch}--{newMajor}-{newMinor}-{newPatch}.sql` to upgrade to the new version. Include ONLY your migration code, not the entire contents of the new version.
* Add tests for your functions in `tests/XX-your-function-name.sql`
* Submit a PR
23 changes: 23 additions & 0 deletions supabase_test_helpers--0.0.1--0.0.2.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
-- complain if script is sourced in psql, rather than via CREATE EXTENSION
\echo Use "CREATE EXTENSION supabase_test_helpers" to load this file. \quit

/**
* ### tests.authenticate_as_service_role()
* Clears authentication object and sets role to service_role.
*
* Returns:
* - `void`
*
* Example:
* ```sql
* SELECT tests.authenticate_as_service_role();
* ```
*/
CREATE OR REPLACE FUNCTION tests.authenticate_as_service_role ()
RETURNS void
AS $$
BEGIN
perform set_config('role', 'service_role', true);
perform set_config('request.jwt.claims', null, true);
END
$$ LANGUAGE plpgsql;
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
SELECT pgtle.install_extension
(
'supabase_test_helpers',
'0.1',
'pgTAP test helpers for interacting with Supabase, including RLS and Authentication',
$_pg_tle_$
-- complain if script is sourced in psql, rather than via CREATE EXTENSION
\echo Use "CREATE EXTENSION supabase_test_helpers" to load this file. \quit

-- We want to store all of this in the tests schema to keep it
-- separate from any application data
Expand Down Expand Up @@ -165,6 +161,7 @@ CREATE OR REPLACE FUNCTION tests.authenticate_as (identifier text)
END
$$ LANGUAGE plpgsql;


/**
* ### tests.clear_authentication()
* Clears out the authentication and sets role to anon
Expand Down Expand Up @@ -246,7 +243,4 @@ RETURNS TEXT AS $$
1,
testing_table || 'table in the' || testing_schema || ' schema should have row level security enabled'
);
$$ LANGUAGE sql;

$_pg_tle_$
);
$$ LANGUAGE sql;
44 changes: 25 additions & 19 deletions supabase_test_helpers.sql → supabase_test_helpers--0.0.2.sql
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
-- Enable pgTAP if it's not already enabled
create extension if not exists pgtap with schema extensions;
-- complain if script is sourced in psql, rather than via CREATE EXTENSION
\echo Use "CREATE EXTENSION supabase_test_helpers" to load this file. \quit

-- We want to store all of this in the tests schema to keep it
-- separate from any application data
Expand Down Expand Up @@ -161,6 +161,28 @@ CREATE OR REPLACE FUNCTION tests.authenticate_as (identifier text)
END
$$ LANGUAGE plpgsql;

/**
* ### tests.authenticate_as_service_role()
* Clears authentication object and sets role to service_role.
*
* Returns:
* - `void`
*
* Example:
* ```sql
* SELECT tests.authenticate_as_service_role();
* ```
*/
CREATE OR REPLACE FUNCTION tests.authenticate_as_service_role ()
RETURNS void
AS $$
BEGIN
perform set_config('role', 'service_role', true);
perform set_config('request.jwt.claims', null, true);
END
$$ LANGUAGE plpgsql;


/**
* ### tests.clear_authentication()
* Clears out the authentication and sets role to anon
Expand Down Expand Up @@ -242,20 +264,4 @@ RETURNS TEXT AS $$
1,
testing_table || 'table in the' || testing_schema || ' schema should have row level security enabled'
);
$$ LANGUAGE sql;

-- we have to run some tests to get this to pass as the first test file.
-- investigating options to make this better. Maybe a dedicated test harness
-- but we dont' want these functions to always exist on the database.
BEGIN;

select plan(7);
select function_returns('tests', 'create_supabase_user', Array['text', 'text', 'text', 'jsonb'], 'uuid');
select function_returns('tests', 'get_supabase_uid', Array['text'], 'uuid');
select function_returns('tests', 'get_supabase_user', Array['text'], 'json');
select function_returns('tests', 'authenticate_as', Array['text'], 'void');
select function_returns('tests', 'clear_authentication', Array[null], 'void');
select function_returns('tests', 'rls_enabled', Array['text', 'text'], 'text');
select function_returns('tests', 'rls_enabled', Array['text'], 'text');
select * from finish();
ROLLBACK;
$$ LANGUAGE sql;
5 changes: 5 additions & 0 deletions supabase_test_helpers.control
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
default_version = 0.0.2
comment = 'A collection of functions designed to make testing Supabase projects easier'
relocatable = false
requires = pgtap
superuser = false
24 changes: 24 additions & 0 deletions tests/04-authenticate-as-service-role.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
BEGIN;
CREATE EXTENSION supabase_test_helpers;

select plan(8);

select tests.create_supabase_user('test');

select lives_ok($$ select tests.authenticate_as('test') $$, 'Successfully authenticated as test user');
select is((select tests.get_supabase_uid('test')), auth.uid(), 'Authenticates as the correct user');
select is((select current_role::text), 'authenticated', 'Sets the current role to authenticated');

select tests.authenticate_as_service_role();

select is((select current_role::text), 'service_role', 'Sets the current role to service_role');
select is((select auth.uid()), null, 'Clears out authentication');

select lives_ok($$ select tests.authenticate_as('test') $$, 'Successfully authenticated as test user');
select is((select tests.get_supabase_uid('test')), auth.uid(), 'Authenticates as the correct user');
select is((select current_role::text), 'authenticated', 'Sets the current role to authenticated');



select * from finish();
ROLLBACK;
File renamed without changes.

0 comments on commit 4ffec5e

Please sign in to comment.