Files
supabase/apps/studio/data/reports/database-charts.test.ts

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([])
})
})