Files
supabase/apps/studio/components/interfaces/Auth/PerformanceSettingsForm.test.ts
Ali Waseem e8e0842be3 fix(studio): validate auth conn percentage input between 1 and 100 (#45061)
## 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 -->
2026-04-21 07:59:35 -06:00

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)
})
})
})