mirror of
https://github.com/supabase/supabase.git
synced 2026-05-08 09:50:33 -04:00
e8e0842be3
## Summary - Closes [FE-3039](https://linear.app/supabase/issue/FE-3039/validate-conn-percentage-input-between-1-and-100). - Adds a `superRefine`d `DatabaseFormSchema` in `PerformanceSettingsForm.tsx` that blocks submission when `DB_MAX_POOL_SIZE_UNIT === 'percent'` and the value falls outside 1-100. Connections (fixed pool size) path keeps the existing `min(1)` behavior per the ticket. - Updates the number input's `min`/`max` attributes to match: percent is now `1`-`100` (was `3`-`80`); connections unchanged (`3`-`Math.floor(maxConnectionLimit * 0.8)`). ## Test plan - [x] Unit tests added in `PerformanceSettingsForm.test.ts` covering bounds (1, 100), out-of-range (0, 101, -5, 150), mid-range, string coercion, connections path (no upper zod bound), and enum rejection. All 12 pass. - [x] Manually verify in Auth → Performance settings that entering 0 or 101 in percent mode shows a validation error and blocks save, and that switching to absolute connections still uses the existing bounds. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Bug Fixes** * Refined database pool-size validation and input constraints; percentage unit enforces values between 1–100 and rejects zero, negative, and out-of-range entries. String inputs that represent numbers are coerced where appropriate; unknown unit values are rejected. * **Tests** * Added comprehensive tests for boundary, invalid, string, and unknown-unit cases and for validation error messages. * **Refactor** * Validation moved to a centralized schema and HTML min/max input attributes were removed. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
112 lines
3.1 KiB
TypeScript
112 lines
3.1 KiB
TypeScript
import { describe, expect, it } from 'vitest'
|
|
|
|
import { DatabaseFormSchema } from './PerformanceSettingsForm'
|
|
|
|
describe('DatabaseFormSchema', () => {
|
|
describe('percent unit', () => {
|
|
it('accepts 1 (lower bound)', () => {
|
|
const result = DatabaseFormSchema.safeParse({
|
|
DB_MAX_POOL_SIZE: 1,
|
|
DB_MAX_POOL_SIZE_UNIT: 'percent',
|
|
})
|
|
expect(result.success).toBe(true)
|
|
})
|
|
|
|
it('accepts 100 (upper bound)', () => {
|
|
const result = DatabaseFormSchema.safeParse({
|
|
DB_MAX_POOL_SIZE: 100,
|
|
DB_MAX_POOL_SIZE_UNIT: 'percent',
|
|
})
|
|
expect(result.success).toBe(true)
|
|
})
|
|
|
|
it('accepts a mid-range value', () => {
|
|
const result = DatabaseFormSchema.safeParse({
|
|
DB_MAX_POOL_SIZE: 50,
|
|
DB_MAX_POOL_SIZE_UNIT: 'percent',
|
|
})
|
|
expect(result.success).toBe(true)
|
|
})
|
|
|
|
it('rejects 0', () => {
|
|
const result = DatabaseFormSchema.safeParse({
|
|
DB_MAX_POOL_SIZE: 0,
|
|
DB_MAX_POOL_SIZE_UNIT: 'percent',
|
|
})
|
|
expect(result.success).toBe(false)
|
|
})
|
|
|
|
it('rejects 101', () => {
|
|
const result = DatabaseFormSchema.safeParse({
|
|
DB_MAX_POOL_SIZE: 101,
|
|
DB_MAX_POOL_SIZE_UNIT: 'percent',
|
|
})
|
|
expect(result.success).toBe(false)
|
|
if (!result.success) {
|
|
const issue = result.error.issues.find((i) => i.path[0] === 'DB_MAX_POOL_SIZE')
|
|
expect(issue?.message).toBe('Percentage must be between 1 and 100')
|
|
}
|
|
})
|
|
|
|
it('rejects negative values', () => {
|
|
const result = DatabaseFormSchema.safeParse({
|
|
DB_MAX_POOL_SIZE: -5,
|
|
DB_MAX_POOL_SIZE_UNIT: 'percent',
|
|
})
|
|
expect(result.success).toBe(false)
|
|
})
|
|
|
|
it('coerces string input', () => {
|
|
const result = DatabaseFormSchema.safeParse({
|
|
DB_MAX_POOL_SIZE: '75',
|
|
DB_MAX_POOL_SIZE_UNIT: 'percent',
|
|
})
|
|
expect(result.success).toBe(true)
|
|
})
|
|
|
|
it('rejects out-of-range string input', () => {
|
|
const result = DatabaseFormSchema.safeParse({
|
|
DB_MAX_POOL_SIZE: '150',
|
|
DB_MAX_POOL_SIZE_UNIT: 'percent',
|
|
})
|
|
expect(result.success).toBe(false)
|
|
})
|
|
})
|
|
|
|
describe('connections unit', () => {
|
|
it('accepts 1 (min)', () => {
|
|
const result = DatabaseFormSchema.safeParse({
|
|
DB_MAX_POOL_SIZE: 1,
|
|
DB_MAX_POOL_SIZE_UNIT: 'connections',
|
|
})
|
|
expect(result.success).toBe(true)
|
|
})
|
|
|
|
it('accepts values above 100 (no upper schema bound for absolute)', () => {
|
|
const result = DatabaseFormSchema.safeParse({
|
|
DB_MAX_POOL_SIZE: 500,
|
|
DB_MAX_POOL_SIZE_UNIT: 'connections',
|
|
})
|
|
expect(result.success).toBe(true)
|
|
})
|
|
|
|
it('rejects 0', () => {
|
|
const result = DatabaseFormSchema.safeParse({
|
|
DB_MAX_POOL_SIZE: 0,
|
|
DB_MAX_POOL_SIZE_UNIT: 'connections',
|
|
})
|
|
expect(result.success).toBe(false)
|
|
})
|
|
})
|
|
|
|
describe('unit enum', () => {
|
|
it('rejects unknown unit values', () => {
|
|
const result = DatabaseFormSchema.safeParse({
|
|
DB_MAX_POOL_SIZE: 10,
|
|
DB_MAX_POOL_SIZE_UNIT: 'bytes',
|
|
})
|
|
expect(result.success).toBe(false)
|
|
})
|
|
})
|
|
})
|