fix: web unittests

This commit is contained in:
hjlarry 2026-04-13 11:43:47 +08:00
parent 71e7aeb489
commit 6f30ecd717
8 changed files with 77 additions and 39 deletions

View File

@ -93,6 +93,10 @@ vi.mock('@/service/tag', () => ({
fetchTagList: vi.fn().mockResolvedValue([]),
}))
vi.mock('@/service/apps', () => ({
fetchWorkflowOnlineUsers: vi.fn().mockResolvedValue({}),
}))
vi.mock('@/service/use-apps', () => ({
useInfiniteAppList: () => ({
data: { pages: mockPages },

View File

@ -80,6 +80,10 @@ vi.mock('@/service/tag', () => ({
fetchTagList: vi.fn().mockResolvedValue([]),
}))
vi.mock('@/service/apps', () => ({
fetchWorkflowOnlineUsers: vi.fn().mockResolvedValue({}),
}))
vi.mock('@/service/use-apps', () => ({
useInfiniteAppList: () => ({
data: { pages: mockPages },

View File

@ -157,7 +157,7 @@ describe('useDatasetCardState', () => {
expect(result.current.modalState.showRenameModal).toBe(false)
})
it('should close confirm delete modal when closeConfirmDelete is called', () => {
it('should close confirm delete modal when closeConfirmDelete is called', async () => {
const dataset = createMockDataset()
const { result } = renderHook(() =>
useDatasetCardState({ dataset, onSuccess: vi.fn() }),
@ -168,7 +168,7 @@ describe('useDatasetCardState', () => {
result.current.detectIsUsedByApp()
})
waitFor(() => {
await waitFor(() => {
expect(result.current.modalState.showConfirmDelete).toBe(true)
})

View File

@ -1,4 +1,4 @@
import { fireEvent, render, screen, waitFor } from '@testing-library/react'
import { fireEvent, render, screen, waitFor, within } from '@testing-library/react'
import userEvent from '@testing-library/user-event'
import { ParamType } from '../../../types'
import List from '../list'
@ -32,7 +32,7 @@ describe('parameter-extractor/extract-parameter/list', () => {
it('edits and deletes parameters through the real item and modal flow', async () => {
const user = userEvent.setup()
const handleChange = vi.fn()
const { container, rerender } = render(
const { rerender } = render(
<List
readonly={false}
list={[createParam()]}
@ -40,19 +40,33 @@ describe('parameter-extractor/extract-parameter/list', () => {
/>,
)
const editAndDeleteButtons = container.querySelectorAll('.cursor-pointer.rounded-md.p-1')
const cityLabel = screen.getByText('city')
const cityRow = cityLabel.closest('.group.relative')
if (!cityRow)
throw new Error('Failed to locate city row')
const editAndDeleteButtons = cityRow.querySelectorAll('.cursor-pointer.rounded-md.p-1')
fireEvent.click(editAndDeleteButtons[0] as HTMLElement)
fireEvent.change(screen.getByDisplayValue('city'), { target: { value: 'city_name' } })
fireEvent.change(screen.getByDisplayValue('City name'), { target: { value: 'Updated city description' } })
await user.click(screen.getByRole('button', { name: 'common.operation.save' }))
await screen.findByRole('dialog')
const dialog = screen.getAllByRole('dialog').at(-1)!
fireEvent.change(
within(dialog).getByPlaceholderText('workflow.nodes.parameterExtractor.addExtractParameterContent.namePlaceholder'),
{ target: { value: 'cityname' } },
)
fireEvent.change(
within(dialog).getByPlaceholderText('workflow.nodes.parameterExtractor.addExtractParameterContent.descriptionPlaceholder'),
{ target: { value: 'Updated city description' } },
)
fireEvent.click(within(dialog).getByRole('button', { name: 'common.operation.save' }))
await waitFor(() => {
expect(handleChange.mock.lastCall).toEqual([[{
name: 'city_name',
expect(handleChange).toHaveBeenCalled()
expect(handleChange.mock.lastCall?.[0]).toEqual([{
name: 'cityname',
type: ParamType.string,
description: 'Updated city description',
required: false,
}], undefined])
}])
})
handleChange.mockClear()
@ -65,7 +79,11 @@ describe('parameter-extractor/extract-parameter/list', () => {
/>,
)
const deleteButtons = container.querySelectorAll('.cursor-pointer.rounded-md.p-1')
const budgetLabel = screen.getByText('budget')
const budgetRow = budgetLabel.closest('.group.relative')
if (!budgetRow)
throw new Error('Failed to locate budget row')
const deleteButtons = budgetRow.querySelectorAll('.cursor-pointer.rounded-md.p-1')
fireEvent.click(deleteButtons[1] as HTMLElement)
expect(handleChange).toHaveBeenCalledWith([])

View File

@ -123,7 +123,9 @@ describe('parameter-extractor/extract-parameter/update', () => {
await user.click(screen.getByRole('button', { name: 'common.operation.save' }))
expect(handleSave).not.toHaveBeenCalled()
expect(mockToast.error).toHaveBeenCalled()
await waitFor(() => {
expect(mockToast.error).toHaveBeenCalled()
})
})
it('requires options before saving a select parameter', async () => {
@ -145,6 +147,8 @@ describe('parameter-extractor/extract-parameter/update', () => {
await user.click(screen.getByRole('button', { name: 'common.operation.save' }))
expect(handleSave).not.toHaveBeenCalled()
expect(mockToast.error).toHaveBeenCalled()
await waitFor(() => {
expect(mockToast.error).toHaveBeenCalled()
})
})
})

View File

@ -45,12 +45,8 @@ describe('trigger-schedule components', () => {
const trigger = screen.getByRole('button', { name: 'workflow.nodes.triggerSchedule.frequency.daily' })
await user.click(trigger)
await waitFor(() => {
expect(trigger).toHaveAttribute('aria-expanded', 'true')
})
await user.click(await screen.findByText('workflow.nodes.triggerSchedule.frequency.weekly'))
await user.keyboard('{ArrowDown}')
await user.keyboard('{Enter}')
await waitFor(() => {
expect(onChange).toHaveBeenCalledWith('weekly')

View File

@ -1,17 +1,26 @@
import type { WebhookParameter } from '../../types'
import { act, fireEvent, render, screen, waitFor } from '@testing-library/react'
import { fireEvent, render, screen, waitFor, within } from '@testing-library/react'
import userEvent from '@testing-library/user-event'
import { VarType } from '@/app/components/workflow/types'
import ParameterTable from '../parameter-table'
const selectOption = async (triggerName: string, optionName: string) => {
await act(async () => {
fireEvent.click(screen.getAllByRole('button', { name: triggerName })[0])
})
const selectOption = async ({
rowKey,
triggerName,
}: {
rowKey: string
triggerName: string
}) => {
const user = userEvent.setup()
const rowInput = screen.getByDisplayValue(rowKey)
const row = rowInput.closest('[style*="min-height"]')
if (!row)
throw new Error('Failed to locate parameter table row')
await act(async () => {
fireEvent.click(await screen.findByRole('option', { name: optionName }))
})
const selectButton = within(row).getByRole('button', { name: triggerName })
await user.click(selectButton)
await user.keyboard('{ArrowDown}')
await user.keyboard('{Enter}')
}
describe('trigger-webhook/parameter-table', () => {
@ -33,7 +42,10 @@ describe('trigger-webhook/parameter-table', () => {
/>,
)
await selectOption('String', 'Number')
await selectOption({
rowKey: 'page',
triggerName: 'String',
})
await waitFor(() => {
expect(onChange).toHaveBeenCalledWith([{

View File

@ -57,16 +57,16 @@ vi.mock('../../hooks/use-nodes-interactions', () => ({
}),
}))
vi.mock('../../hooks', async (importOriginal) => {
const actual = await importOriginal<typeof import('../../hooks')>()
return {
...actual,
useNodesInteractions: () => ({
handleNodeSelect: mockHandleNodeSelect,
}),
useToolIcon: () => '',
}
})
vi.mock('../../hooks', () => ({
useNodesInteractions: () => ({
handleNodeSelect: mockHandleNodeSelect,
}),
useToolIcon: () => '',
}))
vi.mock('@/app/components/workflow/hooks/use-tool-icon', () => ({
useGetToolIcon: () => () => '',
}))
vi.mock('../../nodes/_base/hooks/use-node-crud', () => ({
default: () => ({