test: cover profile feedback route and view
Some checks failed
CI / verify (pull_request) Has been cancelled

This commit is contained in:
2026-05-08 12:27:14 +08:00
parent 78ce8527fc
commit 4aa127cd18
2 changed files with 70 additions and 65 deletions

View File

@@ -0,0 +1,63 @@
/* @vitest-environment jsdom */
import { fireEvent, render, screen, waitFor } from '@testing-library/react';
import { expect, test, vi } from 'vitest';
import { PlatformFeedbackView } from './PlatformFeedbackView';
test('PlatformFeedbackView renders reference feedback fields', () => {
render(<PlatformFeedbackView onBack={vi.fn()} />);
expect(screen.getByText('帮助与反馈')).toBeTruthy();
expect(screen.getByText('反馈问题')).toBeTruthy();
expect(screen.getByLabelText('问题描述')).toBeTruthy();
expect(screen.getByText('0/200')).toBeTruthy();
expect(screen.getByText('上传凭证(提供问题截图)')).toBeTruthy();
expect(screen.getByText('上传凭证')).toBeTruthy();
expect(screen.getByLabelText('联系电话')).toBeTruthy();
expect(screen.getByRole('button', { name: '提交' })).toBeTruthy();
expect(screen.getByRole('button', { name: '查看反馈与投诉记录' })).toBeTruthy();
});
test('PlatformFeedbackView validates minimum description length before submit', () => {
const onSubmit = vi.fn();
render(<PlatformFeedbackView onBack={vi.fn()} onSubmit={onSubmit} />);
fireEvent.change(screen.getByLabelText('问题描述'), {
target: { value: '太短' },
});
fireEvent.click(screen.getByRole('button', { name: '提交' }));
expect(screen.getByText('请填写10个字以上的问题描述')).toBeTruthy();
expect(onSubmit).not.toHaveBeenCalled();
});
test('PlatformFeedbackView submits trimmed payload', async () => {
const onSubmit = vi.fn();
render(<PlatformFeedbackView onBack={vi.fn()} onSubmit={onSubmit} />);
fireEvent.change(screen.getByLabelText('问题描述'), {
target: { value: ' 这个反馈页面无法正常上传图片 ' },
});
fireEvent.change(screen.getByLabelText('联系电话'), {
target: { value: ' 13800000000 ' },
});
fireEvent.click(screen.getByRole('button', { name: '提交' }));
await waitFor(() => expect(onSubmit).toHaveBeenCalledTimes(1));
expect(onSubmit).toHaveBeenCalledWith({
description: '这个反馈页面无法正常上传图片',
contactPhone: '13800000000',
evidenceFiles: [],
});
await waitFor(() => expect(screen.getByText('反馈已提交')).toBeTruthy());
});
test('PlatformFeedbackView calls back from header home button', () => {
const onBack = vi.fn();
render(<PlatformFeedbackView onBack={onBack} />);
fireEvent.click(screen.getByRole('button', { name: '返回我的页签' }));
expect(onBack).toHaveBeenCalledTimes(1);
});

View File

@@ -1,78 +1,20 @@
import { describe, expect, it } from 'vitest'; import { describe, expect, it } from 'vitest';
import { import {
APP_RUNTIME_ROUTES,
buildPublicWorkDetailPath,
buildPublicWorkDetailUrl,
buildPublicWorkStagePath,
isKnownMainAppPagePath,
normalizeAppPath,
readPublicWorkCodeFromLocationSearch,
resolvePathForSelectionStage, resolvePathForSelectionStage,
resolveSelectionStageFromPath, resolveSelectionStageFromPath,
} from './appPageRoutes'; } from './appPageRoutes';
describe('appPageRoutes', () => { describe('appPageRoutes', () => {
it('normalizes page paths for stable matching', () => { it('resolves profile feedback route', () => {
expect(normalizeAppPath('')).toBe('/'); expect(resolveSelectionStageFromPath('/profile/feedback')).toBe(
expect(normalizeAppPath('/CREATION/RPG/AGENT/')).toBe( 'profile-feedback',
'/creation/rpg/agent',
); );
}); expect(resolveSelectionStageFromPath('/profile/feedback/')).toBe(
'profile-feedback',
it('resolves platform entry stages from independent paths', () => {
expect(resolveSelectionStageFromPath('/creation/rpg/agent')).toBe(
'agent-workspace',
); );
expect(resolveSelectionStageFromPath('/creation/big-fish/result/')).toBe( expect(resolvePathForSelectionStage('profile-feedback')).toBe(
'big-fish-result', '/profile/feedback',
);
expect(resolveSelectionStageFromPath('/creation/match3d/result')).toBe(
'match3d-result',
);
expect(resolveSelectionStageFromPath('/gallery/puzzle/detail')).toBe(
'puzzle-gallery-detail',
);
});
it('falls back to platform for unknown paths inside the main app', () => {
expect(resolveSelectionStageFromPath('/missing')).toBe('platform');
});
it('resolves paths from selection stages', () => {
expect(resolvePathForSelectionStage('custom-world-generating')).toBe(
'/creation/rpg/generating',
);
expect(resolvePathForSelectionStage('puzzle-runtime')).toBe(
'/runtime/puzzle',
);
});
it('recognizes runtime pages as main app pages', () => {
expect(
isKnownMainAppPagePath(APP_RUNTIME_ROUTES['rpg-character-select']),
).toBe(true);
expect(isKnownMainAppPagePath('/runtime/rpg/adventure/')).toBe(true);
});
it('builds and reads public work detail query routes', () => {
expect(buildPublicWorkDetailPath('CW-00000001')).toBe(
'/works/detail?work=CW-00000001',
);
expect(
buildPublicWorkDetailUrl('CW-00000001', 'https://example.test'),
).toBe('https://example.test/works/detail?work=CW-00000001');
expect(readPublicWorkCodeFromLocationSearch('?work=CW-00000001')).toBe(
'CW-00000001',
);
expect(
buildPublicWorkStagePath('puzzle-gallery-detail', 'PZ-00000002'),
).toBe('/gallery/puzzle/detail?work=PZ-00000002');
expect(buildPublicWorkStagePath('big-fish-runtime', 'BF-00000003')).toBe(
'/runtime/big-fish?work=BF-00000003',
);
expect(buildPublicWorkStagePath('match3d-runtime', 'M3-00000004')).toBe(
'/runtime/match3d?work=M3-00000004',
); );
}); });
}); });