mirror of
https://github.com/fsolla/teqo.git
synced 2026-11-13 06:43:06 +00:00
CI short-circuited "already aliased" when v13 listed pt.jorgesolla.com.br on a fresh --prod deploy while the domain still pointed at an older Current. Verify only via GET /v2/.../aliases and /v4/aliases?domain=. Also drop invalid --yes on vercel alias set (CLI 55).
369 lines
13 KiB
TypeScript
369 lines
13 KiB
TypeScript
// @vitest-environment node
|
|
|
|
import { describe, expect, it } from 'vitest'
|
|
|
|
import {
|
|
aliasesIncludeHost,
|
|
ensureProductionCustomDomain,
|
|
normalizeHostname,
|
|
parseDeploymentRef,
|
|
PRODUCTION_CUSTOM_DOMAIN,
|
|
sameDeploymentId,
|
|
} from '../../scripts/lib/vercel-production-alias.mjs'
|
|
|
|
const jsonResponse = (ok: boolean, status: number, payload: unknown) =>
|
|
({
|
|
ok,
|
|
status,
|
|
text: async () => (payload === null ? '' : JSON.stringify(payload)),
|
|
}) as Response
|
|
|
|
describe('vercelProductionAlias', () => {
|
|
it('pins the Teqo production hostname', () => {
|
|
expect(PRODUCTION_CUSTOM_DOMAIN).toBe('pt.jorgesolla.com.br')
|
|
})
|
|
|
|
it('normalizeHostname strips protocol and path', () => {
|
|
expect(normalizeHostname('https://PT.jorgesolla.com.br/campanha')).toBe('pt.jorgesolla.com.br')
|
|
})
|
|
|
|
it('aliasesIncludeHost matches hostnames case-insensitively', () => {
|
|
expect(
|
|
aliasesIncludeHost(
|
|
['jorgesolla-solla.vercel.app', 'pt.jorgesolla.com.br'],
|
|
'PT.jorgesolla.com.br',
|
|
),
|
|
).toBe(true)
|
|
expect(aliasesIncludeHost(['jorgesolla-solla.vercel.app'], 'pt.jorgesolla.com.br')).toBe(false)
|
|
})
|
|
|
|
it('sameDeploymentId ignores dpl_ prefix', () => {
|
|
expect(sameDeploymentId('dpl_abc', 'abc')).toBe(true)
|
|
expect(sameDeploymentId('dpl_abc', 'dpl_abc')).toBe(true)
|
|
expect(sameDeploymentId('dpl_abc', 'dpl_other')).toBe(false)
|
|
})
|
|
|
|
it('ensureProductionCustomDomain does not trust GET /v13 alias alone', async () => {
|
|
// v13 lists the custom host (false positive observed in CI) while the domain
|
|
// alias target still points at an older deployment — must promote/alias.
|
|
let aliasHosts = ['jorgesolla-solla.vercel.app']
|
|
let domainTargetId = 'dpl_old'
|
|
const fetchImpl = (async (url: string | URL | Request, init?: RequestInit) => {
|
|
const href = String(url)
|
|
const method = init?.method ?? 'GET'
|
|
if (href.includes('/v9/projects/') && href.includes('/domains') && method === 'GET') {
|
|
return jsonResponse(true, 200, {
|
|
domains: [{ name: 'pt.jorgesolla.com.br', verified: true }],
|
|
})
|
|
}
|
|
if (href.includes('/v9/projects/') && method === 'GET') {
|
|
return jsonResponse(true, 200, { autoAssignCustomDomains: true })
|
|
}
|
|
if (href.includes('/v13/deployments/')) {
|
|
return jsonResponse(true, 200, {
|
|
id: 'dpl_new',
|
|
// Misleading: listed even though domain still points at dpl_old.
|
|
alias: ['pt.jorgesolla.com.br', 'jorgesolla-solla.vercel.app'],
|
|
readyState: 'READY',
|
|
})
|
|
}
|
|
if (href.includes('/v2/deployments/') && href.includes('/aliases') && method === 'GET') {
|
|
return jsonResponse(true, 200, {
|
|
aliases: aliasHosts.map((alias) => ({ alias, uid: alias, created: '' })),
|
|
})
|
|
}
|
|
if (href.includes('/v4/aliases') && method === 'GET') {
|
|
return jsonResponse(true, 200, {
|
|
aliases: [
|
|
{
|
|
alias: 'pt.jorgesolla.com.br',
|
|
deploymentId: domainTargetId,
|
|
uid: 'a1',
|
|
created: '',
|
|
},
|
|
],
|
|
})
|
|
}
|
|
if (href.includes('/promote/') && method === 'POST') {
|
|
return jsonResponse(true, 200, {})
|
|
}
|
|
if (href.includes('/aliases') && method === 'POST') {
|
|
aliasHosts = ['jorgesolla-solla.vercel.app', 'pt.jorgesolla.com.br']
|
|
domainTargetId = 'dpl_new'
|
|
return jsonResponse(true, 200, {
|
|
alias: 'pt.jorgesolla.com.br',
|
|
uid: 'alias_1',
|
|
oldDeploymentId: 'dpl_old',
|
|
created: new Date().toISOString(),
|
|
})
|
|
}
|
|
throw new Error(`unexpected fetch ${method} ${href}`)
|
|
}) as typeof fetch
|
|
|
|
const result = await ensureProductionCustomDomain({
|
|
token: 'tok',
|
|
projectId: 'prj_x',
|
|
teamId: 'team_x',
|
|
deploymentRef: 'dpl_new',
|
|
fetchImpl,
|
|
sleepImpl: async () => {},
|
|
})
|
|
|
|
expect(result.alreadyAssigned).toBe(false)
|
|
expect(result.aliased).toBe(true)
|
|
})
|
|
|
|
it('parseDeploymentRef accepts inspect paths and vercel.app hosts', () => {
|
|
expect(
|
|
parseDeploymentRef('https://vercel.com/solla/jorgesolla/CQkmCejZSvRoFtYP8hHbjzP3pc1L'),
|
|
).toEqual({
|
|
kind: 'id',
|
|
value: 'CQkmCejZSvRoFtYP8hHbjzP3pc1L',
|
|
})
|
|
expect(parseDeploymentRef('https://jorgesolla-k0lwit3lp-solla.vercel.app')).toEqual({
|
|
kind: 'url',
|
|
value: 'jorgesolla-k0lwit3lp-solla.vercel.app',
|
|
})
|
|
expect(parseDeploymentRef('dpl_abc123')).toEqual({ kind: 'id', value: 'dpl_abc123' })
|
|
})
|
|
|
|
it('ensureProductionCustomDomain enables auto-assign, promotes, and aliases explicitly', async () => {
|
|
const calls: string[] = []
|
|
let aliasHosts = ['jorgesolla-solla.vercel.app']
|
|
const fetchImpl = (async (url: string | URL | Request, init?: RequestInit) => {
|
|
const href = String(url)
|
|
const method = init?.method ?? 'GET'
|
|
calls.push(`${method} ${href}`)
|
|
|
|
if (href.includes('/v9/projects/') && href.includes('/domains') && method === 'GET') {
|
|
return jsonResponse(true, 200, {
|
|
domains: [{ name: 'pt.jorgesolla.com.br', verified: true, gitBranch: null }],
|
|
})
|
|
}
|
|
if (href.includes('/v9/projects/') && method === 'GET') {
|
|
return jsonResponse(true, 200, { autoAssignCustomDomains: false, name: 'jorgesolla' })
|
|
}
|
|
if (href.includes('/v9/projects/') && method === 'PATCH' && !href.includes('/domains/')) {
|
|
return jsonResponse(true, 200, { autoAssignCustomDomains: true })
|
|
}
|
|
if (href.includes('/v13/deployments/')) {
|
|
return jsonResponse(true, 200, {
|
|
id: 'dpl_test',
|
|
url: 'jorgesolla-test.vercel.app',
|
|
alias: aliasHosts,
|
|
readyState: 'READY',
|
|
})
|
|
}
|
|
if (href.includes('/v2/deployments/') && href.includes('/aliases') && method === 'GET') {
|
|
return jsonResponse(true, 200, {
|
|
aliases: aliasHosts.map((alias) => ({
|
|
alias,
|
|
uid: alias,
|
|
created: new Date().toISOString(),
|
|
})),
|
|
})
|
|
}
|
|
if (href.includes('/v4/aliases') && method === 'GET') {
|
|
const assigned = aliasHosts.includes('pt.jorgesolla.com.br')
|
|
return jsonResponse(true, 200, {
|
|
aliases: assigned
|
|
? [
|
|
{
|
|
alias: 'pt.jorgesolla.com.br',
|
|
deploymentId: 'dpl_test',
|
|
uid: 'a1',
|
|
created: '',
|
|
projectId: 'prj_x',
|
|
},
|
|
]
|
|
: [],
|
|
})
|
|
}
|
|
if (href.includes('/promote/') && method === 'POST') {
|
|
return jsonResponse(true, 200, {})
|
|
}
|
|
if (href.includes('/aliases') && method === 'POST') {
|
|
aliasHosts = ['jorgesolla-solla.vercel.app', 'pt.jorgesolla.com.br']
|
|
return jsonResponse(true, 200, {
|
|
alias: 'pt.jorgesolla.com.br',
|
|
uid: 'alias_1',
|
|
oldDeploymentId: 'dpl_old',
|
|
created: new Date().toISOString(),
|
|
})
|
|
}
|
|
throw new Error(`unexpected fetch ${method} ${href}`)
|
|
}) as typeof fetch
|
|
|
|
const result = await ensureProductionCustomDomain({
|
|
token: 'tok',
|
|
projectId: 'prj_x',
|
|
teamId: 'team_x',
|
|
deploymentRef: 'https://jorgesolla-test.vercel.app',
|
|
fetchImpl,
|
|
sleepImpl: async () => {},
|
|
})
|
|
|
|
expect(result.aliased).toBe(true)
|
|
expect(result.autoAssignWasFalse).toBe(true)
|
|
expect(result.clearedGitBranch).toBe(false)
|
|
expect(calls.some((c) => c.includes('/aliases') && c.startsWith('POST '))).toBe(true)
|
|
})
|
|
|
|
it('ensureProductionCustomDomain clears gitBranch before aliasing CLI deploys', async () => {
|
|
const calls: string[] = []
|
|
let aliasHosts = ['jorgesolla-solla.vercel.app']
|
|
let domainGitBranch: string | null = 'main'
|
|
const fetchImpl = (async (url: string | URL | Request, init?: RequestInit) => {
|
|
const href = String(url)
|
|
const method = init?.method ?? 'GET'
|
|
calls.push(`${method} ${href}`)
|
|
|
|
if (href.includes('/v9/projects/') && href.includes('/domains') && method === 'GET') {
|
|
return jsonResponse(true, 200, {
|
|
domains: [
|
|
{
|
|
name: 'pt.jorgesolla.com.br',
|
|
verified: true,
|
|
gitBranch: domainGitBranch,
|
|
},
|
|
],
|
|
})
|
|
}
|
|
if (
|
|
href.includes('/v9/projects/') &&
|
|
href.includes('/domains/pt.jorgesolla.com.br') &&
|
|
method === 'PATCH'
|
|
) {
|
|
domainGitBranch = null
|
|
return jsonResponse(true, 200, { name: 'pt.jorgesolla.com.br', gitBranch: null })
|
|
}
|
|
if (href.includes('/v9/projects/') && method === 'GET') {
|
|
return jsonResponse(true, 200, { autoAssignCustomDomains: true, name: 'jorgesolla' })
|
|
}
|
|
if (href.includes('/v13/deployments/')) {
|
|
return jsonResponse(true, 200, {
|
|
id: 'dpl_test',
|
|
alias: aliasHosts,
|
|
readyState: 'READY',
|
|
})
|
|
}
|
|
if (href.includes('/v2/deployments/') && href.includes('/aliases') && method === 'GET') {
|
|
return jsonResponse(true, 200, {
|
|
aliases: aliasHosts.map((alias) => ({ alias, uid: alias, created: '' })),
|
|
})
|
|
}
|
|
if (href.includes('/v4/aliases') && method === 'GET') {
|
|
const assigned = aliasHosts.includes('pt.jorgesolla.com.br')
|
|
return jsonResponse(true, 200, {
|
|
aliases: assigned
|
|
? [{ alias: 'pt.jorgesolla.com.br', deploymentId: 'dpl_test', uid: 'a1', created: '' }]
|
|
: [],
|
|
})
|
|
}
|
|
if (href.includes('/promote/') && method === 'POST') {
|
|
return jsonResponse(true, 200, {})
|
|
}
|
|
if (href.includes('/aliases') && method === 'POST') {
|
|
aliasHosts = ['jorgesolla-solla.vercel.app', 'pt.jorgesolla.com.br']
|
|
return jsonResponse(true, 200, {
|
|
alias: 'pt.jorgesolla.com.br',
|
|
uid: 'alias_1',
|
|
created: new Date().toISOString(),
|
|
})
|
|
}
|
|
throw new Error(`unexpected fetch ${method} ${href}`)
|
|
}) as typeof fetch
|
|
|
|
const result = await ensureProductionCustomDomain({
|
|
token: 'tok',
|
|
projectId: 'prj_x',
|
|
teamId: 'team_x',
|
|
deploymentRef: 'dpl_test',
|
|
fetchImpl,
|
|
sleepImpl: async () => {},
|
|
})
|
|
|
|
expect(result.aliased).toBe(true)
|
|
expect(result.clearedGitBranch).toBe(true)
|
|
expect(
|
|
calls.some((c) => c.startsWith('PATCH ') && c.includes('/domains/pt.jorgesolla.com.br')),
|
|
).toBe(true)
|
|
})
|
|
|
|
it('ensureProductionCustomDomain skips work when alias already present', async () => {
|
|
const fetchImpl = (async (url: string | URL | Request, init?: RequestInit) => {
|
|
const href = String(url)
|
|
const method = init?.method ?? 'GET'
|
|
if (href.includes('/v9/projects/') && href.includes('/domains') && method === 'GET') {
|
|
return jsonResponse(true, 200, {
|
|
domains: [{ name: 'pt.jorgesolla.com.br', verified: true }],
|
|
})
|
|
}
|
|
if (href.includes('/v9/projects/') && method === 'GET') {
|
|
return jsonResponse(true, 200, { autoAssignCustomDomains: true })
|
|
}
|
|
if (href.includes('/v13/deployments/')) {
|
|
return jsonResponse(true, 200, {
|
|
id: 'dpl_test',
|
|
alias: ['pt.jorgesolla.com.br'],
|
|
readyState: 'READY',
|
|
})
|
|
}
|
|
if (href.includes('/v2/deployments/') && href.includes('/aliases') && method === 'GET') {
|
|
return jsonResponse(true, 200, {
|
|
aliases: [{ alias: 'pt.jorgesolla.com.br', uid: 'a1', created: '' }],
|
|
})
|
|
}
|
|
if (href.includes('/v4/aliases') && method === 'GET') {
|
|
return jsonResponse(true, 200, {
|
|
aliases: [
|
|
{
|
|
alias: 'pt.jorgesolla.com.br',
|
|
deploymentId: 'dpl_test',
|
|
uid: 'a1',
|
|
created: '',
|
|
projectId: 'prj_x',
|
|
},
|
|
],
|
|
})
|
|
}
|
|
throw new Error(`unexpected fetch ${method} ${href}`)
|
|
}) as typeof fetch
|
|
|
|
const result = await ensureProductionCustomDomain({
|
|
token: 'tok',
|
|
projectId: 'prj_x',
|
|
teamId: 'team_x',
|
|
deploymentRef: 'dpl_test',
|
|
fetchImpl,
|
|
sleepImpl: async () => {},
|
|
})
|
|
|
|
expect(result.alreadyAssigned).toBe(true)
|
|
})
|
|
|
|
it('ensureProductionCustomDomain fails when the hostname is not on the project', async () => {
|
|
const fetchImpl = (async (url: string | URL | Request, init?: RequestInit) => {
|
|
const href = String(url)
|
|
const method = init?.method ?? 'GET'
|
|
if (href.includes('/v9/projects/') && href.includes('/domains') && method === 'GET') {
|
|
return jsonResponse(true, 200, { domains: [{ name: 'other.example.com' }] })
|
|
}
|
|
if (href.includes('/v9/projects/') && method === 'GET') {
|
|
return jsonResponse(true, 200, { autoAssignCustomDomains: true })
|
|
}
|
|
throw new Error(`unexpected fetch ${method} ${href}`)
|
|
}) as typeof fetch
|
|
|
|
await expect(
|
|
ensureProductionCustomDomain({
|
|
token: 'tok',
|
|
projectId: 'prj_x',
|
|
teamId: 'team_x',
|
|
deploymentRef: 'dpl_test',
|
|
fetchImpl,
|
|
sleepImpl: async () => {},
|
|
}),
|
|
).rejects.toThrow(/not attached to this Vercel project/)
|
|
})
|
|
})
|