diff --git a/web/app/components/app/configuration/dataset-config/card-item/index.spec.tsx b/web/app/components/app/configuration/dataset-config/card-item/index.spec.tsx
index f5a73d9298..3546c642a6 100644
--- a/web/app/components/app/configuration/dataset-config/card-item/index.spec.tsx
+++ b/web/app/components/app/configuration/dataset-config/card-item/index.spec.tsx
@@ -183,7 +183,7 @@ describe('dataset-config/card-item', () => {
expect(onSave).toHaveBeenCalledWith(expect.objectContaining({ name: 'Updated dataset' }))
})
await waitFor(() => {
- expect(screen.getByText('Mock settings modal')).not.toBeVisible()
+ expect(screen.queryByText('Mock settings modal')).not.toBeInTheDocument()
})
})
diff --git a/web/app/components/apps/index.spec.tsx b/web/app/components/apps/index.spec.tsx
index c3dc39955d..c77c1bdb01 100644
--- a/web/app/components/apps/index.spec.tsx
+++ b/web/app/components/apps/index.spec.tsx
@@ -1,3 +1,5 @@
+import type { ReactNode } from 'react'
+import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
import { render, screen } from '@testing-library/react'
import * as React from 'react'
@@ -22,6 +24,15 @@ vi.mock('@/app/education-apply/hooks', () => ({
},
}))
+vi.mock('@/hooks/use-import-dsl', () => ({
+ useImportDSL: () => ({
+ handleImportDSL: vi.fn(),
+ handleImportDSLConfirm: vi.fn(),
+ versions: [],
+ isFetching: false,
+ }),
+}))
+
// Mock List component
vi.mock('./list', () => ({
default: () => {
@@ -30,6 +41,25 @@ vi.mock('./list', () => ({
}))
describe('Apps', () => {
+ const createQueryClient = () => new QueryClient({
+ defaultOptions: {
+ queries: {
+ retry: false,
+ },
+ },
+ })
+
+ const renderWithClient = (ui: React.ReactElement) => {
+ const queryClient = createQueryClient()
+ const wrapper = ({ children }: { children: ReactNode }) => (
+ {children}
+ )
+ return {
+ queryClient,
+ ...render(ui, { wrapper }),
+ }
+ }
+
beforeEach(() => {
vi.clearAllMocks()
documentTitleCalls = []
@@ -38,17 +68,17 @@ describe('Apps', () => {
describe('Rendering', () => {
it('should render without crashing', () => {
- render()
+ renderWithClient()
expect(screen.getByTestId('apps-list')).toBeInTheDocument()
})
it('should render List component', () => {
- render()
+ renderWithClient()
expect(screen.getByText('Apps List')).toBeInTheDocument()
})
it('should have correct container structure', () => {
- const { container } = render()
+ const { container } = renderWithClient()
const wrapper = container.firstChild as HTMLElement
expect(wrapper).toHaveClass('relative', 'flex', 'h-0', 'shrink-0', 'grow', 'flex-col')
})
@@ -56,19 +86,19 @@ describe('Apps', () => {
describe('Hooks', () => {
it('should call useDocumentTitle with correct title', () => {
- render()
+ renderWithClient()
expect(documentTitleCalls).toContain('common.menus.apps')
})
it('should call useEducationInit', () => {
- render()
+ renderWithClient()
expect(educationInitCalls).toBeGreaterThan(0)
})
})
describe('Integration', () => {
it('should render full component tree', () => {
- render()
+ renderWithClient()
// Verify container exists
expect(screen.getByTestId('apps-list')).toBeInTheDocument()
@@ -79,23 +109,32 @@ describe('Apps', () => {
})
it('should handle multiple renders', () => {
- const { rerender } = render()
+ const queryClient = createQueryClient()
+ const { rerender } = render(
+
+
+ ,
+ )
expect(screen.getByTestId('apps-list')).toBeInTheDocument()
- rerender()
+ rerender(
+
+
+ ,
+ )
expect(screen.getByTestId('apps-list')).toBeInTheDocument()
})
})
describe('Styling', () => {
it('should have overflow-y-auto class', () => {
- const { container } = render()
+ const { container } = renderWithClient()
const wrapper = container.firstChild as HTMLElement
expect(wrapper).toHaveClass('overflow-y-auto')
})
it('should have background styling', () => {
- const { container } = render()
+ const { container } = renderWithClient()
const wrapper = container.firstChild as HTMLElement
expect(wrapper).toHaveClass('bg-background-body')
})
diff --git a/web/app/components/base/action-button/index.tsx b/web/app/components/base/action-button/index.tsx
index 735e72b18d..c91d472087 100644
--- a/web/app/components/base/action-button/index.tsx
+++ b/web/app/components/base/action-button/index.tsx
@@ -60,6 +60,7 @@ const ActionButton = ({ className, size, state = ActionButtonState.Default, styl
getActionButtonState(state),
disabled && 'cursor-not-allowed text-text-disabled hover:bg-transparent hover:text-text-disabled',
)}
+ disabled={disabled}
ref={ref}
style={styleCss}
{...props}
diff --git a/web/app/components/base/chat/chat-with-history/hooks.spec.tsx b/web/app/components/base/chat/chat-with-history/hooks.spec.tsx
index f6a8f25cbb..399f16716d 100644
--- a/web/app/components/base/chat/chat-with-history/hooks.spec.tsx
+++ b/web/app/components/base/chat/chat-with-history/hooks.spec.tsx
@@ -5,6 +5,7 @@ import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
import { act, renderHook, waitFor } from '@testing-library/react'
import { ToastProvider } from '@/app/components/base/toast'
import {
+ AppSourceType,
fetchChatList,
fetchConversations,
generationConversationName,
@@ -49,20 +50,24 @@ vi.mock('../utils', async () => {
}
})
-vi.mock('@/service/share', () => ({
- fetchChatList: vi.fn(),
- fetchConversations: vi.fn(),
- generationConversationName: vi.fn(),
- fetchAppInfo: vi.fn(),
- fetchAppMeta: vi.fn(),
- fetchAppParams: vi.fn(),
- getAppAccessModeByAppCode: vi.fn(),
- delConversation: vi.fn(),
- pinConversation: vi.fn(),
- renameConversation: vi.fn(),
- unpinConversation: vi.fn(),
- updateFeedback: vi.fn(),
-}))
+vi.mock('@/service/share', async (importOriginal) => {
+ const actual = await importOriginal()
+ return {
+ ...actual,
+ fetchChatList: vi.fn(),
+ fetchConversations: vi.fn(),
+ generationConversationName: vi.fn(),
+ fetchAppInfo: vi.fn(),
+ fetchAppMeta: vi.fn(),
+ fetchAppParams: vi.fn(),
+ getAppAccessModeByAppCode: vi.fn(),
+ delConversation: vi.fn(),
+ pinConversation: vi.fn(),
+ renameConversation: vi.fn(),
+ unpinConversation: vi.fn(),
+ updateFeedback: vi.fn(),
+ }
+})
const mockFetchConversations = vi.mocked(fetchConversations)
const mockFetchChatList = vi.mocked(fetchChatList)
@@ -162,13 +167,13 @@ describe('useChatWithHistory', () => {
// Assert
await waitFor(() => {
- expect(mockFetchConversations).toHaveBeenCalledWith(false, 'app-1', undefined, true, 100)
+ expect(mockFetchConversations).toHaveBeenCalledWith(AppSourceType.webApp, 'app-1', undefined, true, 100)
})
await waitFor(() => {
- expect(mockFetchConversations).toHaveBeenCalledWith(false, 'app-1', undefined, false, 100)
+ expect(mockFetchConversations).toHaveBeenCalledWith(AppSourceType.webApp, 'app-1', undefined, false, 100)
})
await waitFor(() => {
- expect(mockFetchChatList).toHaveBeenCalledWith('conversation-1', false, 'app-1')
+ expect(mockFetchChatList).toHaveBeenCalledWith('conversation-1', AppSourceType.webApp, 'app-1')
})
await waitFor(() => {
expect(result.current.pinnedConversationList).toEqual(pinnedData.data)
@@ -204,7 +209,7 @@ describe('useChatWithHistory', () => {
// Assert
await waitFor(() => {
- expect(mockGenerationConversationName).toHaveBeenCalledWith(false, 'app-1', 'conversation-new')
+ expect(mockGenerationConversationName).toHaveBeenCalledWith(AppSourceType.webApp, 'app-1', 'conversation-new')
})
await waitFor(() => {
expect(result.current.conversationList[0]).toEqual(generatedConversation)
diff --git a/web/app/components/base/chat/embedded-chatbot/hooks.spec.tsx b/web/app/components/base/chat/embedded-chatbot/hooks.spec.tsx
index b0c09e2fbf..4088e709d1 100644
--- a/web/app/components/base/chat/embedded-chatbot/hooks.spec.tsx
+++ b/web/app/components/base/chat/embedded-chatbot/hooks.spec.tsx
@@ -50,16 +50,20 @@ vi.mock('../utils', async () => {
}
})
-vi.mock('@/service/share', () => ({
- fetchChatList: vi.fn(),
- fetchConversations: vi.fn(),
- generationConversationName: vi.fn(),
- fetchAppInfo: vi.fn(),
- fetchAppMeta: vi.fn(),
- fetchAppParams: vi.fn(),
- getAppAccessModeByAppCode: vi.fn(),
- updateFeedback: vi.fn(),
-}))
+vi.mock('@/service/share', async (importOriginal) => {
+ const actual = await importOriginal()
+ return {
+ ...actual,
+ fetchChatList: vi.fn(),
+ fetchConversations: vi.fn(),
+ generationConversationName: vi.fn(),
+ fetchAppInfo: vi.fn(),
+ fetchAppMeta: vi.fn(),
+ fetchAppParams: vi.fn(),
+ getAppAccessModeByAppCode: vi.fn(),
+ updateFeedback: vi.fn(),
+ }
+})
const mockFetchConversations = vi.mocked(fetchConversations)
const mockFetchChatList = vi.mocked(fetchChatList)
@@ -150,13 +154,13 @@ describe('useEmbeddedChatbot', () => {
// Assert
await waitFor(() => {
- expect(mockFetchConversations).toHaveBeenCalledWith(false, 'app-1', undefined, true, 100)
+ expect(mockFetchConversations).toHaveBeenCalledWith(AppSourceType.webApp, 'app-1', undefined, true, 100)
})
await waitFor(() => {
- expect(mockFetchConversations).toHaveBeenCalledWith(false, 'app-1', undefined, false, 100)
+ expect(mockFetchConversations).toHaveBeenCalledWith(AppSourceType.webApp, 'app-1', undefined, false, 100)
})
await waitFor(() => {
- expect(mockFetchChatList).toHaveBeenCalledWith('conversation-1', false, 'app-1')
+ expect(mockFetchChatList).toHaveBeenCalledWith('conversation-1', AppSourceType.webApp, 'app-1')
})
expect(result.current.pinnedConversationList).toEqual(pinnedData.data)
expect(result.current.conversationList).toEqual(listData.data)
@@ -188,7 +192,7 @@ describe('useEmbeddedChatbot', () => {
// Assert
await waitFor(() => {
- expect(mockGenerationConversationName).toHaveBeenCalledWith(false, 'app-1', 'conversation-new')
+ expect(mockGenerationConversationName).toHaveBeenCalledWith(AppSourceType.webApp, 'app-1', 'conversation-new')
})
await waitFor(() => {
expect(result.current.conversationList[0]).toEqual(generatedConversation)
diff --git a/web/app/components/explore/app-list/index.spec.tsx b/web/app/components/explore/app-list/index.spec.tsx
index e15f37245f..a87d5a2363 100644
--- a/web/app/components/explore/app-list/index.spec.tsx
+++ b/web/app/components/explore/app-list/index.spec.tsx
@@ -16,9 +16,13 @@ let mockIsError = false
const mockHandleImportDSL = vi.fn()
const mockHandleImportDSLConfirm = vi.fn()
-vi.mock('nuqs', () => ({
- useQueryState: () => [mockTabValue, mockSetTab],
-}))
+vi.mock('nuqs', async (importOriginal) => {
+ const actual = await importOriginal()
+ return {
+ ...actual,
+ useQueryState: () => [mockTabValue, mockSetTab],
+ }
+})
vi.mock('ahooks', async () => {
const actual = await vi.importActual('ahooks')
diff --git a/web/app/components/explore/sidebar/index.spec.tsx b/web/app/components/explore/sidebar/index.spec.tsx
index 7f23ce41c4..e06cefd40b 100644
--- a/web/app/components/explore/sidebar/index.spec.tsx
+++ b/web/app/components/explore/sidebar/index.spec.tsx
@@ -98,8 +98,8 @@ describe('SideBar', () => {
renderWithContext(mockInstalledApps)
// Assert
- expect(screen.getByText('explore.sidebar.discovery')).toBeInTheDocument()
- expect(screen.getByText('explore.sidebar.workspace')).toBeInTheDocument()
+ expect(screen.getByText('explore.sidebar.title')).toBeInTheDocument()
+ expect(screen.getByText('explore.sidebar.webApps')).toBeInTheDocument()
expect(screen.getByText('My App')).toBeInTheDocument()
})
})
diff --git a/web/service/use-share.spec.tsx b/web/service/use-share.spec.tsx
index 5b1501bead..a56913c534 100644
--- a/web/service/use-share.spec.tsx
+++ b/web/service/use-share.spec.tsx
@@ -16,15 +16,19 @@ import {
useShareConversations,
} from './use-share'
-vi.mock('./share', () => ({
- fetchChatList: vi.fn(),
- fetchConversations: vi.fn(),
- generationConversationName: vi.fn(),
- fetchAppInfo: vi.fn(),
- fetchAppMeta: vi.fn(),
- fetchAppParams: vi.fn(),
- getAppAccessModeByAppCode: vi.fn(),
-}))
+vi.mock('./share', async (importOriginal) => {
+ const actual = await importOriginal()
+ return {
+ ...actual,
+ fetchChatList: vi.fn(),
+ fetchConversations: vi.fn(),
+ generationConversationName: vi.fn(),
+ fetchAppInfo: vi.fn(),
+ fetchAppMeta: vi.fn(),
+ fetchAppParams: vi.fn(),
+ getAppAccessModeByAppCode: vi.fn(),
+ }
+})
const mockFetchConversations = vi.mocked(fetchConversations)
const mockFetchChatList = vi.mocked(fetchChatList)
@@ -91,7 +95,7 @@ describe('useShareConversations', () => {
// Assert
await waitFor(() => {
- expect(mockFetchConversations).toHaveBeenCalledWith(false, undefined, undefined, true, 50)
+ expect(mockFetchConversations).toHaveBeenCalledWith(AppSourceType.webApp, undefined, undefined, true, 50)
})
await waitFor(() => {
expect(result.current.data).toEqual(response)
@@ -140,7 +144,7 @@ describe('useShareChatList', () => {
// Assert
await waitFor(() => {
- expect(mockFetchChatList).toHaveBeenCalledWith('conversation-1', true, 'app-1')
+ expect(mockFetchChatList).toHaveBeenCalledWith('conversation-1', AppSourceType.installedApp, 'app-1')
})
await waitFor(() => {
expect(result.current.data).toEqual(response)
@@ -235,7 +239,7 @@ describe('useShareConversationName', () => {
// Assert
await waitFor(() => {
- expect(mockGenerationConversationName).toHaveBeenCalledWith(false, undefined, 'conversation-2')
+ expect(mockGenerationConversationName).toHaveBeenCalledWith(AppSourceType.webApp, undefined, 'conversation-2')
})
await waitFor(() => {
expect(result.current.data).toEqual(response)