mirror of
https://github.com/supabase/supabase.git
synced 2026-09-22 13:37:53 +08:00
0b5be1fada
## Context As per PR title - disables creation of read replicas for HA projects. This involves: - Hiding new replica CTA in `DatabaseSelector` - Used in pages like reports - Hiding new replica CTA in `DatabaseParametersSubMenu` - Used in SQL Editor + Explorer - Disabling new replica CTA in settings/infrastructure under Read Replicas <img width="1065" height="401" alt="image" src="https://github.com/user-attachments/assets/18c59cee-2f47-4874-9861-8211684282ab" /> <img width="418" height="366" alt="image" src="https://github.com/user-attachments/assets/553cf75b-ff95-41c0-beca-357430a7e888" /> <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit ## Bug Fixes - Updated read replica controls to accurately reflect project availability. - Hid read replica creation options for high-availability projects. - Prevented read replica deployment for high-availability projects. - Added an explanatory notice and guidance when read replicas are unavailable due to high-availability settings. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
100 lines
3.8 KiB
TypeScript
100 lines
3.8 KiB
TypeScript
import { screen } from '@testing-library/react'
|
||
import userEvent from '@testing-library/user-event'
|
||
import { describe, expect, it, vi } from 'vitest'
|
||
|
||
import { ReadReplicaEligibilityWarnings } from '@/components/interfaces/Settings/Infrastructure/ReadReplicas/ReadReplicaForm/ReadReplicaEligibilityWarnings'
|
||
import { READ_REPLICAS_MAX_COUNT } from '@/data/read-replicas/replicas-query'
|
||
import { customRender } from '@/tests/lib/custom-render'
|
||
|
||
vi.mock('@/data/projects/project-detail-query', () => ({
|
||
useProjectDetailQuery: () => ({ data: undefined, isSuccess: false }),
|
||
}))
|
||
vi.mock('@/data/database/enable-physical-backups-mutation', () => ({
|
||
useEnablePhysicalBackupsMutation: () => ({ mutate: vi.fn(), isPending: false }),
|
||
}))
|
||
vi.mock('@/hooks/misc/useSelectedOrganization', () => ({
|
||
useSelectedOrganizationQuery: () => ({ data: { slug: 'test-org', plan: { id: 'pro' } } }),
|
||
}))
|
||
vi.mock('@/hooks/misc/useSelectedProject', () => ({
|
||
useSelectedProjectQuery: () => ({ data: { dbVersion: 'supabase-postgres-15.1.0' } }),
|
||
}))
|
||
|
||
const eligibility = (delta: Record<string, unknown>) => ({
|
||
can: false,
|
||
hasOverdueInvoices: false,
|
||
isAWSProvider: true,
|
||
isAwsK8s: false,
|
||
isPgVersionBelow15: false,
|
||
isBelowSmallCompute: false,
|
||
isWalgNotEnabled: false,
|
||
isProWithSpendCapEnabled: false,
|
||
isReachedMaxReplicas: false,
|
||
isHighAvailability: false,
|
||
maxNumberOfReplicas: READ_REPLICAS_MAX_COUNT,
|
||
...delta,
|
||
})
|
||
|
||
describe('ReadReplicaEligibilityWarnings – below small compute', () => {
|
||
it('recommends Small compute when project is on pico, nano, or micro compute', async () => {
|
||
const user = userEvent.setup()
|
||
const onRecommendCompute = vi.fn()
|
||
const warningEligibility = eligibility({ isBelowSmallCompute: true })
|
||
|
||
customRender(
|
||
<ReadReplicaEligibilityWarnings
|
||
eligibility={warningEligibility}
|
||
onRecommendCompute={onRecommendCompute}
|
||
/>
|
||
)
|
||
|
||
expect(screen.getByText('Small compute required')).toBeInTheDocument()
|
||
expect(
|
||
screen.getByText(/Read replicas require at least Small compute to keep up/)
|
||
).toBeInTheDocument()
|
||
expect(screen.getByRole('link', { name: 'Learn more' })).toBeInTheDocument()
|
||
expect(screen.getByRole('button', { name: 'Change compute' })).toBeInTheDocument()
|
||
await user.click(screen.getByRole('button', { name: 'Change compute' }))
|
||
expect(onRecommendCompute).toHaveBeenCalledWith('ci_small')
|
||
})
|
||
})
|
||
|
||
describe('ReadReplicaEligibilityWarnings – max replicas reached', () => {
|
||
it('shows upsell to upgrade compute when below the default cap (e.g. ci_small/medium/large → 4 replicas)', () => {
|
||
const warningEligibility = eligibility({ isReachedMaxReplicas: true, maxNumberOfReplicas: 4 })
|
||
|
||
customRender(
|
||
<ReadReplicaEligibilityWarnings
|
||
eligibility={warningEligibility}
|
||
onRecommendCompute={vi.fn()}
|
||
/>
|
||
)
|
||
|
||
expect(
|
||
screen.getByText('You can only deploy up to 4 read replicas at once')
|
||
).toBeInTheDocument()
|
||
expect(screen.getByText(/you may deploy up to/i)).toBeInTheDocument()
|
||
expect(screen.getByRole('button', { name: /change to xl compute/i })).toBeInTheDocument()
|
||
})
|
||
|
||
it('does NOT show the compute upsell when already at the default cap (XL+)', () => {
|
||
const warningEligibility = eligibility({
|
||
isReachedMaxReplicas: true,
|
||
maxNumberOfReplicas: READ_REPLICAS_MAX_COUNT,
|
||
})
|
||
|
||
customRender(
|
||
<ReadReplicaEligibilityWarnings
|
||
eligibility={warningEligibility}
|
||
onRecommendCompute={vi.fn()}
|
||
/>
|
||
)
|
||
|
||
expect(
|
||
screen.getByText(`You can only deploy up to ${READ_REPLICAS_MAX_COUNT} read replicas at once`)
|
||
).toBeInTheDocument()
|
||
expect(screen.queryByText(/you may deploy up to/i)).not.toBeInTheDocument()
|
||
expect(screen.queryByText(/XL compute or higher/i)).not.toBeInTheDocument()
|
||
expect(screen.queryByRole('button', { name: /change to xl compute/i })).not.toBeInTheDocument()
|
||
})
|
||
})
|