mirror of
https://github.com/supabase/supabase.git
synced 2026-10-05 17:35:10 +03:00
## Problem platform, v1 and v2 have been already completely migrated and introduced some changes. Some types have been renamed, some outputs and inputs updated. ## Solution - Update the API types - Fix the TS errors ## Update Taking this over to unblock #50134, which needs the new scoped token permission ids from the regenerated types. - Merged `master`. - Regenerated `api-v2.d.ts` from the production spec. The previous files came from a local API that exposed a webhook events endpoint production doesn't have yet. Production has since added standardized 400 error responses on the v2 organization endpoints. `api-v1.d.ts` and `platform.d.ts` already matched production. - Fixed `verify-production-types`. It formatted the regenerated files in a temp directory outside the repository, so Prettier fell back to its defaults and the comparison could never match the committed files. It now passes the repository config explicitly. `pnpm api:verify-types` passes on this branch. - Verified locally: `pnpm typecheck`, `pnpm api:verify-types`, Studio unit tests. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Bug Fixes** * Preserved descriptions when saving, sharing, moving, or unsharing notebooks, reports, SQL snippets, and saved queries. * Improved handling of empty or null values across notebook descriptions, billing usage, pooler settings, and infrastructure fields. * Improved read-replica connection handling, including read-only connection strings. * Updated storage configuration and capability handling to match current settings. * **API and Compatibility** * Updated organization, project, storage, OAuth, billing, and infrastructure data handling to match current API responses. * OAuth app creation and updates now require scopes. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Alaister Young <10985857+alaister@users.noreply.github.com>
162 lines
4.6 KiB
TypeScript
162 lines
4.6 KiB
TypeScript
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
|
|
import { fireEvent, getByText, render as originalRender, screen } from '@testing-library/react'
|
|
import { platformComponents as components } from 'api-types'
|
|
import type React from 'react'
|
|
import { useState } from 'react'
|
|
import { TooltipProvider } from 'ui'
|
|
import { CommandProvider } from 'ui-patterns/CommandMenu'
|
|
|
|
import { ProjectInfoInfinite } from '@/data/projects/projects-infinite-query'
|
|
import type { Organization } from '@/types'
|
|
|
|
type OrganizationResponse = components['schemas']['OrganizationResponse_Output']
|
|
|
|
interface SelectorOptions {
|
|
container?: HTMLElement
|
|
}
|
|
|
|
/**
|
|
* Returns the toggle button given a text matcher
|
|
*
|
|
* Defaults to screen if container option is not provided
|
|
*/
|
|
export const getToggleByText = (
|
|
text: string | RegExp,
|
|
options: SelectorOptions = {}
|
|
): HTMLElement | null => {
|
|
const container = options?.container
|
|
let textNode
|
|
if (container) {
|
|
textNode = getByText(container as HTMLElement, text)
|
|
} else {
|
|
textNode = screen.getByText(text)
|
|
}
|
|
if (textNode && textNode.parentElement) {
|
|
return textNode.parentElement.querySelector('button')
|
|
} else {
|
|
return textNode
|
|
}
|
|
}
|
|
|
|
export const clickDropdown = (elem: HTMLElement) => {
|
|
fireEvent.pointerDown(
|
|
elem,
|
|
new window.PointerEvent('pointerdown', {
|
|
ctrlKey: false,
|
|
button: 0,
|
|
})
|
|
)
|
|
}
|
|
|
|
export const createMockOrganization = (details: Partial<Organization>): Organization => {
|
|
const base: Organization = {
|
|
id: 1,
|
|
name: 'Organization 1',
|
|
slug: 'abcdefghijklmnopqrst',
|
|
plan: { id: 'free', name: 'Free' },
|
|
managed_by: 'supabase',
|
|
is_owner: true,
|
|
billing_email: 'billing@example.com',
|
|
billing_partner: null,
|
|
integration_source: null,
|
|
usage_billing_enabled: false,
|
|
stripe_customer_id: 'stripe-1',
|
|
subscription_id: 'subscription-1',
|
|
organization_requires_mfa: false,
|
|
opt_in_tags: [],
|
|
restriction_status: null,
|
|
requires_indirect_tax_declaration: false,
|
|
restriction_data: null,
|
|
organization_missing_address: false,
|
|
organization_missing_tax_id: false,
|
|
}
|
|
|
|
return Object.assign(base, details)
|
|
}
|
|
|
|
/**
|
|
* Returns the raw OpenAPI `OrganizationResponse` shape — without the
|
|
* frontend-derived fields (`managed_by`, `partner_id`) that
|
|
* `castOrganizationResponseToOrganization` attaches in the query layer.
|
|
*
|
|
* Use this for MSW mocks at the network boundary (e.g. `/platform/organizations`).
|
|
* Use `createMockOrganization` for in-app fixtures that need the cast shape.
|
|
*/
|
|
export const createMockOrganizationResponse = (
|
|
details: Partial<OrganizationResponse> = {}
|
|
): OrganizationResponse => {
|
|
const base: OrganizationResponse = {
|
|
id: 1,
|
|
name: 'Organization 1',
|
|
slug: 'abcdefghijklmnopqrst',
|
|
plan: { id: 'free', name: 'Free' },
|
|
is_owner: true,
|
|
billing_email: 'billing@example.com',
|
|
billing_partner: null,
|
|
integration_source: null,
|
|
usage_billing_enabled: false,
|
|
stripe_customer_id: 'stripe-1',
|
|
subscription_id: 'subscription-1',
|
|
organization_requires_mfa: false,
|
|
opt_in_tags: [],
|
|
restriction_status: null,
|
|
requires_indirect_tax_declaration: false,
|
|
restriction_data: null,
|
|
organization_missing_address: false,
|
|
organization_missing_tax_id: false,
|
|
}
|
|
|
|
return Object.assign(base, details)
|
|
}
|
|
|
|
export const createMockProject = (details: Partial<ProjectInfoInfinite>): ProjectInfoInfinite => {
|
|
const base: ProjectInfoInfinite = {
|
|
id: 1,
|
|
ref: 'abcdefghijklmnopqrst',
|
|
name: 'Project 1',
|
|
status: 'ACTIVE_HEALTHY',
|
|
organization_id: 1,
|
|
cloud_provider: 'AWS',
|
|
region: 'us-east-1',
|
|
inserted_at: new Date().toISOString(),
|
|
subscription_id: 'subscription-1',
|
|
is_branch_enabled: false,
|
|
is_physical_backups_enabled: false,
|
|
organization_slug: 'slug',
|
|
preview_branch_refs: [],
|
|
}
|
|
|
|
return Object.assign(base, details)
|
|
}
|
|
|
|
/**
|
|
* A custom render function for react testing library
|
|
* https://testing-library.com/docs/react-testing-library/setup/#custom-render
|
|
*/
|
|
const ReactQueryTestConfig: React.FC<React.PropsWithChildren> = ({ children }) => {
|
|
const [queryClient] = useState(
|
|
() =>
|
|
new QueryClient({
|
|
defaultOptions: {
|
|
queries: {
|
|
retry: false,
|
|
},
|
|
},
|
|
})
|
|
)
|
|
|
|
return (
|
|
<TooltipProvider>
|
|
<QueryClientProvider client={queryClient}>
|
|
<CommandProvider openKey="">{children}</CommandProvider>
|
|
</QueryClientProvider>
|
|
</TooltipProvider>
|
|
)
|
|
}
|
|
type renderParams = Parameters<typeof originalRender>
|
|
export const render = ((ui: renderParams[0], options: renderParams[1]) =>
|
|
originalRender(ui, {
|
|
wrapper: ReactQueryTestConfig,
|
|
...options,
|
|
})) as typeof originalRender
|