Files
Genarrative/apps/ai-game-creator-shell/tests/assetDirectUpload.test.ts
T
kdletters 8701f43f75 AGC 渲染层网络与状态下沉 Rust,并修复画布交互与失败文案
- 删除渲染层传输层:services/clientApi.ts、clientHttp 的 fetchClientHttp 与超时封装整体退场,账户、认证、素材直传、错误上报与游戏分发发布改走 Rust typed command。
- 新增宿主封装:accountHost、editorAssetHost、platformSessionRetry、agentRuntimeErrorDetail 与 features/app-shell/workspacePreferences;渲染层不再读写 access token / refresh cookie,localStorage 只剩测试态旧键迁移 shim。
- 修复 DirectProject 失败文案 v2 映射与「查看详情」按需读取,画布标签面板高度夹紧、框选每帧重算、文档预览入口与场景标题栏 key、资源筛选面板样式。
- 补齐与调整回归:accountHost、agentRuntimeErrorDetail、clientAuthHost、clientHttp、platformSession、platformSessionRetry、resourceFilterPanelStyle、directThreadChatSubscription 等定向用例,并清理测试 harness 中无调用方的残留。
2026-09-28 14:15:02 +08:00

82 lines
2.6 KiB
TypeScript

// @vitest-environment jsdom
/**
* AGC 素材直传 facade 的边界。
*
* React 只把用户选择的文件和结构化元数据交给 Rust typed command;凭证、对象存储直传和
* confirm 的网络合同由 Rust 测试覆盖,渲染层这里只验证 IPC 载荷与失败关闭。
*/
import { beforeEach, expect, test, vi } from 'vitest';
import { uploadPlatformMediaAsset } from '../src/services/assetDirectUpload';
const invoke = vi.fn();
function buildCoverFile() {
return new File(['cover-bytes'], 'cover.png', { type: 'image/png' });
}
beforeEach(() => {
invoke.mockReset();
invoke.mockResolvedValue({
assetObjectId: 'asset_cover_1',
objectKey:
'generated-character-drafts/game-distribution/cover/42/cover.png',
});
});
test('把用户文件交给 Rust typed command 并返回素材标识', async () => {
const file = buildCoverFile();
const uploaded = await uploadPlatformMediaAsset({
file,
assetKind: 'game_distribution_cover',
pathSegments: ['game-distribution', 'cover', '42'],
entityId: 'game-distribution-cover',
metadata: { game_distribution_media: 'cover' },
invoke,
});
expect(uploaded).toEqual({
assetObjectId: 'asset_cover_1',
objectKey:
'generated-character-drafts/game-distribution/cover/42/cover.png',
});
expect(invoke).toHaveBeenCalledTimes(1);
expect(invoke).toHaveBeenCalledWith('upload_platform_media_asset', {
input: {
fileName: 'cover.png',
contentType: 'image/png',
assetKind: 'game_distribution_cover',
pathSegments: ['game-distribution', 'cover', '42'],
entityId: 'game-distribution-cover',
bytes: Array.from(new TextEncoder().encode('cover-bytes')),
metadata: {
game_distribution_media: 'cover',
},
},
});
});
test('没有 Tauri command 时明确失败关闭', async () => {
await expect(
uploadPlatformMediaAsset({
file: buildCoverFile(),
assetKind: 'game_distribution_cover',
pathSegments: ['game-distribution', 'cover', '42'],
entityId: 'game-distribution-cover',
}),
).rejects.toThrow('需要在 Tauri App 内上传平台素材');
});
test('Rust 返回缺少素材标识时不把半成功投影给页面', async () => {
invoke.mockResolvedValueOnce({ assetObjectId: '', objectKey: '' });
await expect(
uploadPlatformMediaAsset({
file: buildCoverFile(),
assetKind: 'game_distribution_cover',
pathSegments: ['game-distribution', 'cover', '42'],
entityId: 'game-distribution-cover',
invoke,
}),
).rejects.toThrow('平台素材上传响应缺少素材标识');
});