mirror of
https://github.com/langgenius/dify.git
synced 2026-07-23 20:18:40 +08:00
159 lines
4.3 KiB
TypeScript
159 lines
4.3 KiB
TypeScript
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
|
|
import { render, screen, waitFor } from '@testing-library/react'
|
|
import userEvent from '@testing-library/user-event'
|
|
import { beforeEach, describe, expect, it, vi } from 'vitest'
|
|
import { SourceAppPicker } from '../source-app-picker'
|
|
|
|
const mocks = vi.hoisted(() => {
|
|
const sourceAppsQuery = {
|
|
data: {
|
|
pages: [
|
|
{
|
|
data: [
|
|
{
|
|
id: 'app-1',
|
|
name: 'Workflow App',
|
|
},
|
|
],
|
|
},
|
|
],
|
|
},
|
|
error: null,
|
|
fetchNextPage: vi.fn(),
|
|
hasNextPage: true,
|
|
isFetching: false,
|
|
isFetchingNextPage: false,
|
|
isLoading: false,
|
|
}
|
|
|
|
return {
|
|
sourceAppsQuery,
|
|
useInfiniteScroll: vi.fn(() => ({
|
|
rootRef: vi.fn(),
|
|
sentinelRef: vi.fn(),
|
|
})),
|
|
}
|
|
})
|
|
|
|
vi.mock('@/features/deployments/create-release/state', async () => {
|
|
const { atom } = await import('jotai')
|
|
|
|
return {
|
|
createReleaseSourceAppsAtom: atom(() =>
|
|
mocks.sourceAppsQuery.data.pages.flatMap((page) => page.data),
|
|
),
|
|
createReleaseSourceAppsErrorAtom: atom(() => mocks.sourceAppsQuery.error),
|
|
createReleaseSourceAppsFetchNextPageAtom: atom(() => mocks.sourceAppsQuery.fetchNextPage),
|
|
createReleaseSourceAppsHasNextPageAtom: atom(() => mocks.sourceAppsQuery.hasNextPage),
|
|
createReleaseSourceAppsIsFetchingAtom: atom(() => mocks.sourceAppsQuery.isFetching),
|
|
createReleaseSourceAppsIsFetchingNextPageAtom: atom(
|
|
() => mocks.sourceAppsQuery.isFetchingNextPage,
|
|
),
|
|
createReleaseSourceAppsIsLoadingAtom: atom(() => mocks.sourceAppsQuery.isLoading),
|
|
createReleaseSourceAppSearchTextAtom: atom(''),
|
|
createReleaseSourceAppsQueryAtom: atom(mocks.sourceAppsQuery),
|
|
}
|
|
})
|
|
|
|
vi.mock('@/features/deployments/shared/hooks/use-infinite-scroll', () => ({
|
|
useInfiniteScroll: mocks.useInfiniteScroll,
|
|
}))
|
|
|
|
function renderSourceAppPicker(disabled: boolean) {
|
|
const queryClient = new QueryClient({
|
|
defaultOptions: {
|
|
queries: {
|
|
retry: false,
|
|
},
|
|
},
|
|
})
|
|
|
|
return render(
|
|
<QueryClientProvider client={queryClient}>
|
|
<SourceAppPicker
|
|
value={{ id: 'app-1', name: 'Workflow 1' }}
|
|
onChange={() => undefined}
|
|
disabled={disabled}
|
|
/>
|
|
</QueryClientProvider>,
|
|
)
|
|
}
|
|
|
|
describe('SourceAppPicker', () => {
|
|
beforeEach(() => {
|
|
vi.clearAllMocks()
|
|
Object.assign(mocks.sourceAppsQuery, {
|
|
data: {
|
|
pages: [
|
|
{
|
|
data: [
|
|
{
|
|
id: 'app-1',
|
|
name: 'Workflow App',
|
|
},
|
|
],
|
|
},
|
|
],
|
|
},
|
|
error: null,
|
|
fetchNextPage: vi.fn(),
|
|
hasNextPage: true,
|
|
isFetching: false,
|
|
isFetchingNextPage: false,
|
|
isLoading: false,
|
|
})
|
|
})
|
|
|
|
it('should disable the switch control when disabled', () => {
|
|
renderSourceAppPicker(true)
|
|
|
|
expect(screen.getByText('Workflow 1')).toBeInTheDocument()
|
|
expect(
|
|
screen.getByRole('combobox', { name: 'deployments.versions.sourceAppOption' }),
|
|
).toBeDisabled()
|
|
})
|
|
|
|
it('should use infinite scroll to load more apps when the picker is open', async () => {
|
|
const user = userEvent.setup()
|
|
|
|
renderSourceAppPicker(false)
|
|
|
|
expect(mocks.useInfiniteScroll).toHaveBeenCalledWith(
|
|
expect.objectContaining({
|
|
fetchNextPage: expect.any(Function),
|
|
hasNextPage: true,
|
|
isFetching: false,
|
|
isFetchingNextPage: false,
|
|
isLoading: false,
|
|
}),
|
|
expect.objectContaining({
|
|
enabled: false,
|
|
rootMargin: '0px 0px 160px 0px',
|
|
threshold: 0.1,
|
|
}),
|
|
)
|
|
|
|
await user.click(screen.getByRole('combobox', { name: 'deployments.versions.sourceAppOption' }))
|
|
|
|
await waitFor(() => {
|
|
expect(mocks.useInfiniteScroll).toHaveBeenLastCalledWith(
|
|
expect.objectContaining({
|
|
fetchNextPage: expect.any(Function),
|
|
hasNextPage: true,
|
|
isFetching: false,
|
|
isFetchingNextPage: false,
|
|
isLoading: false,
|
|
}),
|
|
expect.objectContaining({
|
|
enabled: true,
|
|
rootMargin: '0px 0px 160px 0px',
|
|
threshold: 0.1,
|
|
}),
|
|
)
|
|
})
|
|
expect(
|
|
screen.queryByRole('button', { name: /createModal\.loadMoreApps/ }),
|
|
).not.toBeInTheDocument()
|
|
})
|
|
})
|