ebaa7f3c50
ci/woodpecker/manual/woodpecker Pipeline was successful
- 移除未使用的YAML锚点定义 - 替换commands字段中的锚点引用为实际值 - 移除有问题的通知步骤 - 修复测试文件中的问题 - 添加新的测试用例和配置文件
172 lines
4.7 KiB
TypeScript
172 lines
4.7 KiB
TypeScript
import { describe, it, expect, jest, beforeEach } from '@jest/globals';
|
|
import { render, screen, waitFor } from '@testing-library/react';
|
|
import '@testing-library/jest-dom';
|
|
|
|
jest.mock('framer-motion', () => ({
|
|
motion: {
|
|
div: ({ children, className, ...props }: any) => (
|
|
<div className={className} {...props}>
|
|
{children}
|
|
</div>
|
|
),
|
|
section: ({ children, className, ...props }: any) => (
|
|
<section className={className} {...props}>
|
|
{children}
|
|
</section>
|
|
),
|
|
},
|
|
AnimatePresence: ({ children }: any) => <>{children}</>,
|
|
useInView: () => [null, true],
|
|
}));
|
|
|
|
jest.mock('next/link', () => {
|
|
return ({ children, href, ...props }: any) => (
|
|
<a href={href} {...props}>
|
|
{children}
|
|
</a>
|
|
);
|
|
});
|
|
|
|
jest.mock('lucide-react', () => ({
|
|
ArrowRight: () => <span data-testid="arrow-right-icon" />,
|
|
ArrowLeft: () => <span data-testid="arrow-left-icon" />,
|
|
Code: () => <span data-testid="code-icon" />,
|
|
Cloud: () => <span data-testid="cloud-icon" />,
|
|
BarChart3: () => <span data-testid="bar-chart-icon" />,
|
|
Shield: () => <span data-testid="shield-icon" />,
|
|
Search: () => <span data-testid="search-icon" />,
|
|
ChevronLeft: () => <span data-testid="chevron-left-icon" />,
|
|
ChevronRight: () => <span data-testid="chevron-right-icon" />,
|
|
Filter: () => <span data-testid="filter-icon" />,
|
|
}));
|
|
|
|
jest.mock('@/components/ui/button', () => ({
|
|
Button: ({ children, className, ...props }: any) => (
|
|
<button className={className} {...props}>
|
|
{children}
|
|
</button>
|
|
),
|
|
}));
|
|
|
|
jest.mock('@/components/ui/badge', () => ({
|
|
Badge: ({ children, className, ...props }: any) => (
|
|
<span className={className} {...props}>
|
|
{children}
|
|
</span>
|
|
),
|
|
}));
|
|
|
|
jest.mock('@/components/ui/input', () => ({
|
|
Input: ({ className, ...props }: any) => (
|
|
<input className={className} {...props} />
|
|
),
|
|
}));
|
|
|
|
jest.mock('@/components/ui/loading-skeleton', () => ({
|
|
ServiceCardSkeleton: () => <div data-testid="service-card-skeleton">Loading...</div>,
|
|
}));
|
|
|
|
jest.mock('@/components/ui/page-header', () => ({
|
|
PageHeader: ({ title, description }: any) => (
|
|
<header>
|
|
<h1>{title}</h1>
|
|
<p>{description}</p>
|
|
</header>
|
|
),
|
|
}));
|
|
|
|
const mockServices = [
|
|
{
|
|
id: 'software-dev',
|
|
title: '软件开发',
|
|
icon: 'Code',
|
|
description: '定制化软件开发服务',
|
|
features: ['需求分析', '架构设计', '开发测试', '运维支持'],
|
|
},
|
|
{
|
|
id: 'cloud-service',
|
|
title: '云服务',
|
|
icon: 'Cloud',
|
|
description: '企业云服务解决方案',
|
|
features: ['云迁移', '云原生', '云安全', '云运维'],
|
|
},
|
|
];
|
|
|
|
jest.mock('@/hooks/use-services', () => ({
|
|
useServices: () => ({
|
|
services: mockServices,
|
|
loading: false,
|
|
error: null,
|
|
}),
|
|
}));
|
|
|
|
import ServicesPage from './page';
|
|
|
|
describe('ServicesPage', () => {
|
|
beforeEach(() => {
|
|
jest.clearAllMocks();
|
|
});
|
|
|
|
describe('Rendering', () => {
|
|
it('should render services page', async () => {
|
|
const { container } = render(<ServicesPage />);
|
|
await waitFor(() => {
|
|
const pageContainer = container.querySelector('.min-h-screen');
|
|
expect(pageContainer).toBeInTheDocument();
|
|
});
|
|
});
|
|
|
|
it('should render page header', async () => {
|
|
render(<ServicesPage />);
|
|
await waitFor(() => {
|
|
const title = screen.getByText(/核心业务/i);
|
|
expect(title).toBeInTheDocument();
|
|
});
|
|
});
|
|
|
|
it('should render back to home link', async () => {
|
|
render(<ServicesPage />);
|
|
await waitFor(() => {
|
|
const backLink = screen.getByText(/返回首页/i);
|
|
expect(backLink).toBeInTheDocument();
|
|
});
|
|
});
|
|
|
|
it('should render loading skeletons initially', async () => {
|
|
render(<ServicesPage />);
|
|
await waitFor(() => {
|
|
const pageContainer = screen.queryByText('加载中...');
|
|
expect(pageContainer).not.toBeInTheDocument();
|
|
});
|
|
});
|
|
|
|
it('should render CTA section', async () => {
|
|
render(<ServicesPage />);
|
|
await waitFor(() => {
|
|
const cta = screen.getByText(/准备开始您的数字化转型之旅/i);
|
|
expect(cta).toBeInTheDocument();
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('Navigation', () => {
|
|
it('should have contact link', async () => {
|
|
render(<ServicesPage />);
|
|
await waitFor(() => {
|
|
const contactLink = screen.getByRole('link', { name: /立即咨询/i });
|
|
expect(contactLink).toHaveAttribute('href', '/contact');
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('Accessibility', () => {
|
|
it('should have proper heading hierarchy', async () => {
|
|
render(<ServicesPage />);
|
|
await waitFor(() => {
|
|
const h1 = screen.getByRole('heading', { level: 1 });
|
|
expect(h1).toBeInTheDocument();
|
|
});
|
|
});
|
|
});
|
|
});
|