Files
supabase/apps/studio/components/interfaces/Integrations/Vercel/VercelIntegration.utils.test.ts
Danny White c9ed51c99e fix(studio): add return to Vercel escape hatch (#48311)
## I have read the
[CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md)
file.

YES

## What kind of change does this PR introduce?

Bug fix / UX improvement for the Vercel Deploy Button create-project
interstitial.

## What is the current behavior?

On the Vercel create-project step, the organization picker is locked
(correct — the integration is bound to that org) and Cancel is hidden.
If the org can't create a free project (member free-project limits),
users hit a dead end: Upgrade may not help, and there's no way out of
the popup.

Also includes a small capitalisation nit on the Vercel install page.

| Before |
| --- |
| <img width="800" height="629" alt="Create Vercel Project Supabase"
src="https://github.com/user-attachments/assets/2acdc7a3-eb99-43c6-9135-557370647da1"
/> |

## What is the new behavior?

- Replaces `hideCancelButton` with `cancelAction: 'studio' | 'vercel' |
'hidden'`
- Vercel create flow shows **Return to Vercel**, which redirects to the
install `next` URL (closing the popup cleanly)
- Free-project-limit admonition adds a Vercel-only hint pointing at that
button: “Or return to Vercel and restart with a different organization.”
- Main `/new` Cancel behaviour is unchanged
- Org picker stays disabled

## Additional context

Org switching mid-create is intentionally not allowed. That would orphan
the Vercel install. Returning to Vercel is the safe escape hatch so
users can restart Deploy Button with another org, or free a project slot
/ upgrade and try again.

## To test

As far as I can tell, this is impossible to test on prod. Shortly after
merge though, you could test the following:
- [ ] Happy path: create still works; Return to Vercel is secondary and
does not block submit
- [ ] Free-limit blocked org: Create disabled, Return to Vercel visible
and redirects to `next`
- [ ] Main `/new`: Cancel still goes to last org / organizations

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

- **New Features**
- Enhanced project creation flow for Vercel: when a valid return
destination is available, users can choose **“Return to Vercel”**.
- Added additional messaging in the free-project-limit warning to guide
users back to Vercel and restart with a different organization (when
applicable).
- **Bug Fixes**
- Improved cancel behavior and routing consistency by only enabling
Vercel return when the destination is valid.
- **Style**
- Updated the Vercel integration interstitial title capitalization for
consistency.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Joshen Lim <joshenlimek@gmail.com>
2026-07-28 08:14:01 +10:00

33 lines
1.1 KiB
TypeScript

import { describe, expect, test } from 'vitest'
import {
getValidVercelReturnUrl,
isVercelUrl,
} from '@/components/interfaces/Integrations/Vercel/VercelIntegration.utils'
describe('isVercelUrl', () => {
test('accepts https vercel.com urls', () => {
expect(isVercelUrl('https://vercel.com/callback')).toBe(true)
})
test('rejects non-vercel and invalid urls', () => {
expect(isVercelUrl('https://example.com')).toBe(false)
expect(isVercelUrl('http://vercel.com')).toBe(false)
expect(isVercelUrl('not-a-url')).toBe(false)
})
})
describe('getValidVercelReturnUrl', () => {
test('returns the url when it is a valid vercel return url', () => {
expect(getValidVercelReturnUrl('https://vercel.com/callback')).toBe(
'https://vercel.com/callback'
)
})
test('returns undefined for missing or invalid next values', () => {
expect(getValidVercelReturnUrl(undefined)).toBeUndefined()
expect(getValidVercelReturnUrl('https://example.com')).toBeUndefined()
expect(getValidVercelReturnUrl('not-a-url')).toBeUndefined()
})
})