11
Some checks failed
CI / verify (push) Has been cancelled

This commit is contained in:
2026-04-16 21:47:20 +08:00
parent 2456c10c63
commit 09d4c0c31b
79 changed files with 11873 additions and 2341 deletions

View File

@@ -12,12 +12,18 @@ import {
getCustomWorldAgentOperation,
getCustomWorldAgentSession,
} from '../../services/aiService';
import type { AuthUser } from '../../services/authService';
import {
clearProfileBrowseHistory,
getProfileDashboard,
listCustomWorldGallery,
listCustomWorldLibrary,
listProfileBrowseHistory,
upsertCustomWorldProfile,
upsertProfileBrowseHistory,
} from '../../services/storageService';
import type { GameState } from '../../types';
import { AuthUiContext } from '../auth/AuthUiContext';
import {
PreGameSelectionFlow,
type SelectionStage,
@@ -33,11 +39,16 @@ vi.mock('../../services/aiService', () => ({
}));
vi.mock('../../services/storageService', () => ({
clearProfileBrowseHistory: vi.fn(),
getCustomWorldGalleryDetail: vi.fn(),
getProfileDashboard: vi.fn(),
listCustomWorldGallery: vi.fn(),
listCustomWorldLibrary: vi.fn(),
listProfileBrowseHistory: vi.fn(),
publishCustomWorldProfile: vi.fn(),
syncProfileBrowseHistory: vi.fn(),
unpublishCustomWorldProfile: vi.fn(),
upsertProfileBrowseHistory: vi.fn(),
upsertCustomWorldProfile: vi.fn(),
}));
@@ -108,11 +119,21 @@ const mockSession: CustomWorldAgentSessionSnapshot = {
updatedAt: '2026-04-14T12:00:00.000Z',
};
function TestWrapper() {
const mockAuthUser: AuthUser = {
id: 'user-1',
username: 'tester',
displayName: '测试玩家',
phoneNumberMasked: null,
loginMethod: 'password',
bindingStatus: 'active',
wechatBound: false,
};
function TestWrapper({ withAuth = false }: { withAuth?: boolean } = {}) {
const [selectionStage, setSelectionStage] =
useState<SelectionStage>('platform');
return (
const content = (
<PreGameSelectionFlow
selectionStage={selectionStage}
setSelectionStage={setSelectionStage}
@@ -124,14 +145,41 @@ function TestWrapper() {
handleCustomWorldSelect={() => {}}
/>
);
if (!withAuth) {
return content;
}
return (
<AuthUiContext.Provider
value={{
user: mockAuthUser,
openAccountModal: () => {},
logout: async () => {},
setGlobalAccountActionsVisible: () => {},
}}
>
{content}
</AuthUiContext.Provider>
);
}
beforeEach(() => {
vi.clearAllMocks();
window.history.replaceState(null, '', '/');
window.sessionStorage.clear();
window.localStorage.clear();
vi.mocked(getProfileDashboard).mockResolvedValue({
walletBalance: 0,
totalPlayTimeMs: 0,
playedWorldCount: 0,
updatedAt: '2026-04-16T12:00:00.000Z',
});
vi.mocked(listCustomWorldLibrary).mockResolvedValue([]);
vi.mocked(listCustomWorldGallery).mockResolvedValue([]);
vi.mocked(listProfileBrowseHistory).mockResolvedValue([]);
vi.mocked(upsertProfileBrowseHistory).mockResolvedValue([]);
vi.mocked(clearProfileBrowseHistory).mockResolvedValue([]);
vi.mocked(upsertCustomWorldProfile).mockResolvedValue({
entry: {
ownerUserId: 'user-1',
@@ -350,26 +398,56 @@ test('existing draft sessions enter the legacy result layout directly', async ()
await waitFor(
async () => {
expect(await screen.findByText('世界档案')).toBeTruthy();
expect(
screen.getByRole('button', {
name: /||/u,
}),
).toBeTruthy();
expect(screen.getByText('已自动保存')).toBeTruthy();
expect(screen.getByRole('button', { name: //u })).toBeTruthy();
},
{ timeout: 2500 },
);
expect(screen.queryByText(/Agent/u)).toBeNull();
expect(screen.queryByRole('button', { name: /^/u })).toBeNull();
expect(screen.getByText(//u)).toBeTruthy();
expect(screen.getByText(//u)).toBeTruthy();
await user.click(screen.getByRole('button', { name: //u }));
await user.click(screen.getByRole('button', { name: //u }));
expect(await screen.findByText(//u)).toBeTruthy();
expect(
screen.getByRole('button', { name: /AI/u }),
).toBeTruthy();
expect(screen.getByRole('button', { name: /AI/u })).toBeTruthy();
expect(screen.getByText('技能')).toBeTruthy();
});
test('profile tab loads server browse history and can clear it after confirmation', async () => {
const user = userEvent.setup();
vi.mocked(listProfileBrowseHistory).mockResolvedValue([
{
ownerUserId: 'author-1',
profileId: 'world-1',
worldName: '潮雾列岛',
subtitle: '旧灯塔与失控航路',
summaryText: '最近浏览过的公开作品。',
coverImageSrc: null,
themeMode: 'tide',
authorDisplayName: '潮汐作者',
visitedAt: '2026-04-16T12:00:00.000Z',
},
]);
vi.mocked(clearProfileBrowseHistory).mockResolvedValue([]);
vi.spyOn(window, 'confirm').mockReturnValue(true);
render(<TestWrapper withAuth />);
await user.click(screen.getByRole('button', { name: '我的' }));
expect(await screen.findByText('潮雾列岛')).toBeTruthy();
await user.click(screen.getByRole('button', { name: '清空' }));
await waitFor(() => {
expect(clearProfileBrowseHistory).toHaveBeenCalledTimes(1);
});
expect(
screen.getByText('你最近还没有浏览过作品详情,去首页或发现逛一逛吧。'),
).toBeTruthy();
});