fix: 修复Woodpecker CI配置文件中的linter错误
ci/woodpecker/manual/woodpecker Pipeline was successful

- 移除未使用的YAML锚点定义
- 替换commands字段中的锚点引用为实际值
- 移除有问题的通知步骤
- 修复测试文件中的问题
- 添加新的测试用例和配置文件
This commit is contained in:
张翔
2026-03-28 09:42:45 +08:00
parent a5ee6489a1
commit ebaa7f3c50
53 changed files with 4564 additions and 818 deletions
+88 -51
View File
@@ -1,5 +1,5 @@
import { describe, it, expect, jest, beforeAll } from '@jest/globals';
import { render, screen, fireEvent } from '@testing-library/react';
import { describe, it, expect, jest, beforeAll, beforeEach } from '@jest/globals';
import { render, screen, fireEvent, waitFor } from '@testing-library/react';
import '@testing-library/jest-dom';
jest.mock('framer-motion', () => ({
@@ -33,6 +33,8 @@ jest.mock('lucide-react', () => ({
ArrowRight: () => <span data-testid="arrow-right-icon" />,
ArrowLeft: () => <span data-testid="arrow-left-icon" />,
Filter: () => <span data-testid="filter-icon" />,
ChevronLeft: () => <span data-testid="chevron-left-icon" />,
ChevronRight: () => <span data-testid="chevron-right-icon" />,
}));
jest.mock('@/components/ui/button', () => ({
@@ -79,23 +81,33 @@ jest.mock('@/components/ui/page-header', () => ({
),
}));
jest.mock('@/lib/constants', () => ({
NEWS: [
{
id: 'news-1',
title: '公司成立新闻',
category: '公司新闻',
date: '2026-01-15',
excerpt: '公司正式成立,开启数字化转型之旅',
},
{
id: 'news-2',
title: '产品发布新闻',
category: '产品发布',
date: '2026-02-01',
excerpt: '新产品正式发布',
},
],
const mockNews = [
{
id: 'news-1',
title: '公司成立新闻',
category: '公司新闻',
date: '2026-01-15',
excerpt: '公司正式成立,开启数字化转型之旅',
content: '详细内容',
slug: 'company-founded',
},
{
id: 'news-2',
title: '产品发布新闻',
category: '产品发布',
date: '2026-02-01',
excerpt: '新产品正式发布',
content: '详细内容',
slug: 'product-released',
},
];
jest.mock('@/hooks/use-news', () => ({
useNews: () => ({
news: mockNews,
loading: false,
error: null,
}),
}));
import NewsListPage from './page';
@@ -112,71 +124,96 @@ describe('NewsListPage', () => {
expect(pageContainer).toBeInTheDocument();
});
it('should render page header', () => {
it('should render page header', async () => {
render(<NewsListPage />);
const title = screen.getByText(/新闻动态/i);
expect(title).toBeInTheDocument();
await waitFor(() => {
const title = screen.getByText(/新闻动态/i);
expect(title).toBeInTheDocument();
});
});
it('should render back to home link', () => {
it('should render back to home link', async () => {
render(<NewsListPage />);
const backLink = screen.getByText(/返回首页/i);
expect(backLink).toBeInTheDocument();
await waitFor(() => {
const backLink = screen.getByText(/返回首页/i);
expect(backLink).toBeInTheDocument();
});
});
it('should render news cards', () => {
it('should render news cards', async () => {
render(<NewsListPage />);
const newsCards = screen.getAllByRole('heading', { level: 3 });
expect(newsCards.length).toBeGreaterThan(0);
await waitFor(() => {
const headings = screen.getAllByRole('heading');
const newsCards = headings.filter(h => h.tagName === 'H3');
expect(newsCards.length).toBeGreaterThan(0);
});
});
it('should render category filter', () => {
it('should render category filter', async () => {
render(<NewsListPage />);
const filterLabel = screen.getByText(/分类筛选/i);
expect(filterLabel).toBeInTheDocument();
await waitFor(() => {
const allButton = screen.getByRole('button', { name: '全部' });
expect(allButton).toBeInTheDocument();
});
});
it('should render search input', () => {
it('should render search input', async () => {
render(<NewsListPage />);
const searchInput = screen.getByPlaceholderText(/搜索新闻/i);
expect(searchInput).toBeInTheDocument();
await waitFor(() => {
const searchInput = screen.getByPlaceholderText(/搜索新闻/i);
expect(searchInput).toBeInTheDocument();
});
});
});
describe('Filtering', () => {
it('should filter news by category', () => {
it('should filter news by category', async () => {
render(<NewsListPage />);
const companyNewsButton = screen.getByRole('button', { name: '公司新闻' });
fireEvent.click(companyNewsButton);
await waitFor(() => {
const companyNewsButton = screen.getByRole('button', { name: '公司新闻' });
fireEvent.click(companyNewsButton);
});
const newsCards = screen.getAllByRole('heading', { level: 3 });
expect(newsCards.length).toBe(1);
await waitFor(() => {
const headings = screen.getAllByRole('heading');
const newsCards = headings.filter(h => h.tagName === 'H3');
expect(newsCards.length).toBe(1);
});
});
it('should filter news by search query', () => {
it('should filter news by search query', async () => {
render(<NewsListPage />);
const searchInput = screen.getByPlaceholderText(/搜索新闻/i);
fireEvent.change(searchInput, { target: { value: '成立' } });
await waitFor(() => {
const searchInput = screen.getByPlaceholderText(/搜索新闻/i);
fireEvent.change(searchInput, { target: { value: '成立' } });
});
const newsCards = screen.getAllByRole('heading', { level: 3 });
expect(newsCards.length).toBe(1);
await waitFor(() => {
const headings = screen.getAllByRole('heading');
const newsCards = headings.filter(h => h.tagName === 'H3');
expect(newsCards.length).toBe(1);
});
});
});
describe('Navigation', () => {
it('should have news detail links', () => {
it('should have news detail links', async () => {
render(<NewsListPage />);
const links = screen.getAllByRole('link');
const newsLinks = links.filter(link => link.getAttribute('href')?.startsWith('/news/'));
expect(newsLinks.length).toBeGreaterThan(0);
await waitFor(() => {
const links = screen.getAllByRole('link');
const newsLinks = links.filter(link => link.getAttribute('href')?.startsWith('/news/'));
expect(newsLinks.length).toBeGreaterThan(0);
});
});
});
describe('Accessibility', () => {
it('should have proper heading hierarchy', () => {
it('should have proper heading hierarchy', async () => {
render(<NewsListPage />);
const h1 = screen.getByRole('heading', { level: 1 });
expect(h1).toBeInTheDocument();
await waitFor(() => {
const h1 = screen.getByRole('heading', { level: 1 });
expect(h1).toBeInTheDocument();
});
});
});
});
+1 -1
View File
@@ -147,7 +147,7 @@ export default function NewsListPage() {
animate={isContentInView ? { opacity: 1, y: 0 } : {}}
transition={{ duration: 0.5, delay: 0.2 + index * 0.1 }}
>
<Link href={`/news/${newsItem.slug}`}>
<Link href={`/news/${newsItem.id}`}>
<Card className="h-full hover:shadow-lg transition-shadow cursor-pointer border-[#E5E5E5] hover:border-[#C41E3A]">
<CardContent className="p-0">
{newsItem.image ? (