mirror of
https://github.com/supabase/supabase.git
synced 2026-09-07 02:20:52 +08:00
## What kind of change does this PR introduce? Bug fix for the Vercel Deploy Button → Studio handoff. ## What is the current behavior? Vercel sometimes opens our install popup with `source=marketplace` while still sending Deploy Button params (`currentProjectId`, `external-id`). We trust `source` alone, so users are routed to choose-project (connect) instead of create — which is why create never gets reached in the Deploy Button flow. ## What is the new behavior? - When both Deploy Button signals (`currentProjectId` + `externalId`) are present, route to create even if Vercel sent `source=marketplace` / `external` - Hide Skip (and related empty-state copy) on choose-project when those signals are present, so Deploy Button users can't continue without linking ## Additional context Stacked on #48230. Test plan: - [ ] Unit tests for `resolveVercelInstallSource` / `hasVercelDeployButtonSignals` pass - [ ] Deploy Button flow with mislabeled `source=marketplace` + both params → lands on create after org install/continue - [ ] Genuine marketplace install (no `currentProjectId`/`external-id`) → still lands on choose-project with Skip available - [ ] If choose-project is opened with both Deploy Button params, Skip is hidden <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **New Features** - Improved Vercel installation handling for Deploy Button workflows, ensuring the correct setup path is selected. - Added clearer project-connection guidance when no projects are available (including conditional skip copy). - **Bug Fixes** - Prevented Deploy Button installations from incorrectly offering a skip option. - Preserved the skip-and-connect-later guidance for other Vercel installation flows. - Improved recognition of Deploy Button installations even when the reported Vercel source differs. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Joshen Lim <joshenlimek@gmail.com>
136 lines
4.2 KiB
TypeScript
136 lines
4.2 KiB
TypeScript
import { describe, expect, test } from 'vitest'
|
|
|
|
import {
|
|
buildVercelInstallRouteQuery,
|
|
getErrorMessage,
|
|
hasVercelDeployButtonSignals,
|
|
resolveVercelInstallSource,
|
|
} from '@/lib/integrations/vercel-install.utils'
|
|
|
|
describe('getErrorMessage', () => {
|
|
test('returns the message from an Error instance', () => {
|
|
expect(getErrorMessage(new Error('Something went wrong'))).toBe('Something went wrong')
|
|
})
|
|
|
|
test('returns the message from an error-like object', () => {
|
|
expect(getErrorMessage({ message: 'Request failed' })).toBe('Request failed')
|
|
})
|
|
|
|
test('returns undefined for non-string object messages', () => {
|
|
expect(getErrorMessage({ message: 404 })).toBeUndefined()
|
|
})
|
|
|
|
test('returns undefined for primitive and empty inputs', () => {
|
|
expect(getErrorMessage('Request failed')).toBeUndefined()
|
|
expect(getErrorMessage(null)).toBeUndefined()
|
|
expect(getErrorMessage(undefined)).toBeUndefined()
|
|
})
|
|
})
|
|
|
|
describe('buildVercelInstallRouteQuery', () => {
|
|
test('only keeps deploy-button destination params', () => {
|
|
expect(
|
|
buildVercelInstallRouteQuery({
|
|
source: 'deploy-button',
|
|
organizationSlug: 'acme',
|
|
currentProjectId: 'vercel-project',
|
|
externalId: 'github-repo',
|
|
next: 'https://vercel.com/callback',
|
|
configurationId: 'configuration-id',
|
|
})
|
|
).toStrictEqual({
|
|
organizationSlug: 'acme',
|
|
currentProjectId: 'vercel-project',
|
|
externalId: 'github-repo',
|
|
next: 'https://vercel.com/callback',
|
|
})
|
|
})
|
|
|
|
test('keeps marketplace params and passes through deploy-button ids when present', () => {
|
|
expect(
|
|
buildVercelInstallRouteQuery({
|
|
source: 'marketplace',
|
|
organizationSlug: 'acme',
|
|
configurationId: 'configuration-id',
|
|
currentProjectId: 'vercel-project',
|
|
externalId: 'github-repo',
|
|
next: 'https://vercel.com/callback',
|
|
})
|
|
).toStrictEqual({
|
|
organizationSlug: 'acme',
|
|
configurationId: 'configuration-id',
|
|
currentProjectId: 'vercel-project',
|
|
externalId: 'github-repo',
|
|
next: 'https://vercel.com/callback',
|
|
})
|
|
})
|
|
|
|
test('removes undefined params', () => {
|
|
expect(
|
|
buildVercelInstallRouteQuery({
|
|
source: 'external',
|
|
organizationSlug: 'acme',
|
|
configurationId: undefined,
|
|
next: undefined,
|
|
})
|
|
).toStrictEqual({ organizationSlug: 'acme' })
|
|
})
|
|
|
|
test('only keeps organizationSlug when source is undefined', () => {
|
|
expect(
|
|
buildVercelInstallRouteQuery({
|
|
source: undefined,
|
|
organizationSlug: 'acme',
|
|
configurationId: 'configuration-id',
|
|
currentProjectId: 'vercel-project',
|
|
externalId: 'github-repo',
|
|
next: 'https://vercel.com/callback',
|
|
})
|
|
).toStrictEqual({ organizationSlug: 'acme' })
|
|
})
|
|
})
|
|
|
|
describe('hasVercelDeployButtonSignals', () => {
|
|
test('requires both currentProjectId and externalId', () => {
|
|
expect(
|
|
hasVercelDeployButtonSignals({
|
|
currentProjectId: 'prj_123',
|
|
externalId: 'https://github.com/org/repo',
|
|
})
|
|
).toBe(true)
|
|
expect(hasVercelDeployButtonSignals({ currentProjectId: 'prj_123' })).toBe(false)
|
|
expect(hasVercelDeployButtonSignals({ externalId: 'https://github.com/org/repo' })).toBe(false)
|
|
expect(hasVercelDeployButtonSignals({})).toBe(false)
|
|
})
|
|
})
|
|
|
|
describe('resolveVercelInstallSource', () => {
|
|
test('overrides marketplace and external when deploy-button signals are present', () => {
|
|
expect(
|
|
resolveVercelInstallSource({
|
|
source: 'marketplace',
|
|
currentProjectId: 'prj_123',
|
|
externalId: 'https://github.com/org/repo',
|
|
})
|
|
).toBe('deploy-button')
|
|
expect(
|
|
resolveVercelInstallSource({
|
|
source: 'external',
|
|
currentProjectId: 'prj_123',
|
|
externalId: 'https://github.com/org/repo',
|
|
})
|
|
).toBe('deploy-button')
|
|
})
|
|
|
|
test('keeps the declared source when deploy-button signals are incomplete', () => {
|
|
expect(
|
|
resolveVercelInstallSource({
|
|
source: 'marketplace',
|
|
currentProjectId: 'prj_123',
|
|
})
|
|
).toBe('marketplace')
|
|
expect(resolveVercelInstallSource({ source: 'deploy-button' })).toBe('deploy-button')
|
|
expect(resolveVercelInstallSource({ source: undefined })).toBeUndefined()
|
|
})
|
|
})
|