AGC 退役发布表单弹窗外壳,错误统一走发布提示弹窗
- 删除已无现役调用方的 GameDistributionPublishPanel,发布资料表单只保留内联形态 - useGameDistributionPublishForm 去掉 inline 开关与 handleSubmit,onError 改为必填 - GameDistributionPublishFormView 去掉弹窗分支与 open / onClose 入参,只渲染内联布局 - 原专属测试迁移到内联表单并改名为 gameDistributionPublishForm.test.tsx
This commit is contained in:
+51
-160
@@ -12,26 +12,19 @@ import {
|
||||
} from './useGameDistributionPublishForm';
|
||||
|
||||
/**
|
||||
* 发布资料表单的表现层:弹窗与工作台内联共用同一份 DOM 结构。
|
||||
* 发布资料表单的表现层(工作台内联形态)。
|
||||
*
|
||||
* 状态全部来自 `form`(`useGameDistributionPublishForm` 的返回值);内联形态把主行动换成
|
||||
* 内容末尾整行橙色的「打包并发布」。
|
||||
* 状态全部来自 `form`(`useGameDistributionPublishForm` 的返回值);主行动是内容末尾整行
|
||||
* 橙色的「打包并发布」,校验 / 提交错误由面板根的「发布提示」弹窗承载。
|
||||
*/
|
||||
export function GameDistributionPublishFormView({
|
||||
form,
|
||||
inline = false,
|
||||
open,
|
||||
onClose,
|
||||
packaging = false,
|
||||
}: {
|
||||
form: GameDistributionPublishFormState;
|
||||
inline?: boolean;
|
||||
open: boolean;
|
||||
onClose: () => void;
|
||||
packaging?: boolean;
|
||||
}) {
|
||||
const {
|
||||
packageResult,
|
||||
title,
|
||||
setTitle,
|
||||
summary,
|
||||
@@ -39,7 +32,6 @@ export function GameDistributionPublishFormView({
|
||||
category,
|
||||
setCategory,
|
||||
busy,
|
||||
error,
|
||||
clearError,
|
||||
result,
|
||||
cover,
|
||||
@@ -66,7 +58,6 @@ export function GameDistributionPublishFormView({
|
||||
handleGenerateCover,
|
||||
handleScreenshotsSelected,
|
||||
removeScreenshot,
|
||||
handleSubmit,
|
||||
handlePackageAndPublish,
|
||||
} = form;
|
||||
|
||||
@@ -349,160 +340,60 @@ export function GameDistributionPublishFormView({
|
||||
</ThemedModal>
|
||||
);
|
||||
|
||||
if (inline) {
|
||||
return (
|
||||
<div
|
||||
className="flex h-full min-h-0 flex-col gap-3 overflow-auto p-3"
|
||||
aria-label="游戏发布表单"
|
||||
>
|
||||
<section className="rounded-2xl border border-[#e2cbb8] bg-[#fffaf5] p-4">
|
||||
<span className="game-distribution-publish-panel__eyebrow">
|
||||
发布到游戏广场
|
||||
</span>
|
||||
<h2 className="mt-1 text-base font-semibold text-[#3d1f10]">
|
||||
让玩家现在就能试玩
|
||||
</h2>
|
||||
</section>
|
||||
{result ? (
|
||||
<div
|
||||
className="game-distribution-publish-panel__success"
|
||||
role="status"
|
||||
>
|
||||
<strong>已提交审核</strong>
|
||||
<p>版本已进入审核队列,审核通过后才会在游戏广场公开展示。</p>
|
||||
<p className="game-distribution-publish-panel__mono">
|
||||
版本 {result.versionNumber} ·{' '}
|
||||
{result.packageSizeBytes.toLocaleString()} B ·{' '}
|
||||
{result.packageSha256.slice(0, 16)}…
|
||||
</p>
|
||||
</div>
|
||||
) : (
|
||||
<>
|
||||
{fieldsAndMedia}
|
||||
<button
|
||||
type="button"
|
||||
disabled={
|
||||
busy ||
|
||||
generatingCover ||
|
||||
screenshotsUploading ||
|
||||
Boolean(uploadingLabel) ||
|
||||
Boolean(packaging)
|
||||
}
|
||||
onClick={() => void handlePackageAndPublish()}
|
||||
className="inline-flex w-full items-center justify-center gap-2 rounded-xl border border-[#c7653d] bg-[#c7653d] px-6 py-4 text-lg font-bold tracking-wide text-white shadow-md transition enabled:hover:bg-[#b4562f] disabled:cursor-not-allowed disabled:opacity-45"
|
||||
>
|
||||
{packaging
|
||||
? '正在打包…'
|
||||
: busy
|
||||
? '上传中…'
|
||||
: generatingCover
|
||||
? '封面生成中…'
|
||||
: screenshotsUploading
|
||||
? '截图上传中…'
|
||||
: uploadingLabel
|
||||
? '素材上传中…'
|
||||
: '打包并发布'}
|
||||
</button>
|
||||
</>
|
||||
)}
|
||||
{coverConfirmDialog}
|
||||
{previewDialog}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<ThemedModal
|
||||
open={open}
|
||||
ariaLabel="发布到游戏广场"
|
||||
onClose={busy || generatingCover ? () => undefined : onClose}
|
||||
panelClassName="game-distribution-publish-panel"
|
||||
closeOnBackdrop={!busy && !generatingCover}
|
||||
closeOnEscape={!busy && !generatingCover}
|
||||
>
|
||||
<header className="game-distribution-publish-panel__header">
|
||||
<div>
|
||||
<span className="game-distribution-publish-panel__eyebrow">
|
||||
发布到游戏广场
|
||||
</span>
|
||||
<h2>让玩家现在就能试玩</h2>
|
||||
</div>
|
||||
<div
|
||||
className="flex h-full min-h-0 flex-col gap-3 overflow-auto p-3"
|
||||
aria-label="游戏发布表单"
|
||||
>
|
||||
<section className="rounded-2xl border border-[#e2cbb8] bg-[#fffaf5] p-4">
|
||||
<span className="game-distribution-publish-panel__eyebrow">
|
||||
发布到游戏广场
|
||||
</span>
|
||||
<h2 className="mt-1 text-base font-semibold text-[#3d1f10]">
|
||||
让玩家现在就能试玩
|
||||
</h2>
|
||||
</section>
|
||||
{result ? (
|
||||
<div className="game-distribution-publish-panel__success" role="status">
|
||||
<strong>已提交审核</strong>
|
||||
<p>版本已进入审核队列,审核通过后才会在游戏广场公开展示。</p>
|
||||
<p className="game-distribution-publish-panel__mono">
|
||||
版本 {result.versionNumber} ·{' '}
|
||||
{result.packageSizeBytes.toLocaleString()} B ·{' '}
|
||||
{result.packageSha256.slice(0, 16)}…
|
||||
</p>
|
||||
</div>
|
||||
) : (
|
||||
<>
|
||||
{fieldsAndMedia}
|
||||
<button
|
||||
type="button"
|
||||
onClick={onClose}
|
||||
disabled={busy || generatingCover}
|
||||
aria-label="关闭发布面板"
|
||||
disabled={
|
||||
busy ||
|
||||
generatingCover ||
|
||||
screenshotsUploading ||
|
||||
Boolean(uploadingLabel) ||
|
||||
Boolean(packaging)
|
||||
}
|
||||
onClick={() => void handlePackageAndPublish()}
|
||||
className="inline-flex w-full items-center justify-center gap-2 rounded-xl border border-[#c7653d] bg-[#c7653d] px-6 py-4 text-lg font-bold tracking-wide text-white shadow-md transition enabled:hover:bg-[#b4562f] disabled:cursor-not-allowed disabled:opacity-45"
|
||||
>
|
||||
×
|
||||
{packaging
|
||||
? '正在打包…'
|
||||
: busy
|
||||
? '上传中…'
|
||||
: generatingCover
|
||||
? '封面生成中…'
|
||||
: screenshotsUploading
|
||||
? '截图上传中…'
|
||||
: uploadingLabel
|
||||
? '素材上传中…'
|
||||
: '打包并发布'}
|
||||
</button>
|
||||
</header>
|
||||
{result ? (
|
||||
<div
|
||||
className="game-distribution-publish-panel__success"
|
||||
role="status"
|
||||
>
|
||||
<strong>已提交审核</strong>
|
||||
<p>版本已进入审核队列,审核通过后才会在游戏广场公开展示。</p>
|
||||
<p className="game-distribution-publish-panel__mono">
|
||||
版本 {result.versionNumber} ·{' '}
|
||||
{result.packageSizeBytes.toLocaleString()} B ·{' '}
|
||||
{result.packageSha256.slice(0, 16)}…
|
||||
</p>
|
||||
<div className="game-distribution-publish-panel__actions">
|
||||
<button type="button" onClick={onClose}>
|
||||
完成
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
) : (
|
||||
<>
|
||||
{fieldsAndMedia}
|
||||
{error ? (
|
||||
<p
|
||||
className="game-distribution-publish-panel__error"
|
||||
role="alert"
|
||||
>
|
||||
{error}
|
||||
</p>
|
||||
) : null}
|
||||
<div className="game-distribution-publish-panel__actions">
|
||||
<button
|
||||
type="button"
|
||||
onClick={onClose}
|
||||
disabled={busy || generatingCover || screenshotsUploading}
|
||||
>
|
||||
稍后再说
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => void handleSubmit()}
|
||||
disabled={
|
||||
busy ||
|
||||
generatingCover ||
|
||||
screenshotsUploading ||
|
||||
Boolean(uploadingLabel) ||
|
||||
!title.trim() ||
|
||||
!summary.trim() ||
|
||||
!packageResult
|
||||
}
|
||||
>
|
||||
{busy
|
||||
? '上传中…'
|
||||
: generatingCover
|
||||
? '封面生成中…'
|
||||
: screenshotsUploading
|
||||
? '截图上传中…'
|
||||
: uploadingLabel
|
||||
? '素材上传中…'
|
||||
: '发布游戏'}
|
||||
</button>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
</ThemedModal>
|
||||
</>
|
||||
)}
|
||||
{coverConfirmDialog}
|
||||
{previewDialog}
|
||||
</>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
-43
@@ -1,43 +0,0 @@
|
||||
import type { GameCreationAppManifest } from '../../../../../packages/shared/src/contracts/gameCreationApp';
|
||||
import type { LocalProjectExportPackageResult } from '../../app/types';
|
||||
import type { GameDistributionPublishResult } from '../../services/gameDistributionPublish';
|
||||
import { GameDistributionPublishFormView } from './GameDistributionPublishFormView';
|
||||
import { useGameDistributionPublishForm } from './useGameDistributionPublishForm';
|
||||
|
||||
/**
|
||||
* 发布资料表单的弹窗外壳:点按钮弹出的独立面板。
|
||||
*
|
||||
* 表单状态在 `useGameDistributionPublishForm`;工作台内联形态把它提升到导出面板根
|
||||
* (`useTaonierTab`),切 tab 不丢。这里保留「弹窗 + 关闭」的入口形态。
|
||||
*/
|
||||
export function GameDistributionPublishPanel({
|
||||
open,
|
||||
projectPath,
|
||||
manifest,
|
||||
packageResult,
|
||||
onClose,
|
||||
onPublished,
|
||||
}: {
|
||||
open: boolean;
|
||||
projectPath: string;
|
||||
manifest: GameCreationAppManifest;
|
||||
packageResult: LocalProjectExportPackageResult | null;
|
||||
onClose: () => void;
|
||||
onPublished?: (result: GameDistributionPublishResult) => void;
|
||||
}) {
|
||||
const form = useGameDistributionPublishForm({
|
||||
open,
|
||||
inline: false,
|
||||
projectPath,
|
||||
manifest,
|
||||
packageResult,
|
||||
onPublished,
|
||||
});
|
||||
return (
|
||||
<GameDistributionPublishFormView
|
||||
form={form}
|
||||
open={open}
|
||||
onClose={onClose}
|
||||
/>
|
||||
);
|
||||
}
|
||||
+7
-31
@@ -148,14 +148,11 @@ export type GameDistributionPublishFormState = ReturnType<
|
||||
/**
|
||||
* 发布资料表单的全部状态与动作。
|
||||
*
|
||||
* 弹窗形态由 `GameDistributionPublishPanel` 自己调用;工作台内联形态把它提升到导出面板根
|
||||
* (`useTaonierTab`),这样切走 tab、页面组件卸载也不会丢掉已经填好的发布资料。
|
||||
*
|
||||
* `inline` 决定初始化开关:弹窗每次带着新试玩包打开都重来;内联常驻左栏,只在换项目时重来。
|
||||
* 由导出面板根(`useTaonierTab`)持有,这样切走 tab、页面组件卸载也不会丢掉已经填好的发布资料;
|
||||
* 初始化只在换项目 / 打开时重来,不因为「打包结果变化」清掉用户填好的资料。
|
||||
*/
|
||||
export function useGameDistributionPublishForm({
|
||||
open,
|
||||
inline,
|
||||
projectPath,
|
||||
manifest,
|
||||
packageResult,
|
||||
@@ -164,17 +161,13 @@ export function useGameDistributionPublishForm({
|
||||
onError,
|
||||
}: {
|
||||
open: boolean;
|
||||
inline: boolean;
|
||||
projectPath: string;
|
||||
manifest: GameCreationAppManifest | null;
|
||||
packageResult: LocalProjectExportPackageResult | null;
|
||||
onPublished?: (result: GameDistributionPublishResult) => void;
|
||||
onEnsurePackage?: () => Promise<LocalProjectExportPackageResult | null>;
|
||||
/**
|
||||
* 错误出口:内联工作台把表单校验 / 提交错误交给面板根的 `GamePublishBlockedDialog`
|
||||
* (发布提示弹窗)展示;弹窗形态不传,退回表单里的内联文案。`null` 表示清掉弹窗。
|
||||
*/
|
||||
onError?: (message: string | null) => void;
|
||||
/** 表单校验 / 提交错误的出口:面板根用它驱动「发布提示」弹窗(`GamePublishBlockedDialog`)。 */
|
||||
onError: (message: string | null) => void;
|
||||
}) {
|
||||
const manifestRef = useRef(manifest);
|
||||
manifestRef.current = manifest;
|
||||
@@ -211,14 +204,6 @@ export function useGameDistributionPublishForm({
|
||||
const uploadedAssetCacheRef = useRef(new Map<string, string>());
|
||||
const objectUrlsRef = useRef(new Set<string>());
|
||||
|
||||
/**
|
||||
* 表单初始化开关:弹窗每次带着新试玩包打开都要重来;内联常驻左栏,只在换项目时重来,
|
||||
* 不能因为「打包完包结果变化」就把用户已经填好的资料清掉。
|
||||
*/
|
||||
const resetKey = inline
|
||||
? 'inline'
|
||||
: (packageResult?.packageRelativePath ?? '');
|
||||
|
||||
useEffect(() => {
|
||||
if (!open) return;
|
||||
const currentManifest = manifestRef.current;
|
||||
@@ -231,7 +216,7 @@ export function useGameDistributionPublishForm({
|
||||
setCategory('其他');
|
||||
setBusy(false);
|
||||
setError('');
|
||||
onError?.(null);
|
||||
onError(null);
|
||||
setResult(null);
|
||||
setMetadataSuggestionPending(false);
|
||||
setMetadataSuggestionReady(false);
|
||||
@@ -268,7 +253,7 @@ export function useGameDistributionPublishForm({
|
||||
setMetadataSuggestionPending(false);
|
||||
}
|
||||
});
|
||||
}, [manifest?.projectId, open, resetKey, onError]);
|
||||
}, [manifest?.projectId, open, onError]);
|
||||
|
||||
useEffect(() => {
|
||||
if (open) {
|
||||
@@ -519,7 +504,7 @@ export function useGameDistributionPublishForm({
|
||||
*/
|
||||
function reportError(message: string) {
|
||||
setError(message);
|
||||
onError?.(message.trim() ? message : null);
|
||||
onError(message.trim() ? message : null);
|
||||
}
|
||||
|
||||
/** 用户一改字段就把上一次的校验错误收起来,别让已经修好的字段继续挂着红字。 */
|
||||
@@ -587,14 +572,6 @@ export function useGameDistributionPublishForm({
|
||||
}
|
||||
}
|
||||
|
||||
async function handleSubmit() {
|
||||
if (!packageResult) {
|
||||
reportError('请先导出有效的试玩包');
|
||||
return;
|
||||
}
|
||||
await submitPackage(packageResult);
|
||||
}
|
||||
|
||||
/**
|
||||
* 内联主行动:一次点击完成「打包 → 发布」。
|
||||
*
|
||||
@@ -665,7 +642,6 @@ export function useGameDistributionPublishForm({
|
||||
handleGenerateCover,
|
||||
handleScreenshotsSelected,
|
||||
removeScreenshot,
|
||||
handleSubmit,
|
||||
handlePackageAndPublish,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -231,7 +231,6 @@ export function useTaonierTab({
|
||||
*/
|
||||
const publishForm = useGameDistributionPublishForm({
|
||||
open: formEnabled,
|
||||
inline: true,
|
||||
projectPath: projectPath ?? '',
|
||||
manifest,
|
||||
packageResult,
|
||||
|
||||
-3
@@ -32,9 +32,6 @@ export function PublishPane({ tab }: { tab: TaonierTabState }) {
|
||||
>
|
||||
<GameDistributionPublishFormView
|
||||
form={tab.publishForm}
|
||||
inline
|
||||
open
|
||||
onClose={() => undefined}
|
||||
packaging={tab.progress?.phase === 'running'}
|
||||
/>
|
||||
</div>
|
||||
|
||||
+61
-18
@@ -13,13 +13,16 @@ import {
|
||||
waitFor,
|
||||
within,
|
||||
} from '@testing-library/react';
|
||||
import { useState } from 'react';
|
||||
import { afterEach, beforeEach, describe, expect, test, vi } from 'vitest';
|
||||
|
||||
import type { GameCreationAppManifest } from '../../../packages/shared/src/contracts/gameCreationApp';
|
||||
import type { LocalProjectExportPackageResult } from '../src/app/types';
|
||||
import { GameDistributionPublishPanel } from '../src/components/game-distribution/GameDistributionPublishPanel';
|
||||
import { GameDistributionPublishFormView } from '../src/components/game-distribution/GameDistributionPublishFormView';
|
||||
import { useGameDistributionPublishForm } from '../src/components/game-distribution/useGameDistributionPublishForm';
|
||||
import { uploadPlatformMediaAsset } from '../src/services/assetDirectUpload';
|
||||
import {
|
||||
type GameDistributionPublishResult,
|
||||
generateGameDistributionCover,
|
||||
publishLocalProjectGame,
|
||||
readGameCoverGenerationPrice,
|
||||
@@ -94,13 +97,49 @@ async function selectCover(
|
||||
await screen.findByText(new RegExp(`已选择「${file.name}」`, 'u'));
|
||||
}
|
||||
|
||||
/**
|
||||
* 内联化之后,原弹窗外壳已退役;测试直接挂在现役的内联表单上(去掉面板根那层状态提升),
|
||||
* 继续覆盖预填、门禁、上传与成功 / 失败边界。
|
||||
*/
|
||||
function PublishFormHarness({
|
||||
open,
|
||||
projectPath,
|
||||
manifest,
|
||||
packageResult,
|
||||
onPublished,
|
||||
}: {
|
||||
open: boolean;
|
||||
projectPath: string;
|
||||
manifest: GameCreationAppManifest;
|
||||
packageResult: LocalProjectExportPackageResult | null;
|
||||
onClose: () => void;
|
||||
onPublished?: (result: GameDistributionPublishResult) => void;
|
||||
}) {
|
||||
const [notice, setNotice] = useState<string | null>(null);
|
||||
const form = useGameDistributionPublishForm({
|
||||
open,
|
||||
projectPath,
|
||||
manifest,
|
||||
packageResult,
|
||||
onPublished,
|
||||
// 内联形态在面板根用「发布提示」弹窗承载错误;测试里用一个等价的 alert 节点接住。
|
||||
onError: setNotice,
|
||||
});
|
||||
return (
|
||||
<>
|
||||
{notice ? <p role="alert">{notice}</p> : null}
|
||||
<GameDistributionPublishFormView form={form} />
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
function renderPanel(
|
||||
overrides: Partial<Parameters<typeof GameDistributionPublishPanel>[0]> = {},
|
||||
overrides: Partial<Parameters<typeof PublishFormHarness>[0]> = {},
|
||||
) {
|
||||
const onClose = vi.fn();
|
||||
const onPublished = vi.fn();
|
||||
render(
|
||||
<GameDistributionPublishPanel
|
||||
<PublishFormHarness
|
||||
open
|
||||
projectPath="/tmp/authorized-game"
|
||||
manifest={MANIFEST}
|
||||
@@ -136,7 +175,7 @@ afterEach(() => {
|
||||
(window.localStorage as Storage | undefined)?.clear();
|
||||
});
|
||||
|
||||
describe('GameDistributionPublishPanel', () => {
|
||||
describe('AGC 发布资料表单(内联形态)', () => {
|
||||
test('打开时预填游戏资料且不展示发行包技术摘要', async () => {
|
||||
installTauriInvoke(async () => undefined);
|
||||
renderPanel();
|
||||
@@ -260,7 +299,7 @@ describe('GameDistributionPublishPanel', () => {
|
||||
),
|
||||
).not.toBeNull();
|
||||
|
||||
fireEvent.click(screen.getByRole('button', { name: '发布游戏' }));
|
||||
fireEvent.click(screen.getByRole('button', { name: '打包并发布' }));
|
||||
await waitFor(() =>
|
||||
expect(publishLocalProjectGame).toHaveBeenCalledTimes(1),
|
||||
);
|
||||
@@ -298,7 +337,7 @@ describe('GameDistributionPublishPanel', () => {
|
||||
target: { files: [buildImageFile('shot-1.png')] },
|
||||
});
|
||||
await screen.findByRole('button', { name: '删除截图 1' });
|
||||
fireEvent.click(screen.getByRole('button', { name: '发布游戏' }));
|
||||
fireEvent.click(screen.getByRole('button', { name: '打包并发布' }));
|
||||
|
||||
await waitFor(() =>
|
||||
expect(publishLocalProjectGame).toHaveBeenCalledTimes(1),
|
||||
@@ -335,7 +374,7 @@ describe('GameDistributionPublishPanel', () => {
|
||||
renderPanel();
|
||||
await selectCover();
|
||||
|
||||
const submit = screen.getByRole('button', { name: '发布游戏' });
|
||||
const submit = screen.getByRole('button', { name: '打包并发布' });
|
||||
fireEvent.click(submit);
|
||||
fireEvent.click(submit);
|
||||
|
||||
@@ -362,7 +401,7 @@ describe('GameDistributionPublishPanel', () => {
|
||||
renderPanel();
|
||||
await selectCover();
|
||||
|
||||
fireEvent.click(screen.getByRole('button', { name: '发布游戏' }));
|
||||
fireEvent.click(screen.getByRole('button', { name: '打包并发布' }));
|
||||
|
||||
expect(
|
||||
await screen.findByText(
|
||||
@@ -376,7 +415,7 @@ describe('GameDistributionPublishPanel', () => {
|
||||
installTauriInvoke(async () => undefined);
|
||||
renderPanel();
|
||||
|
||||
fireEvent.click(screen.getByRole('button', { name: '发布游戏' }));
|
||||
fireEvent.click(screen.getByRole('button', { name: '打包并发布' }));
|
||||
|
||||
expect(
|
||||
await screen.findByText('请先选择游戏封面(JPG/PNG/WebP)'),
|
||||
@@ -398,7 +437,7 @@ describe('GameDistributionPublishPanel', () => {
|
||||
}),
|
||||
);
|
||||
|
||||
fireEvent.click(screen.getByRole('button', { name: '发布游戏' }));
|
||||
fireEvent.click(screen.getByRole('button', { name: '打包并发布' }));
|
||||
await waitFor(() =>
|
||||
expect(publishLocalProjectGame).toHaveBeenCalledTimes(1),
|
||||
);
|
||||
@@ -499,7 +538,7 @@ describe('GameDistributionPublishPanel', () => {
|
||||
expect(screen.queryByRole('dialog', { name: '截图预览' })).toBeNull();
|
||||
});
|
||||
|
||||
fireEvent.click(screen.getByRole('button', { name: '发布游戏' }));
|
||||
fireEvent.click(screen.getByRole('button', { name: '打包并发布' }));
|
||||
await waitFor(() =>
|
||||
expect(publishLocalProjectGame).toHaveBeenCalledTimes(1),
|
||||
);
|
||||
@@ -541,19 +580,23 @@ describe('GameDistributionPublishPanel', () => {
|
||||
expect(publishLocalProjectGame).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
test('不在 Tauri 宿主或缺少试玩包时失败关闭且不调用发布接口', async () => {
|
||||
test('缺少封面或试玩包时失败关闭且不调用发布接口', async () => {
|
||||
renderPanel();
|
||||
fireEvent.click(screen.getByRole('button', { name: '发布游戏' }));
|
||||
expect(await screen.findByText('需要在 Tauri App 内发布')).not.toBeNull();
|
||||
fireEvent.click(screen.getByRole('button', { name: '打包并发布' }));
|
||||
// 校验前置:没有封面时在点击当下就给出提示,不进入打包也不提交发布。
|
||||
expect(
|
||||
await screen.findByText('请先选择游戏封面(JPG/PNG/WebP)'),
|
||||
).not.toBeNull();
|
||||
expect(publishLocalProjectGame).not.toHaveBeenCalled();
|
||||
|
||||
cleanup();
|
||||
installTauriInvoke(async () => undefined);
|
||||
renderPanel({ packageResult: null });
|
||||
expect(screen.getByRole('button', { name: '发布游戏' })).toHaveProperty(
|
||||
'disabled',
|
||||
true,
|
||||
);
|
||||
await selectCover();
|
||||
fireEvent.click(screen.getByRole('button', { name: '打包并发布' }));
|
||||
// 没有试玩包、也没有打包回调时,同样在点击当下就地给出原因,而不是灰掉按钮。
|
||||
expect(await screen.findByText('请先导出有效的试玩包')).not.toBeNull();
|
||||
expect(publishLocalProjectGame).not.toHaveBeenCalled();
|
||||
expect(screen.queryByLabelText('发行包摘要')).toBeNull();
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user