mirror of
https://github.com/langgenius/dify.git
synced 2026-04-05 16:59:21 +08:00
refactor: migrate high-risk overlay follow-up selectors (#33795)
Signed-off-by: yyh <yuanyouhuilyz@gmail.com> Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
This commit is contained in:
@@ -32,16 +32,21 @@ vi.mock('@/service/base', () => ({
|
||||
ssePost: mockSsePost,
|
||||
}))
|
||||
|
||||
// Mock Toast.notify - static method that manipulates DOM, needs mocking to verify calls
|
||||
const { mockToastNotify } = vi.hoisted(() => ({
|
||||
mockToastNotify: vi.fn(),
|
||||
// Mock toast.add because the component reports errors through the UI toast manager.
|
||||
const { mockToastAdd } = vi.hoisted(() => ({
|
||||
mockToastAdd: vi.fn(),
|
||||
}))
|
||||
|
||||
vi.mock('@/app/components/base/toast', () => ({
|
||||
default: {
|
||||
notify: mockToastNotify,
|
||||
},
|
||||
}))
|
||||
vi.mock('@/app/components/base/ui/toast', async (importOriginal) => {
|
||||
const actual = await importOriginal<typeof import('@/app/components/base/ui/toast')>()
|
||||
return {
|
||||
...actual,
|
||||
toast: {
|
||||
...actual.toast,
|
||||
add: mockToastAdd,
|
||||
},
|
||||
}
|
||||
})
|
||||
|
||||
// Mock useGetDataSourceAuth - API service hook requires mocking
|
||||
const { mockUseGetDataSourceAuth } = vi.hoisted(() => ({
|
||||
@@ -192,6 +197,7 @@ const createDefaultProps = (overrides?: Partial<OnlineDocumentsProps>): OnlineDo
|
||||
describe('OnlineDocuments', () => {
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks()
|
||||
mockToastAdd.mockReset()
|
||||
|
||||
// Reset store state
|
||||
mockStoreState.documentsData = []
|
||||
@@ -509,9 +515,9 @@ describe('OnlineDocuments', () => {
|
||||
render(<OnlineDocuments {...props} />)
|
||||
|
||||
await waitFor(() => {
|
||||
expect(mockToastNotify).toHaveBeenCalledWith({
|
||||
expect(mockToastAdd).toHaveBeenCalledWith({
|
||||
type: 'error',
|
||||
message: 'Something went wrong',
|
||||
title: 'Something went wrong',
|
||||
})
|
||||
})
|
||||
})
|
||||
@@ -774,9 +780,9 @@ describe('OnlineDocuments', () => {
|
||||
render(<OnlineDocuments {...props} />)
|
||||
|
||||
await waitFor(() => {
|
||||
expect(mockToastNotify).toHaveBeenCalledWith({
|
||||
expect(mockToastAdd).toHaveBeenCalledWith({
|
||||
type: 'error',
|
||||
message: 'API Error Message',
|
||||
title: 'API Error Message',
|
||||
})
|
||||
})
|
||||
})
|
||||
@@ -1094,9 +1100,9 @@ describe('OnlineDocuments', () => {
|
||||
render(<OnlineDocuments {...props} />)
|
||||
|
||||
await waitFor(() => {
|
||||
expect(mockToastNotify).toHaveBeenCalledWith({
|
||||
expect(mockToastAdd).toHaveBeenCalledWith({
|
||||
type: 'error',
|
||||
message: 'Failed to fetch documents',
|
||||
title: 'Failed to fetch documents',
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
@@ -45,15 +45,20 @@ vi.mock('@/service/use-datasource', () => ({
|
||||
useGetDataSourceAuth: mockUseGetDataSourceAuth,
|
||||
}))
|
||||
|
||||
const { mockToastNotify } = vi.hoisted(() => ({
|
||||
mockToastNotify: vi.fn(),
|
||||
const { mockToastAdd } = vi.hoisted(() => ({
|
||||
mockToastAdd: vi.fn(),
|
||||
}))
|
||||
|
||||
vi.mock('@/app/components/base/toast', () => ({
|
||||
default: {
|
||||
notify: mockToastNotify,
|
||||
},
|
||||
}))
|
||||
vi.mock('@/app/components/base/ui/toast', async (importOriginal) => {
|
||||
const actual = await importOriginal<typeof import('@/app/components/base/ui/toast')>()
|
||||
return {
|
||||
...actual,
|
||||
toast: {
|
||||
...actual.toast,
|
||||
add: mockToastAdd,
|
||||
},
|
||||
}
|
||||
})
|
||||
|
||||
// Note: zustand/react/shallow useShallow is imported directly (simple utility function)
|
||||
|
||||
@@ -231,6 +236,7 @@ const resetMockStoreState = () => {
|
||||
describe('OnlineDrive', () => {
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks()
|
||||
mockToastAdd.mockReset()
|
||||
|
||||
// Reset store state
|
||||
resetMockStoreState()
|
||||
@@ -541,9 +547,9 @@ describe('OnlineDrive', () => {
|
||||
render(<OnlineDrive {...props} />)
|
||||
|
||||
await waitFor(() => {
|
||||
expect(mockToastNotify).toHaveBeenCalledWith({
|
||||
expect(mockToastAdd).toHaveBeenCalledWith({
|
||||
type: 'error',
|
||||
message: errorMessage,
|
||||
title: errorMessage,
|
||||
})
|
||||
})
|
||||
})
|
||||
@@ -915,9 +921,9 @@ describe('OnlineDrive', () => {
|
||||
render(<OnlineDrive {...props} />)
|
||||
|
||||
await waitFor(() => {
|
||||
expect(mockToastNotify).toHaveBeenCalledWith({
|
||||
expect(mockToastAdd).toHaveBeenCalledWith({
|
||||
type: 'error',
|
||||
message: errorMessage,
|
||||
title: errorMessage,
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@@ -1,13 +1,26 @@
|
||||
import type { MockInstance } from 'vitest'
|
||||
import type { RAGPipelineVariables } from '@/models/pipeline'
|
||||
import { fireEvent, render, screen } from '@testing-library/react'
|
||||
import * as React from 'react'
|
||||
import { BaseFieldType } from '@/app/components/base/form/form-scenarios/base/types'
|
||||
import Toast from '@/app/components/base/toast'
|
||||
import { CrawlStep } from '@/models/datasets'
|
||||
import { PipelineInputVarType } from '@/models/pipeline'
|
||||
import Options from '../index'
|
||||
|
||||
const { mockToastAdd } = vi.hoisted(() => ({
|
||||
mockToastAdd: vi.fn(),
|
||||
}))
|
||||
|
||||
vi.mock('@/app/components/base/ui/toast', async (importOriginal) => {
|
||||
const actual = await importOriginal<typeof import('@/app/components/base/ui/toast')>()
|
||||
return {
|
||||
...actual,
|
||||
toast: {
|
||||
...actual.toast,
|
||||
add: mockToastAdd,
|
||||
},
|
||||
}
|
||||
})
|
||||
|
||||
// Mock useInitialData and useConfigurations hooks
|
||||
const { mockUseInitialData, mockUseConfigurations } = vi.hoisted(() => ({
|
||||
mockUseInitialData: vi.fn(),
|
||||
@@ -116,13 +129,9 @@ const createDefaultProps = (overrides?: Partial<OptionsProps>): OptionsProps =>
|
||||
})
|
||||
|
||||
describe('Options', () => {
|
||||
let toastNotifySpy: MockInstance
|
||||
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks()
|
||||
|
||||
// Spy on Toast.notify instead of mocking the entire module
|
||||
toastNotifySpy = vi.spyOn(Toast, 'notify').mockImplementation(() => ({ clear: vi.fn() }))
|
||||
mockToastAdd.mockReset()
|
||||
|
||||
// Reset mock form values
|
||||
Object.keys(mockFormValues).forEach(key => delete mockFormValues[key])
|
||||
@@ -132,10 +141,6 @@ describe('Options', () => {
|
||||
mockUseConfigurations.mockReturnValue([createMockConfiguration()])
|
||||
})
|
||||
|
||||
afterEach(() => {
|
||||
toastNotifySpy.mockRestore()
|
||||
})
|
||||
|
||||
describe('Rendering', () => {
|
||||
it('should render without crashing', () => {
|
||||
const props = createDefaultProps()
|
||||
@@ -638,7 +643,7 @@ describe('Options', () => {
|
||||
fireEvent.click(screen.getByRole('button'))
|
||||
|
||||
// Assert - Toast should be called with error message
|
||||
expect(toastNotifySpy).toHaveBeenCalledWith(
|
||||
expect(mockToastAdd).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
type: 'error',
|
||||
}),
|
||||
@@ -660,10 +665,10 @@ describe('Options', () => {
|
||||
fireEvent.click(screen.getByRole('button'))
|
||||
|
||||
// Assert - Toast message should contain field path
|
||||
expect(toastNotifySpy).toHaveBeenCalledWith(
|
||||
expect(mockToastAdd).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
type: 'error',
|
||||
message: expect.stringContaining('email_address'),
|
||||
title: expect.stringContaining('email_address'),
|
||||
}),
|
||||
)
|
||||
})
|
||||
@@ -714,8 +719,8 @@ describe('Options', () => {
|
||||
fireEvent.click(screen.getByRole('button'))
|
||||
|
||||
// Assert - Toast should be called once (only first error)
|
||||
expect(toastNotifySpy).toHaveBeenCalledTimes(1)
|
||||
expect(toastNotifySpy).toHaveBeenCalledWith(
|
||||
expect(mockToastAdd).toHaveBeenCalledTimes(1)
|
||||
expect(mockToastAdd).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
type: 'error',
|
||||
}),
|
||||
@@ -738,7 +743,7 @@ describe('Options', () => {
|
||||
fireEvent.click(screen.getByRole('button'))
|
||||
|
||||
// Assert - No toast error, onSubmit called
|
||||
expect(toastNotifySpy).not.toHaveBeenCalled()
|
||||
expect(mockToastAdd).not.toHaveBeenCalled()
|
||||
expect(mockOnSubmit).toHaveBeenCalled()
|
||||
})
|
||||
|
||||
@@ -835,7 +840,7 @@ describe('Options', () => {
|
||||
fireEvent.click(screen.getByRole('button'))
|
||||
|
||||
expect(mockOnSubmit).toHaveBeenCalled()
|
||||
expect(toastNotifySpy).not.toHaveBeenCalled()
|
||||
expect(mockToastAdd).not.toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('should fail validation with invalid data', () => {
|
||||
@@ -854,7 +859,7 @@ describe('Options', () => {
|
||||
fireEvent.click(screen.getByRole('button'))
|
||||
|
||||
expect(mockOnSubmit).not.toHaveBeenCalled()
|
||||
expect(toastNotifySpy).toHaveBeenCalled()
|
||||
expect(mockToastAdd).toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('should show error toast message when validation fails', () => {
|
||||
@@ -871,10 +876,10 @@ describe('Options', () => {
|
||||
|
||||
fireEvent.click(screen.getByRole('button'))
|
||||
|
||||
expect(toastNotifySpy).toHaveBeenCalledWith(
|
||||
expect(mockToastAdd).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
type: 'error',
|
||||
message: expect.any(String),
|
||||
title: expect.any(String),
|
||||
}),
|
||||
)
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user