mirror of
https://github.com/supabase/supabase.git
synced 2026-10-06 01:45:10 +03:00
How to test: 1. Connect a project to GH repo 2. Deploy the `config.toml` once 3. Change some setting in Auth 4. You should see a change in `/dashboard/project/_/settings/code-configuration` <img width="1271" height="1186" alt="Screenshot 2026-09-16 at 16 26 39" src="https://github.com/user-attachments/assets/dfc135a4-e495-489e-88fd-b760383793b4" /> <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **New Features** - Configuration drift comparisons now use a consistent project configuration schema. - Drift details display complete current-environment and `config.toml` values, grouped by section. - Matching and unmanaged settings are organized into dedicated sections. - Configuration fields link directly to relevant Studio settings. - Added a warning that GitHub deployments overwrite local changes. - **Bug Fixes** - Configuration updates now refresh project configuration data automatically. - Improved labels and formatting for boolean and redirect URL values. - Drift errors identify invalid configuration paths and provide corrective guidance. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
196 lines
5.9 KiB
TypeScript
196 lines
5.9 KiB
TypeScript
import { describe, expect, it } from 'vitest'
|
|
|
|
import {
|
|
createConfigurationDriftRows,
|
|
groupMatchedConfigFields,
|
|
groupUnmanagedConfigFields,
|
|
} from './ConfigurationDriftPage.utils'
|
|
import type {
|
|
GitHubConfigDriftField,
|
|
MatchedConfigField,
|
|
UnmanagedConfigField,
|
|
} from './github-config-drift'
|
|
|
|
const PROJECT_REF = 'abcdefgh'
|
|
|
|
function driftField(overrides: Partial<GitHubConfigDriftField>): GitHubConfigDriftField {
|
|
return {
|
|
section: 'api',
|
|
configPath: 'api.max_rows',
|
|
settingHref: (projectRef) => `/project/${projectRef}/settings/api`,
|
|
dashboardValue: 1000,
|
|
githubValue: 500,
|
|
...overrides,
|
|
}
|
|
}
|
|
|
|
function unmanagedField(overrides: Partial<UnmanagedConfigField>): UnmanagedConfigField {
|
|
return {
|
|
section: 'api',
|
|
configPath: 'api.max_rows',
|
|
dashboardValue: 1000,
|
|
...overrides,
|
|
}
|
|
}
|
|
|
|
function matchedField(overrides: Partial<MatchedConfigField>): MatchedConfigField {
|
|
return {
|
|
section: 'api',
|
|
configPath: 'api.max_rows',
|
|
value: 1000,
|
|
...overrides,
|
|
}
|
|
}
|
|
|
|
describe('createConfigurationDriftRows', () => {
|
|
it('resolves the setting href against the project ref and marks the row as drifted', () => {
|
|
const [row] = createConfigurationDriftRows([driftField({})], PROJECT_REF)
|
|
|
|
expect(row.status).toBe('drifted')
|
|
expect(row.settingHref).toBe('/project/abcdefgh/settings/api')
|
|
})
|
|
|
|
it('uses the hand-written label for a known config path', () => {
|
|
const [row] = createConfigurationDriftRows(
|
|
[driftField({ configPath: 'auth.enable_signup' })],
|
|
PROJECT_REF
|
|
)
|
|
|
|
expect(row.settingLabel).toBe('New user signups')
|
|
})
|
|
|
|
it('labels an external auth provider field as "<provider> · <key>"', () => {
|
|
const [row] = createConfigurationDriftRows(
|
|
[driftField({ configPath: 'auth.external.google.client_id' })],
|
|
PROJECT_REF
|
|
)
|
|
|
|
expect(row.settingLabel).toBe('Google client ID')
|
|
})
|
|
|
|
it('falls back to a title-cased last path segment for an unrecognized config path', () => {
|
|
const [row] = createConfigurationDriftRows(
|
|
[driftField({ configPath: 'some.unknown_setting' })],
|
|
PROJECT_REF
|
|
)
|
|
|
|
expect(row.settingLabel).toBe('Unknown Setting')
|
|
})
|
|
|
|
it('formats a missing scalar value as "Not set"', () => {
|
|
const [row] = createConfigurationDriftRows(
|
|
[driftField({ configPath: 'auth.site_url', dashboardValue: '', githubValue: undefined })],
|
|
PROJECT_REF
|
|
)
|
|
|
|
expect(row.valueDiff).toEqual({
|
|
kind: 'scalar',
|
|
dashboardValue: 'Not set',
|
|
configValue: 'Not set',
|
|
})
|
|
})
|
|
|
|
it('builds a list diff for redirect URLs, normalizing and comparing entries', () => {
|
|
const [row] = createConfigurationDriftRows(
|
|
[
|
|
driftField({
|
|
configPath: 'auth.additional_redirect_urls',
|
|
dashboardValue: ['https://a.com', 'https://b.com'],
|
|
githubValue: [' https://a.com ', 'https://c.com'],
|
|
}),
|
|
],
|
|
PROJECT_REF
|
|
)
|
|
|
|
expect(row.valueDiff).toEqual({
|
|
configValue: ' https://a.com \nhttps://c.com',
|
|
dashboardValue: 'https://a.com\nhttps://b.com',
|
|
kind: 'scalar',
|
|
})
|
|
})
|
|
})
|
|
|
|
describe('groupUnmanagedConfigFields', () => {
|
|
it('returns an empty array when there are no unmanaged fields', () => {
|
|
expect(groupUnmanagedConfigFields([])).toEqual([])
|
|
})
|
|
|
|
it('groups fields from the same section into a single group', () => {
|
|
const groups = groupUnmanagedConfigFields([
|
|
unmanagedField({ configPath: 'api.max_rows', dashboardValue: 1000 }),
|
|
unmanagedField({ configPath: 'api.enabled', dashboardValue: true }),
|
|
])
|
|
|
|
expect(groups).toHaveLength(1)
|
|
expect(groups[0]).toEqual({
|
|
section: 'api',
|
|
sectionLabel: 'API',
|
|
rows: [
|
|
{ configPath: 'api.max_rows', label: 'Max rows', value: '1000' },
|
|
{ configPath: 'api.enabled', label: 'API enabled', value: 'true' },
|
|
],
|
|
})
|
|
})
|
|
|
|
it('orders groups by CONFIG_SECTIONS order, not by input order', () => {
|
|
const groups = groupUnmanagedConfigFields([
|
|
unmanagedField({ section: 'storage', configPath: 'storage.enabled', dashboardValue: true }),
|
|
unmanagedField({ section: 'api', configPath: 'api.enabled', dashboardValue: true }),
|
|
])
|
|
|
|
expect(groups.map((group) => group.section)).toEqual(['api', 'storage'])
|
|
})
|
|
|
|
it('formats an empty-value field as "Not set"', () => {
|
|
const groups = groupUnmanagedConfigFields([
|
|
unmanagedField({ configPath: 'auth.site_url', section: 'auth', dashboardValue: undefined }),
|
|
])
|
|
|
|
expect(groups[0].rows[0].value).toBe('Not set')
|
|
})
|
|
|
|
it('joins a normalized redirect URL list with newlines', () => {
|
|
const groups = groupUnmanagedConfigFields([
|
|
unmanagedField({
|
|
section: 'auth',
|
|
configPath: 'auth.additional_redirect_urls',
|
|
dashboardValue: ['https://b.com', 'https://a.com', 'https://a.com'],
|
|
}),
|
|
])
|
|
|
|
expect(groups[0].rows[0].value).toBe('https://b.com\nhttps://a.com\nhttps://a.com')
|
|
})
|
|
})
|
|
|
|
describe('groupMatchedConfigFields', () => {
|
|
it('returns an empty array when there are no matched fields', () => {
|
|
expect(groupMatchedConfigFields([])).toEqual([])
|
|
})
|
|
|
|
it('groups fields from the same section into a single group', () => {
|
|
const groups = groupMatchedConfigFields([
|
|
matchedField({ configPath: 'api.max_rows', value: 1000 }),
|
|
matchedField({ configPath: 'api.enabled', value: true }),
|
|
])
|
|
|
|
expect(groups).toHaveLength(1)
|
|
expect(groups[0]).toEqual({
|
|
section: 'api',
|
|
sectionLabel: 'API',
|
|
rows: [
|
|
{ configPath: 'api.max_rows', label: 'Max rows', value: '1000' },
|
|
{ configPath: 'api.enabled', label: 'API enabled', value: 'true' },
|
|
],
|
|
})
|
|
})
|
|
|
|
it('orders groups by CONFIG_SECTIONS order, not by input order', () => {
|
|
const groups = groupMatchedConfigFields([
|
|
matchedField({ section: 'storage', configPath: 'storage.enabled', value: true }),
|
|
matchedField({ section: 'api', configPath: 'api.enabled', value: true }),
|
|
])
|
|
|
|
expect(groups.map((group) => group.section)).toEqual(['api', 'storage'])
|
|
})
|
|
})
|