chore: sync marketing pages, CMS extensions, tests and project docs
同步工作区剩余变更,主要包括: - 营销页面组件与布局持续优化(about/news/services/solutions/team 等) - 详情页四层叙事组件、布局组件、UI 组件调整 - CMS 数据模型、API 路由、权限、工作流、站内通知、媒体管理扩展 - 新增/补充单元测试与 E2E 测试(cms-workflow.spec.ts 等) - ESLint 9 迁移、jest/tsconfig 配置更新、依赖调整 - 新增 ADR、CMS 评估文档、Release Review / Acceptance 报告 - 移除水墨装饰组件与大体积未使用字体文件
This commit is contained in:
@@ -0,0 +1,96 @@
|
||||
import { render, screen } from '@testing-library/react';
|
||||
import '@testing-library/jest-dom';
|
||||
import ServicesPage from './page';
|
||||
|
||||
jest.mock('@/lib/cms/data-server', () => ({
|
||||
getPublishedItems: jest.fn(),
|
||||
}));
|
||||
|
||||
jest.mock('./services-content-v3', () => ({
|
||||
__esModule: true,
|
||||
default: function MockServicesContentV3({ services }: { services: Array<{ id: string; title: string }> }) {
|
||||
return (
|
||||
<div data-testid="services-content">
|
||||
{services.map((item) => (
|
||||
<div key={item.id} data-testid="service-item">{item.title}</div>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
},
|
||||
}));
|
||||
|
||||
import { getPublishedItems } from '@/lib/cms/data-server';
|
||||
const mockedGetPublishedItems = getPublishedItems as jest.MockedFunction<typeof getPublishedItems>;
|
||||
|
||||
const createMockService = (topOverrides: Record<string, unknown> = {}, dataOverrides: Record<string, unknown> = {}) => ({
|
||||
id: 'item-1',
|
||||
modelId: 'model-service',
|
||||
modelCode: 'service',
|
||||
title: '测试服务',
|
||||
slug: 'test-service',
|
||||
locale: 'zh-CN',
|
||||
status: 'published',
|
||||
data: {
|
||||
id: 'test-service',
|
||||
slug: 'test-service',
|
||||
title: '测试服务',
|
||||
description: '测试服务描述',
|
||||
icon: 'Lightbulb',
|
||||
overview: '测试服务概述',
|
||||
features: ['能力一:描述一'],
|
||||
benefits: ['价值一'],
|
||||
capabilities: ['能力一'],
|
||||
process: ['步骤一:描述一'],
|
||||
heroThemeId: 'service',
|
||||
caseStudies: [],
|
||||
dataProofs: [],
|
||||
...dataOverrides,
|
||||
},
|
||||
version: 1,
|
||||
sortOrder: 0,
|
||||
createdBy: 'system',
|
||||
updatedBy: 'system',
|
||||
createdAt: new Date().toISOString(),
|
||||
updatedAt: new Date().toISOString(),
|
||||
...topOverrides,
|
||||
});
|
||||
|
||||
describe('ServicesPage', () => {
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks();
|
||||
mockedGetPublishedItems.mockResolvedValue([]);
|
||||
});
|
||||
|
||||
it('renders empty state when no CMS service items exist', async () => {
|
||||
const page = await ServicesPage();
|
||||
render(page);
|
||||
|
||||
expect(screen.getByTestId('services-content')).toBeInTheDocument();
|
||||
expect(screen.queryByTestId('service-item')).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('maps CMS items to Service shape', async () => {
|
||||
mockedGetPublishedItems.mockResolvedValue([
|
||||
createMockService(),
|
||||
] as unknown as Awaited<ReturnType<typeof getPublishedItems>>);
|
||||
|
||||
const page = await ServicesPage();
|
||||
render(page);
|
||||
|
||||
expect(screen.getByText('测试服务')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('falls back to item.title when data.title is missing', async () => {
|
||||
mockedGetPublishedItems.mockResolvedValue([
|
||||
createMockService(
|
||||
{ title: 'Fallback Title' },
|
||||
{ title: undefined },
|
||||
),
|
||||
] as unknown as Awaited<ReturnType<typeof getPublishedItems>>);
|
||||
|
||||
const page = await ServicesPage();
|
||||
render(page);
|
||||
|
||||
expect(screen.getByText('Fallback Title')).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user