mirror of
https://github.com/supabase/supabase.git
synced 2026-10-06 09:55:06 +03:00
* chore: Refactor `NewAccessTokenButton` to use shadcn components This brings `NewAccessTokenButton` into conformance with the latest UI patterns of using shadcn based components, zod schemas, and react-hook-form for form submission. I based this refactor on the implementation of `CreateSecretAPIKeyDialog`, which already made use of the above. * add success and failure toasts * add smoke test for `NewAccessTokenButton`, fix vitest config This adds a minimal test for `NewAccessTokenButton` but more importantly fixes a critical bug in the vitest configuration for `studio`. Because `restoreMocks: true` was set in the config, this meant that the mock implementation for `window.matchMedia` defined in the `tests/vitestSetup.ts` file was being **reset** to an empty function before each test suite was run. While this didn't appear to be a problem before, that appears to be because none of the existing tests had `motion.div` in their component trees. Since `motion.div` calls `addListener` on a media query as part of it's lifecycle, that meant that any test which included it would fail as `addListener` would be undefined in this situation. Removing `restoreMocks: true` from the config results in the desired mocking behavior. This change is necessary in order to test any component that has the `FormItemLayout` component, as it uses `framer-motion` to animate in error messages for input elements. * add warning comment in case of future config regression * update test cases, reset form on dialog close, testing setup fixes This fixes an issue with the polyfills for the testing environment, where a call to `useMutation` would fail as a result of `TransformStream` being set to `null`. Basic tests for access token creation and form resetting added. Adds `@faker-js/faker` to the studio app devDependencies to generate mock data for `msw` endpoint response. Adds `shx` to the docs app devDependencies to ensure that the `codegen:examples` script runs cross-platform. * ensure mocked date is a string * update testing setup, pollyfills and add rich type support to addAPIMock * add missing changes * Move `EditSecretModal` to be child of `SecretRow` In the accompanying PR for `DeleteSecretModal`, that one will also be moved over to `SecretRow` * Update studio testing setup files Improves API mocking type safety and polyfills browser APIs necessary to run tests with framer-motion components * chore: Refactor `NewAccessTokenButton` to use shadcn components This brings `NewAccessTokenButton` into conformance with the latest UI patterns of using shadcn based components, zod schemas, and react-hook-form for form submission. I based this refactor on the implementation of `CreateSecretAPIKeyDialog`, which already made use of the above. * add success and failure toasts * add smoke test for `NewAccessTokenButton`, fix vitest config This adds a minimal test for `NewAccessTokenButton` but more importantly fixes a critical bug in the vitest configuration for `studio`. Because `restoreMocks: true` was set in the config, this meant that the mock implementation for `window.matchMedia` defined in the `tests/vitestSetup.ts` file was being **reset** to an empty function before each test suite was run. While this didn't appear to be a problem before, that appears to be because none of the existing tests had `motion.div` in their component trees. Since `motion.div` calls `addListener` on a media query as part of it's lifecycle, that meant that any test which included it would fail as `addListener` would be undefined in this situation. Removing `restoreMocks: true` from the config results in the desired mocking behavior. This change is necessary in order to test any component that has the `FormItemLayout` component, as it uses `framer-motion` to animate in error messages for input elements. * update test cases, reset form on dialog close, testing setup fixes This fixes an issue with the polyfills for the testing environment, where a call to `useMutation` would fail as a result of `TransformStream` being set to `null`. Basic tests for access token creation and form resetting added. Adds `@faker-js/faker` to the studio app devDependencies to generate mock data for `msw` endpoint response. Adds `shx` to the docs app devDependencies to ensure that the `codegen:examples` script runs cross-platform. * ensure mocked date is a string * update testing setup, pollyfills and add rich type support to addAPIMock * add missing changes * Move `EditSecretModal` to be child of `SecretRow` In the accompanying PR for `DeleteSecretModal`, that one will also be moved over to `SecretRow` * fix imports * Update test, fix rebase errors * remove unnecessary code * resolve type errors * fix missing listen call for msw, resolve test type error * fix imports * Update studio testing setup files Improves API mocking type safety and polyfills browser APIs necessary to run tests with framer-motion components * fix missing listen call for msw, resolve test type error * fix imports * remove duplicate test * update testing setup * implement requested changes * cleanup unnecessary conditional logic for undefined `secret` prop * remove unused import * remove unnecessary code * cleanup, replace lodash import with JS * add required router mock * fix broken lockfile --------- Co-authored-by: Terry Sutton <saltcod@gmail.com>
70 lines
2.3 KiB
TypeScript
70 lines
2.3 KiB
TypeScript
import { setupServer } from 'msw/node'
|
|
import { GlobalAPIMocks } from './msw-global-api-mocks'
|
|
import { http, HttpResponse, HttpResponseResolver } from 'msw'
|
|
import { API_URL } from 'lib/constants'
|
|
import type { paths } from '../../data/api'
|
|
|
|
export const mswServer = setupServer(...GlobalAPIMocks)
|
|
|
|
mswServer.events.on('request:start', ({ request }) => {
|
|
console.log('[MSW] Outgoing:', request.method, request.url)
|
|
})
|
|
|
|
// Recursively changes params in an endpoint path segment from {param}
|
|
// format to :param format which is expected by Mock Service Worker
|
|
type RemapParams<T extends string> = T extends `${infer Before}{${infer Param}}${infer After}`
|
|
? `${Before}:${Param}${RemapParams<After>}`
|
|
: T
|
|
|
|
type TrimQueryParams<T extends string> = T extends `${infer Endpoint}?${string}` ? Endpoint : T
|
|
|
|
// We need to remap all keys from our openapi-typescript generated types
|
|
// so that they follow MSW's parameter formatting
|
|
type RemapPaths = {
|
|
[K in keyof paths as RemapParams<K>]: paths[K]
|
|
}
|
|
|
|
type Endpoints = keyof RemapPaths
|
|
type Methods = Exclude<keyof typeof http, 'all'>
|
|
|
|
// Extract either the 200 or 201 response object
|
|
type SuccessResponse<P extends Endpoints, M extends Methods> = RemapPaths[P][M] extends {
|
|
responses: { 200: { content: { 'application/json': infer R200 } } }
|
|
}
|
|
? R200
|
|
: RemapPaths[P][M] extends {
|
|
responses: { 201: { content: { 'application/json': infer R201 } } }
|
|
}
|
|
? R201
|
|
: never
|
|
|
|
const isResponseResolver = (val: unknown): val is HttpResponseResolver => typeof val === `function`
|
|
|
|
export const addAPIMock = <P extends Endpoints | `${Endpoints}?${string}`, M extends Methods>({
|
|
method,
|
|
path,
|
|
response,
|
|
}: SuccessResponse<TrimQueryParams<P>, M> extends never
|
|
? // Don't require a mocked response when the API doesn't return one
|
|
{ method: M; path: P; response?: never }
|
|
: {
|
|
method: M
|
|
path: P
|
|
response: SuccessResponse<TrimQueryParams<P>, M> | HttpResponseResolver
|
|
}) => {
|
|
const fullPath = `${API_URL}${path}`
|
|
console.log('[MSW] Adding mock:', method.toUpperCase(), fullPath)
|
|
|
|
mswServer.use(
|
|
http[method](
|
|
fullPath,
|
|
isResponseResolver(response)
|
|
? response
|
|
: ({ request }) => {
|
|
console.log('[MSW] Handling request:', request.method, request.url, response)
|
|
return HttpResponse.json(response ?? null)
|
|
}
|
|
)
|
|
)
|
|
}
|