From 836952ce354b984b2e9b6e5ab5bc89702adfd917 Mon Sep 17 00:00:00 2001 From: Rodrigo Mansueli Nunes Date: Tue, 11 Jul 2023 10:02:53 -0300 Subject: [PATCH 1/9] feat: add edge unit tests to the docs --- .../NavigationMenu.constants.ts | 1 + .../docs/pages/guides/functions/unit-test.mdx | 132 ++++++++++++++++++ 2 files changed, 133 insertions(+) create mode 100644 apps/docs/pages/guides/functions/unit-test.mdx diff --git a/apps/docs/components/Navigation/NavigationMenu/NavigationMenu.constants.ts b/apps/docs/components/Navigation/NavigationMenu/NavigationMenu.constants.ts index 5c251f809ea..9ef274f026d 100644 --- a/apps/docs/components/Navigation/NavigationMenu/NavigationMenu.constants.ts +++ b/apps/docs/components/Navigation/NavigationMenu/NavigationMenu.constants.ts @@ -760,6 +760,7 @@ export const functions: NavMenuConstant = { name: 'Connecting directly to Postgres', url: '/guides/functions/connect-to-postgres', }, + { name: 'Unit Tests for Edge Functions', url: '/guides/functions/unit-test' }, { name: 'Troubleshooting', url: '/guides/functions/troubleshooting' }, ], }, diff --git a/apps/docs/pages/guides/functions/unit-test.mdx b/apps/docs/pages/guides/functions/unit-test.mdx new file mode 100644 index 00000000000..8bb3d753fae --- /dev/null +++ b/apps/docs/pages/guides/functions/unit-test.mdx @@ -0,0 +1,132 @@ +import Layout from '~/layouts/DefaultGuideLayout' + +export const meta = { + id: 'unit-test', + title: 'Unit Tests for Edge Functions', + description: 'Unit Tests for Edge Functions with Deno Test', +} +To ensure the correctness and performance of your Edge Functions, testing is an essential step in the development process. Let's discuss the significance of testing and examining the code in the `deno-test.ts` file, which demonstrates how to test the Supabase client and the `hello-world` function. + +```typescript +// deno-test.ts + +// Import required libraries and modules +import { + assert, + assertExists, + assertEquals, +} from 'https://deno.land/std@0.192.0/testing/asserts.ts' +import { createClient, SupabaseClient } from 'https://esm.sh/@supabase/supabase-js@2.23.0' +import { delay } from 'https://deno.land/x/delay@v0.2.0/mod.ts' + +// Set up the configuration for the Supabase client +const supabaseUrl = Deno.env.get('SUPABASE_URL') ?? '' +const supabaseKey = Deno.env.get('SUPABASE_ANON_KEY') ?? '' +const options = { + auth: { + autoRefreshToken: false, + persistSession: false, + detectSessionInUrl: false, + }, +} + +// Test the creation and functionality of the Supabase client +const testClientCreation = async () => { + var client: SupabaseClient = createClient(supabaseUrl, supabaseKey, options) + + // Verify if the Supabase URL and key are provided + if (!supabaseUrl) throw new Error('supabaseUrl is required.') + if (!supabaseKey) throw new Error('supabaseKey is required.') + + // Test a simple query to the database + const { data: table_data, error: table_error } = await client + .from('my_table') + .select('*') + .limit(1) + if (table_error) { + throw new Error('Invalid Supabase client: ' + table_error.message) + } + assert(table_data, 'Data should be returned from the query.') +} + +// Test the 'hello-world' function +const testHelloWorld = async () => { + var client: SupabaseClient = createClient(supabaseUrl, supabaseKey, options) + + // Invoke the 'hello-world' function with a parameter + const { data: func_data, error: func_error } = await client.functions.invoke('hello-world', { + body: { name: 'bar' }, + }) + + // Check for errors from the function invocation + if (func_error) { + throw new Error('Invalid response: ' + func_error.message) + } + + // Log the response from the function + console.log(JSON.stringify(func_data, null, 2)) + + // Assert that the function returned the expected result + assertEquals(func_data.message, 'Hello bar!') +} + +// Register and run the tests +Deno.test('Client Creation Test', testClientCreation) +Deno.test('Hello-world Function Test', testHelloWorld) +``` + +This test case consists of two parts. The first part tests the client library and verifies that the database can be connected to and returns values from a table (`my_table`). The second part tests the edge function and checks if the received value matches the expected value. Here's a brief overview of the code: + +- We import various testing functions from the Deno standard library, including `assert`, `assertExists`, and `assertEquals`. +- We import the `createClient` and `SupabaseClient` classes from the `@supabase/supabase-js` library to interact with the Supabase client. +- We define the necessary configuration for the Supabase client, including the Supabase URL, API key, and authentication options. +- The `testClientCreation` function tests the creation of a Supabase client instance and queries the database for data from a table. It verifies that data is returned from the query. +- The `testHelloWorld` function tests the "Hello-world" Edge Function by invoking it using the Supabase client's `functions.invoke` method. It checks if the response message matches the expected greeting. +- We run the tests using the `Deno.test` function, providing a descriptive name for each test case and the corresponding test function. + +Note: Please make sure to replace the placeholders (`supabaseUrl`, `supabaseKey`, `my_table`) with the actual values relevant to your Supabase setup. + +### Running Edge Functions Locally + +To locally test and debug Edge Functions, you can utilize the Supabase CLI. Let's explore how to run Edge Functions locally using the Supabase CLI: + +1. Ensure that the Supabase server is running by executing the following command: + + ```bash + supabase start + ``` + +2. In your terminal, use the following command to serve the Edge Functions locally: + + ```bash + supabase functions serve + ``` + + This command starts a local server that runs your Edge Functions, enabling you to test and debug them in a development environment. + +3. Create the environment variables file: + + ```bash + # creates the file + touch .env.local + # adds the SUPABASE_URL secret + echo "SUPABASE_URL=http://localhost:54321" >> .env.local + # adds the SUPABASE_ANON_KEY secret + echo "SUPABASE_ANON_KEY=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZS1kZW1vIiwicm9sZSI6ImFub24iLCJleHAiOjE5ODM4MTI5OTZ9.CRXP1A7WOeoJeXxjNni43kdQwgnWNReilDMblYTn_I0" >> .env.local + # Alternatively, you can open it in your editor: + open .env.local + ``` + +4. To run the tests, use the following command in your terminal: + + ```bash + deno test --allow-all deno-test.ts --env-file .env.local + ``` + +## Resources + +- Full guide on Testing Supabase Edge Functions on [Mansueli's tips](https://blog.mansueli.com/testing-supabase-edge-functions-with-deno-test) + +export const Page = ({ children }) => + +export default Page From af3f677052396254725aac3df132cc07af179a99 Mon Sep 17 00:00:00 2001 From: Rodrigo Mansueli Nunes Date: Tue, 11 Jul 2023 10:57:33 -0300 Subject: [PATCH 2/9] Added the test folder in the quickstart with a link addressed the feedback about naming. --- apps/docs/pages/guides/functions/quickstart.mdx | 8 ++++++-- apps/docs/pages/guides/functions/unit-test.mdx | 2 +- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/apps/docs/pages/guides/functions/quickstart.mdx b/apps/docs/pages/guides/functions/quickstart.mdx index 235556c439e..45eb7a32ef1 100644 --- a/apps/docs/pages/guides/functions/quickstart.mdx +++ b/apps/docs/pages/guides/functions/quickstart.mdx @@ -199,7 +199,8 @@ For use-cases which require low-latency we recommend [Edge Functions](/docs/guid ## Organizing your Edge Functions -We recommend developing “fat functions”. This means that you should develop few large functions, rather than many small functions. One common pattern when developing Functions is that you need to share code between two or more Functions. To do this, you can store any shared code in a folder prefixed with an underscore (`_`). We recommend this folder structure: +We recommend developing “fat functions”. This means that you should develop few large functions, rather than many small functions. One common pattern when developing Functions is that you need to share code between two or more Functions. To do this, you can store any shared code in a folder prefixed with an underscore (`_`). We also recommend a separate folder for [Unit Tests](/docs/guides/functions/unit-test) including the name of the funtion followed by a `-test` suffix. +We recommend this folder structure: ```bash └── supabase @@ -212,7 +213,10 @@ We recommend developing “fat functions”. This means that you should develop │ ├── function-one # Use hyphens to name functions. │ │ └── index.ts │ └── function-two - │ └── index.ts + │ │ └── index.ts + │ └── tests + │ └── function-one-test.ts + │ └── function-two-test.ts ├── migrations └── config.toml ``` diff --git a/apps/docs/pages/guides/functions/unit-test.mdx b/apps/docs/pages/guides/functions/unit-test.mdx index 8bb3d753fae..0bc8686cc4d 100644 --- a/apps/docs/pages/guides/functions/unit-test.mdx +++ b/apps/docs/pages/guides/functions/unit-test.mdx @@ -5,7 +5,7 @@ export const meta = { title: 'Unit Tests for Edge Functions', description: 'Unit Tests for Edge Functions with Deno Test', } -To ensure the correctness and performance of your Edge Functions, testing is an essential step in the development process. Let's discuss the significance of testing and examining the code in the `deno-test.ts` file, which demonstrates how to test the Supabase client and the `hello-world` function. +To ensure the correctness and performance of your Edge Functions, testing is an essential step in the development process. Let's discuss the significance of testing and examining the code in the `deno-test.ts` file, which demonstrates how to test the Supabase client and the `hello-world` function. When creating test files for Edge Functions, it is recommended to place them in the `supabase/tests` directory and name the file by the function name followed by `-test.ts`. For example, `hello-world-test.ts`. ```typescript // deno-test.ts From 8a8b5e6c929724cc77e05589aa7f8508bf78dbf3 Mon Sep 17 00:00:00 2001 From: Rodrigo Mansueli Nunes Date: Tue, 11 Jul 2023 11:02:06 -0300 Subject: [PATCH 3/9] chore: typo --- apps/docs/pages/guides/functions/quickstart.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/docs/pages/guides/functions/quickstart.mdx b/apps/docs/pages/guides/functions/quickstart.mdx index 45eb7a32ef1..14de4f79620 100644 --- a/apps/docs/pages/guides/functions/quickstart.mdx +++ b/apps/docs/pages/guides/functions/quickstart.mdx @@ -199,7 +199,7 @@ For use-cases which require low-latency we recommend [Edge Functions](/docs/guid ## Organizing your Edge Functions -We recommend developing “fat functions”. This means that you should develop few large functions, rather than many small functions. One common pattern when developing Functions is that you need to share code between two or more Functions. To do this, you can store any shared code in a folder prefixed with an underscore (`_`). We also recommend a separate folder for [Unit Tests](/docs/guides/functions/unit-test) including the name of the funtion followed by a `-test` suffix. +We recommend developing “fat functions”. This means that you should develop few large functions, rather than many small functions. One common pattern when developing Functions is that you need to share code between two or more Functions. To do this, you can store any shared code in a folder prefixed with an underscore (`_`). We also recommend a separate folder for [Unit Tests](/docs/guides/functions/unit-test) including the name of the function followed by a `-test` suffix. We recommend this folder structure: ```bash From 2d4f7c260069e55dba82bec200bd31f7a8ad4761 Mon Sep 17 00:00:00 2001 From: Rodrigo Martins Mansueli Date: Tue, 11 Jul 2023 13:13:38 -0300 Subject: [PATCH 4/9] Update apps/docs/pages/guides/functions/unit-test.mdx Co-authored-by: Copple <10214025+kiwicopple@users.noreply.github.com> --- apps/docs/pages/guides/functions/unit-test.mdx | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/apps/docs/pages/guides/functions/unit-test.mdx b/apps/docs/pages/guides/functions/unit-test.mdx index 0bc8686cc4d..e7512d45387 100644 --- a/apps/docs/pages/guides/functions/unit-test.mdx +++ b/apps/docs/pages/guides/functions/unit-test.mdx @@ -5,7 +5,10 @@ export const meta = { title: 'Unit Tests for Edge Functions', description: 'Unit Tests for Edge Functions with Deno Test', } -To ensure the correctness and performance of your Edge Functions, testing is an essential step in the development process. Let's discuss the significance of testing and examining the code in the `deno-test.ts` file, which demonstrates how to test the Supabase client and the `hello-world` function. When creating test files for Edge Functions, it is recommended to place them in the `supabase/tests` directory and name the file by the function name followed by `-test.ts`. For example, `hello-world-test.ts`. + +Testing is an essential step in the development process to ensure the correctness and performance of your Edge Functions. + +When creating test files for Edge Functions, it is recommended to place them in the `supabase/tests` directory and name the file by the function name followed by `-test.ts`. For example, `hello-world-test.ts`. ```typescript // deno-test.ts From 6f1f7fc4a80864d6a8ffa55f6c2580545d4f8f8b Mon Sep 17 00:00:00 2001 From: Rodrigo Martins Mansueli Date: Tue, 11 Jul 2023 13:13:55 -0300 Subject: [PATCH 5/9] Update apps/docs/pages/guides/functions/unit-test.mdx Co-authored-by: Copple <10214025+kiwicopple@users.noreply.github.com> --- apps/docs/pages/guides/functions/unit-test.mdx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/docs/pages/guides/functions/unit-test.mdx b/apps/docs/pages/guides/functions/unit-test.mdx index e7512d45387..e12fe8358cd 100644 --- a/apps/docs/pages/guides/functions/unit-test.mdx +++ b/apps/docs/pages/guides/functions/unit-test.mdx @@ -2,8 +2,8 @@ import Layout from '~/layouts/DefaultGuideLayout' export const meta = { id: 'unit-test', - title: 'Unit Tests for Edge Functions', - description: 'Unit Tests for Edge Functions with Deno Test', + title: 'Testing your Edge Functions', + description: 'Writing Unit Tests for Edge Functions using Deno Test', } Testing is an essential step in the development process to ensure the correctness and performance of your Edge Functions. From 98c4d504dde1db0f04628aeb1162af7d33a882a3 Mon Sep 17 00:00:00 2001 From: Rodrigo Mansueli Nunes Date: Tue, 11 Jul 2023 13:14:18 -0300 Subject: [PATCH 6/9] Update NavigationMenu.constants.ts --- .../Navigation/NavigationMenu/NavigationMenu.constants.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/docs/components/Navigation/NavigationMenu/NavigationMenu.constants.ts b/apps/docs/components/Navigation/NavigationMenu/NavigationMenu.constants.ts index 9ef274f026d..b6d0ec39ca3 100644 --- a/apps/docs/components/Navigation/NavigationMenu/NavigationMenu.constants.ts +++ b/apps/docs/components/Navigation/NavigationMenu/NavigationMenu.constants.ts @@ -760,7 +760,7 @@ export const functions: NavMenuConstant = { name: 'Connecting directly to Postgres', url: '/guides/functions/connect-to-postgres', }, - { name: 'Unit Tests for Edge Functions', url: '/guides/functions/unit-test' }, + { name: 'Testing your Edge Functions', url: '/guides/functions/unit-test' }, { name: 'Troubleshooting', url: '/guides/functions/troubleshooting' }, ], }, From 5e3dbced81a452011e6d401105574d9f2b449d72 Mon Sep 17 00:00:00 2001 From: Rodrigo Mansueli Nunes Date: Tue, 11 Jul 2023 13:19:31 -0300 Subject: [PATCH 7/9] add Admonition --- apps/docs/pages/guides/functions/unit-test.mdx | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/apps/docs/pages/guides/functions/unit-test.mdx b/apps/docs/pages/guides/functions/unit-test.mdx index e12fe8358cd..1228a20f65a 100644 --- a/apps/docs/pages/guides/functions/unit-test.mdx +++ b/apps/docs/pages/guides/functions/unit-test.mdx @@ -80,14 +80,18 @@ Deno.test('Hello-world Function Test', testHelloWorld) This test case consists of two parts. The first part tests the client library and verifies that the database can be connected to and returns values from a table (`my_table`). The second part tests the edge function and checks if the received value matches the expected value. Here's a brief overview of the code: + - We import various testing functions from the Deno standard library, including `assert`, `assertExists`, and `assertEquals`. - We import the `createClient` and `SupabaseClient` classes from the `@supabase/supabase-js` library to interact with the Supabase client. - We define the necessary configuration for the Supabase client, including the Supabase URL, API key, and authentication options. - The `testClientCreation` function tests the creation of a Supabase client instance and queries the database for data from a table. It verifies that data is returned from the query. - The `testHelloWorld` function tests the "Hello-world" Edge Function by invoking it using the Supabase client's `functions.invoke` method. It checks if the response message matches the expected greeting. -- We run the tests using the `Deno.test` function, providing a descriptive name for each test case and the corresponding test function. +- We run the tests using the `deno test` function, providing a descriptive name for each test case and the corresponding test function. + -Note: Please make sure to replace the placeholders (`supabaseUrl`, `supabaseKey`, `my_table`) with the actual values relevant to your Supabase setup. + +Please make sure to replace the placeholders (`supabaseUrl`, `supabaseKey`, `my_table`) with the actual values relevant to your Supabase setup. + ### Running Edge Functions Locally From b721065e1a2ec85d5c271242061f6e6e4d1855d8 Mon Sep 17 00:00:00 2001 From: Rodrigo Mansueli Nunes Date: Tue, 11 Jul 2023 13:34:38 -0300 Subject: [PATCH 8/9] prettier --- .../docs/pages/guides/functions/unit-test.mdx | 21 ++++++++++++------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/apps/docs/pages/guides/functions/unit-test.mdx b/apps/docs/pages/guides/functions/unit-test.mdx index 1228a20f65a..9f6d26abcf8 100644 --- a/apps/docs/pages/guides/functions/unit-test.mdx +++ b/apps/docs/pages/guides/functions/unit-test.mdx @@ -6,7 +6,7 @@ export const meta = { description: 'Writing Unit Tests for Edge Functions using Deno Test', } -Testing is an essential step in the development process to ensure the correctness and performance of your Edge Functions. +Testing is an essential step in the development process to ensure the correctness and performance of your Edge Functions. When creating test files for Edge Functions, it is recommended to place them in the `supabase/tests` directory and name the file by the function name followed by `-test.ts`. For example, `hello-world-test.ts`. @@ -81,16 +81,21 @@ Deno.test('Hello-world Function Test', testHelloWorld) This test case consists of two parts. The first part tests the client library and verifies that the database can be connected to and returns values from a table (`my_table`). The second part tests the edge function and checks if the received value matches the expected value. Here's a brief overview of the code: -- We import various testing functions from the Deno standard library, including `assert`, `assertExists`, and `assertEquals`. -- We import the `createClient` and `SupabaseClient` classes from the `@supabase/supabase-js` library to interact with the Supabase client. -- We define the necessary configuration for the Supabase client, including the Supabase URL, API key, and authentication options. -- The `testClientCreation` function tests the creation of a Supabase client instance and queries the database for data from a table. It verifies that data is returned from the query. -- The `testHelloWorld` function tests the "Hello-world" Edge Function by invoking it using the Supabase client's `functions.invoke` method. It checks if the response message matches the expected greeting. -- We run the tests using the `deno test` function, providing a descriptive name for each test case and the corresponding test function. + - We import various testing functions from the Deno standard library, including `assert`, + `assertExists`, and `assertEquals`. - We import the `createClient` and `SupabaseClient` classes + from the `@supabase/supabase-js` library to interact with the Supabase client. - We define the + necessary configuration for the Supabase client, including the Supabase URL, API key, and + authentication options. - The `testClientCreation` function tests the creation of a Supabase + client instance and queries the database for data from a table. It verifies that data is returned + from the query. - The `testHelloWorld` function tests the "Hello-world" Edge Function by invoking + it using the Supabase client's `functions.invoke` method. It checks if the response message + matches the expected greeting. - We run the tests using the `deno test` function, providing a + descriptive name for each test case and the corresponding test function. -Please make sure to replace the placeholders (`supabaseUrl`, `supabaseKey`, `my_table`) with the actual values relevant to your Supabase setup. + Please make sure to replace the placeholders (`supabaseUrl`, `supabaseKey`, `my_table`) with the + actual values relevant to your Supabase setup. ### Running Edge Functions Locally From 026ec7e36d97fc8953288613b9984b6f7833c858 Mon Sep 17 00:00:00 2001 From: Rodrigo Mansueli Nunes Date: Tue, 11 Jul 2023 14:22:17 -0300 Subject: [PATCH 9/9] Update unit-test.mdx --- .../docs/pages/guides/functions/unit-test.mdx | 24 ++++++++----------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/apps/docs/pages/guides/functions/unit-test.mdx b/apps/docs/pages/guides/functions/unit-test.mdx index 9f6d26abcf8..9532e435858 100644 --- a/apps/docs/pages/guides/functions/unit-test.mdx +++ b/apps/docs/pages/guides/functions/unit-test.mdx @@ -80,22 +80,18 @@ Deno.test('Hello-world Function Test', testHelloWorld) This test case consists of two parts. The first part tests the client library and verifies that the database can be connected to and returns values from a table (`my_table`). The second part tests the edge function and checks if the received value matches the expected value. Here's a brief overview of the code: - - - We import various testing functions from the Deno standard library, including `assert`, - `assertExists`, and `assertEquals`. - We import the `createClient` and `SupabaseClient` classes - from the `@supabase/supabase-js` library to interact with the Supabase client. - We define the - necessary configuration for the Supabase client, including the Supabase URL, API key, and - authentication options. - The `testClientCreation` function tests the creation of a Supabase - client instance and queries the database for data from a table. It verifies that data is returned - from the query. - The `testHelloWorld` function tests the "Hello-world" Edge Function by invoking - it using the Supabase client's `functions.invoke` method. It checks if the response message - matches the expected greeting. - We run the tests using the `deno test` function, providing a - descriptive name for each test case and the corresponding test function. - +- We import various testing functions from the Deno standard library, including `assert`, `assertExists`, and `assertEquals`. +- We import the `createClient` and `SupabaseClient` classes from the `@supabase/supabase-js` library to interact with the Supabase client. +- We define the necessary configuration for the Supabase client, including the Supabase URL, API key, and authentication options. +- The `testClientCreation` function tests the creation of a Supabase client instance and queries the database for data from a table. It verifies that data is returned from the query. +- The `testHelloWorld` function tests the "Hello-world" Edge Function by invoking it using the Supabase client's `functions.invoke` method. It checks if the response message matches the expected greeting. +- We run the tests using the `Deno.test` function, providing a descriptive name for each test case and the corresponding test function. - Please make sure to replace the placeholders (`supabaseUrl`, `supabaseKey`, `my_table`) with the - actual values relevant to your Supabase setup. + +Please make sure to replace the placeholders (`supabaseUrl`, `supabaseKey`, `my_table`) with the +actual values relevant to your Supabase setup. + ### Running Edge Functions Locally