import { describe, it, expect, beforeEach, afterEach, jest } from '@jest/globals';
import { render, screen, waitFor } from '@testing-library/react';
import '@testing-library/jest-dom';
import { ServicesSection } from './services-section';
jest.mock('framer-motion', () => ({
motion: {
div: ({ children, ...props }: any) =>
{children}
,
},
useInView: () => true,
}));
jest.mock('next/link', () => {
return ({ children, href }: any) => {children};
});
jest.mock('@/hooks/use-services', () => ({
useServices: jest.fn(),
}));
const { useServices } = require('@/hooks/use-services');
describe('ServicesSection Integration', () => {
beforeEach(() => {
jest.clearAllMocks();
});
afterEach(() => {
jest.restoreAllMocks();
});
describe('Data Loading States', () => {
it('should show loading state when data is loading', () => {
useServices.mockReturnValue({
services: [],
loading: true,
error: null,
refetch: jest.fn(),
});
render();
expect(screen.getByText('加载中...')).toBeInTheDocument();
});
it('should render services when data is loaded successfully', async () => {
const mockServices = [
{
id: '1',
title: '测试服务1',
description: '这是一个测试服务',
icon: 'Code',
},
{
id: '2',
title: '测试服务2',
description: '这是另一个测试服务',
icon: 'Cloud',
},
];
useServices.mockReturnValue({
services: mockServices,
loading: false,
error: null,
refetch: jest.fn(),
});
render();
await waitFor(() => {
expect(screen.getByText('测试服务1')).toBeInTheDocument();
expect(screen.getByText('测试服务2')).toBeInTheDocument();
});
});
it('should show error message when data loading fails', async () => {
useServices.mockReturnValue({
services: [],
loading: false,
error: new Error('Failed to load services'),
refetch: jest.fn(),
});
render();
await waitFor(() => {
expect(screen.getByText('加载服务信息失败,请稍后重试')).toBeInTheDocument();
});
});
it('should show empty state when no services are available', async () => {
useServices.mockReturnValue({
services: [],
loading: false,
error: null,
refetch: jest.fn(),
});
render();
await waitFor(() => {
expect(screen.getByText('暂无服务信息')).toBeInTheDocument();
});
});
});
describe('Service Display', () => {
it('should render all services from API', async () => {
const mockServices = [
{
id: '1',
title: '服务A',
description: '描述A',
icon: 'Code',
},
{
id: '2',
title: '服务B',
description: '描述B',
icon: 'Cloud',
},
{
id: '3',
title: '服务C',
description: '描述C',
icon: 'BarChart3',
},
];
useServices.mockReturnValue({
services: mockServices,
loading: false,
error: null,
refetch: jest.fn(),
});
render();
await waitFor(() => {
expect(screen.getByText('服务A')).toBeInTheDocument();
expect(screen.getByText('服务B')).toBeInTheDocument();
expect(screen.getByText('服务C')).toBeInTheDocument();
});
});
it('should display service descriptions', async () => {
const mockServices = [
{
id: '1',
title: '服务A',
description: '这是一个专业的软件开发服务',
icon: 'Code',
},
];
useServices.mockReturnValue({
services: mockServices,
loading: false,
error: null,
refetch: jest.fn(),
});
render();
await waitFor(() => {
expect(screen.getByText('这是一个专业的软件开发服务')).toBeInTheDocument();
});
});
it('should display service icons', async () => {
const mockServices = [
{
id: '1',
title: '服务A',
description: '描述A',
icon: 'Code',
},
];
useServices.mockReturnValue({
services: mockServices,
loading: false,
error: null,
refetch: jest.fn(),
});
render();
await waitFor(() => {
const icons = document.querySelectorAll('svg');
expect(icons.length).toBeGreaterThan(0);
});
});
});
describe('Service Filtering', () => {
it('should filter services by items config', async () => {
const mockServices = [
{
id: '1',
title: '服务A',
description: '描述A',
icon: 'Code',
},
{
id: '2',
title: '服务B',
description: '描述B',
icon: 'Cloud',
},
{
id: '3',
title: '服务C',
description: '描述C',
icon: 'BarChart3',
},
];
useServices.mockReturnValue({
services: mockServices,
loading: false,
error: null,
refetch: jest.fn(),
});
render();
await waitFor(() => {
expect(screen.getByText('服务A')).toBeInTheDocument();
expect(screen.getByText('服务C')).toBeInTheDocument();
expect(screen.queryByText('服务B')).not.toBeInTheDocument();
});
});
it('should show all services when no items config is provided', async () => {
const mockServices = [
{
id: '1',
title: '服务A',
description: '描述A',
icon: 'Code',
},
{
id: '2',
title: '服务B',
description: '描述B',
icon: 'Cloud',
},
];
useServices.mockReturnValue({
services: mockServices,
loading: false,
error: null,
refetch: jest.fn(),
});
render();
await waitFor(() => {
expect(screen.getByText('服务A')).toBeInTheDocument();
expect(screen.getByText('服务B')).toBeInTheDocument();
});
});
});
describe('Navigation', () => {
it('should link to service detail pages', async () => {
const mockServices = [
{
id: '1',
title: '服务A',
description: '描述A',
icon: 'Code',
},
];
useServices.mockReturnValue({
services: mockServices,
loading: false,
error: null,
refetch: jest.fn(),
});
render();
await waitFor(() => {
const serviceLink = screen.getByRole('link', { name: /服务A/ });
expect(serviceLink).toHaveAttribute('href', '/services/1');
});
});
it('should link to all services page', async () => {
const mockServices = [
{
id: '1',
title: '服务A',
description: '描述A',
icon: 'Code',
},
];
useServices.mockReturnValue({
services: mockServices,
loading: false,
error: null,
refetch: jest.fn(),
});
render();
await waitFor(() => {
const allServicesLink = screen.getByRole('link', { name: /查看全部服务/ });
expect(allServicesLink).toHaveAttribute('href', '/services');
});
});
});
describe('Accessibility', () => {
it('should maintain accessibility with dynamic data', async () => {
const mockServices = [
{
id: '1',
title: '服务A',
description: '描述A',
icon: 'Code',
},
];
useServices.mockReturnValue({
services: mockServices,
loading: false,
error: null,
refetch: jest.fn(),
});
render();
await waitFor(() => {
const section = screen.getByRole('region');
expect(section).toBeInTheDocument();
expect(section).toHaveAttribute('aria-labelledby', 'services-heading');
});
});
});
});