test: cover profile feedback route and view
Some checks failed
CI / verify (pull_request) Has been cancelled
Some checks failed
CI / verify (pull_request) Has been cancelled
This commit is contained in:
63
src/components/platform-entry/PlatformFeedbackView.test.tsx
Normal file
63
src/components/platform-entry/PlatformFeedbackView.test.tsx
Normal 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);
|
||||||
|
});
|
||||||
@@ -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',
|
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user