mirror of
https://github.com/langgenius/dify.git
synced 2026-05-03 08:58:09 +08:00
test(web): enhance unit tests for credential and popup components
- Updated tests for CredentialItem to improve delete button interaction and check icon rendering. - Enhanced PopupItem tests by mocking credential panel state for various scenarios, ensuring accurate rendering based on credit status. - Adjusted Popup tests to include trial credits mock for better coverage of credit management logic. - Refactored model list item tests to include wrapper for consistent rendering context.
This commit is contained in:
@ -122,14 +122,16 @@ describe('CredentialItem', () => {
|
||||
|
||||
render(<CredentialItem credential={credential} disabled onDelete={onDelete} />)
|
||||
|
||||
fireEvent.click(screen.getByTestId('delete-icon').closest('button') as HTMLButtonElement)
|
||||
const deleteButton = screen.getAllByRole('button')
|
||||
.find(b => b.querySelector('.i-ri-delete-bin-line'))!
|
||||
fireEvent.click(deleteButton)
|
||||
|
||||
expect(onDelete).not.toHaveBeenCalled()
|
||||
})
|
||||
|
||||
// showSelectedIcon=true: check icon area is always rendered; check icon only appears when IDs match
|
||||
it('should render check icon area when showSelectedIcon=true and selectedCredentialId matches', () => {
|
||||
render(
|
||||
const { container } = render(
|
||||
<CredentialItem
|
||||
credential={credential}
|
||||
showSelectedIcon
|
||||
@ -137,7 +139,7 @@ describe('CredentialItem', () => {
|
||||
/>,
|
||||
)
|
||||
|
||||
expect(screen.getByTestId('check-icon')).toBeInTheDocument()
|
||||
expect(container.querySelector('.i-ri-check-line')).toBeInTheDocument()
|
||||
})
|
||||
|
||||
it('should not render check icon when showSelectedIcon=true but selectedCredentialId does not match', () => {
|
||||
|
||||
@ -43,6 +43,22 @@ vi.mock('@/app/components/base/tooltip', () => ({
|
||||
default: ({ children }: { children: React.ReactNode }) => <div>{children}</div>,
|
||||
}))
|
||||
|
||||
const mockCredentialPanelState = vi.hoisted(() => vi.fn())
|
||||
vi.mock('../provider-added-card/use-credential-panel-state', () => ({
|
||||
useCredentialPanelState: mockCredentialPanelState,
|
||||
}))
|
||||
|
||||
vi.mock('../provider-added-card/use-change-provider-priority', () => ({
|
||||
useChangeProviderPriority: () => ({
|
||||
isChangingPriority: false,
|
||||
handleChangePriority: vi.fn(),
|
||||
}),
|
||||
}))
|
||||
|
||||
vi.mock('../provider-added-card/model-auth-dropdown/dropdown-content', () => ({
|
||||
default: () => null,
|
||||
}))
|
||||
|
||||
const mockSetShowModelModal = vi.hoisted(() => vi.fn())
|
||||
vi.mock('@/context/modal-context', () => ({
|
||||
useModalContext: () => ({
|
||||
@ -100,6 +116,16 @@ describe('PopupItem', () => {
|
||||
mockUseAppContext.mockReturnValue({
|
||||
currentWorkspace: { trial_credits: 200, trial_credits_used: 0 },
|
||||
})
|
||||
mockCredentialPanelState.mockReturnValue({
|
||||
variant: 'api-active',
|
||||
priority: 'apiKey',
|
||||
supportsCredits: false,
|
||||
showPrioritySwitcher: false,
|
||||
hasCredentials: true,
|
||||
isCreditsExhausted: false,
|
||||
credentialName: 'my-api-key',
|
||||
credits: 200,
|
||||
})
|
||||
})
|
||||
|
||||
it('should call onSelect when clicking an active model', () => {
|
||||
@ -206,6 +232,16 @@ describe('PopupItem', () => {
|
||||
},
|
||||
})],
|
||||
})
|
||||
mockCredentialPanelState.mockReturnValue({
|
||||
variant: 'api-required-configure',
|
||||
priority: 'apiKey',
|
||||
supportsCredits: false,
|
||||
showPrioritySwitcher: false,
|
||||
hasCredentials: false,
|
||||
isCreditsExhausted: false,
|
||||
credentialName: undefined,
|
||||
credits: 0,
|
||||
})
|
||||
|
||||
render(<PopupItem model={makeModel()} onSelect={vi.fn()} onHide={vi.fn()} />)
|
||||
|
||||
@ -218,6 +254,16 @@ describe('PopupItem', () => {
|
||||
preferred_provider_type: PreferredProviderTypeEnum.system,
|
||||
})],
|
||||
})
|
||||
mockCredentialPanelState.mockReturnValue({
|
||||
variant: 'credits-active',
|
||||
priority: 'credits',
|
||||
supportsCredits: true,
|
||||
showPrioritySwitcher: true,
|
||||
hasCredentials: false,
|
||||
isCreditsExhausted: false,
|
||||
credentialName: undefined,
|
||||
credits: 200,
|
||||
})
|
||||
|
||||
render(<PopupItem model={makeModel()} onSelect={vi.fn()} onHide={vi.fn()} />)
|
||||
|
||||
@ -233,6 +279,16 @@ describe('PopupItem', () => {
|
||||
mockUseAppContext.mockReturnValue({
|
||||
currentWorkspace: { trial_credits: 100, trial_credits_used: 100 },
|
||||
})
|
||||
mockCredentialPanelState.mockReturnValue({
|
||||
variant: 'credits-exhausted',
|
||||
priority: 'credits',
|
||||
supportsCredits: true,
|
||||
showPrioritySwitcher: true,
|
||||
hasCredentials: false,
|
||||
isCreditsExhausted: true,
|
||||
credentialName: undefined,
|
||||
credits: 0,
|
||||
})
|
||||
|
||||
render(<PopupItem model={makeModel()} onSelect={vi.fn()} onHide={vi.fn()} />)
|
||||
|
||||
|
||||
@ -49,6 +49,16 @@ vi.mock('@/context/provider-context', () => ({
|
||||
useProviderContext: () => ({ modelProviders: [] }),
|
||||
}))
|
||||
|
||||
vi.mock('../provider-added-card/use-trial-credits', () => ({
|
||||
useTrialCredits: () => ({
|
||||
credits: 200,
|
||||
totalCredits: 200,
|
||||
isExhausted: false,
|
||||
isLoading: false,
|
||||
nextCreditResetDate: undefined,
|
||||
}),
|
||||
}))
|
||||
|
||||
vi.mock('next-themes', () => ({
|
||||
useTheme: () => ({ theme: 'light' }),
|
||||
}))
|
||||
|
||||
@ -155,6 +155,7 @@ describe('ModelListItem', () => {
|
||||
provider={mockProvider}
|
||||
isConfigurable={false}
|
||||
/>,
|
||||
{ wrapper: createWrapper() },
|
||||
)
|
||||
|
||||
// Assert
|
||||
@ -180,6 +181,7 @@ describe('ModelListItem', () => {
|
||||
provider={mockProvider}
|
||||
isConfigurable={false}
|
||||
/>,
|
||||
{ wrapper: createWrapper() },
|
||||
)
|
||||
|
||||
// Assert - Badge component should render
|
||||
@ -200,6 +202,7 @@ describe('ModelListItem', () => {
|
||||
provider={mockProvider}
|
||||
isConfigurable={false}
|
||||
/>,
|
||||
{ wrapper: createWrapper() },
|
||||
)
|
||||
|
||||
// Assert - ConfigModel should show because plan.type === 'sandbox'
|
||||
@ -219,6 +222,7 @@ describe('ModelListItem', () => {
|
||||
provider={mockProvider}
|
||||
isConfigurable={false}
|
||||
/>,
|
||||
{ wrapper: createWrapper() },
|
||||
)
|
||||
|
||||
// Assert - ConfigModel should NOT show because plan.type !== 'sandbox' and load balancing is disabled
|
||||
@ -238,6 +242,7 @@ describe('ModelListItem', () => {
|
||||
provider={mockProvider}
|
||||
isConfigurable={false}
|
||||
/>,
|
||||
{ wrapper: createWrapper() },
|
||||
)
|
||||
|
||||
// Assert - ConfigModel should not render because status is not active/disabled
|
||||
@ -259,6 +264,7 @@ describe('ModelListItem', () => {
|
||||
provider={mockProvider}
|
||||
isConfigurable={true}
|
||||
/>,
|
||||
{ wrapper: createWrapper() },
|
||||
)
|
||||
|
||||
// Assert
|
||||
|
||||
@ -438,7 +438,7 @@ describe('PluginTaskList Component', () => {
|
||||
// Translation key is returned as text in tests, multiple matches expected (title + status)
|
||||
expect(screen.getAllByText(/task\.installing/i).length).toBeGreaterThan(0)
|
||||
// Verify section container is rendered
|
||||
expect(document.querySelector('.max-h-\\[200px\\]')).toBeInTheDocument()
|
||||
expect(document.querySelector('.max-h-\\[300px\\]')).toBeInTheDocument()
|
||||
})
|
||||
|
||||
it('should render success plugins section when plugins exist', () => {
|
||||
@ -467,7 +467,7 @@ describe('PluginTaskList Component', () => {
|
||||
)
|
||||
|
||||
// All sections should be present
|
||||
expect(document.querySelectorAll('.max-h-\\[200px\\]').length).toBe(3)
|
||||
expect(document.querySelectorAll('.max-h-\\[300px\\]').length).toBe(3)
|
||||
})
|
||||
})
|
||||
|
||||
@ -523,8 +523,9 @@ describe('PluginTaskList Component', () => {
|
||||
/>,
|
||||
)
|
||||
|
||||
// The individual clear button has the text 'operation.clear'
|
||||
fireEvent.click(screen.getByRole('button', { name: /operation\.clear/i }))
|
||||
const closeButton = screen.getAllByRole('button')
|
||||
.find(btn => btn.querySelector('.i-ri-close-line'))!
|
||||
fireEvent.click(closeButton)
|
||||
|
||||
expect(handleClearSingle).toHaveBeenCalledWith('task-123', 'error-plugin-1')
|
||||
})
|
||||
@ -844,7 +845,7 @@ describe('PluginTasks Integration', () => {
|
||||
fireEvent.click(document.getElementById('plugin-task-trigger')!)
|
||||
|
||||
// All sections should be visible
|
||||
const sections = document.querySelectorAll('.max-h-\\[200px\\]')
|
||||
const sections = document.querySelectorAll('.max-h-\\[300px\\]')
|
||||
expect(sections.length).toBe(3)
|
||||
})
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user