159 lines
4.4 KiB
TypeScript
159 lines
4.4 KiB
TypeScript
import { afterEach, expect, test, vi } from 'vitest';
|
|
|
|
import {
|
|
createDeployment,
|
|
createSession,
|
|
deleteSession,
|
|
getSession,
|
|
listDeployments,
|
|
searchBranches,
|
|
searchCommits,
|
|
uninstallDeployment,
|
|
} from './api';
|
|
|
|
afterEach(() => {
|
|
vi.unstubAllGlobals();
|
|
});
|
|
|
|
test('lists deployments from the same-origin control plane', async () => {
|
|
const fetchMock = vi.fn().mockResolvedValue(
|
|
new Response(
|
|
JSON.stringify({
|
|
deployments: [
|
|
{
|
|
id: 'preview-1',
|
|
branch: 'feature/demo',
|
|
status: 'running',
|
|
health: 'healthy',
|
|
createdAt: '2026-08-15T00:00:00Z',
|
|
updatedAt: '2026-08-15T00:01:00Z',
|
|
},
|
|
],
|
|
}),
|
|
{ status: 200, headers: { 'Content-Type': 'application/json' } },
|
|
),
|
|
);
|
|
vi.stubGlobal('fetch', fetchMock);
|
|
|
|
const deployments = await listDeployments();
|
|
|
|
expect(deployments).toHaveLength(1);
|
|
expect(fetchMock).toHaveBeenCalledWith(
|
|
'/api/preview-deployer/deployments',
|
|
expect.objectContaining({ credentials: 'same-origin' }),
|
|
);
|
|
});
|
|
|
|
test('uses an http-only session without browser token persistence', async () => {
|
|
const fetchMock = vi
|
|
.fn()
|
|
.mockImplementation((_url: string, init: RequestInit) =>
|
|
Promise.resolve(
|
|
new Response(
|
|
init.method === 'DELETE'
|
|
? null
|
|
: JSON.stringify({ authenticated: true }),
|
|
{ status: 200, headers: { 'Content-Type': 'application/json' } },
|
|
),
|
|
),
|
|
);
|
|
vi.stubGlobal('fetch', fetchMock);
|
|
|
|
expect(await getSession()).toEqual({ authenticated: true });
|
|
await createSession('team-access-token');
|
|
await deleteSession();
|
|
|
|
expect(fetchMock).toHaveBeenNthCalledWith(
|
|
2,
|
|
'/api/preview-deployer/session',
|
|
expect.objectContaining({
|
|
method: 'POST',
|
|
credentials: 'same-origin',
|
|
body: JSON.stringify({ accessToken: 'team-access-token' }),
|
|
}),
|
|
);
|
|
expect(fetchMock).toHaveBeenNthCalledWith(
|
|
3,
|
|
'/api/preview-deployer/session',
|
|
expect.objectContaining({ method: 'DELETE' }),
|
|
);
|
|
});
|
|
|
|
test('submits only branch and optional commit to fixed endpoints', async () => {
|
|
const buildResponse = () =>
|
|
new Response(
|
|
JSON.stringify({
|
|
id: 'preview-2',
|
|
branch: 'master',
|
|
status: 'queued',
|
|
health: 'pending',
|
|
createdAt: '2026-08-15T00:00:00Z',
|
|
updatedAt: '2026-08-15T00:00:00Z',
|
|
}),
|
|
{ status: 200, headers: { 'Content-Type': 'application/json' } },
|
|
);
|
|
const fetchMock = vi
|
|
.fn()
|
|
.mockImplementation(() => Promise.resolve(buildResponse()));
|
|
vi.stubGlobal('fetch', fetchMock);
|
|
|
|
await createDeployment({ branch: 'master', commitHash: 'aa5221abc' });
|
|
await uninstallDeployment('preview/2');
|
|
|
|
expect(fetchMock).toHaveBeenNthCalledWith(
|
|
1,
|
|
'/api/preview-deployer/deployments',
|
|
expect.objectContaining({
|
|
method: 'POST',
|
|
body: JSON.stringify({ branch: 'master', commitHash: 'aa5221abc' }),
|
|
}),
|
|
);
|
|
expect(fetchMock).toHaveBeenNthCalledWith(
|
|
2,
|
|
'/api/preview-deployer/deployments/preview%2F2/uninstall',
|
|
expect.objectContaining({ method: 'POST' }),
|
|
);
|
|
});
|
|
|
|
test('searches branches and branch-scoped commits with encoded queries', async () => {
|
|
const fetchMock = vi
|
|
.fn()
|
|
.mockResolvedValueOnce(
|
|
new Response(
|
|
JSON.stringify({
|
|
items: [{ name: 'feature/search', commitHash: 'abcdef123456' }],
|
|
}),
|
|
{ status: 200, headers: { 'Content-Type': 'application/json' } },
|
|
),
|
|
)
|
|
.mockResolvedValueOnce(
|
|
new Response(
|
|
JSON.stringify({
|
|
items: [
|
|
{
|
|
commitHash: 'abcdef123456',
|
|
shortHash: 'abcdef1',
|
|
subject: '搜索提交',
|
|
},
|
|
],
|
|
}),
|
|
{ status: 200, headers: { 'Content-Type': 'application/json' } },
|
|
),
|
|
);
|
|
vi.stubGlobal('fetch', fetchMock);
|
|
|
|
expect(await searchBranches('feature/search')).toHaveLength(1);
|
|
expect(await searchCommits('feature/search', 'abc def')).toHaveLength(1);
|
|
|
|
expect(fetchMock).toHaveBeenNthCalledWith(
|
|
1,
|
|
'/api/preview-deployer/refs/branches?q=feature%2Fsearch',
|
|
expect.objectContaining({ credentials: 'same-origin' }),
|
|
);
|
|
expect(fetchMock).toHaveBeenNthCalledWith(
|
|
2,
|
|
'/api/preview-deployer/refs/commits?branch=feature%2Fsearch&q=abc%20def',
|
|
expect.objectContaining({ credentials: 'same-origin' }),
|
|
);
|
|
});
|