mirror of
https://github.com/langgenius/dify.git
synced 2026-02-24 18:05:11 +00:00
138 lines
3.8 KiB
TypeScript
138 lines
3.8 KiB
TypeScript
import { fireEvent, render, screen } from '@testing-library/react'
|
|
import { MARKETPLACE_URL_PREFIX } from '@/config'
|
|
import { AppModeEnum } from '@/types/app'
|
|
import Apps from './index'
|
|
|
|
const mockUseExploreAppList = vi.fn()
|
|
|
|
vi.mock('ahooks', () => ({
|
|
useDebounceFn: (fn: () => void) => ({
|
|
run: () => setTimeout(fn, 0),
|
|
cancel: vi.fn(),
|
|
flush: () => fn(),
|
|
}),
|
|
}))
|
|
vi.mock('@/context/app-context', () => ({
|
|
useAppContext: () => ({ isCurrentWorkspaceEditor: true }),
|
|
}))
|
|
vi.mock('nuqs', () => ({
|
|
useQueryState: () => ['Recommended', vi.fn()],
|
|
}))
|
|
vi.mock('@/service/use-explore', () => ({
|
|
useExploreAppList: () => mockUseExploreAppList(),
|
|
}))
|
|
vi.mock('@/app/components/app/type-selector', () => ({
|
|
default: ({ value, onChange }: { value: AppModeEnum[], onChange: (value: AppModeEnum[]) => void }) => (
|
|
<button data-testid="type-selector" onClick={() => onChange([...value, 'chat' as AppModeEnum])}>{value.join(',')}</button>
|
|
),
|
|
}))
|
|
vi.mock('../app-card', () => ({
|
|
default: ({ app, onCreate }: { app: any, onCreate: () => void }) => (
|
|
<div
|
|
data-testid="app-card"
|
|
data-name={app.app.name}
|
|
onClick={onCreate}
|
|
>
|
|
{app.app.name}
|
|
</div>
|
|
),
|
|
}))
|
|
vi.mock('@/app/components/explore/create-app-modal', () => ({
|
|
default: () => <div data-testid="create-from-template-modal" />,
|
|
}))
|
|
vi.mock('@/app/components/base/toast', () => ({
|
|
default: { notify: vi.fn() },
|
|
}))
|
|
vi.mock('@/app/components/base/amplitude', () => ({
|
|
trackEvent: vi.fn(),
|
|
}))
|
|
vi.mock('@/service/apps', () => ({
|
|
importDSL: vi.fn().mockResolvedValue({ app_id: '1' }),
|
|
}))
|
|
vi.mock('@/service/explore', () => ({
|
|
fetchAppDetail: vi.fn().mockResolvedValue({
|
|
export_data: 'dsl',
|
|
mode: 'chat',
|
|
}),
|
|
}))
|
|
vi.mock('@/app/components/workflow/plugin-dependency/hooks', () => ({
|
|
usePluginDependencies: () => ({
|
|
handleCheckPluginDependencies: vi.fn(),
|
|
}),
|
|
}))
|
|
vi.mock('@/utils/app-redirection', () => ({
|
|
getRedirection: vi.fn(),
|
|
}))
|
|
vi.mock('next/navigation', () => ({
|
|
useRouter: () => ({ push: vi.fn() }),
|
|
}))
|
|
|
|
const createAppEntry = (name: string, category: string) => ({
|
|
app_id: name,
|
|
category,
|
|
app: {
|
|
id: name,
|
|
name,
|
|
icon_type: 'emoji',
|
|
icon: '🙂',
|
|
icon_background: '#000',
|
|
icon_url: null,
|
|
description: 'desc',
|
|
mode: AppModeEnum.CHAT,
|
|
},
|
|
})
|
|
|
|
describe('Apps', () => {
|
|
const defaultData = {
|
|
allList: [
|
|
createAppEntry('Alpha', 'Cat A'),
|
|
createAppEntry('Bravo', 'Cat B'),
|
|
],
|
|
categories: ['Cat A', 'Cat B'],
|
|
}
|
|
|
|
beforeEach(() => {
|
|
vi.clearAllMocks()
|
|
mockUseExploreAppList.mockReturnValue({
|
|
data: defaultData,
|
|
isLoading: false,
|
|
})
|
|
})
|
|
|
|
it('renders template cards when data is available', () => {
|
|
render(<Apps />)
|
|
|
|
expect(screen.getAllByTestId('app-card')).toHaveLength(2)
|
|
expect(screen.getByText('Alpha')).toBeInTheDocument()
|
|
expect(screen.getByText('Bravo')).toBeInTheDocument()
|
|
})
|
|
|
|
it('opens create modal when a template card is clicked', () => {
|
|
render(<Apps />)
|
|
|
|
fireEvent.click(screen.getAllByTestId('app-card')[0])
|
|
expect(screen.getByTestId('create-from-template-modal')).toBeInTheDocument()
|
|
})
|
|
|
|
it('shows no template message when list is empty', () => {
|
|
mockUseExploreAppList.mockReturnValueOnce({
|
|
data: { allList: [], categories: [] },
|
|
isLoading: false,
|
|
})
|
|
|
|
render(<Apps />)
|
|
|
|
expect(screen.getByText('app.newApp.noTemplateFound')).toBeInTheDocument()
|
|
expect(screen.getByText('app.newApp.noTemplateFoundTip')).toBeInTheDocument()
|
|
})
|
|
|
|
it('renders explore community link', () => {
|
|
render(<Apps />)
|
|
|
|
const link = screen.getByRole('link', { name: 'app.newApp.exploreCommunity' })
|
|
expect(link).toHaveAttribute('href', `${MARKETPLACE_URL_PREFIX.replace(/\/$/, '')}/templates`)
|
|
expect(link).toHaveAttribute('target', '_blank')
|
|
expect(link).toHaveAttribute('rel', 'noopener noreferrer')
|
|
})
|
|
})
|