init with react+axum+spacetimedb
Some checks failed
CI / verify (push) Has been cancelled

This commit is contained in:
2026-04-26 18:06:23 +08:00
commit cbc27bad4a
20199 changed files with 883714 additions and 0 deletions

View File

@@ -0,0 +1,158 @@
import { beforeEach, describe, expect, it, vi } from 'vitest';
const { requestJsonMock } = vi.hoisted(() => ({
requestJsonMock: vi.fn(),
}));
import {
clearRpgProfileBrowseHistory,
listRpgProfileBrowseHistory,
listRpgProfileSaveArchives,
resumeRpgProfileSaveArchive,
syncRpgProfileBrowseHistory,
upsertRpgProfileBrowseHistory,
} from './rpgProfileClient';
vi.mock('../apiClient', () => ({
requestJson: requestJsonMock,
}));
describe('rpgProfileClient browse history routes', () => {
beforeEach(() => {
requestJsonMock.mockReset();
requestJsonMock.mockResolvedValue({ entries: [] });
});
it('reads browse history from the runtime profile route', async () => {
await listRpgProfileBrowseHistory();
expect(requestJsonMock).toHaveBeenCalledWith(
'/api/runtime/profile/browse-history',
expect.objectContaining({ method: 'GET' }),
'读取浏览历史失败',
expect.objectContaining({
retry: expect.objectContaining({ maxRetries: 1 }),
}),
);
});
it('writes browse history through the runtime profile route', async () => {
await upsertRpgProfileBrowseHistory({
ownerUserId: 'user-1',
profileId: 'profile-1',
worldName: '测试世界',
subtitle: '测试副标题',
summaryText: '测试摘要',
coverImageSrc: null,
themeMode: 'mythic',
authorDisplayName: '测试作者',
});
expect(requestJsonMock).toHaveBeenCalledWith(
'/api/runtime/profile/browse-history',
expect.objectContaining({
method: 'POST',
headers: { 'Content-Type': 'application/json' },
}),
'写入浏览历史失败',
expect.objectContaining({
retry: expect.objectContaining({
maxRetries: 1,
retryUnsafeMethods: true,
}),
}),
);
});
it('syncs browse history through the runtime profile route', async () => {
await syncRpgProfileBrowseHistory([
{
ownerUserId: 'user-1',
profileId: 'profile-1',
worldName: '测试世界',
subtitle: '测试副标题',
summaryText: '测试摘要',
coverImageSrc: null,
themeMode: 'mythic',
authorDisplayName: '测试作者',
},
]);
expect(requestJsonMock).toHaveBeenCalledWith(
'/api/runtime/profile/browse-history',
expect.objectContaining({
method: 'POST',
headers: { 'Content-Type': 'application/json' },
}),
'同步浏览历史失败',
expect.any(Object),
);
});
it('clears browse history through the runtime profile route', async () => {
await clearRpgProfileBrowseHistory();
expect(requestJsonMock).toHaveBeenCalledWith(
'/api/runtime/profile/browse-history',
expect.objectContaining({ method: 'DELETE' }),
'清空浏览历史失败',
expect.objectContaining({
retry: expect.objectContaining({
maxRetries: 1,
retryUnsafeMethods: true,
}),
}),
);
});
});
describe('rpgProfileClient save archive routes', () => {
beforeEach(() => {
requestJsonMock.mockReset();
requestJsonMock.mockResolvedValue({ entries: [] });
});
it('reads save archives from the runtime profile route', async () => {
await listRpgProfileSaveArchives();
expect(requestJsonMock).toHaveBeenCalledWith(
'/api/runtime/profile/save-archives',
expect.objectContaining({ method: 'GET' }),
'读取存档列表失败',
expect.objectContaining({
retry: expect.objectContaining({ maxRetries: 1 }),
}),
);
});
it('resumes a save archive through the runtime profile route', async () => {
requestJsonMock.mockResolvedValueOnce({
entry: {
worldKey: 'custom:world-1',
},
snapshot: {
version: 2,
savedAt: '2026-04-19T10:15:00.000Z',
bottomTab: 'adventure',
currentStory: null,
gameState: {
worldType: 'CUSTOM',
},
},
});
await resumeRpgProfileSaveArchive('custom:world-1');
expect(requestJsonMock).toHaveBeenCalledWith(
'/api/runtime/profile/save-archives/custom%3Aworld-1',
expect.objectContaining({ method: 'POST' }),
'恢复存档失败',
expect.objectContaining({
retry: expect.objectContaining({
maxRetries: 1,
retryUnsafeMethods: true,
}),
}),
);
});
});