dify/web/features/deployments/deployment-actions/__tests__/edit-dialog.spec.tsx
Stephen Zhou a84c2d36a3
style: format with vp fmt (#38803)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-07-12 15:57:46 +00:00

139 lines
3.8 KiB
TypeScript

import type { DeploymentActionAppInstance } from '../types'
import { render, screen, within } from '@testing-library/react'
import userEvent from '@testing-library/user-event'
import { ScopeProvider } from 'jotai-scope'
import { EditDeploymentDialog } from '../edit-dialog'
import { deploymentActionAppInstanceAtom, editDeploymentDialogOpenAtom } from '../state'
const updateMutationMock = vi.hoisted(() => ({
isPending: false,
mutate: vi.fn(),
}))
const useMutationMock = vi.hoisted(() =>
vi.fn(() => ({
isPending: updateMutationMock.isPending,
mutate: updateMutationMock.mutate,
})),
)
const toastMock = vi.hoisted(() => ({
error: vi.fn(),
success: vi.fn(),
}))
vi.mock('@tanstack/react-query', () => ({
useMutation: useMutationMock,
}))
vi.mock('@langgenius/dify-ui/toast', () => ({
toast: toastMock,
}))
vi.mock('@/service/client', () => ({
consoleQuery: {
enterprise: {
appInstanceService: {
updateAppInstance: {
mutationOptions: () => ({ mutationKey: ['updateAppInstance'] }),
},
},
},
},
}))
function createAppInstance(
overrides: Partial<DeploymentActionAppInstance> = {},
): DeploymentActionAppInstance {
return {
id: 'app-instance-1',
displayName: 'Deployment 1',
description: 'Initial description',
...overrides,
}
}
function renderDialog({
appInstance = createAppInstance(),
open = true,
}: {
appInstance?: DeploymentActionAppInstance
open?: boolean
} = {}) {
render(
<ScopeProvider
atoms={[
[deploymentActionAppInstanceAtom, appInstance],
[editDeploymentDialogOpenAtom, open],
]}
name="EditDeploymentDialogTest"
>
<EditDeploymentDialog />
</ScopeProvider>,
)
}
describe('EditDeploymentDialog', () => {
beforeEach(() => {
vi.clearAllMocks()
updateMutationMock.isPending = false
})
describe('Form submission', () => {
it('should not mount the update mutation before the dialog is opened', () => {
renderDialog({ open: false })
expect(useMutationMock).not.toHaveBeenCalled()
})
it('should render form values from the passed app instance', () => {
renderDialog()
const dialog = screen.getByRole('dialog', { name: 'deployments.card.menu.editInfo' })
expect(
within(dialog).getByRole('textbox', { name: 'deployments.settings.name' }),
).toHaveValue('Deployment 1')
expect(
within(dialog).getByRole('textbox', { name: 'deployments.settings.description' }),
).toHaveValue('Initial description')
})
it('should submit trimmed deployment metadata through the component mutation', async () => {
const user = userEvent.setup()
renderDialog()
const dialog = screen.getByRole('dialog', { name: 'deployments.card.menu.editInfo' })
await user.clear(within(dialog).getByRole('textbox', { name: 'deployments.settings.name' }))
await user.type(
within(dialog).getByRole('textbox', { name: 'deployments.settings.name' }),
' Deployment 2 ',
)
await user.clear(
within(dialog).getByRole('textbox', { name: 'deployments.settings.description' }),
)
await user.type(
within(dialog).getByRole('textbox', { name: 'deployments.settings.description' }),
' Updated description ',
)
await user.click(within(dialog).getByRole('button', { name: 'deployments.settings.save' }))
expect(updateMutationMock.mutate).toHaveBeenCalledWith(
{
params: {
appInstanceId: 'app-instance-1',
},
body: {
appInstanceId: 'app-instance-1',
displayName: 'Deployment 2',
description: 'Updated description',
},
},
expect.objectContaining({
onSuccess: expect.any(Function),
onError: expect.any(Function),
}),
)
})
})
})