This commit is contained in:
@@ -0,0 +1,137 @@
|
||||
/* @vitest-environment jsdom */
|
||||
|
||||
import { fireEvent, render, screen, waitFor } from '@testing-library/react';
|
||||
import { beforeEach, expect, test, vi } from 'vitest';
|
||||
|
||||
import type {
|
||||
DropSquareHoleShapeRequest,
|
||||
SquareHoleRunSnapshot,
|
||||
} from '../../../packages/shared/src/contracts/squareHoleRuntime';
|
||||
import { SquareHoleRuntimeShell } from './SquareHoleRuntimeShell';
|
||||
|
||||
function buildRun(): SquareHoleRunSnapshot {
|
||||
return {
|
||||
runId: 'run-1',
|
||||
profileId: 'profile-1',
|
||||
ownerUserId: 'user-1',
|
||||
status: 'running',
|
||||
snapshotVersion: 3,
|
||||
startedAtMs: Date.now(),
|
||||
durationLimitMs: 60_000,
|
||||
remainingMs: 60_000,
|
||||
totalShapeCount: 8,
|
||||
completedShapeCount: 0,
|
||||
combo: 0,
|
||||
bestCombo: 0,
|
||||
score: 0,
|
||||
ruleLabel: '把当前选项投入指定洞口',
|
||||
backgroundImageSrc: null,
|
||||
currentShape: {
|
||||
shapeId: 'shape-1',
|
||||
shapeKind: 'square',
|
||||
label: '当前选项',
|
||||
targetHoleId: 'hole-b',
|
||||
color: '#38bdf8',
|
||||
imageSrc: null,
|
||||
},
|
||||
holes: [
|
||||
{
|
||||
holeId: 'hole-a',
|
||||
holeKind: 'hole-a',
|
||||
label: '洞口 A',
|
||||
x: 0.28,
|
||||
y: 0.32,
|
||||
imageSrc: null,
|
||||
},
|
||||
{
|
||||
holeId: 'hole-b',
|
||||
holeKind: 'hole-b',
|
||||
label: '洞口 B',
|
||||
x: 0.66,
|
||||
y: 0.52,
|
||||
imageSrc: null,
|
||||
},
|
||||
],
|
||||
lastFeedback: null,
|
||||
};
|
||||
}
|
||||
|
||||
function renderRuntime() {
|
||||
const run = buildRun();
|
||||
const onDropShape = vi.fn(async (_payload: DropSquareHoleShapeRequest) => ({
|
||||
feedback: {
|
||||
accepted: true,
|
||||
rejectReason: null,
|
||||
message: '已投入',
|
||||
},
|
||||
run,
|
||||
}));
|
||||
|
||||
render(
|
||||
<SquareHoleRuntimeShell
|
||||
run={run}
|
||||
onBack={vi.fn()}
|
||||
onRestart={vi.fn()}
|
||||
onDropShape={onDropShape}
|
||||
/>,
|
||||
);
|
||||
|
||||
return { onDropShape };
|
||||
}
|
||||
|
||||
beforeEach(() => {
|
||||
Object.defineProperty(HTMLElement.prototype, 'setPointerCapture', {
|
||||
configurable: true,
|
||||
value: vi.fn(),
|
||||
});
|
||||
Object.defineProperty(HTMLElement.prototype, 'releasePointerCapture', {
|
||||
configurable: true,
|
||||
value: vi.fn(),
|
||||
});
|
||||
});
|
||||
|
||||
test('点击洞口会提交该洞口选择', async () => {
|
||||
const { onDropShape } = renderRuntime();
|
||||
|
||||
fireEvent.click(screen.getByRole('button', { name: '投入 洞口 B' }));
|
||||
|
||||
await waitFor(() => expect(onDropShape).toHaveBeenCalledTimes(1));
|
||||
expect(onDropShape.mock.calls[0]?.[0]).toMatchObject({
|
||||
runId: 'run-1',
|
||||
holeId: 'hole-b',
|
||||
clientSnapshotVersion: 3,
|
||||
});
|
||||
});
|
||||
|
||||
test('引导高亮不会默认指向当前正确洞口', () => {
|
||||
renderRuntime();
|
||||
|
||||
const correctHole = screen.getByRole('button', { name: '投入 洞口 B' });
|
||||
const hintedHole = screen.getByRole('button', { name: '投入 洞口 A' });
|
||||
|
||||
expect(correctHole.className).not.toContain('ring-2');
|
||||
expect(hintedHole.className).toContain('ring-2');
|
||||
});
|
||||
|
||||
test('拖拽当前选项到洞口上松开会提交该洞口选择', async () => {
|
||||
const { onDropShape } = renderRuntime();
|
||||
const shape = screen.getByRole('button', { name: '拖拽当前选项' });
|
||||
const hole = screen.getByRole('button', { name: '投入 洞口 A' });
|
||||
const elementsFromPoint = vi.fn(() => [hole]);
|
||||
Object.defineProperty(document, 'elementsFromPoint', {
|
||||
configurable: true,
|
||||
value: elementsFromPoint,
|
||||
});
|
||||
|
||||
fireEvent.pointerDown(shape, { pointerId: 1, clientX: 20, clientY: 20 });
|
||||
fireEvent.pointerMove(shape, { pointerId: 1, clientX: 140, clientY: 160 });
|
||||
fireEvent.pointerUp(shape, { pointerId: 1, clientX: 140, clientY: 160 });
|
||||
|
||||
await waitFor(() => expect(onDropShape).toHaveBeenCalledTimes(1));
|
||||
expect(onDropShape.mock.calls[0]?.[0]).toMatchObject({
|
||||
runId: 'run-1',
|
||||
holeId: 'hole-a',
|
||||
clientSnapshotVersion: 3,
|
||||
});
|
||||
expect(elementsFromPoint).toHaveBeenCalled();
|
||||
});
|
||||
Reference in New Issue
Block a user