Files
Genarrative/apps/preview-deployer-web/src/PreviewDeployerApp.test.tsx
T
kdletters ced4b56dee
Project CI / Repository checks (push) Successful in 1m22s
Project CI / Frontend tests (push) Successful in 2m55s
Project CI / Backend tests (push) Successful in 3m56s
Project CI / Native shell tests (push) Successful in 14m7s
优化预览发布记录展示
发布记录增加后端校验后的 Web 端口号

列表隐藏已成功卸载的容器记录

兼容恢复旧运行记录并回填 Web 端口

补充后端、前端测试和技术说明
2026-08-17 10:47:58 +08:00

111 lines
3.3 KiB
TypeScript

/* @vitest-environment jsdom */
import {
cleanup,
fireEvent,
render,
screen,
waitFor,
} from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { afterEach, beforeEach, expect, test, vi } from 'vitest';
import * as api from './api';
import { PreviewDeployerApp } from './PreviewDeployerApp';
vi.mock('./api');
afterEach(() => {
cleanup();
});
beforeEach(() => {
vi.mocked(api.getSession).mockResolvedValue({ authenticated: true });
vi.mocked(api.createSession).mockResolvedValue({ authenticated: true });
vi.mocked(api.deleteSession).mockResolvedValue(undefined);
vi.mocked(api.listDeployments).mockResolvedValue([]);
vi.mocked(api.createDeployment).mockResolvedValue({
id: 'preview-1',
branch: 'master',
status: 'queued',
health: 'pending',
createdAt: '2026-08-15T00:00:00Z',
updatedAt: '2026-08-15T00:00:00Z',
});
vi.mocked(api.uninstallDeployment).mockResolvedValue({
id: 'preview-1',
branch: 'master',
status: 'uninstalling',
health: 'pending',
createdAt: '2026-08-15T00:00:00Z',
updatedAt: '2026-08-15T00:02:00Z',
});
});
test('requires an access token before showing deployments', async () => {
const user = userEvent.setup();
vi.mocked(api.getSession).mockResolvedValue({ authenticated: false });
render(<PreviewDeployerApp />);
expect(await screen.findByText('访问口令')).toBeTruthy();
await user.type(screen.getByPlaceholderText('请输入访问口令'), 'team-token');
await user.click(screen.getByRole('button', { name: '进入发布面板' }));
await waitFor(() => {
expect(api.createSession).toHaveBeenCalledWith('team-token');
});
expect(await screen.findByText('构建并发布一个分支')).toBeTruthy();
});
test('submits a branch with an optional commit hash', async () => {
const user = userEvent.setup();
render(<PreviewDeployerApp />);
const branchInput = await screen.findByPlaceholderText('master');
await user.clear(branchInput);
await user.type(branchInput, 'feature/preview');
await user.type(
screen.getByPlaceholderText('留空则构建分支最新提交'),
'aa5221abc',
);
await user.click(screen.getByRole('button', { name: '开始构建' }));
await waitFor(() => {
expect(api.createDeployment).toHaveBeenCalledWith({
branch: 'feature/preview',
commitHash: 'aa5221abc',
});
});
});
test('shows health and web url, then confirms uninstall', async () => {
vi.mocked(api.listDeployments).mockResolvedValue([
{
id: 'preview-2',
branch: 'feature/demo',
resolvedCommit: '1234567890abcdef',
status: 'running',
health: 'healthy',
webPort: 8400,
webUrl: 'http://192.168.35.82:8400',
createdAt: 1_787_270_400,
updatedAt: 1_787_270_460,
},
]);
render(<PreviewDeployerApp />);
expect(await screen.findByText('健康')).toBeTruthy();
expect(screen.getByText('端口 8400')).toBeTruthy();
expect(
screen.getByRole('link', { name: /打开 Web/u }).getAttribute('href'),
).toBe('http://192.168.35.82:8400');
fireEvent.click(screen.getByRole('button', { name: '卸载' }));
expect(screen.getByRole('dialog')).toBeTruthy();
fireEvent.click(screen.getByRole('button', { name: '确认卸载' }));
await waitFor(() => {
expect(api.uninstallDeployment).toHaveBeenCalledWith('preview-2');
});
});