import { describe, expect, it } from 'vitest'; import { createDefaultWorksAppId, describeWorksPublishFailure, } from '@/lib/works-project-publish'; describe('works project publish guidance', () => { it.each([ ['PROJECT_FILE_MISSING', '项目文件不完整', '修复当前项目模板'], ['PROJECT_TYPE_UNPUBLISHABLE', '这个项目没有配置发布方式', '新建小游戏或小程序项目'], ['DEPENDENCY_PREFETCH_FAILED', '暂时无法下载项目依赖', 'package-lock.json'], ['OUTPUT_MISSING', '没有生成可运行页面', 'index.html'], ['RELEASE_STORE_FAILED', '平台暂时无法保存发布文件', '无需修改项目'], ['BUILD_PIPELINE_UNSUPPORTED', '这个项目暂不支持自动发布', '联系运营人员'], ['BROWSER_SMOKE_FAILED', '自动打开作品时发现问题', 'npm run build'], ['BROWSER_SMOKE_TIMEOUT', '自动打开作品超时', '首屏资源'], ['BROWSER_SMOKE_UNAVAILABLE', '自动验收环境暂时不可用', '无需修改项目'], ])('maps %s to actionable Chinese guidance', (code, title, nextStep) => { const failure = describeWorksPublishFailure(code); expect(failure.title).toBe(title); expect(failure.nextStep).toContain(nextStep); }); it.each([ [401, '需要重新登录'], [403, '当前账号不能发布这个作品'], [409, '这个作品已有版本在处理中'], [413, '项目压缩包太大'], [503, '发布服务暂时不可用'], ])('maps HTTP %s without exposing a server response', (status, title) => { const failure = describeWorksPublishFailure(null, status); expect(failure.title).toBe(title); expect(JSON.stringify(failure)).not.toContain('Traceback'); }); it('uses a safe fallback for an unknown internal code', () => { const failure = describeWorksPublishFailure('INTERNAL_DATABASE_FAILURE'); expect(failure.title).toBe('提交没有完成'); expect(failure.nextStep).toContain('联系运营人员'); expect(JSON.stringify(failure)).not.toContain('INTERNAL_DATABASE_FAILURE'); }); it('creates a valid fallback app id for a non-Latin project name', () => { expect(createDefaultWorksAppId({ id: 'prj_7f86a', name: '我的小游戏' })) .toBe('makelore-prj-7f86a'); }); it('keeps the app id stable when the project is renamed', () => { expect(createDefaultWorksAppId({ id: 'prj_7f86a', name: '旧名称' })) .toBe(createDefaultWorksAppId({ id: 'prj_7f86a', name: '新名称' })); }); });