mirror of
https://github.com/supabase/supabase.git
synced 2026-10-06 01:45:10 +03:00
Adds integrations settings page to each oauth integration to show associated resources (e.g. API keys, config, oauth apps, etc) <img width="1150" height="892" alt="Screenshot 2026-06-16 at 2 44 31 PM" src="https://github.com/user-attachments/assets/035cc602-886d-43bc-a5a7-e14f76dd37c3" /> <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit ## Summary * **New Features** * Added a Marketplace “Settings” tab with a grouped **Connected resources** view (OAuth apps, API keys, Edge Function secrets, SMTP), including loading/empty/missing-resource states and per-kind removal actions. * Added a resource-group section UI plus integration-aware grouping/copy customization and missing-kind zero-states. * **Bug Fixes** * Improved installed-state detection for Grafana and Doppler by broadening conditions. * Added an orphaned-resources warning when expected OAuth apps are missing. * **Refactor** * Unified connected-resource removal into a single flow with OAuth-specific revoke handling. * **Tests** * Added comprehensive UI and utility coverage for grouping, states, and destructive removal behavior. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
58 lines
2.4 KiB
TypeScript
58 lines
2.4 KiB
TypeScript
import { describe, expect, test } from 'vitest'
|
|
|
|
import { getGroupContent, KIND_ORDER } from './MarketplaceIntegrationSettingsTab.utils'
|
|
import { type ConnectedResourceUsage } from '@/components/interfaces/Integrations/Landing/Landing.utils'
|
|
|
|
const base = { integrationName: 'Grafana', orgSlug: 'acme', projectRef: 'abcdefghijklmnop' }
|
|
|
|
describe('getGroupContent', () => {
|
|
test('falls back to generic copy when no usage override is provided', () => {
|
|
const group = getGroupContent({ kind: 'api_key', count: 1, ...base })
|
|
expect(group.note).toContain('Removing this key')
|
|
expect(group.missingNote).toContain('No secret API key is connected for Grafana')
|
|
})
|
|
|
|
test('uses integration-specific usage copy when provided', () => {
|
|
const usage: ConnectedResourceUsage = {
|
|
removalWarning: 'Removing this key stops metrics collection.',
|
|
noteWhenAbsent: 'No API key connected. Dashboards will not receive data.',
|
|
}
|
|
const group = getGroupContent({ kind: 'api_key', count: 1, ...base, usage })
|
|
expect(group.note).toBe(usage.removalWarning)
|
|
expect(group.missingNote).toBe(usage.noteWhenAbsent)
|
|
})
|
|
|
|
test('pluralizes the title and notes based on count', () => {
|
|
const single = getGroupContent({ kind: 'api_key', count: 1, ...base })
|
|
const plural = getGroupContent({ kind: 'api_key', count: 3, ...base })
|
|
expect(single.title).toBe('Secret API key')
|
|
expect(plural.title).toBe('Secret API keys')
|
|
expect(plural.note).toContain('a key')
|
|
})
|
|
|
|
test('exposes the OAuth app manage action only when an org slug is present', () => {
|
|
expect(getGroupContent({ kind: 'oauth_app', count: 1, ...base }).manageAction).toEqual({
|
|
label: 'Manage access',
|
|
href: '/org/acme/apps',
|
|
})
|
|
expect(
|
|
getGroupContent({ kind: 'oauth_app', count: 1, integrationName: 'Grafana' }).manageAction
|
|
).toBeUndefined()
|
|
})
|
|
|
|
test('points the SMTP manage action at the project auth settings', () => {
|
|
const group = getGroupContent({ kind: 'smtp', count: 1, ...base })
|
|
expect(group.manageAction).toEqual({
|
|
label: 'Manage settings',
|
|
href: '/project/abcdefghijklmnop/auth/smtp',
|
|
})
|
|
})
|
|
|
|
test('always returns a missing note for every resource kind', () => {
|
|
for (const kind of KIND_ORDER) {
|
|
const group = getGroupContent({ kind, count: 1, ...base })
|
|
expect(group.missingNote.length).toBeGreaterThan(0)
|
|
}
|
|
})
|
|
})
|