mirror of
https://github.com/supabase/supabase.git
synced 2026-10-15 22:29:11 +03:00
This pull request enhances the project creation flow by introducing support for filtering Postgres versions based on the OrioleDB engine. The main changes involve updating the `PostgresVersionSelector` component to allow filtering for OrioleDB-specific versions, and integrating this logic into the internal-only configuration step of project creation. This provides a clearer and more flexible experience when selecting Postgres versions, especially for internal or advanced users. **Postgres Version Selection Enhancements:** * Added a new `useOrioleDbForCreate` prop to `PostgresVersionSelector`, allowing the component to filter available Postgres versions to only OrioleDB-based options or exclude them, based on user selection. The prop defaults to `undefined` for no filtering. [[1]](diffhunk://#diff-1842d78cb2a4be2c2b6e1581981d8111304fd9aaf0ad45df273d8c001938bcd9R41-R50) [[2]](diffhunk://#diff-1842d78cb2a4be2c2b6e1581981d8111304fd9aaf0ad45df273d8c001938bcd9R82-R85) [[3]](diffhunk://#diff-1842d78cb2a4be2c2b6e1581981d8111304fd9aaf0ad45df273d8c001938bcd9L92-R114) * Added a `description` prop to `PostgresVersionSelector` for improved UI guidance, and passed this prop through the form. [[1]](diffhunk://#diff-1842d78cb2a4be2c2b6e1581981d8111304fd9aaf0ad45df273d8c001938bcd9R41-R50) [[2]](diffhunk://#diff-1842d78cb2a4be2c2b6e1581981d8111304fd9aaf0ad45df273d8c001938bcd9R82-R85) [[3]](diffhunk://#diff-1842d78cb2a4be2c2b6e1581981d8111304fd9aaf0ad45df273d8c001938bcd9L139-R161) **Integration with Project Creation Flow:** * Updated `InternalOnlyConfiguration` to watch the `useOrioleDb` form field and pass its value to `PostgresVersionSelector`, ensuring the version list is filtered appropriately during project creation. Also, conditionally set the description to guide users toward advanced configuration for OrioleDB. [[1]](diffhunk://#diff-f0fa51a1cc67bb1a2c38d2c595eb3cab3a45813a027a04942d684914f2c3de93R33) [[2]](diffhunk://#diff-f0fa51a1cc67bb1a2c38d2c595eb3cab3a45813a027a04942d684914f2c3de93R60-R65) * Adjusted the render order in `ProjectCreationForm` to ensure advanced configuration and internal-only configuration are displayed in a logical sequence. **Other Improvements:** * Imported the `isSuccess` utility from `effect/Result` in `PostgresVersionSelector.tsx` to support the updated logic. --------- Co-authored-by: Alaister Young <alaister@users.noreply.github.com> Co-authored-by: Joshen Lim <joshenlimek@gmail.com>
334 lines
11 KiB
TypeScript
334 lines
11 KiB
TypeScript
import { AWS_REGIONS } from 'shared-data'
|
|
import { describe, expect, it } from 'vitest'
|
|
|
|
import {
|
|
HIGH_AVAILABILITY_INSTANCE_SIZE,
|
|
HIGH_AVAILABILITY_POSTGRES_ENGINE,
|
|
HIGH_AVAILABILITY_RELEASE_CHANNEL,
|
|
} from './ProjectCreation.constants'
|
|
import type { AvailableRegions } from './ProjectCreation.utils'
|
|
import {
|
|
extractPostgresVersionDetails,
|
|
filterHighAvailabilityRegions,
|
|
getAvailableRegions,
|
|
getFreeTierGeneralRegionExperimentVariant,
|
|
getHighAvailabilityRegionCode,
|
|
getRegionSelectionType,
|
|
getSpecificRegionsLinkVariant,
|
|
resolveDefaultDbRegion,
|
|
resolvePostgresVersion,
|
|
} from './ProjectCreation.utils'
|
|
import type { PostgresEngine, ReleaseChannel } from '@/data/projects/new-project.constants'
|
|
|
|
describe('resolveDefaultDbRegion', () => {
|
|
const base = {
|
|
cloudProvider: 'AWS_NIMBUS',
|
|
isHighAvailabilityRestricted: false,
|
|
highAvailabilityRegionName: undefined,
|
|
isSmartRegionEnabled: false,
|
|
recommendedSmartRegion: undefined,
|
|
autoDefaultRegion: undefined,
|
|
fixedDefaultRegion: AWS_REGIONS.EAST_US.displayName,
|
|
environment: 'prod',
|
|
} as const
|
|
|
|
it('prefers the high availability region when restricted, even while it is still loading', () => {
|
|
expect(
|
|
resolveDefaultDbRegion({
|
|
...base,
|
|
isHighAvailabilityRestricted: true,
|
|
highAvailabilityRegionName: AWS_REGIONS.EAST_US.displayName,
|
|
})
|
|
).toBe(AWS_REGIONS.EAST_US.displayName)
|
|
expect(resolveDefaultDbRegion({ ...base, isHighAvailabilityRestricted: true })).toBeUndefined()
|
|
})
|
|
|
|
it('uses the recommended smart region when smart regions are enabled', () => {
|
|
expect(
|
|
resolveDefaultDbRegion({
|
|
...base,
|
|
cloudProvider: 'AWS',
|
|
isSmartRegionEnabled: true,
|
|
recommendedSmartRegion: 'Americas',
|
|
autoDefaultRegion: AWS_REGIONS.SOUTHEAST_ASIA.displayName,
|
|
})
|
|
).toBe('Americas')
|
|
})
|
|
|
|
it('uses the geolocated region when the provider offers it', () => {
|
|
expect(
|
|
resolveDefaultDbRegion({
|
|
...base,
|
|
cloudProvider: 'AWS',
|
|
autoDefaultRegion: AWS_REGIONS.SOUTHEAST_ASIA.displayName,
|
|
})
|
|
).toBe(AWS_REGIONS.SOUTHEAST_ASIA.displayName)
|
|
})
|
|
|
|
it('falls back to the fixed default when the provider does not offer the geolocated region', () => {
|
|
expect(
|
|
resolveDefaultDbRegion({ ...base, autoDefaultRegion: AWS_REGIONS.SOUTHEAST_ASIA.displayName })
|
|
).toBe(AWS_REGIONS.EAST_US.displayName)
|
|
})
|
|
|
|
it('falls back to the fixed default when no geolocated region resolved', () => {
|
|
expect(resolveDefaultDbRegion(base)).toBe(AWS_REGIONS.EAST_US.displayName)
|
|
})
|
|
})
|
|
|
|
describe('getAvailableRegions', () => {
|
|
it.each(['local', 'staging', 'prod'])('returns all AWS regions for AWS on %s', (environment) => {
|
|
expect(getAvailableRegions('AWS', environment)).toEqual(AWS_REGIONS)
|
|
expect(getAvailableRegions('AWS_K8S', environment)).toEqual(AWS_REGIONS)
|
|
})
|
|
|
|
it.each([
|
|
['local', { SOUTHEAST_ASIA: AWS_REGIONS.SOUTHEAST_ASIA }],
|
|
['staging', { SOUTHEAST_ASIA: AWS_REGIONS.SOUTHEAST_ASIA }],
|
|
['prod', { EAST_US: AWS_REGIONS.EAST_US }],
|
|
])('returns the single AWS_NIMBUS region on %s', (environment, expectedRegions) => {
|
|
expect(getAvailableRegions('AWS_NIMBUS', environment)).toEqual(expectedRegions)
|
|
})
|
|
})
|
|
|
|
describe('High Availability project creation constraints', () => {
|
|
it('pins the Alpha Postgres engine, release channel, and compute size', () => {
|
|
expect(HIGH_AVAILABILITY_POSTGRES_ENGINE).toBe('17')
|
|
expect(HIGH_AVAILABILITY_RELEASE_CHANNEL).toBe('ga')
|
|
expect(HIGH_AVAILABILITY_INSTANCE_SIZE).toBe('large')
|
|
})
|
|
|
|
it.each([
|
|
['local', 'eu-central-1'],
|
|
['staging', 'us-east-1'],
|
|
['prod', 'us-east-1'],
|
|
])('resolves the %s region restriction', (environment, expectedRegion) => {
|
|
expect(getHighAvailabilityRegionCode(environment)).toBe(expectedRegion)
|
|
})
|
|
|
|
it.each([
|
|
['local', undefined],
|
|
['staging', 'us-east-1'],
|
|
['prod', 'us-east-1'],
|
|
])(
|
|
'applies the %s region restriction to high availability projects',
|
|
(environment, expectedRegion) => {
|
|
const regions = [{ code: 'us-east-1' }, { code: 'eu-central-1' }, { code: 'ap-southeast-1' }]
|
|
|
|
expect(filterHighAvailabilityRegions(regions, true, environment)).toEqual(
|
|
expectedRegion === undefined ? regions : [{ code: expectedRegion }]
|
|
)
|
|
expect(filterHighAvailabilityRegions(regions, false, environment)).toEqual(regions)
|
|
}
|
|
)
|
|
})
|
|
|
|
describe('getFreeTierGeneralRegionExperimentVariant', () => {
|
|
const base = {
|
|
isFreePlan: true,
|
|
smartRegionEnabled: true,
|
|
enrollmentFlag: true,
|
|
selectionFlag: true,
|
|
}
|
|
|
|
it('returns test when in the experiment and the selection flag is on', () => {
|
|
expect(getFreeTierGeneralRegionExperimentVariant(base)).toBe('test')
|
|
})
|
|
|
|
it('returns control when in the experiment and the selection flag is off', () => {
|
|
expect(getFreeTierGeneralRegionExperimentVariant({ ...base, selectionFlag: false })).toBe(
|
|
'control'
|
|
)
|
|
})
|
|
|
|
it('returns undefined when overridden, even if otherwise enrolled', () => {
|
|
expect(
|
|
getFreeTierGeneralRegionExperimentVariant({ ...base, isOverridden: true })
|
|
).toBeUndefined()
|
|
})
|
|
|
|
it('returns undefined for a paid plan', () => {
|
|
expect(
|
|
getFreeTierGeneralRegionExperimentVariant({ ...base, isFreePlan: false })
|
|
).toBeUndefined()
|
|
})
|
|
|
|
it('returns undefined when smart regions are disabled (AWS_NIMBUS)', () => {
|
|
expect(
|
|
getFreeTierGeneralRegionExperimentVariant({ ...base, smartRegionEnabled: false })
|
|
).toBeUndefined()
|
|
})
|
|
|
|
it('returns undefined when the enrollment flag is off', () => {
|
|
expect(
|
|
getFreeTierGeneralRegionExperimentVariant({ ...base, enrollmentFlag: false })
|
|
).toBeUndefined()
|
|
})
|
|
|
|
it('returns undefined when the enrollment flag is off even if the selection flag is on', () => {
|
|
expect(
|
|
getFreeTierGeneralRegionExperimentVariant({
|
|
...base,
|
|
enrollmentFlag: false,
|
|
selectionFlag: true,
|
|
})
|
|
).toBeUndefined()
|
|
})
|
|
})
|
|
|
|
describe('getRegionSelectionType', () => {
|
|
const availableRegions: AvailableRegions = {
|
|
smartGroup: [{ code: 'americas', name: 'Americas', type: 'smartGroup' }],
|
|
specific: [
|
|
{ code: 'us-east-1', name: 'East US (North Virginia)', provider: 'AWS', type: 'specific' },
|
|
],
|
|
}
|
|
|
|
it('classifies a smart group region as general', () => {
|
|
expect(getRegionSelectionType({ dbRegion: 'Americas', availableRegions })).toBe('general')
|
|
})
|
|
|
|
it('classifies a specific region as specific', () => {
|
|
expect(getRegionSelectionType({ dbRegion: 'East US (North Virginia)', availableRegions })).toBe(
|
|
'specific'
|
|
)
|
|
})
|
|
|
|
it('returns undefined when the region matches neither list', () => {
|
|
expect(getRegionSelectionType({ dbRegion: 'Nonexistent', availableRegions })).toBeUndefined()
|
|
})
|
|
|
|
it('returns undefined when dbRegion is undefined', () => {
|
|
expect(getRegionSelectionType({ dbRegion: undefined, availableRegions })).toBeUndefined()
|
|
})
|
|
|
|
it('returns undefined when availableRegions is undefined', () => {
|
|
expect(
|
|
getRegionSelectionType({ dbRegion: 'Americas', availableRegions: undefined })
|
|
).toBeUndefined()
|
|
})
|
|
|
|
it('classifies an untouched field as auto, even if it resolved to a specific region', () => {
|
|
expect(
|
|
getRegionSelectionType({
|
|
dbRegion: 'East US (North Virginia)',
|
|
availableRegions,
|
|
isDbRegionDirty: false,
|
|
})
|
|
).toBe('auto')
|
|
})
|
|
|
|
it('returns undefined for an untouched field holding a stale region matching neither list', () => {
|
|
expect(
|
|
getRegionSelectionType({
|
|
dbRegion: 'Nonexistent',
|
|
availableRegions,
|
|
isDbRegionDirty: false,
|
|
})
|
|
).toBeUndefined()
|
|
})
|
|
|
|
it('classifies a touched field normally', () => {
|
|
expect(
|
|
getRegionSelectionType({ dbRegion: 'Americas', availableRegions, isDbRegionDirty: true })
|
|
).toBe('general')
|
|
})
|
|
})
|
|
|
|
describe('getSpecificRegionsLinkVariant', () => {
|
|
const base = {
|
|
isFreePlan: true,
|
|
smartRegionEnabled: true,
|
|
linkFlag: true,
|
|
}
|
|
|
|
it('returns test when eligible and the flag is on', () => {
|
|
expect(getSpecificRegionsLinkVariant(base)).toBe('test')
|
|
})
|
|
|
|
it('returns control when eligible and the flag is off', () => {
|
|
expect(getSpecificRegionsLinkVariant({ ...base, linkFlag: false })).toBe('control')
|
|
})
|
|
|
|
it('returns undefined for a paid plan', () => {
|
|
expect(getSpecificRegionsLinkVariant({ ...base, isFreePlan: false })).toBeUndefined()
|
|
})
|
|
|
|
it('returns undefined when smart regions are disabled (AWS_NIMBUS)', () => {
|
|
expect(getSpecificRegionsLinkVariant({ ...base, smartRegionEnabled: false })).toBeUndefined()
|
|
})
|
|
})
|
|
|
|
describe('extractPostgresVersionDetails', () => {
|
|
it('splits engine and release channel', () => {
|
|
expect(extractPostgresVersionDetails('17|ga')).toEqual({
|
|
postgresEngine: '17',
|
|
releaseChannel: 'ga',
|
|
})
|
|
})
|
|
|
|
it('returns undefined fields for an empty value', () => {
|
|
expect(extractPostgresVersionDetails('')).toEqual({
|
|
postgresEngine: undefined,
|
|
releaseChannel: undefined,
|
|
})
|
|
})
|
|
})
|
|
|
|
describe('resolvePostgresVersion', () => {
|
|
const availableOrioleVersion: {
|
|
postgres_engine: PostgresEngine
|
|
release_channel: ReleaseChannel
|
|
} = { postgres_engine: '17-oriole', release_channel: 'preview' }
|
|
|
|
it('uses the selection for OrioleDB when it is an OrioleDB version', () => {
|
|
expect(
|
|
resolvePostgresVersion({
|
|
postgresVersionSelection: '17-oriole|ga',
|
|
useOrioleDb: true,
|
|
availableOrioleVersion,
|
|
})
|
|
).toEqual({ postgresEngine: '17-oriole', releaseChannel: 'ga' })
|
|
})
|
|
|
|
it('falls back to the available OrioleDB image when there is no selection', () => {
|
|
expect(
|
|
resolvePostgresVersion({
|
|
postgresVersionSelection: '',
|
|
useOrioleDb: true,
|
|
availableOrioleVersion,
|
|
})
|
|
).toEqual({ postgresEngine: '17-oriole', releaseChannel: 'preview' })
|
|
})
|
|
|
|
it('falls back to the available OrioleDB image when the selection is a stale Postgres version', () => {
|
|
expect(
|
|
resolvePostgresVersion({
|
|
postgresVersionSelection: '17|ga',
|
|
useOrioleDb: true,
|
|
availableOrioleVersion,
|
|
})
|
|
).toEqual({ postgresEngine: '17-oriole', releaseChannel: 'preview' })
|
|
})
|
|
|
|
it('uses the selection for Postgres', () => {
|
|
expect(
|
|
resolvePostgresVersion({
|
|
postgresVersionSelection: '17|ga',
|
|
useOrioleDb: false,
|
|
availableOrioleVersion,
|
|
})
|
|
).toEqual({ postgresEngine: '17', releaseChannel: 'ga' })
|
|
})
|
|
|
|
it('ignores a stale OrioleDB selection when OrioleDB is off', () => {
|
|
expect(
|
|
resolvePostgresVersion({
|
|
postgresVersionSelection: '17-oriole|ga',
|
|
useOrioleDb: false,
|
|
availableOrioleVersion,
|
|
})
|
|
).toEqual({})
|
|
})
|
|
})
|