mirror of
https://github.com/supabase/supabase.git
synced 2026-10-05 17:35:10 +03:00
165 lines
5.9 KiB
TypeScript
165 lines
5.9 KiB
TypeScript
import { describe, expect, it } from 'vitest'
|
|
|
|
import { getReportAttributesV2, shouldShowDiskIOBurstBalanceChart } from './database-charts'
|
|
import { RESOURCE_WARNING_MESSAGES } from '@/components/ui/ResourceExhaustionWarningBanner/ResourceExhaustionWarningBanner.constants'
|
|
import { Project } from '@/data/projects/project-detail-query'
|
|
|
|
const PROJECT: Project = {
|
|
cloud_provider: 'AWS',
|
|
connectionString: 'postgresql://postgres:password@db.project-ref.supabase.co:5432/postgres',
|
|
db_host: 'db.project-ref.supabase.co',
|
|
dbVersion: 'supabase-postgres-15.1.0',
|
|
high_availability: false,
|
|
id: 1,
|
|
infra_compute_size: 'micro',
|
|
inserted_at: '2026-01-01T00:00:00.000Z',
|
|
integration_source: null,
|
|
is_branch_enabled: false,
|
|
is_physical_backups_enabled: false,
|
|
name: 'Production',
|
|
organization_id: 1,
|
|
ref: 'project-ref',
|
|
region: 'us-east-1',
|
|
restUrl: 'https://project-ref.supabase.co',
|
|
status: 'ACTIVE_HEALTHY',
|
|
subscription_id: 'subscription-1',
|
|
updated_at: '2026-01-01T00:00:00.000Z',
|
|
}
|
|
|
|
const ENTITLED_FEATURES = ['database']
|
|
|
|
const buildProject = (overrides: Partial<Project> = {}): Project => ({ ...PROJECT, ...overrides })
|
|
|
|
const getDedicatedPoolerChart = (project: Project) => {
|
|
const chart = getReportAttributesV2(ENTITLED_FEATURES, project).find(
|
|
(attribute) => attribute.id === 'pgbouncer-connections'
|
|
)
|
|
if (!chart) throw new Error('Expected the dedicated pooler chart to exist')
|
|
return chart
|
|
}
|
|
|
|
const getClientConnectionsAttribute = (chart: ReturnType<typeof getDedicatedPoolerChart>) => {
|
|
const attribute = chart.attributes?.find(
|
|
(attr) => attr !== false && attr.attribute === 'client_connections_pgbouncer'
|
|
)
|
|
if (!attribute) throw new Error('Expected the client connections attribute to exist')
|
|
return attribute
|
|
}
|
|
|
|
const getBurstBalanceChart = (project: Project, showDiskIOBurstBalanceChart = true) =>
|
|
getReportAttributesV2(
|
|
ENTITLED_FEATURES,
|
|
project,
|
|
undefined,
|
|
undefined,
|
|
undefined,
|
|
false,
|
|
showDiskIOBurstBalanceChart
|
|
).find((chart) => chart.id === 'disk-io-burst-balance')
|
|
|
|
describe('getReportAttributesV2 dedicated pooler chart', () => {
|
|
it('uses PgBouncer copy and links to the docs for standard projects', () => {
|
|
const chart = getDedicatedPoolerChart(buildProject())
|
|
const attribute = getClientConnectionsAttribute(chart)
|
|
|
|
expect(chart.titleTooltip).toBeUndefined()
|
|
expect(chart.docsUrl).toContain('/guides/platform/compute-and-disk#limits-and-constraints')
|
|
expect(attribute).toMatchObject({ label: 'pgbouncer', tooltip: 'PgBouncer connections' })
|
|
})
|
|
|
|
it('uses multipooler copy and drops the docs link for High Availability projects', () => {
|
|
const chart = getDedicatedPoolerChart(buildProject({ high_availability: true }))
|
|
const attribute = getClientConnectionsAttribute(chart)
|
|
|
|
expect(chart.docsUrl).toBeUndefined()
|
|
expect(chart.titleTooltip).toContain('multipooler')
|
|
expect(chart.titleTooltip).toContain('docs coming soon')
|
|
expect(attribute).toMatchObject({ label: 'multipooler', tooltip: 'Multipooler connections' })
|
|
})
|
|
})
|
|
|
|
const getSupavisorChart = (project: Project) =>
|
|
getReportAttributesV2(ENTITLED_FEATURES, project).find(
|
|
(chart) => chart.id === 'supavisor-connections-active'
|
|
)
|
|
|
|
describe('getReportAttributesV2 shared pooler chart', () => {
|
|
it('shows the chart for standard projects', () => {
|
|
expect(getSupavisorChart(buildProject())?.hide).toBe(false)
|
|
})
|
|
|
|
it('hides the chart for high availability projects', () => {
|
|
expect(getSupavisorChart(buildProject({ high_availability: true }))?.hide).toBe(true)
|
|
})
|
|
|
|
it('hides the chart when the database entitlement is missing', () => {
|
|
expect(
|
|
getReportAttributesV2([], buildProject()).find(
|
|
(chart) => chart.id === 'supavisor-connections-active'
|
|
)?.hide
|
|
).toBe(true)
|
|
})
|
|
})
|
|
|
|
describe('getReportAttributesV2 disk-io-burst-balance chart', () => {
|
|
it('shows the chart for burstable non high availability projects', () => {
|
|
expect(getBurstBalanceChart(buildProject())?.hide).toBe(false)
|
|
})
|
|
|
|
it('hides the chart for high availability projects', () => {
|
|
expect(getBurstBalanceChart(buildProject({ high_availability: true }))?.hide).toBe(true)
|
|
})
|
|
|
|
it('hides the chart when the feature flag is off', () => {
|
|
expect(getBurstBalanceChart(buildProject(), false)?.hide).toBe(true)
|
|
})
|
|
|
|
it('hides the chart for non burstable compute sizes', () => {
|
|
expect(getBurstBalanceChart(buildProject({ infra_compute_size: '16xlarge' }))?.hide).toBe(true)
|
|
})
|
|
})
|
|
|
|
describe('shouldShowDiskIOBurstBalanceChart', () => {
|
|
it('shows the chart for burstable non high availability projects when the flag is on', () => {
|
|
expect(shouldShowDiskIOBurstBalanceChart(buildProject(), true)).toBe(true)
|
|
})
|
|
|
|
it('hides the chart when the flag is off', () => {
|
|
expect(shouldShowDiskIOBurstBalanceChart(buildProject(), false)).toBe(false)
|
|
})
|
|
|
|
it('hides the chart for non burstable compute sizes', () => {
|
|
expect(
|
|
shouldShowDiskIOBurstBalanceChart(buildProject({ infra_compute_size: '4xlarge' }), true)
|
|
).toBe(false)
|
|
})
|
|
|
|
it('hides the chart for high availability projects', () => {
|
|
expect(
|
|
shouldShowDiskIOBurstBalanceChart(
|
|
buildProject({ high_availability: true, infra_compute_size: 'large' }),
|
|
true
|
|
)
|
|
).toBe(false)
|
|
})
|
|
|
|
it('hides the chart when the project is unknown', () => {
|
|
expect(shouldShowDiskIOBurstBalanceChart(undefined, true)).toBe(false)
|
|
})
|
|
})
|
|
|
|
describe('resource warning metrics chart IDs', () => {
|
|
it('keeps every configured chart target visible in the database report', () => {
|
|
const visibleChartIds = new Set(
|
|
getReportAttributesV2(ENTITLED_FEATURES, buildProject())
|
|
.filter((chart) => !chart.hide)
|
|
.map((chart) => chart.id)
|
|
)
|
|
const missingChartIds = Object.values(RESOURCE_WARNING_MESSAGES)
|
|
.flatMap((message) => message.metricsChartId ?? [])
|
|
.filter((chartId) => !visibleChartIds.has(chartId))
|
|
|
|
expect(missingChartIds).toEqual([])
|
|
})
|
|
})
|