import { render, screen, waitFor } from '@testing-library/react' import userEvent from '@testing-library/user-event' import type { ReactNode } from 'react' import AssistedAssemblyClient from './AssistedAssemblyClient' import { createDraftGroup } from '@/lib/open-product/platform-api' import type { AssemblyWorkspaceSnapshot } from '@/lib/open-product/assembly-workspace' let mockSearchParams = new URLSearchParams() jest.mock('next/link', () => ({ __esModule: true, default: ({ href, children }: { href: string; children: ReactNode }) => {children}, })) const push = jest.fn() jest.mock('next/navigation', () => ({ useRouter: () => ({ push }), useSearchParams: () => mockSearchParams, })) jest.mock('@/components/platform/AssemblyWorkbenchV2', () => ({ __esModule: true, AssemblyWorkbenchV2: ({ value, onChange, rightDrawerContent, }: { value: AssemblyWorkspaceSnapshot onChange: (next: AssemblyWorkspaceSnapshot) => void rightDrawerContent?: ReactNode }) => (
{rightDrawerContent}
辅助拼装工作台
库存:{value.inventory.length}
节点:{value.nodes.length}
首个规格款:{value.inventory[0]?.selectedVariantId ?? 'none'}
), })) jest.mock('@/lib/open-product/platform-api', () => ({ __esModule: true, createDraftGroup: jest.fn(), })) describe('AssistedAssemblyClient', () => { beforeEach(() => { push.mockReset() jest.mocked(createDraftGroup).mockReset() mockSearchParams = new URLSearchParams() }) it('默认会预选当前品类下的最新资产族,且调整选择后会同步到辅助拼装工作台', async () => { const actor = userEvent.setup() render( , ) expect(screen.getByText('辅助拼装工作台')).toBeInTheDocument() expect(screen.getByText('库存:2')).toBeInTheDocument() await actor.click(screen.getByRole('button', { name: '支撑组件' })) await actor.click(screen.getByRole('button', { name: /桌腿A/ })) await waitFor(() => { expect(screen.getByText('库存:1')).toBeInTheDocument() }) await actor.click(screen.getByRole('button', { name: /桌腿A/ })) await waitFor(() => { expect(screen.getByText('库存:2')).toBeInTheDocument() }) }) it('保存草稿组时会发送去模板化后的辅助拼装输入', async () => { const actor = userEvent.setup() jest.mocked(createDraftGroup).mockResolvedValue({ draftGroup: { id: 'draft-group-1' }, } as never) render( , ) await actor.click(screen.getByRole('button', { name: /准备可保存工作台/ })) await actor.clear(screen.getByLabelText('草稿组名称')) await actor.type(screen.getByLabelText('草稿组名称'), '测试草稿组') await actor.click(screen.getByRole('button', { name: /仅保存草稿/ })) await waitFor(() => { expect(createDraftGroup).toHaveBeenCalledWith( expect.objectContaining({ categoryId: 'category-desk', assemblies: [ expect.objectContaining({ source: 'assisted-assembly', }), ], }), ) }) expect(jest.mocked(createDraftGroup).mock.calls[0]?.[0]).not.toHaveProperty('seriesTemplateId') }) it('资产中心带料进入时,会保留来源资产族并保留草稿规格款作为默认选择', async () => { const actor = userEvent.setup() mockSearchParams = new URLSearchParams( 'entryMode=asset-center&source=asset-center&desktopFamilyIds=family-board-draft', ) render( , ) await waitFor(() => { expect(screen.getByText('辅助拼装工作台')).toBeInTheDocument() expect(screen.getByText('库存:1')).toBeInTheDocument() expect(screen.getByText('首个规格款:variant-board-draft')).toBeInTheDocument() }) await actor.click(screen.getByRole('button', { name: '板件资产' })) await waitFor(() => { expect(screen.getByRole('button', { name: /草稿桌面/ })).toHaveAttribute('aria-pressed', 'true') }) }) it('源 SKU 新增进入时,只预选来源装配涉及的资产族,不会回退成全量默认选中', async () => { const actor = userEvent.setup() mockSearchParams = new URLSearchParams( 'entryMode=source-sku&source=assisted-assembly&sourceSkuId=sku-source-1&desktopFamilyIds=family-board-source', ) render( , ) await waitFor(() => { expect(screen.getByText('库存:1')).toBeInTheDocument() expect(screen.getByText('首个规格款:variant-board-source')).toBeInTheDocument() }) await actor.click(screen.getByRole('button', { name: '板件资产' })) await waitFor(() => { expect(screen.getByRole('button', { name: /源桌面/ })).toHaveAttribute('aria-pressed', 'true') expect(screen.getByRole('button', { name: /额外桌面/ })).toHaveAttribute('aria-pressed', 'false') }) }) })