mirror of
https://github.com/langgenius/dify.git
synced 2026-02-09 23:20:12 -05:00
test: fix test (#31869)
This commit is contained in:
@@ -16,6 +16,14 @@ vi.mock('react-i18next', () => ({
|
|||||||
}),
|
}),
|
||||||
}))
|
}))
|
||||||
|
|
||||||
|
vi.mock('@/config', async (importOriginal) => {
|
||||||
|
const actual = await importOriginal() as object
|
||||||
|
return {
|
||||||
|
...actual,
|
||||||
|
IS_CLOUD_EDITION: true,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
const mockUseGetTryAppInfo = vi.fn()
|
const mockUseGetTryAppInfo = vi.fn()
|
||||||
|
|
||||||
vi.mock('@/service/use-try-app', () => ({
|
vi.mock('@/service/use-try-app', () => ({
|
||||||
|
|||||||
@@ -14,6 +14,14 @@ vi.mock('react-i18next', () => ({
|
|||||||
}),
|
}),
|
||||||
}))
|
}))
|
||||||
|
|
||||||
|
vi.mock('@/config', async (importOriginal) => {
|
||||||
|
const actual = await importOriginal() as object
|
||||||
|
return {
|
||||||
|
...actual,
|
||||||
|
IS_CLOUD_EDITION: true,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
describe('Tab', () => {
|
describe('Tab', () => {
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
cleanup()
|
cleanup()
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import type { TriggerSubscriptionBuilder } from '@/app/components/workflow/block-selector/types'
|
import type { TriggerSubscriptionBuilder } from '@/app/components/workflow/block-selector/types'
|
||||||
import { fireEvent, render, screen, waitFor } from '@testing-library/react'
|
import { act, fireEvent, render, screen, waitFor } from '@testing-library/react'
|
||||||
import * as React from 'react'
|
import * as React from 'react'
|
||||||
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
|
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
|
||||||
// Import after mocks
|
// Import after mocks
|
||||||
@@ -821,6 +821,9 @@ describe('CommonCreateModal', () => {
|
|||||||
expect(mockCreateBuilder).toHaveBeenCalled()
|
expect(mockCreateBuilder).toHaveBeenCalled()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// Flush pending state updates from createBuilder promise resolution
|
||||||
|
await act(async () => {})
|
||||||
|
|
||||||
const input = screen.getByTestId('form-field-webhook_url')
|
const input = screen.getByTestId('form-field-webhook_url')
|
||||||
fireEvent.change(input, { target: { value: 'https://example.com/webhook' } })
|
fireEvent.change(input, { target: { value: 'https://example.com/webhook' } })
|
||||||
|
|
||||||
|
|||||||
@@ -140,13 +140,13 @@ class MockFileReader {
|
|||||||
onload: ((e: { target: { result: string | null } }) => void) | null = null
|
onload: ((e: { target: { result: string | null } }) => void) | null = null
|
||||||
|
|
||||||
readAsText(_file: File) {
|
readAsText(_file: File) {
|
||||||
// Simulate async file reading
|
// Simulate async file reading using queueMicrotask for more reliable async behavior
|
||||||
setTimeout(() => {
|
queueMicrotask(() => {
|
||||||
this.result = 'test file content'
|
this.result = 'test file content'
|
||||||
if (this.onload) {
|
if (this.onload) {
|
||||||
this.onload({ target: { result: this.result } })
|
this.onload({ target: { result: this.result } })
|
||||||
}
|
}
|
||||||
}, 0)
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -174,6 +174,7 @@ describe('UpdateDSLModal', () => {
|
|||||||
status: DSLImportStatus.COMPLETED,
|
status: DSLImportStatus.COMPLETED,
|
||||||
pipeline_id: 'test-pipeline-id',
|
pipeline_id: 'test-pipeline-id',
|
||||||
})
|
})
|
||||||
|
mockHandleCheckPluginDependencies.mockResolvedValue(undefined)
|
||||||
|
|
||||||
// Mock FileReader
|
// Mock FileReader
|
||||||
originalFileReader = globalThis.FileReader
|
originalFileReader = globalThis.FileReader
|
||||||
@@ -472,14 +473,14 @@ describe('UpdateDSLModal', () => {
|
|||||||
await waitFor(() => {
|
await waitFor(() => {
|
||||||
const importButton = screen.getByText('common.overwriteAndImport')
|
const importButton = screen.getByText('common.overwriteAndImport')
|
||||||
expect(importButton).not.toBeDisabled()
|
expect(importButton).not.toBeDisabled()
|
||||||
})
|
}, { timeout: 1000 })
|
||||||
|
|
||||||
const importButton = screen.getByText('common.overwriteAndImport')
|
const importButton = screen.getByText('common.overwriteAndImport')
|
||||||
fireEvent.click(importButton)
|
fireEvent.click(importButton)
|
||||||
|
|
||||||
await waitFor(() => {
|
await waitFor(() => {
|
||||||
expect(mockOnImport).toHaveBeenCalled()
|
expect(mockOnImport).toHaveBeenCalled()
|
||||||
})
|
}, { timeout: 1000 })
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should show warning notification on import with warnings', async () => {
|
it('should show warning notification on import with warnings', async () => {
|
||||||
@@ -664,7 +665,7 @@ describe('UpdateDSLModal', () => {
|
|||||||
await waitFor(() => {
|
await waitFor(() => {
|
||||||
const importButton = screen.getByText('common.overwriteAndImport')
|
const importButton = screen.getByText('common.overwriteAndImport')
|
||||||
expect(importButton).not.toBeDisabled()
|
expect(importButton).not.toBeDisabled()
|
||||||
})
|
}, { timeout: 1000 })
|
||||||
|
|
||||||
const importButton = screen.getByText('common.overwriteAndImport')
|
const importButton = screen.getByText('common.overwriteAndImport')
|
||||||
fireEvent.click(importButton)
|
fireEvent.click(importButton)
|
||||||
@@ -672,7 +673,7 @@ describe('UpdateDSLModal', () => {
|
|||||||
// Wait for the error modal to be shown after setTimeout
|
// Wait for the error modal to be shown after setTimeout
|
||||||
await waitFor(() => {
|
await waitFor(() => {
|
||||||
expect(screen.getByText('newApp.appCreateDSLErrorTitle')).toBeInTheDocument()
|
expect(screen.getByText('newApp.appCreateDSLErrorTitle')).toBeInTheDocument()
|
||||||
}, { timeout: 500 })
|
}, { timeout: 1000 })
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should show version info in error modal', async () => {
|
it('should show version info in error modal', async () => {
|
||||||
|
|||||||
@@ -61,6 +61,12 @@ vi.mock('@/service/use-pipeline', () => ({
|
|||||||
}),
|
}),
|
||||||
}))
|
}))
|
||||||
|
|
||||||
|
// Mock download utility
|
||||||
|
const mockDownloadBlob = vi.fn()
|
||||||
|
vi.mock('@/utils/download', () => ({
|
||||||
|
downloadBlob: (...args: unknown[]) => mockDownloadBlob(...args),
|
||||||
|
}))
|
||||||
|
|
||||||
// Mock workflow service
|
// Mock workflow service
|
||||||
const mockFetchWorkflowDraft = vi.fn()
|
const mockFetchWorkflowDraft = vi.fn()
|
||||||
vi.mock('@/service/workflow', () => ({
|
vi.mock('@/service/workflow', () => ({
|
||||||
@@ -77,33 +83,9 @@ vi.mock('@/app/components/workflow/constants', () => ({
|
|||||||
// ============================================================================
|
// ============================================================================
|
||||||
|
|
||||||
describe('useDSL', () => {
|
describe('useDSL', () => {
|
||||||
let mockLink: { href: string, download: string, click: ReturnType<typeof vi.fn> }
|
|
||||||
let originalCreateElement: typeof document.createElement
|
|
||||||
let mockCreateObjectURL: ReturnType<typeof vi.spyOn>
|
|
||||||
let mockRevokeObjectURL: ReturnType<typeof vi.spyOn>
|
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
vi.clearAllMocks()
|
vi.clearAllMocks()
|
||||||
|
|
||||||
// Create a proper mock link element
|
|
||||||
mockLink = {
|
|
||||||
href: '',
|
|
||||||
download: '',
|
|
||||||
click: vi.fn(),
|
|
||||||
}
|
|
||||||
|
|
||||||
// Save original and mock selectively - only intercept 'a' elements
|
|
||||||
originalCreateElement = document.createElement.bind(document)
|
|
||||||
document.createElement = vi.fn((tagName: string) => {
|
|
||||||
if (tagName === 'a') {
|
|
||||||
return mockLink as unknown as HTMLElement
|
|
||||||
}
|
|
||||||
return originalCreateElement(tagName)
|
|
||||||
}) as typeof document.createElement
|
|
||||||
|
|
||||||
mockCreateObjectURL = vi.spyOn(URL, 'createObjectURL').mockReturnValue('blob:test-url')
|
|
||||||
mockRevokeObjectURL = vi.spyOn(URL, 'revokeObjectURL').mockImplementation(() => {})
|
|
||||||
|
|
||||||
// Default store state
|
// Default store state
|
||||||
mockWorkflowStoreGetState.mockReturnValue({
|
mockWorkflowStoreGetState.mockReturnValue({
|
||||||
pipelineId: 'test-pipeline-id',
|
pipelineId: 'test-pipeline-id',
|
||||||
@@ -118,9 +100,6 @@ describe('useDSL', () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
document.createElement = originalCreateElement
|
|
||||||
mockCreateObjectURL.mockRestore()
|
|
||||||
mockRevokeObjectURL.mockRestore()
|
|
||||||
vi.clearAllMocks()
|
vi.clearAllMocks()
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -187,9 +166,7 @@ describe('useDSL', () => {
|
|||||||
await result.current.handleExportDSL()
|
await result.current.handleExportDSL()
|
||||||
})
|
})
|
||||||
|
|
||||||
expect(document.createElement).toHaveBeenCalledWith('a')
|
expect(mockDownloadBlob).toHaveBeenCalled()
|
||||||
expect(mockCreateObjectURL).toHaveBeenCalled()
|
|
||||||
expect(mockRevokeObjectURL).toHaveBeenCalledWith('blob:test-url')
|
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should use correct file extension for download', async () => {
|
it('should use correct file extension for download', async () => {
|
||||||
@@ -199,17 +176,25 @@ describe('useDSL', () => {
|
|||||||
await result.current.handleExportDSL()
|
await result.current.handleExportDSL()
|
||||||
})
|
})
|
||||||
|
|
||||||
expect(mockLink.download).toBe('Test Knowledge Base.pipeline')
|
expect(mockDownloadBlob).toHaveBeenCalledWith(
|
||||||
|
expect.objectContaining({
|
||||||
|
fileName: 'Test Knowledge Base.pipeline',
|
||||||
|
}),
|
||||||
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should trigger download click', async () => {
|
it('should pass blob data to downloadBlob', async () => {
|
||||||
const { result } = renderHook(() => useDSL())
|
const { result } = renderHook(() => useDSL())
|
||||||
|
|
||||||
await act(async () => {
|
await act(async () => {
|
||||||
await result.current.handleExportDSL()
|
await result.current.handleExportDSL()
|
||||||
})
|
})
|
||||||
|
|
||||||
expect(mockLink.click).toHaveBeenCalled()
|
expect(mockDownloadBlob).toHaveBeenCalledWith(
|
||||||
|
expect.objectContaining({
|
||||||
|
data: expect.any(Blob),
|
||||||
|
}),
|
||||||
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should show error notification on export failure', async () => {
|
it('should show error notification on export failure', async () => {
|
||||||
|
|||||||
@@ -172,6 +172,9 @@ describe('EditCustomCollectionModal', () => {
|
|||||||
expect(parseParamsSchemaMock).toHaveBeenCalledWith('{}')
|
expect(parseParamsSchemaMock).toHaveBeenCalledWith('{}')
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// Flush pending state updates from parseParamsSchema promise resolution
|
||||||
|
await act(async () => {})
|
||||||
|
|
||||||
await act(async () => {
|
await act(async () => {
|
||||||
fireEvent.click(screen.getByText('common.operation.save'))
|
fireEvent.click(screen.getByText('common.operation.save'))
|
||||||
})
|
})
|
||||||
@@ -184,6 +187,10 @@ describe('EditCustomCollectionModal', () => {
|
|||||||
credentials: {
|
credentials: {
|
||||||
auth_type: 'none',
|
auth_type: 'none',
|
||||||
},
|
},
|
||||||
|
icon: {
|
||||||
|
content: '🕵️',
|
||||||
|
background: '#FEF7C3',
|
||||||
|
},
|
||||||
labels: [],
|
labels: [],
|
||||||
}))
|
}))
|
||||||
expect(toastNotifySpy).not.toHaveBeenCalled()
|
expect(toastNotifySpy).not.toHaveBeenCalled()
|
||||||
|
|||||||
Reference in New Issue
Block a user