From beec87ab99e92601ec2c23d89e99f25b65fb6f02 Mon Sep 17 00:00:00 2001 From: yyh Date: Thu, 15 Jan 2026 22:05:12 +0800 Subject: [PATCH] test: update goto-anything tests to use new oRPC service mocks Migrate test mocks from legacy API functions (fetchAppList, fetchDatasets, postMarketplace) to new oRPC-based service functions (searchApps, searchDatasets, searchPlugins) to align with the contract-first architecture refactor. --- .../search-error-handling.test.ts | 71 ++++++++----------- 1 file changed, 28 insertions(+), 43 deletions(-) diff --git a/web/__tests__/goto-anything/search-error-handling.test.ts b/web/__tests__/goto-anything/search-error-handling.test.ts index 5423cd5bda..a5998d7d28 100644 --- a/web/__tests__/goto-anything/search-error-handling.test.ts +++ b/web/__tests__/goto-anything/search-error-handling.test.ts @@ -10,9 +10,7 @@ import type { MockedFunction } from 'vitest' */ import { appScope, knowledgeScope, pluginScope, searchAnything } from '@/app/components/goto-anything/actions' -import { fetchAppList } from '@/service/apps' -import { postMarketplace } from '@/service/base' -import { fetchDatasets } from '@/service/datasets' +import { searchApps, searchDatasets, searchPlugins } from '@/service/use-goto-anything' // Mock react-i18next before importing modules that use it vi.mock('react-i18next', () => ({ @@ -22,22 +20,16 @@ vi.mock('react-i18next', () => ({ }), })) -// Mock API functions -vi.mock('@/service/base', () => ({ - postMarketplace: vi.fn(), +// Mock the new oRPC-based service functions +vi.mock('@/service/use-goto-anything', () => ({ + searchApps: vi.fn(), + searchDatasets: vi.fn(), + searchPlugins: vi.fn(), })) -vi.mock('@/service/apps', () => ({ - fetchAppList: vi.fn(), -})) - -vi.mock('@/service/datasets', () => ({ - fetchDatasets: vi.fn(), -})) - -const mockPostMarketplace = postMarketplace as MockedFunction -const mockFetchAppList = fetchAppList as MockedFunction -const mockFetchDatasets = fetchDatasets as MockedFunction +const mockSearchApps = searchApps as MockedFunction +const mockSearchDatasets = searchDatasets as MockedFunction +const mockSearchPlugins = searchPlugins as MockedFunction const searchScopes = [appScope, knowledgeScope, pluginScope] describe('GotoAnything Search Error Handling', () => { @@ -56,26 +48,19 @@ describe('GotoAnything Search Error Handling', () => { describe('@plugin search error handling', () => { it('should return empty array when API fails instead of throwing error', async () => { // Mock marketplace API failure (403 permission denied) - mockPostMarketplace.mockRejectedValue(new Error('HTTP 403: Forbidden')) + mockSearchPlugins.mockRejectedValue(new Error('HTTP 403: Forbidden')) const result = await pluginScope.search('@plugin', 'test', 'en') // Should return empty array instead of throwing error expect(result).toEqual([]) - expect(mockPostMarketplace).toHaveBeenCalledWith('/plugins/search/advanced', { - body: { - page: 1, - page_size: 10, - query: 'test', - type: 'plugin', - }, - }) + expect(mockSearchPlugins).toHaveBeenCalledWith('test') }) it('should return empty array when user has no plugin data', async () => { // Mock marketplace returning empty data - mockPostMarketplace.mockResolvedValue({ - data: { plugins: [] }, + mockSearchPlugins.mockResolvedValue({ + data: { plugins: [], total: 0 }, }) const result = await pluginScope.search('@plugin', '', 'en') @@ -85,9 +70,9 @@ describe('GotoAnything Search Error Handling', () => { it('should return empty array when API returns unexpected data structure', async () => { // Mock API returning unexpected data structure - mockPostMarketplace.mockResolvedValue({ + mockSearchPlugins.mockResolvedValue({ data: null, - }) + } as any) const result = await pluginScope.search('@plugin', 'test', 'en') @@ -98,7 +83,7 @@ describe('GotoAnything Search Error Handling', () => { describe('Other search types error handling', () => { it('@app search should return empty array when API fails', async () => { // Mock app API failure - mockFetchAppList.mockRejectedValue(new Error('API Error')) + mockSearchApps.mockRejectedValue(new Error('API Error')) const result = await appScope.search('@app', 'test', 'en') @@ -107,7 +92,7 @@ describe('GotoAnything Search Error Handling', () => { it('@knowledge search should return empty array when API fails', async () => { // Mock knowledge API failure - mockFetchDatasets.mockRejectedValue(new Error('API Error')) + mockSearchDatasets.mockRejectedValue(new Error('API Error')) const result = await knowledgeScope.search('@knowledge', 'test', 'en') @@ -118,9 +103,9 @@ describe('GotoAnything Search Error Handling', () => { describe('Unified search entry error handling', () => { it('regular search (without @prefix) should return successful results even when partial APIs fail', async () => { // Set app and knowledge success, plugin failure - mockFetchAppList.mockResolvedValue({ data: [], has_more: false, limit: 10, page: 1, total: 0 }) - mockFetchDatasets.mockResolvedValue({ data: [], has_more: false, limit: 10, page: 1, total: 0 }) - mockPostMarketplace.mockRejectedValue(new Error('Plugin API failed')) + mockSearchApps.mockResolvedValue({ data: [], has_more: false, limit: 10, page: 1, total: 0 }) + mockSearchDatasets.mockResolvedValue({ data: [], has_more: false, limit: 10, page: 1, total: 0 }) + mockSearchPlugins.mockRejectedValue(new Error('Plugin API failed')) const result = await searchAnything('en', 'test', undefined, searchScopes) @@ -131,7 +116,7 @@ describe('GotoAnything Search Error Handling', () => { it('@plugin dedicated search should return empty array when API fails', async () => { // Mock plugin API failure - mockPostMarketplace.mockRejectedValue(new Error('Plugin service unavailable')) + mockSearchPlugins.mockRejectedValue(new Error('Plugin service unavailable')) const result = await searchAnything('en', '@plugin test', pluginScope, searchScopes) @@ -141,7 +126,7 @@ describe('GotoAnything Search Error Handling', () => { it('@app dedicated search should return empty array when API fails', async () => { // Mock app API failure - mockFetchAppList.mockRejectedValue(new Error('App service unavailable')) + mockSearchApps.mockRejectedValue(new Error('App service unavailable')) const result = await searchAnything('en', '@app test', appScope, searchScopes) @@ -152,9 +137,9 @@ describe('GotoAnything Search Error Handling', () => { describe('Error handling consistency validation', () => { it('all search types should return empty array when encountering errors', async () => { // Mock all APIs to fail - mockPostMarketplace.mockRejectedValue(new Error('Plugin API failed')) - mockFetchAppList.mockRejectedValue(new Error('App API failed')) - mockFetchDatasets.mockRejectedValue(new Error('Dataset API failed')) + mockSearchPlugins.mockRejectedValue(new Error('Plugin API failed')) + mockSearchApps.mockRejectedValue(new Error('App API failed')) + mockSearchDatasets.mockRejectedValue(new Error('Dataset API failed')) const actions = [ { name: '@plugin', action: pluginScope }, @@ -171,7 +156,7 @@ describe('GotoAnything Search Error Handling', () => { describe('Edge case testing', () => { it('empty search term should be handled properly', async () => { - mockPostMarketplace.mockResolvedValue({ data: { plugins: [] } }) + mockSearchPlugins.mockResolvedValue({ data: { plugins: [], total: 0 } }) const result = await searchAnything('en', '@plugin ', pluginScope, searchScopes) expect(result).toEqual([]) @@ -181,7 +166,7 @@ describe('GotoAnything Search Error Handling', () => { const timeoutError = new Error('Network timeout') timeoutError.name = 'TimeoutError' - mockPostMarketplace.mockRejectedValue(timeoutError) + mockSearchPlugins.mockRejectedValue(timeoutError) const result = await searchAnything('en', '@plugin test', pluginScope, searchScopes) expect(result).toEqual([]) @@ -189,7 +174,7 @@ describe('GotoAnything Search Error Handling', () => { it('JSON parsing errors should be handled correctly', async () => { const parseError = new SyntaxError('Unexpected token in JSON') - mockPostMarketplace.mockRejectedValue(parseError) + mockSearchPlugins.mockRejectedValue(parseError) const result = await searchAnything('en', '@plugin test', pluginScope, searchScopes) expect(result).toEqual([])