diff --git a/web/__tests__/apps/app-card-operations-flow.test.tsx b/web/__tests__/apps/app-card-operations-flow.test.tsx index ec0156fc563..f6397211113 100644 --- a/web/__tests__/apps/app-card-operations-flow.test.tsx +++ b/web/__tests__/apps/app-card-operations-flow.test.tsx @@ -19,7 +19,6 @@ import { exportAppConfig, updateAppInfo } from '@/service/apps' import { AppModeEnum } from '@/types/app' import { AppACLPermission } from '@/utils/permission' -let mockIsCurrentWorkspaceEditor = true let mockSystemFeatures = { branding: { enabled: false }, webapp_auth: { enabled: false }, @@ -80,23 +79,6 @@ vi.mock('@/next/dynamic', () => ({ }, })) -vi.mock('@/context/app-context', () => ({ - useAppContext: () => ({ - isCurrentWorkspaceEditor: mockIsCurrentWorkspaceEditor, - userProfile: { id: 'user-1' }, - workspacePermissionKeys: mockIsCurrentWorkspaceEditor ? ['app.create_and_management'] : [], - }), - useSelector: (selector: (state: { - isCurrentWorkspaceEditor: boolean - userProfile: { id: string } - workspacePermissionKeys: string[] - }) => T): T => selector({ - isCurrentWorkspaceEditor: mockIsCurrentWorkspaceEditor, - userProfile: { id: 'user-1' }, - workspacePermissionKeys: mockIsCurrentWorkspaceEditor ? ['app.create_and_management'] : [], - }), -})) - vi.mock('@/context/provider-context', () => ({ useProviderContext: () => ({ onPlanInfoChanged: mockOnPlanInfoChanged, @@ -278,7 +260,6 @@ describe('App Card Operations Flow', () => { beforeEach(() => { vi.clearAllMocks() mockDeleteMutationPending = false - mockIsCurrentWorkspaceEditor = true mockSystemFeatures = { branding: { enabled: false }, webapp_auth: { enabled: false }, @@ -376,7 +357,6 @@ describe('App Card Operations Flow', () => { // -- Access mode display -- describe('Access Mode Display', () => { it('should not render operations menu when user has no app permissions', () => { - mockIsCurrentWorkspaceEditor = false renderAppCard({ name: 'Readonly App', created_by: 'another-user', permission_keys: [] }) expect(screen.queryByRole('button', { name: 'common.operation.more' })).not.toBeInTheDocument() diff --git a/web/__tests__/apps/app-list-browsing-flow.test.tsx b/web/__tests__/apps/app-list-browsing-flow.test.tsx index 972f538abfa..5091ebb0e6b 100644 --- a/web/__tests__/apps/app-list-browsing-flow.test.tsx +++ b/web/__tests__/apps/app-list-browsing-flow.test.tsx @@ -17,8 +17,6 @@ import { AccessMode } from '@/models/access-control' import { createNuqsTestWrapper } from '@/test/nuqs-testing' import { AppModeEnum } from '@/types/app' -let mockIsCurrentWorkspaceEditor = true -let mockIsCurrentWorkspaceDatasetOperator = false let mockIsLoadingCurrentWorkspace = false let mockWorkspacePermissionKeys: string[] = ['app.create_and_management'] @@ -60,21 +58,6 @@ vi.mock('@/next/dynamic', () => ({ }, })) -vi.mock('@/context/app-context', () => ({ - useAppContext: () => ({ - isCurrentWorkspaceEditor: mockIsCurrentWorkspaceEditor, - isCurrentWorkspaceDatasetOperator: mockIsCurrentWorkspaceDatasetOperator, - isLoadingCurrentWorkspace: mockIsLoadingCurrentWorkspace, - userProfile: { id: 'member-1' }, - isLoadingWorkspacePermissionKeys: mockIsLoadingCurrentWorkspace, - workspacePermissionKeys: mockWorkspacePermissionKeys, - }), - useSelector: (selector: (state: { userProfile: { id: string }, workspacePermissionKeys: string[] }) => unknown) => selector({ - userProfile: { id: 'user-1' }, - workspacePermissionKeys: mockWorkspacePermissionKeys, - }), -})) - vi.mock('@/context/app-context-state', async (importOriginal) => { const { createAppContextStateAtomMock } = await import('@/__tests__/utils/mock-app-context-state') @@ -238,8 +221,6 @@ const renderList = (searchParams?: Record) => { describe('App List Browsing Flow', () => { beforeEach(() => { vi.clearAllMocks() - mockIsCurrentWorkspaceEditor = true - mockIsCurrentWorkspaceDatasetOperator = false mockIsLoadingCurrentWorkspace = false mockWorkspacePermissionKeys = ['app.create_and_management'] mockSystemFeatures = { @@ -331,7 +312,6 @@ describe('App List Browsing Flow', () => { }) it('should hide the create menu when user lacks app creation permission', () => { - mockIsCurrentWorkspaceEditor = false mockWorkspacePermissionKeys = [] mockPages = [createPage([ createMockApp({ name: 'Test App' }), @@ -378,7 +358,6 @@ describe('App List Browsing Flow', () => { }) it('should hide drag-drop hint without app creation permission', () => { - mockIsCurrentWorkspaceEditor = false mockWorkspacePermissionKeys = [] mockPages = [createPage([createMockApp()])] renderList() @@ -464,7 +443,6 @@ describe('App List Browsing Flow', () => { // -- Dataset operator behavior -- describe('Dataset Operator Behavior', () => { it('should not redirect at list component level for dataset operators', () => { - mockIsCurrentWorkspaceDatasetOperator = true renderList() expect(mockRouterReplace).not.toHaveBeenCalled() diff --git a/web/__tests__/apps/create-app-flow.test.tsx b/web/__tests__/apps/create-app-flow.test.tsx index b93de421d1b..6b6d6b22084 100644 --- a/web/__tests__/apps/create-app-flow.test.tsx +++ b/web/__tests__/apps/create-app-flow.test.tsx @@ -18,8 +18,6 @@ import { AccessMode } from '@/models/access-control' import { createNuqsTestWrapper } from '@/test/nuqs-testing' import { AppModeEnum } from '@/types/app' -let mockIsCurrentWorkspaceEditor = true -let mockIsCurrentWorkspaceDatasetOperator = false let mockIsLoadingCurrentWorkspace = false let mockWorkspacePermissionKeys: string[] = ['app.create_and_management'] let mockSystemFeatures = { @@ -47,20 +45,6 @@ vi.mock('@/next/navigation', () => ({ useSearchParams: () => new URLSearchParams(), })) -vi.mock('@/context/app-context', () => ({ - useAppContext: () => ({ - isCurrentWorkspaceEditor: mockIsCurrentWorkspaceEditor, - isCurrentWorkspaceDatasetOperator: mockIsCurrentWorkspaceDatasetOperator, - isLoadingCurrentWorkspace: mockIsLoadingCurrentWorkspace, - isLoadingWorkspacePermissionKeys: mockIsLoadingCurrentWorkspace, - workspacePermissionKeys: mockWorkspacePermissionKeys, - }), - useSelector: (selector: (state: { userProfile: { id: string }, workspacePermissionKeys: string[] }) => unknown) => selector({ - userProfile: { id: 'user-1' }, - workspacePermissionKeys: mockWorkspacePermissionKeys, - }), -})) - vi.mock('@/context/app-context-state', async (importOriginal) => { const { createAppContextStateAtomMock } = await import('@/__tests__/utils/mock-app-context-state') @@ -284,8 +268,6 @@ const clickCreateMenuItem = (label: string) => { describe('Create App Flow', () => { beforeEach(() => { vi.clearAllMocks() - mockIsCurrentWorkspaceEditor = true - mockIsCurrentWorkspaceDatasetOperator = false mockIsLoadingCurrentWorkspace = false mockWorkspacePermissionKeys = ['app.create_and_management'] mockSystemFeatures = { @@ -310,7 +292,6 @@ describe('Create App Flow', () => { }) it('should render disabled the create menu when user lacks app creation permission', () => { - mockIsCurrentWorkspaceEditor = false mockWorkspacePermissionKeys = [] renderList() diff --git a/web/__tests__/billing/billing-integration.test.tsx b/web/__tests__/billing/billing-integration.test.tsx index 5820e552b95..2a8057e6a71 100644 --- a/web/__tests__/billing/billing-integration.test.tsx +++ b/web/__tests__/billing/billing-integration.test.tsx @@ -32,10 +32,6 @@ vi.mock('@/context/provider-context', () => ({ useProviderContext: () => mockProviderCtx, })) -vi.mock('@/context/app-context', () => ({ - useAppContext: () => mockAppCtx, -})) - vi.mock('@/context/app-context-state', async (importOriginal) => { const { createAppContextStateAtomMock } = await import('@/__tests__/utils/mock-app-context-state') return createAppContextStateAtomMock(importOriginal, () => mockAppCtx) diff --git a/web/__tests__/billing/cloud-plan-payment-flow.test.tsx b/web/__tests__/billing/cloud-plan-payment-flow.test.tsx index e5e9ec4ed4e..24c3a9c1dd2 100644 --- a/web/__tests__/billing/cloud-plan-payment-flow.test.tsx +++ b/web/__tests__/billing/cloud-plan-payment-flow.test.tsx @@ -24,9 +24,6 @@ const mockInvoices = vi.fn() const mockOpenAsyncWindow = vi.fn() // ─── Context mocks ─────────────────────────────────────────────────────────── -vi.mock('@/context/app-context', () => ({ - useAppContext: () => mockAppCtx, -})) vi.mock('@/context/app-context-state', async (importOriginal) => { const { createAppContextStateAtomMock } = await import('@/__tests__/utils/mock-app-context-state') diff --git a/web/__tests__/billing/education-verification-flow.test.tsx b/web/__tests__/billing/education-verification-flow.test.tsx index 381bd37dafb..35905255800 100644 --- a/web/__tests__/billing/education-verification-flow.test.tsx +++ b/web/__tests__/billing/education-verification-flow.test.tsx @@ -37,10 +37,6 @@ vi.mock('@/context/provider-context', () => ({ useProviderContext: () => mockProviderCtx, })) -vi.mock('@/context/app-context', () => ({ - useAppContext: () => mockAppCtx, -})) - vi.mock('@/context/app-context-state', async (importOriginal) => { const { createAppContextStateAtomMock } = await import('@/__tests__/utils/mock-app-context-state') return createAppContextStateAtomMock(importOriginal, () => mockAppCtx) diff --git a/web/__tests__/billing/pricing-modal-flow.test.tsx b/web/__tests__/billing/pricing-modal-flow.test.tsx index 2298105c651..3892e44b18b 100644 --- a/web/__tests__/billing/pricing-modal-flow.test.tsx +++ b/web/__tests__/billing/pricing-modal-flow.test.tsx @@ -24,10 +24,6 @@ vi.mock('@/context/provider-context', () => ({ useProviderContext: () => mockProviderCtx, })) -vi.mock('@/context/app-context', () => ({ - useAppContext: () => mockAppCtx, -})) - vi.mock('@/context/app-context-state', async (importOriginal) => { const { createAppContextStateAtomMock } = await import('@/__tests__/utils/mock-app-context-state') return createAppContextStateAtomMock(importOriginal, () => mockAppCtx) diff --git a/web/__tests__/billing/self-hosted-plan-flow.test.tsx b/web/__tests__/billing/self-hosted-plan-flow.test.tsx index 6fc2626ad63..4a7ed46f411 100644 --- a/web/__tests__/billing/self-hosted-plan-flow.test.tsx +++ b/web/__tests__/billing/self-hosted-plan-flow.test.tsx @@ -20,10 +20,6 @@ let mockAppCtx: Record = {} const originalLocation = window.location let assignedHref = '' -vi.mock('@/context/app-context', () => ({ - useAppContext: () => mockAppCtx, -})) - vi.mock('@/context/app-context-state', async (importOriginal) => { const { createAppContextStateAtomMock } = await import('@/__tests__/utils/mock-app-context-state') return createAppContextStateAtomMock(importOriginal, () => mockAppCtx) diff --git a/web/__tests__/datasets/dataset-settings-flow.test.tsx b/web/__tests__/datasets/dataset-settings-flow.test.tsx index 1c07128eb67..e33f9bad895 100644 --- a/web/__tests__/datasets/dataset-settings-flow.test.tsx +++ b/web/__tests__/datasets/dataset-settings-flow.test.tsx @@ -28,16 +28,6 @@ const mockMutateDatasets = vi.fn() const mockInvalidDatasetList = vi.fn() const mockUpdateDatasetSetting = vi.fn().mockResolvedValue({}) -vi.mock('@/context/app-context', () => ({ - useSelector: (selector: (state: { - userProfile: { id: string } - workspacePermissionKeys: string[] - }) => T): T => selector({ - userProfile: { id: 'user-1' }, - workspacePermissionKeys: ['dataset.create_and_management'], - }), -})) - vi.mock('@/service/datasets', () => ({ updateDatasetSetting: (...args: unknown[]) => mockUpdateDatasetSetting(...args), })) diff --git a/web/__tests__/develop/api-key-management-flow.test.tsx b/web/__tests__/develop/api-key-management-flow.test.tsx index 0267fdd45e1..9d3c3eac255 100644 --- a/web/__tests__/develop/api-key-management-flow.test.tsx +++ b/web/__tests__/develop/api-key-management-flow.test.tsx @@ -31,14 +31,6 @@ async function flushUI() { // ---------- mocks ---------- -vi.mock('@/context/app-context', () => ({ - useAppContext: () => ({ - currentWorkspace: { id: 'ws-1', name: 'Workspace' }, - isCurrentWorkspaceManager: true, - isCurrentWorkspaceEditor: true, - }), -})) - vi.mock('@/hooks/use-timestamp', () => ({ default: () => ({ formatTime: vi.fn((val: number) => `Time:${val}`), diff --git a/web/__tests__/develop/develop-page-flow.test.tsx b/web/__tests__/develop/develop-page-flow.test.tsx index 4c4bcd0f064..175b5fe6959 100644 --- a/web/__tests__/develop/develop-page-flow.test.tsx +++ b/web/__tests__/develop/develop-page-flow.test.tsx @@ -50,16 +50,6 @@ vi.mock('@/i18n-config/language', async (importOriginal) => { } }) -vi.mock('@/context/app-context', () => ({ - useAppContext: () => ({ - currentWorkspace: { id: 'ws-1', name: 'Workspace' }, - isCurrentWorkspaceManager: true, - isCurrentWorkspaceEditor: true, - }), - useSelector: (selector: (state: { userProfile: { id: string }, workspacePermissionKeys: string[] }) => unknown) => - selector({ userProfile: { id: 'user-1' }, workspacePermissionKeys: ['app.create_and_management'] }), -})) - vi.mock('@/hooks/use-timestamp', () => ({ default: () => ({ formatTime: vi.fn((val: number) => `Time:${val}`), diff --git a/web/__tests__/explore/explore-app-list-flow.test.tsx b/web/__tests__/explore/explore-app-list-flow.test.tsx index 7776f2bbe99..a3b09eb0d8f 100644 --- a/web/__tests__/explore/explore-app-list-flow.test.tsx +++ b/web/__tests__/explore/explore-app-list-flow.test.tsx @@ -118,11 +118,6 @@ vi.mock('@/service/client', () => ({ }, })) -vi.mock('@/context/app-context', () => ({ - useAppContext: mockUseAppContext, - useSelector: (selector: (state: MockAppContext) => T): T => selector(mockUseAppContext()), -})) - vi.mock('@/context/app-context-state', async (importOriginal) => { const { createAppContextStateAtomMock } = await import('@/__tests__/utils/mock-app-context-state') diff --git a/web/__tests__/header/account-dropdown-flow.test.tsx b/web/__tests__/header/account-dropdown-flow.test.tsx index c949bb3f99a..82b989eac7b 100644 --- a/web/__tests__/header/account-dropdown-flow.test.tsx +++ b/web/__tests__/header/account-dropdown-flow.test.tsx @@ -48,10 +48,6 @@ vi.mock('react-i18next', () => ({ }), })) -vi.mock('@/context/app-context', () => ({ - useAppContext: () => mockAppContextState, -})) - vi.mock('@/context/app-context-state', async (importOriginal) => { const { createAppContextStateAtomMock } = await import('@/__tests__/utils/mock-app-context-state') return createAppContextStateAtomMock(importOriginal, () => mockAppContextState) diff --git a/web/__tests__/plugins/plugin-auth-flow.test.tsx b/web/__tests__/plugins/plugin-auth-flow.test.tsx index cc42d5204ba..1862ccd1f8d 100644 --- a/web/__tests__/plugins/plugin-auth-flow.test.tsx +++ b/web/__tests__/plugins/plugin-auth-flow.test.tsx @@ -25,12 +25,6 @@ vi.mock('react-i18next', () => ({ }), })) -vi.mock('@/context/app-context', () => ({ - useAppContext: () => ({ - isCurrentWorkspaceManager: true, - }), -})) - vi.mock('@langgenius/dify-ui/cn', () => ({ cn: (...args: unknown[]) => args.filter(Boolean).join(' '), })) diff --git a/web/__tests__/plugins/plugin-page-shell-flow.test.tsx b/web/__tests__/plugins/plugin-page-shell-flow.test.tsx index 14eebf2554a..8f0e8b16e74 100644 --- a/web/__tests__/plugins/plugin-page-shell-flow.test.tsx +++ b/web/__tests__/plugins/plugin-page-shell-flow.test.tsx @@ -39,27 +39,6 @@ vi.mock('@/context/i18n', () => ({ useDocLink: () => (path: string) => `https://docs.example.com${path}`, })) -vi.mock('@/context/app-context', () => ({ - useAppContext: () => ({ - isCurrentWorkspaceManager: false, - isCurrentWorkspaceOwner: false, - langGeniusVersionInfo: { - current_env: 'CLOUD', - current_version: '1.0.0', - latest_version: '1.0.0', - version: '1.0.0', - release_date: '', - release_notes: '', - can_auto_update: false, - }, - workspacePermissionKeys: [ - 'plugin.install', - 'plugin.delete', - 'plugin.plugin_preferences', - ], - }), -})) - vi.mock('@/context/app-context-state', async (importOriginal) => { const { createAppContextStateAtomMock } = await import('@/__tests__/utils/mock-app-context-state') return createAppContextStateAtomMock(importOriginal, () => ({ diff --git a/web/__tests__/tools/provider-list-shell-flow.test.tsx b/web/__tests__/tools/provider-list-shell-flow.test.tsx index 39677decc59..2cd8585668c 100644 --- a/web/__tests__/tools/provider-list-shell-flow.test.tsx +++ b/web/__tests__/tools/provider-list-shell-flow.test.tsx @@ -20,18 +20,6 @@ vi.mock('@/app/components/plugins/hooks', () => ({ }), })) -vi.mock('@/context/app-context', () => ({ - useAppContext: () => ({ - userProfile: { id: 'user-1', timezone: 'UTC' }, - workspacePermissionKeys: ['tool.manage', 'mcp.manage', 'plugin.install', 'plugin.delete', 'plugin.plugin_preferences'], - langGeniusVersionInfo: { current_version: '1.0.0' }, - }), - useSelector: (selector: (state: { workspacePermissionKeys: string[] }) => unknown) => - selector({ - workspacePermissionKeys: ['tool.manage', 'mcp.manage', 'plugin.install', 'plugin.delete', 'plugin.plugin_preferences'], - }), -})) - vi.mock('@/service/use-tools', () => ({ useAllToolProviders: () => ({ data: [ diff --git a/web/__tests__/tools/tool-browsing-and-filtering.test.tsx b/web/__tests__/tools/tool-browsing-and-filtering.test.tsx index fa1706b047b..6bc5c1b2589 100644 --- a/web/__tests__/tools/tool-browsing-and-filtering.test.tsx +++ b/web/__tests__/tools/tool-browsing-and-filtering.test.tsx @@ -43,18 +43,6 @@ vi.mock('@/app/components/plugins/hooks', () => ({ }), })) -vi.mock('@/context/app-context', () => ({ - useAppContext: () => ({ - userProfile: { id: 'user-1', timezone: 'UTC' }, - workspacePermissionKeys: ['tool.manage', 'mcp.manage', 'plugin.install', 'plugin.delete', 'plugin.plugin_preferences'], - langGeniusVersionInfo: { current_version: '1.0.0' }, - }), - useSelector: (selector: (state: { workspacePermissionKeys: string[] }) => unknown) => - selector({ - workspacePermissionKeys: ['tool.manage', 'mcp.manage', 'plugin.install', 'plugin.delete', 'plugin.plugin_preferences'], - }), -})) - vi.mock('@/service/use-plugins', () => ({ useCheckInstalled: () => ({ data: null }), useInvalidateInstalledPluginList: () => vi.fn(), diff --git a/web/__tests__/tools/tool-provider-detail-flow.test.tsx b/web/__tests__/tools/tool-provider-detail-flow.test.tsx index fe7b55189bc..abd0283145c 100644 --- a/web/__tests__/tools/tool-provider-detail-flow.test.tsx +++ b/web/__tests__/tools/tool-provider-detail-flow.test.tsx @@ -44,15 +44,6 @@ vi.mock('@/i18n-config/language', () => ({ getLanguage: () => 'en_US', })) -vi.mock('@/context/app-context', () => ({ - useAppContext: () => ({ - isCurrentWorkspaceManager: true, - }), - useSelector: (selector: (state: { workspacePermissionKeys: string[] }) => unknown) => selector({ - workspacePermissionKeys: ['tool.manage', 'credential.create', 'credential.manage', 'credential.use'], - }), -})) - vi.mock('@/context/app-context-state', async (importOriginal) => { const { createAppContextStateAtomMock } = await import('@/__tests__/utils/mock-app-context-state') return createAppContextStateAtomMock(importOriginal, () => ({ diff --git a/web/__tests__/utils/mock-app-context-state.ts b/web/__tests__/utils/mock-app-context-state.ts index c36f2a3095f..10fcd01c7bd 100644 --- a/web/__tests__/utils/mock-app-context-state.ts +++ b/web/__tests__/utils/mock-app-context-state.ts @@ -1,4 +1,4 @@ -import type { LangGeniusVersionResponse } from '@/models/common' +import type { ICurrentWorkspace, LangGeniusVersionResponse } from '@/models/common' const APP_CONTEXT_STATE_ATOM_KIND = Symbol('app-context-state-atom-kind') @@ -11,10 +11,10 @@ export type AppContextStateMockState = { avatar_url?: string | null is_password_set?: boolean } | null - currentWorkspace?: { + currentWorkspace?: ({ id?: string name?: string - } | null + } & Partial) | null isCurrentWorkspaceManager?: boolean isCurrentWorkspaceOwner?: boolean isCurrentWorkspaceEditor?: boolean @@ -25,6 +25,8 @@ export type AppContextStateMockState = { langGeniusVersionInfo?: Partial refreshUserProfile?: () => void refreshCurrentWorkspace?: () => void + mutateUserProfile?: () => void + mutateCurrentWorkspace?: () => void } type AppContextStateAtomKind @@ -66,7 +68,15 @@ const defaultUserProfile = { const defaultCurrentWorkspace = { id: 'workspace-1', name: 'Workspace', -} + plan: '', + status: '', + created_at: 0, + role: 'owner', + providers: [], + trial_credits: 0, + trial_credits_used: 0, + next_credit_reset_date: 0, +} satisfies ICurrentWorkspace const defaultLangGeniusVersionInfo = { current_env: 'CLOUD', @@ -95,7 +105,7 @@ const getUserProfile = (state: AppContextStateMockState) => ({ ...state.userProfile, }) -const getCurrentWorkspace = (state: AppContextStateMockState) => ({ +const getCurrentWorkspace = (state: AppContextStateMockState): ICurrentWorkspace => ({ ...defaultCurrentWorkspace, ...state.currentWorkspace, }) diff --git a/web/app/(commonLayout)/app/(appDetailLayout)/[appId]/overview/__tests__/chart-view.spec.tsx b/web/app/(commonLayout)/app/(appDetailLayout)/[appId]/overview/__tests__/chart-view.spec.tsx index 75516435b66..b3b3b5a8cf0 100644 --- a/web/app/(commonLayout)/app/(appDetailLayout)/[appId]/overview/__tests__/chart-view.spec.tsx +++ b/web/app/(commonLayout)/app/(appDetailLayout)/[appId]/overview/__tests__/chart-view.spec.tsx @@ -20,13 +20,6 @@ vi.mock('@/app/components/app/store', () => ({ }), })) -vi.mock('@/context/app-context', () => ({ - useSelector: vi.fn((selector: (state: { userProfile: { id: string }, workspacePermissionKeys: string[] }) => unknown) => selector({ - userProfile: { id: testState.currentUserId }, - workspacePermissionKeys: testState.workspacePermissionKeys, - })), -})) - vi.mock('@/context/i18n', () => ({ useDocLink: () => (path: string) => path, })) diff --git a/web/app/(commonLayout)/app/(appDetailLayout)/[appId]/overview/__tests__/view.spec.tsx b/web/app/(commonLayout)/app/(appDetailLayout)/[appId]/overview/__tests__/view.spec.tsx index f95ff2b17e0..63fe536f496 100644 --- a/web/app/(commonLayout)/app/(appDetailLayout)/[appId]/overview/__tests__/view.spec.tsx +++ b/web/app/(commonLayout)/app/(appDetailLayout)/[appId]/overview/__tests__/view.spec.tsx @@ -20,13 +20,6 @@ vi.mock('@/app/components/app/store', () => ({ }), })) -vi.mock('@/context/app-context', () => ({ - useSelector: vi.fn((selector: (state: { userProfile: { id: string }, workspacePermissionKeys: string[] }) => unknown) => selector({ - userProfile: { id: testState.currentUserId }, - workspacePermissionKeys: testState.workspacePermissionKeys, - })), -})) - vi.mock('@/app/components/app/overview/apikey-info-panel', () => ({ default: () =>
api key info panel
, })) diff --git a/web/app/(commonLayout)/app/(appDetailLayout)/[appId]/overview/tracing/__tests__/panel.spec.tsx b/web/app/(commonLayout)/app/(appDetailLayout)/[appId]/overview/tracing/__tests__/panel.spec.tsx index 13d770439cf..7bf8b7a5d2f 100644 --- a/web/app/(commonLayout)/app/(appDetailLayout)/[appId]/overview/tracing/__tests__/panel.spec.tsx +++ b/web/app/(commonLayout)/app/(appDetailLayout)/[appId]/overview/tracing/__tests__/panel.spec.tsx @@ -17,12 +17,6 @@ vi.mock('@/next/navigation', () => ({ usePathname: () => '/app/app-1/overview', })) -vi.mock('@/context/app-context', () => ({ - useSelector: vi.fn((selector: (state: { workspacePermissionKeys: string[] }) => unknown) => selector({ - workspacePermissionKeys: testState.workspacePermissionKeys, - })), -})) - vi.mock('@/app/components/app/store', () => ({ useStore: vi.fn((selector: (state: { appDetail: { permission_keys: string[] } }) => unknown) => selector({ appDetail: { diff --git a/web/app/(commonLayout)/datasets/(datasetDetailLayout)/[datasetId]/__tests__/layout-main.spec.tsx b/web/app/(commonLayout)/datasets/(datasetDetailLayout)/[datasetId]/__tests__/layout-main.spec.tsx index 7bb628997df..c76ef6ec268 100644 --- a/web/app/(commonLayout)/datasets/(datasetDetailLayout)/[datasetId]/__tests__/layout-main.spec.tsx +++ b/web/app/(commonLayout)/datasets/(datasetDetailLayout)/[datasetId]/__tests__/layout-main.spec.tsx @@ -23,29 +23,6 @@ vi.mock('@/service/knowledge/use-dataset', () => ({ useDatasetDetail: vi.fn(), })) -vi.mock('@/context/app-context', () => ({ - useAppContext: () => ({ - isCurrentWorkspaceDatasetOperator: false, - isLoadingCurrentWorkspace: false, - isLoadingWorkspacePermissionKeys: false, - userProfile: { id: 'user-1' }, - workspacePermissionKeys: [], - }), - useSelector: (selector: (state: { - isCurrentWorkspaceDatasetOperator: boolean - isLoadingCurrentWorkspace: boolean - isLoadingWorkspacePermissionKeys: boolean - userProfile: { id: string } - workspacePermissionKeys: string[] - }) => unknown) => selector({ - isCurrentWorkspaceDatasetOperator: false, - isLoadingCurrentWorkspace: false, - isLoadingWorkspacePermissionKeys: false, - userProfile: { id: 'user-1' }, - workspacePermissionKeys: [], - }), -})) - vi.mock('@/context/app-context-state', async (importOriginal) => { const { createDatasetAccessAtomMock } = await import('@/app/components/datasets/__tests__/mock-dataset-access') diff --git a/web/app/(commonLayout)/datasets/layout.spec.tsx b/web/app/(commonLayout)/datasets/layout.spec.tsx index 98ac56c6fce..9e162dc2e70 100644 --- a/web/app/(commonLayout)/datasets/layout.spec.tsx +++ b/web/app/(commonLayout)/datasets/layout.spec.tsx @@ -15,11 +15,6 @@ vi.mock('@/next/navigation', () => ({ usePathname: () => mockPathname, })) -vi.mock('@/context/app-context', () => ({ - useAppContext: () => mockUseAppContext(), - useSelector: (selector: (state: AppContextMock) => unknown) => selector(mockUseAppContext()), -})) - vi.mock('@/context/app-context-state', async (importOriginal) => { const { createDatasetAccessAtomMock } = await import('@/app/components/datasets/__tests__/mock-dataset-access') diff --git a/web/app/(commonLayout)/layout.tsx b/web/app/(commonLayout)/layout.tsx index 02302752df8..e70e660f1c8 100644 --- a/web/app/(commonLayout)/layout.tsx +++ b/web/app/(commonLayout)/layout.tsx @@ -7,7 +7,7 @@ import MaintenanceNotice from '@/app/components/header/maintenance-notice' import MainNavLayout from '@/app/components/main-nav/layout' import { NextRouteStateBridge } from '@/app/components/next-route-state' import { OAuthRegistrationAnalytics } from '@/app/components/oauth-registration-analytics' -import { AppContextProvider } from '@/context/app-context-provider' +import { AppBootstrapEffects } from '@/context/app-bootstrap-effects' import { EventEmitterContextProvider } from '@/context/event-emitter-provider' import { ModalContextProvider } from '@/context/modal-context-provider' import { ProviderContextProvider } from '@/context/provider-context-provider' @@ -31,18 +31,17 @@ export default async function Layout({
- - - - - - {children} - - - - - - + + + + + + {children} + + + + +
diff --git a/web/app/account/(commonLayout)/account-page/index.tsx b/web/app/account/(commonLayout)/account-page/index.tsx index 70bcf7c7922..34b20419741 100644 --- a/web/app/account/(commonLayout)/account-page/index.tsx +++ b/web/app/account/(commonLayout)/account-page/index.tsx @@ -48,7 +48,7 @@ export default function AccountPage() { })) const apps = appList?.data || [] const queryClient = useQueryClient() - // Cache is warmed by AppContextProvider's useSuspenseQuery; this hits cache synchronously. + // Cache is hydrated by CommonLayoutHydrationBoundary; this hits cache synchronously. const { data: userProfileResp } = useSuspenseQuery(userProfileQueryOptions()) const userProfile = userProfileResp.profile const mutateUserProfile = () => queryClient.invalidateQueries({ queryKey: userProfileQueryOptions().queryKey }) diff --git a/web/app/account/(commonLayout)/avatar.tsx b/web/app/account/(commonLayout)/avatar.tsx index 63e443f89d6..b0d637b4979 100644 --- a/web/app/account/(commonLayout)/avatar.tsx +++ b/web/app/account/(commonLayout)/avatar.tsx @@ -19,7 +19,7 @@ import { useLogout } from '@/service/use-common' export default function AppSelector() { const router = useRouter() const { t } = useTranslation() - // Cache is warmed by AppContextProvider's useSuspenseQuery; this hits cache synchronously. + // Cache is hydrated by CommonLayoutHydrationBoundary; this hits cache synchronously. const { data: userProfileResp } = useSuspenseQuery(userProfileQueryOptions()) const userProfile = userProfileResp.profile const { isEducationAccount } = useProviderContext() diff --git a/web/app/account/(commonLayout)/layout.tsx b/web/app/account/(commonLayout)/layout.tsx index 9420503c08b..292010773c7 100644 --- a/web/app/account/(commonLayout)/layout.tsx +++ b/web/app/account/(commonLayout)/layout.tsx @@ -6,7 +6,7 @@ import { EducationVerifyActionRecorder } from '@/app/components/education-verify import HeaderWrapper from '@/app/components/header/header-wrapper' import MaintenanceNotice from '@/app/components/header/maintenance-notice' import { OAuthRegistrationAnalytics } from '@/app/components/oauth-registration-analytics' -import { AppContextProvider } from '@/context/app-context-provider' +import { AppBootstrapEffects } from '@/context/app-bootstrap-effects' import { EventEmitterContextProvider } from '@/context/event-emitter-provider' import { ModalContextProvider } from '@/context/modal-context-provider' import { ProviderContextProvider } from '@/context/provider-context-provider' @@ -22,20 +22,19 @@ export default async function Layout({ children }: { children: React.ReactNode }
- - - - - -
- -
- {children} -
- - - - + + + + + +
+ +
+ {children} +
+ + +
diff --git a/web/app/components/app/access-config/__tests__/index.spec.tsx b/web/app/components/app/access-config/__tests__/index.spec.tsx index 9530a49c2d2..82c7a026f6e 100644 --- a/web/app/components/app/access-config/__tests__/index.spec.tsx +++ b/web/app/components/app/access-config/__tests__/index.spec.tsx @@ -43,10 +43,6 @@ const mockMutations = vi.hoisted(() => ({ removeMemberBindings: vi.fn(), })) -vi.mock('@/context/app-context', () => ({ - useAppContext: () => mockAppContext, -})) - vi.mock('@/context/app-context-state', async (importOriginal) => { const { createAppContextStateAtomMock } = await import('@/__tests__/utils/mock-app-context-state') diff --git a/web/app/components/app/app-access-control/__tests__/access-control.spec.tsx b/web/app/components/app/app-access-control/__tests__/access-control.spec.tsx index 52c2a0dd543..b5e53457cdd 100644 --- a/web/app/components/app/app-access-control/__tests__/access-control.spec.tsx +++ b/web/app/components/app/app-access-control/__tests__/access-control.spec.tsx @@ -23,19 +23,6 @@ const intersectionObserverMocks = vi.hoisted(() => ({ callback: null as null | ((entries: Array<{ isIntersecting: boolean }>) => void), })) -vi.mock('@/context/app-context', () => ({ - useSelector: (selector: (value: { userProfile: { email: string, id?: string, name?: string, avatar?: string, avatar_url?: string, is_password_set?: boolean } }) => T) => selector({ - userProfile: { - id: 'current-user', - name: 'Current User', - email: 'member@example.com', - avatar: '', - avatar_url: '', - is_password_set: true, - }, - }), -})) - vi.mock('@/service/access-control', () => ({ useAppWhiteListSubjects: (...args: unknown[]) => mockUseAppWhiteListSubjects(...args), useSearchForWhiteListCandidates: (...args: unknown[]) => mockUseSearchForWhiteListCandidates(...args), diff --git a/web/app/components/app/app-access-control/__tests__/add-member-or-group-pop.spec.tsx b/web/app/components/app/app-access-control/__tests__/add-member-or-group-pop.spec.tsx index d34756e85e4..25df73c08ba 100644 --- a/web/app/components/app/app-access-control/__tests__/add-member-or-group-pop.spec.tsx +++ b/web/app/components/app/app-access-control/__tests__/add-member-or-group-pop.spec.tsx @@ -10,14 +10,6 @@ const intersectionObserverMocks = vi.hoisted(() => ({ callback: null as null | ((entries: Array<{ isIntersecting: boolean }>) => void), })) -vi.mock('@/context/app-context', () => ({ - useSelector: (selector: (value: { userProfile: { email: string } }) => T) => selector({ - userProfile: { - email: 'member@example.com', - }, - }), -})) - vi.mock('@/service/access-control', () => ({ useSearchForWhiteListCandidates: (...args: unknown[]) => mockUseSearchForWhiteListCandidates(...args), })) diff --git a/web/app/components/app/app-publisher/__tests__/index.spec.tsx b/web/app/components/app/app-publisher/__tests__/index.spec.tsx index d6fb10c8163..9b1033d754a 100644 --- a/web/app/components/app/app-publisher/__tests__/index.spec.tsx +++ b/web/app/components/app/app-publisher/__tests__/index.spec.tsx @@ -107,15 +107,6 @@ vi.mock('@/service/use-tools', () => ({ useInvalidateWorkflowToolDetailByAppID: () => vi.fn(), })) -vi.mock('@/context/app-context', () => ({ - useAppContext: () => ({ - isCurrentWorkspaceManager: true, - }), - useSelector: (selector: (state: { workspacePermissionKeys: string[] }) => T): T => selector({ - workspacePermissionKeys: mockWorkspacePermissionKeys, - }), -})) - vi.mock('@/context/app-context-state', async (importOriginal) => { const { createAppContextStateAtomMock } = await import('@/__tests__/utils/mock-app-context-state') return createAppContextStateAtomMock(importOriginal, () => ({ diff --git a/web/app/components/app/configuration/dataset-config/__tests__/index.spec.tsx b/web/app/components/app/configuration/dataset-config/__tests__/index.spec.tsx index 9611da5c814..8a6c41954a0 100644 --- a/web/app/components/app/configuration/dataset-config/__tests__/index.spec.tsx +++ b/web/app/components/app/configuration/dataset-config/__tests__/index.spec.tsx @@ -37,15 +37,6 @@ vi.mock('@/app/components/header/account-setting/model-provider-page/hooks', () })), })) -vi.mock('@/context/app-context', () => ({ - useSelector: vi.fn((fn: any) => fn({ - userProfile: { - id: 'user-123', - }, - workspacePermissionKeys: [], - })), -})) - vi.mock('@/context/app-context-state', async (importOriginal) => { const { createAppContextStateAtomMock } = await import('@/__tests__/utils/mock-app-context-state') diff --git a/web/app/components/app/configuration/dataset-config/select-dataset/__tests__/index.spec.tsx b/web/app/components/app/configuration/dataset-config/select-dataset/__tests__/index.spec.tsx index d0331de79c6..70edc50e7dd 100644 --- a/web/app/components/app/configuration/dataset-config/select-dataset/__tests__/index.spec.tsx +++ b/web/app/components/app/configuration/dataset-config/select-dataset/__tests__/index.spec.tsx @@ -34,11 +34,6 @@ vi.mock('@/service/knowledge/use-dataset', () => ({ })) let mockWorkspacePermissionKeys = ['dataset.create_and_management'] -vi.mock('@/context/app-context', () => ({ - useSelector: (selector: (state: { workspacePermissionKeys: string[] }) => unknown) => selector({ - workspacePermissionKeys: mockWorkspacePermissionKeys, - }), -})) vi.mock('@/context/app-context-state', async (importOriginal) => { const { createAppContextStateAtomMock } = await import('@/__tests__/utils/mock-app-context-state') diff --git a/web/app/components/app/configuration/dataset-config/settings-modal/__tests__/index.spec.tsx b/web/app/components/app/configuration/dataset-config/settings-modal/__tests__/index.spec.tsx index 092ad6d7ec2..95bd3dec761 100644 --- a/web/app/components/app/configuration/dataset-config/settings-modal/__tests__/index.spec.tsx +++ b/web/app/components/app/configuration/dataset-config/settings-modal/__tests__/index.spec.tsx @@ -67,24 +67,6 @@ vi.mock('@/service/use-common', async () => ({ useMembers: vi.fn(), })) -vi.mock('@/context/app-context', () => ({ - useAppContext: () => { - throw new Error('legacy workspace dataset_operator state should not be used by SettingsModal') - }, - useSelector: (selector: (value: { - userProfile: { id: string, name: string, email: string, avatar_url: string } - workspacePermissionKeys: string[] - }) => T) => selector({ - userProfile: { - id: 'user-1', - name: 'User One', - email: 'user@example.com', - avatar_url: 'avatar.png', - }, - workspacePermissionKeys: [], - }), -})) - vi.mock('@/context/modal-context', () => ({ useModalContext: () => ({ setShowAccountSettingModal: mockSetShowAccountSettingModal, diff --git a/web/app/components/app/configuration/debug/debug-with-multiple-model/__tests__/chat-item.spec.tsx b/web/app/components/app/configuration/debug/debug-with-multiple-model/__tests__/chat-item.spec.tsx index 5117aced684..9591343a29f 100644 --- a/web/app/components/app/configuration/debug/debug-with-multiple-model/__tests__/chat-item.spec.tsx +++ b/web/app/components/app/configuration/debug/debug-with-multiple-model/__tests__/chat-item.spec.tsx @@ -29,10 +29,6 @@ let capturedChatProps: { let eventSubscriptionCallback: ((v: { type: string, payload?: Record }) => void) | null = null -vi.mock('@/context/app-context', () => ({ - useAppContext: () => mockUseAppContext(), -})) - vi.mock('@/context/debug-configuration', () => ({ useDebugConfigurationContext: () => mockUseDebugConfigurationContext(), })) diff --git a/web/app/components/app/configuration/debug/debug-with-single-model/__tests__/index.spec.tsx b/web/app/components/app/configuration/debug/debug-with-single-model/__tests__/index.spec.tsx index fc1df42ea4b..60a26dcf16e 100644 --- a/web/app/components/app/configuration/debug/debug-with-single-model/__tests__/index.spec.tsx +++ b/web/app/components/app/configuration/debug/debug-with-single-model/__tests__/index.spec.tsx @@ -307,10 +307,6 @@ const { mockUseAppContext } = vi.hoisted(() => ({ mockUseAppContext.mockReturnValue(mockAppContext) -vi.mock('@/context/app-context', () => ({ - useAppContext: mockUseAppContext, -})) - type FeatureState = { moreLikeThis: { enabled: boolean } opening: { enabled: boolean, opening_statement: string, suggested_questions: string[] } diff --git a/web/app/components/app/configuration/hooks/__tests__/use-configuration.spec.tsx b/web/app/components/app/configuration/hooks/__tests__/use-configuration.spec.tsx index af04a9572ee..6039f76630d 100644 --- a/web/app/components/app/configuration/hooks/__tests__/use-configuration.spec.tsx +++ b/web/app/components/app/configuration/hooks/__tests__/use-configuration.spec.tsx @@ -51,18 +51,6 @@ vi.mock('ahooks', async () => { } }) -vi.mock('@/context/app-context', () => ({ - useAppContext: () => ({ - currentWorkspace: { id: 'workspace-1' }, - isLoadingCurrentWorkspace: false, - workspacePermissionKeys: ['app.create_and_management'], - }), - useSelector: (selector: (state: { userProfile: { id: string }, workspacePermissionKeys: string[] }) => unknown) => selector({ - userProfile: { id: 'user-1' }, - workspacePermissionKeys: ['app.create_and_management'], - }), -})) - vi.mock('@/context/app-context-state', async (importOriginal) => { const { createAppContextStateAtomMock } = await import('@/__tests__/utils/mock-app-context-state') diff --git a/web/app/components/app/create-app-dialog/app-list/__tests__/index.spec.tsx b/web/app/components/app/create-app-dialog/app-list/__tests__/index.spec.tsx index 711f6f3b37f..ea215c52b44 100644 --- a/web/app/components/app/create-app-dialog/app-list/__tests__/index.spec.tsx +++ b/web/app/components/app/create-app-dialog/app-list/__tests__/index.spec.tsx @@ -16,7 +16,6 @@ const mockTrackCreateApp = vi.fn() const mockInvalidateAppList = vi.hoisted(() => vi.fn()) let latestDebounceFn = () => {} let mockWorkspacePermissionKeys: string[] = ['app.create_and_management'] -let mockIsCurrentWorkspaceEditor = true const mockUserProfile = { id: 'user-1' } vi.mock('ahooks', () => ({ @@ -29,13 +28,6 @@ vi.mock('ahooks', () => ({ } }, })) -vi.mock('@/context/app-context', () => ({ - useAppContext: () => ({ - isCurrentWorkspaceEditor: mockIsCurrentWorkspaceEditor, - userProfile: mockUserProfile, - workspacePermissionKeys: mockWorkspacePermissionKeys, - }), -})) vi.mock('@/context/app-context-state', async (importOriginal) => { const { createAppContextStateAtomMock } = await import('@/__tests__/utils/mock-app-context-state') @@ -198,7 +190,6 @@ describe('Apps', () => { vi.clearAllMocks() localStorage.clear() mockWorkspacePermissionKeys = ['app.create_and_management'] - mockIsCurrentWorkspaceEditor = true mockUseExploreAppList.mockReturnValue({ data: defaultData, isLoading: false, @@ -230,7 +221,6 @@ describe('Apps', () => { }) it('passes app.create_and_management permission to template cards even when user is not a workspace editor', () => { - mockIsCurrentWorkspaceEditor = false mockWorkspacePermissionKeys = ['app.create_and_management'] render() @@ -239,7 +229,6 @@ describe('Apps', () => { }) it('does not allow template creation when app.create_and_management permission is missing', () => { - mockIsCurrentWorkspaceEditor = true mockWorkspacePermissionKeys = [] render() diff --git a/web/app/components/app/create-app-modal/__tests__/index.spec.tsx b/web/app/components/app/create-app-modal/__tests__/index.spec.tsx index 1e8266990e8..941f055969c 100644 --- a/web/app/components/app/create-app-modal/__tests__/index.spec.tsx +++ b/web/app/components/app/create-app-modal/__tests__/index.spec.tsx @@ -74,9 +74,6 @@ vi.mock('@/utils/app-redirection', () => ({ vi.mock('@/context/provider-context', () => ({ useProviderContext: vi.fn(), })) -vi.mock('@/context/app-context', () => ({ - useAppContext: mockUseAppContext, -})) vi.mock('@/context/app-context-state', async (importOriginal) => { const { createAppContextStateAtomMock } = await import('@/__tests__/utils/mock-app-context-state') diff --git a/web/app/components/app/create-from-dsl-modal/__tests__/index.spec.tsx b/web/app/components/app/create-from-dsl-modal/__tests__/index.spec.tsx index a6932f6daaf..905c07e37d4 100644 --- a/web/app/components/app/create-from-dsl-modal/__tests__/index.spec.tsx +++ b/web/app/components/app/create-from-dsl-modal/__tests__/index.spec.tsx @@ -85,14 +85,6 @@ vi.mock('@/app/components/workflow/plugin-dependency/hooks', () => ({ }), })) -vi.mock('@/context/app-context', () => ({ - useAppContext: () => ({ - isCurrentWorkspaceEditor: true, - userProfile: mockUserProfile, - workspacePermissionKeys: mockWorkspacePermissionKeys, - }), -})) - vi.mock('@/context/app-context-state', async (importOriginal) => { const { createAppContextStateAtomMock } = await import('@/__tests__/utils/mock-app-context-state') diff --git a/web/app/components/app/log/__tests__/list.spec.tsx b/web/app/components/app/log/__tests__/list.spec.tsx index cc63b774edf..2a8caa5dacb 100644 --- a/web/app/components/app/log/__tests__/list.spec.tsx +++ b/web/app/components/app/log/__tests__/list.spec.tsx @@ -31,14 +31,6 @@ vi.mock('react-i18next', () => ({ }), })) -vi.mock('@/context/app-context', () => ({ - useAppContext: () => ({ - userProfile: { - timezone: 'Asia/Shanghai', - }, - }), -})) - vi.mock('@/hooks/use-timestamp', () => ({ default: () => ({ formatTime: (timestamp: number) => `formatted-${timestamp}`, diff --git a/web/app/components/app/overview/__tests__/trigger-card.spec.tsx b/web/app/components/app/overview/__tests__/trigger-card.spec.tsx index e7a838d0e6f..3518762ec9b 100644 --- a/web/app/components/app/overview/__tests__/trigger-card.spec.tsx +++ b/web/app/components/app/overview/__tests__/trigger-card.spec.tsx @@ -14,16 +14,6 @@ vi.mock('react-i18next', () => ({ }), })) -vi.mock('@/context/app-context', () => ({ - useAppContext: () => ({ - isCurrentWorkspaceEditor: true, - }), - useSelector: (selector: (state: { userProfile: { id: string }, workspacePermissionKeys: string[] }) => T) => selector({ - userProfile: { id: 'user-1' }, - workspacePermissionKeys: [], - }), -})) - vi.mock('@/context/i18n', () => ({ useDocLink: () => (path: string) => `https://docs.example.com${path}`, })) diff --git a/web/app/components/app/overview/embedded/__tests__/index.spec.tsx b/web/app/components/app/overview/embedded/__tests__/index.spec.tsx index 8c661829a97..653cb78d8fc 100644 --- a/web/app/components/app/overview/embedded/__tests__/index.spec.tsx +++ b/web/app/components/app/overview/embedded/__tests__/index.spec.tsx @@ -24,27 +24,12 @@ const mockThemeBuilder = { primaryColor: '#123456', }, } -const mockUseAppContext = vi.fn(() => ({ - langGeniusVersionInfo: { - current_env: 'PRODUCTION', - current_version: '', - latest_version: '', - release_date: '', - release_notes: '', - version: '', - can_auto_update: false, - }, -})) - vi.mock('copy-to-clipboard', () => ({ default: vi.fn(), })) vi.mock('@/app/components/base/chat/embedded-chatbot/theme/theme-context', () => ({ useThemeContext: () => mockThemeBuilder, })) -vi.mock('@/context/app-context', () => ({ - useAppContext: () => mockUseAppContext(), -})) const mockWindowOpen = vi.spyOn(window, 'open').mockImplementation(() => null) const mockedCopy = vi.mocked(copy) const originalCompressionStream = globalThis.CompressionStream diff --git a/web/app/components/app/switch-app-modal/__tests__/index.spec.tsx b/web/app/components/app/switch-app-modal/__tests__/index.spec.tsx index eda5f2cc11a..0964745c57b 100644 --- a/web/app/components/app/switch-app-modal/__tests__/index.spec.tsx +++ b/web/app/components/app/switch-app-modal/__tests__/index.spec.tsx @@ -28,19 +28,6 @@ vi.mock('@/service/apps', () => ({ deleteApp: (...args: unknown[]) => mockDeleteApp(...args), })) -let mockIsEditor = true -vi.mock('@/context/app-context', () => ({ - useAppContext: () => ({ - isCurrentWorkspaceEditor: mockIsEditor, - userProfile: { - email: 'user@example.com', - }, - langGeniusVersionInfo: { - current_version: '1.0.0', - }, - }), -})) - let mockEnableBilling = false let mockPlan = { type: Plan.sandbox, @@ -172,7 +159,6 @@ describe('SwitchAppModal', () => { originalSetAppDetail(...args) }) useAppStore.setState({ setAppDetail: setAppDetailSpy as typeof originalSetAppDetail }) - mockIsEditor = true mockEnableBilling = false mockPlan = { type: Plan.sandbox, diff --git a/web/app/components/app/workflow-log/__tests__/index.spec.tsx b/web/app/components/app/workflow-log/__tests__/index.spec.tsx index 79afa706293..7e683c7ebab 100644 --- a/web/app/components/app/workflow-log/__tests__/index.spec.tsx +++ b/web/app/components/app/workflow-log/__tests__/index.spec.tsx @@ -78,16 +78,6 @@ vi.mock('@/hooks/use-theme', () => ({ }, })) -vi.mock('@/context/app-context', () => ({ - useAppContext: () => ({ - userProfile: { timezone: 'UTC' }, - }), - useSelector: (selector: (state: { userProfile: { id: string, timezone: string }, workspacePermissionKeys: string[] }) => unknown) => selector({ - userProfile: { id: 'user-1', timezone: 'UTC' }, - workspacePermissionKeys: ['app.create_and_management'], - }), -})) - // Mock WorkflowContextProvider vi.mock('@/app/components/workflow/context', () => ({ WorkflowContextProvider: ({ children }: { children: React.ReactNode }) => ( diff --git a/web/app/components/apps/__tests__/app-card.spec.tsx b/web/app/components/apps/__tests__/app-card.spec.tsx index 0c333204702..d984aeae6d1 100644 --- a/web/app/components/apps/__tests__/app-card.spec.tsx +++ b/web/app/components/apps/__tests__/app-card.spec.tsx @@ -75,10 +75,6 @@ const mockAppContext = vi.hoisted(() => ({ })) // Mock app context -vi.mock('@/context/app-context', () => ({ - useAppContext: () => mockAppContext, - useSelector: (selector: (state: typeof mockAppContext) => unknown) => selector(mockAppContext), -})) vi.mock('@/context/app-context-state', async (importOriginal) => { const { createAppContextStateAtomMock } = await import('@/__tests__/utils/mock-app-context-state') diff --git a/web/app/components/apps/__tests__/creators-filter.spec.tsx b/web/app/components/apps/__tests__/creators-filter.spec.tsx index 3a95174f0a3..9f87aacf598 100644 --- a/web/app/components/apps/__tests__/creators-filter.spec.tsx +++ b/web/app/components/apps/__tests__/creators-filter.spec.tsx @@ -3,12 +3,6 @@ import CreatorsFilter from '../creators-filter' const mockOnChange = vi.hoisted(() => vi.fn()) -vi.mock('@/context/app-context', () => ({ - useAppContext: () => ({ - userProfile: { id: 'member-2' }, - }), -})) - vi.mock('@/context/app-context-state', async (importOriginal) => { const { createAppContextStateAtomMock } = await import('@/__tests__/utils/mock-app-context-state') diff --git a/web/app/components/apps/__tests__/index.spec.tsx b/web/app/components/apps/__tests__/index.spec.tsx index 8ea477bd7cb..1ca6f30f3b7 100644 --- a/web/app/components/apps/__tests__/index.spec.tsx +++ b/web/app/components/apps/__tests__/index.spec.tsx @@ -69,15 +69,6 @@ vi.mock('@/app/education-apply/hooks', () => ({ }, })) -vi.mock('@/context/app-context', () => ({ - useSelector: (selector: (state: { workspacePermissionKeys: string[] }) => unknown) => selector({ - workspacePermissionKeys: mockWorkspacePermissionKeys, - }), - useAppContext: () => ({ - workspacePermissionKeys: mockWorkspacePermissionKeys, - }), -})) - vi.mock('@/context/app-context-state', async (importOriginal) => { const { createAppContextStateAtomMock } = await import('@/__tests__/utils/mock-app-context-state') diff --git a/web/app/components/apps/__tests__/list.spec.tsx b/web/app/components/apps/__tests__/list.spec.tsx index 47d40e1d9a8..af5945beb8d 100644 --- a/web/app/components/apps/__tests__/list.spec.tsx +++ b/web/app/components/apps/__tests__/list.spec.tsx @@ -70,22 +70,6 @@ vi.mock('@/service/client', () => ({ const mockIsCurrentWorkspaceDatasetOperator = vi.fn(() => false) let mockWorkspacePermissionKeys = ['app.create_and_management'] -vi.mock('@/context/app-context', () => ({ - useAppContext: () => ({ - isCurrentWorkspaceDatasetOperator: mockIsCurrentWorkspaceDatasetOperator(), - userProfile: { id: 'creator-1' }, - workspacePermissionKeys: mockWorkspacePermissionKeys, - }), - useSelector: (selector: (state: { - isCurrentWorkspaceDatasetOperator: boolean - userProfile: { id: string } - workspacePermissionKeys: string[] - }) => unknown) => selector({ - isCurrentWorkspaceDatasetOperator: mockIsCurrentWorkspaceDatasetOperator(), - userProfile: { id: 'creator-1' }, - workspacePermissionKeys: mockWorkspacePermissionKeys, - }), -})) vi.mock('@/context/app-context-state', async (importOriginal) => { const { createAppContextStateAtomMock } = await import('@/__tests__/utils/mock-app-context-state') diff --git a/web/app/components/base/amplitude/registration-tracking.ts b/web/app/components/base/amplitude/registration-tracking.ts index 4c43ab37f0c..19bc8fc5c23 100644 --- a/web/app/components/base/amplitude/registration-tracking.ts +++ b/web/app/components/base/amplitude/registration-tracking.ts @@ -31,7 +31,7 @@ const getSessionStorage = (): Storage | null => { * Amplitude attributes events to whatever identity is active when `track` runs. At * registration time the client does not yet know the user ID, so firing the event * immediately records it under an anonymous profile. We persist the event here and - * replay it once `setUserId` runs in the app context provider after the redirect. + * replay it once `setUserId` runs in the bootstrap effects after the redirect. */ export const rememberRegistrationSuccess = ( { method, utmInfo }: { method: RegistrationMethod, utmInfo?: Record | null }, diff --git a/web/app/components/base/chat/chat/answer/human-input-content/__tests__/unsubmitted.spec.tsx b/web/app/components/base/chat/chat/answer/human-input-content/__tests__/unsubmitted.spec.tsx index 046890157b8..b85a7cb26f0 100644 --- a/web/app/components/base/chat/chat/answer/human-input-content/__tests__/unsubmitted.spec.tsx +++ b/web/app/components/base/chat/chat/answer/human-input-content/__tests__/unsubmitted.spec.tsx @@ -1,22 +1,11 @@ import type { InputVarType } from '@/app/components/workflow/types' -import type { AppContextValue } from '@/context/app-context' import type { HumanInputFormData } from '@/types/workflow' import { render, screen, waitFor } from '@testing-library/react' import userEvent from '@testing-library/user-event' import { describe, expect, it, vi } from 'vitest' import { UserActionButtonType } from '@/app/components/workflow/nodes/human-input/types' -import { useSelector } from '@/context/app-context' import { UnsubmittedHumanInputContent } from '../unsubmitted' -// Mock AppContext's useSelector to control user profile data -vi.mock('@/context/app-context', async (importOriginal) => { - const actual = await importOriginal() - return { - ...actual, - useSelector: vi.fn(), - } -}) - describe('UnsubmittedHumanInputContent Integration', () => { const user = userEvent.setup() @@ -49,18 +38,6 @@ describe('UnsubmittedHumanInputContent Integration', () => { beforeEach(() => { vi.clearAllMocks() - vi.mocked(useSelector).mockImplementation((selector: (value: AppContextValue) => unknown) => { - return selector({ - userProfile: { - id: 'user_123', - name: 'Test User', - email: 'test@example.com', - avatar: '', - avatar_url: '', - is_password_set: false, - }, - } as AppContextValue) - }) }) describe('Rendering', () => { diff --git a/web/app/components/billing/apps-full-in-dialog/__tests__/index.spec.tsx b/web/app/components/billing/apps-full-in-dialog/__tests__/index.spec.tsx index 790fba4a4e4..7adf905b358 100644 --- a/web/app/components/billing/apps-full-in-dialog/__tests__/index.spec.tsx +++ b/web/app/components/billing/apps-full-in-dialog/__tests__/index.spec.tsx @@ -1,7 +1,7 @@ import type { GetAccountProfileResponse } from '@dify/contracts/api/console/account/types.gen' import type { Mock } from 'vitest' +import type { AppContextStateMockState } from '@/__tests__/utils/mock-app-context-state' import type { UsagePlanInfo } from '@/app/components/billing/type' -import type { AppContextValue } from '@/context/app-context' import type { ProviderContextState } from '@/context/provider-context' import type { ICurrentWorkspace, LangGeniusVersionResponse } from '@/models/common' import { render, screen } from '@testing-library/react' @@ -10,7 +10,7 @@ import { mailToSupport } from '@/app/components/header/utils/util' import { baseProviderContextValue, useProviderContext } from '@/context/provider-context' import AppsFull from '../index' -let mockAppContextState: AppContextValue +let mockAppContextState: AppContextStateMockState const mockUseAppContext = vi.hoisted(() => vi.fn()) vi.mock('@/config', async (importOriginal) => { @@ -21,10 +21,6 @@ vi.mock('@/config', async (importOriginal) => { } }) -vi.mock('@/context/app-context', () => ({ - useAppContext: mockUseAppContext, -})) - vi.mock('@/context/app-context-state', async (importOriginal) => { const { createAppContextStateAtomMock } = await import('@/__tests__/utils/mock-app-context-state') return createAppContextStateAtomMock(importOriginal, () => mockAppContextState) @@ -79,7 +75,7 @@ const buildProviderContext = (overrides: Partial = {}): Pr ...overrides, }) -const buildAppContext = (overrides: Partial = {}): AppContextValue => { +const buildAppContext = (overrides: Partial = {}): AppContextStateMockState => { const userProfile: GetAccountProfileResponse = { id: 'user-id', name: 'Test User', @@ -109,7 +105,7 @@ const buildAppContext = (overrides: Partial = {}): AppContextVa version: '', can_auto_update: false, } - const base: Omit = { + const base: AppContextStateMockState = { userProfile, currentWorkspace, isCurrentWorkspaceManager: false, @@ -120,13 +116,10 @@ const buildAppContext = (overrides: Partial = {}): AppContextVa mutateCurrentWorkspace: vi.fn(), langGeniusVersionInfo, isLoadingCurrentWorkspace: false, - isValidatingCurrentWorkspace: false, workspacePermissionKeys: [], } - const useSelector: AppContextValue['useSelector'] = selector => selector({ ...base, useSelector }) return { ...base, - useSelector, ...overrides, } } diff --git a/web/app/components/billing/billing-page/__tests__/index.spec.tsx b/web/app/components/billing/billing-page/__tests__/index.spec.tsx index 25f93ff5c05..24fcb1d60eb 100644 --- a/web/app/components/billing/billing-page/__tests__/index.spec.tsx +++ b/web/app/components/billing/billing-page/__tests__/index.spec.tsx @@ -34,13 +34,6 @@ vi.mock('@/hooks/use-async-window-open', () => ({ useAsyncWindowOpen: () => openAsyncWindowMock, })) -vi.mock('@/context/app-context', () => ({ - useAppContext: () => ({ - isCurrentWorkspaceManager: isManager, - workspacePermissionKeys, - }), -})) - vi.mock('@/context/app-context-state', async (importOriginal) => { const { createAppContextStateAtomMock } = await import('@/__tests__/utils/mock-app-context-state') return createAppContextStateAtomMock(importOriginal, () => ({ diff --git a/web/app/components/billing/plan/__tests__/index.spec.tsx b/web/app/components/billing/plan/__tests__/index.spec.tsx index 9e0437ffd7f..6eed7388436 100644 --- a/web/app/components/billing/plan/__tests__/index.spec.tsx +++ b/web/app/components/billing/plan/__tests__/index.spec.tsx @@ -44,14 +44,6 @@ vi.mock('@/context/provider-context', () => ({ useProviderContext: () => providerContextMock(), })) -vi.mock('@/context/app-context', () => ({ - useAppContext: () => ({ - userProfile: { email: 'user@example.com' }, - isCurrentWorkspaceManager, - workspacePermissionKeys, - }), -})) - vi.mock('@/context/app-context-state', async (importOriginal) => { const { createAppContextStateAtomMock } = await import('@/__tests__/utils/mock-app-context-state') return createAppContextStateAtomMock(importOriginal, () => ({ diff --git a/web/app/components/billing/pricing/__tests__/dialog.spec.tsx b/web/app/components/billing/pricing/__tests__/dialog.spec.tsx index 3a1d4f353e3..9c4e329641d 100644 --- a/web/app/components/billing/pricing/__tests__/dialog.spec.tsx +++ b/web/app/components/billing/pricing/__tests__/dialog.spec.tsx @@ -44,10 +44,6 @@ vi.mock('../footer', () => ({ default: () =>
footer
, })) -vi.mock('@/context/app-context', () => ({ - useAppContext: () => mockAppCtx, -})) - vi.mock('@/context/app-context-state', async (importOriginal) => { const { createAppContextStateAtomMock } = await import('@/__tests__/utils/mock-app-context-state') return createAppContextStateAtomMock(importOriginal, () => mockAppCtx) diff --git a/web/app/components/billing/pricing/__tests__/index.spec.tsx b/web/app/components/billing/pricing/__tests__/index.spec.tsx index 1e5df7614d9..5ecb2d79d3a 100644 --- a/web/app/components/billing/pricing/__tests__/index.spec.tsx +++ b/web/app/components/billing/pricing/__tests__/index.spec.tsx @@ -27,10 +27,6 @@ vi.mock('@/next/link', () => ({ ), })) -vi.mock('@/context/app-context', () => ({ - useAppContext: () => mockAppCtx, -})) - vi.mock('@/context/app-context-state', async (importOriginal) => { const { createAppContextStateAtomMock } = await import('@/__tests__/utils/mock-app-context-state') return createAppContextStateAtomMock(importOriginal, () => mockAppCtx) diff --git a/web/app/components/billing/pricing/plans/cloud-plan-item/__tests__/index.spec.tsx b/web/app/components/billing/pricing/plans/cloud-plan-item/__tests__/index.spec.tsx index d0e874cd9e0..f86d5390e94 100644 --- a/web/app/components/billing/pricing/plans/cloud-plan-item/__tests__/index.spec.tsx +++ b/web/app/components/billing/pricing/plans/cloud-plan-item/__tests__/index.spec.tsx @@ -14,10 +14,6 @@ import CloudPlanItem from '../index' let mockAppCtx: Record = {} const mockUseAppContext = vi.hoisted(() => vi.fn()) -vi.mock('@/context/app-context', () => ({ - useAppContext: mockUseAppContext, -})) - vi.mock('@/context/app-context-state', async (importOriginal) => { const { createAppContextStateAtomMock } = await import('@/__tests__/utils/mock-app-context-state') return createAppContextStateAtomMock(importOriginal, () => mockAppCtx) diff --git a/web/app/components/billing/pricing/plans/self-hosted-plan-item/__tests__/index.spec.tsx b/web/app/components/billing/pricing/plans/self-hosted-plan-item/__tests__/index.spec.tsx index 99c1643d68d..9e09f06e228 100644 --- a/web/app/components/billing/pricing/plans/self-hosted-plan-item/__tests__/index.spec.tsx +++ b/web/app/components/billing/pricing/plans/self-hosted-plan-item/__tests__/index.spec.tsx @@ -17,10 +17,6 @@ vi.mock('../list', () => ({ ), })) -vi.mock('@/context/app-context', () => ({ - useAppContext: mockUseAppContext, -})) - vi.mock('@/context/app-context-state', async (importOriginal) => { const { createAppContextStateAtomMock } = await import('@/__tests__/utils/mock-app-context-state') return createAppContextStateAtomMock(importOriginal, () => mockAppCtx) diff --git a/web/app/components/custom/custom-page/__tests__/index.spec.tsx b/web/app/components/custom/custom-page/__tests__/index.spec.tsx index e4bbaca971c..1cb103accaf 100644 --- a/web/app/components/custom/custom-page/__tests__/index.spec.tsx +++ b/web/app/components/custom/custom-page/__tests__/index.spec.tsx @@ -1,5 +1,5 @@ import type { ReactElement } from 'react' -import type { AppContextValue } from '@/context/app-context' +import type { AppContextStateMockState } from '@/__tests__/utils/mock-app-context-state' import { screen } from '@testing-library/react' import userEvent from '@testing-library/user-event' import { beforeEach, describe, expect, it, vi } from 'vitest' @@ -11,7 +11,7 @@ import { initialLangGeniusVersionInfo, initialWorkspaceInfo, userProfilePlaceholder, -} from '@/context/app-context' +} from '@/context/app-context-defaults' import { useModalContext } from '@/context/modal-context' import { useProviderContext } from '@/context/provider-context' import CustomPage from '../index' @@ -53,13 +53,6 @@ vi.mock('@/context/provider-context', () => ({ vi.mock('@/context/modal-context', () => ({ useModalContext: vi.fn(), })) -vi.mock('@/context/app-context', async (importOriginal) => { - const actual = await importOriginal() - return { - ...actual, - useAppContext: mockUseAppContext, - } -}) vi.mock('@langgenius/dify-ui/toast', () => ({ toast: mockToast, })) @@ -83,7 +76,7 @@ const createProviderContext = ({ }) } -const createAppContextValue = (): AppContextValue => ({ +const createAppContextValue = (): AppContextStateMockState => ({ userProfile: userProfilePlaceholder, mutateUserProfile: vi.fn(), currentWorkspace: { @@ -99,9 +92,7 @@ const createAppContextValue = (): AppContextValue => ({ isCurrentWorkspaceDatasetOperator: false, mutateCurrentWorkspace: vi.fn(), langGeniusVersionInfo: initialLangGeniusVersionInfo, - useSelector: vi.fn() as unknown as AppContextValue['useSelector'], isLoadingCurrentWorkspace: false, - isValidatingCurrentWorkspace: false, workspacePermissionKeys: [], }) diff --git a/web/app/components/custom/custom-web-app-brand/hooks/__tests__/use-web-app-brand.spec.tsx b/web/app/components/custom/custom-web-app-brand/hooks/__tests__/use-web-app-brand.spec.tsx index 058b381b323..5ce08a990ab 100644 --- a/web/app/components/custom/custom-web-app-brand/hooks/__tests__/use-web-app-brand.spec.tsx +++ b/web/app/components/custom/custom-web-app-brand/hooks/__tests__/use-web-app-brand.spec.tsx @@ -1,6 +1,7 @@ import type { GetSystemFeaturesResponse } from '@dify/contracts/api/console/system-features/types.gen' import type { ChangeEvent } from 'react' -import type { AppContextValue } from '@/context/app-context' +import type { AppContextStateMockState } from '@/__tests__/utils/mock-app-context-state' +import type { ICurrentWorkspace } from '@/models/common' import { act } from '@testing-library/react' import { beforeEach, describe, expect, it, vi } from 'vitest' import { createMockProviderContextValue } from '@/__mocks__/provider-context' @@ -12,7 +13,7 @@ import { initialLangGeniusVersionInfo, initialWorkspaceInfo, userProfilePlaceholder, -} from '@/context/app-context' +} from '@/context/app-context-defaults' import { useProviderContext } from '@/context/provider-context' import { updateCurrentWorkspace } from '@/service/common' import useWebAppBrand from '../use-web-app-brand' @@ -43,7 +44,7 @@ const { mockNotify, mockToast } = vi.hoisted(() => { return { mockNotify, mockToast } }) const appContextStateRef = vi.hoisted(() => ({ - value: undefined as AppContextValue | undefined, + value: undefined as AppContextStateMockState | undefined, })) const mockUseAppContext = vi.hoisted(() => vi.fn()) @@ -53,13 +54,6 @@ vi.mock('@langgenius/dify-ui/toast', () => ({ vi.mock('@/service/common', () => ({ updateCurrentWorkspace: vi.fn(), })) -vi.mock('@/context/app-context', async (importOriginal) => { - const actual = await importOriginal() - return { - ...actual, - useAppContext: mockUseAppContext, - } -}) vi.mock('@/context/app-context-state', async (importOriginal) => { const { createAppContextStateAtomMock } = await import('@/__tests__/utils/mock-app-context-state') @@ -102,9 +96,9 @@ const createProviderContext = ({ }) } -const createAppContextValue = (overrides: Partial = {}): AppContextValue => { +const createAppContextValue = (overrides: Partial = {}): AppContextStateMockState => { const { currentWorkspace: currentWorkspaceOverride, ...restOverrides } = overrides - const workspaceOverrides: Partial = currentWorkspaceOverride ?? {} + const workspaceOverrides: Partial = currentWorkspaceOverride ?? {} const currentWorkspace = { ...initialWorkspaceInfo, ...workspaceOverrides, @@ -125,17 +119,15 @@ const createAppContextValue = (overrides: Partial = {}): AppCon workspacePermissionKeys: ['customization.manage'], mutateCurrentWorkspace: vi.fn(), langGeniusVersionInfo: initialLangGeniusVersionInfo, - useSelector: vi.fn() as unknown as AppContextValue['useSelector'], isLoadingCurrentWorkspace: false, - isValidatingCurrentWorkspace: false, ...restOverrides, currentWorkspace, } } describe('useWebAppBrand', () => { - let appContextValue: AppContextValue - const setAppContextValue = (nextValue: AppContextValue) => { + let appContextValue: AppContextStateMockState + const setAppContextValue = (nextValue: AppContextStateMockState) => { appContextValue = nextValue appContextStateRef.value = nextValue } @@ -146,7 +138,7 @@ describe('useWebAppBrand', () => { setAppContextValue(createAppContextValue()) currentBrandingOverrides = {} - mockUpdateCurrentWorkspace.mockResolvedValue(appContextValue.currentWorkspace) + mockUpdateCurrentWorkspace.mockResolvedValue(appContextValue.currentWorkspace as ICurrentWorkspace) mockUseAppContext.mockImplementation(() => appContextValue) mockUseProviderContext.mockReturnValue(createProviderContext()) mockGetImageUploadErrorMessage.mockReturnValue('upload error') diff --git a/web/app/components/datasets/access-config/__tests__/index.spec.tsx b/web/app/components/datasets/access-config/__tests__/index.spec.tsx index df6d3d7c1fa..39c7cc8e794 100644 --- a/web/app/components/datasets/access-config/__tests__/index.spec.tsx +++ b/web/app/components/datasets/access-config/__tests__/index.spec.tsx @@ -75,10 +75,6 @@ vi.mock('@/context/dataset-detail', () => ({ }), })) -vi.mock('@/context/app-context', () => ({ - useSelector: vi.fn((selector: (state: typeof mockAppContextState) => unknown) => selector(mockAppContextState)), -})) - vi.mock('@/context/app-context-state', async (importOriginal) => { const { createDatasetAccessAtomMock } = await import('@/app/components/datasets/__tests__/mock-dataset-access') diff --git a/web/app/components/datasets/create/__tests__/index.spec.tsx b/web/app/components/datasets/create/__tests__/index.spec.tsx index 04a8c68f9c9..aad3d88b67d 100644 --- a/web/app/components/datasets/create/__tests__/index.spec.tsx +++ b/web/app/components/datasets/create/__tests__/index.spec.tsx @@ -40,19 +40,6 @@ vi.mock('@/next/navigation', () => ({ let mockCurrentUserId = 'user-1' let mockWorkspacePermissionKeys = ['dataset.create_and_management'] let mockIsLoadingWorkspacePermissionKeys = false -vi.mock('@/context/app-context', () => ({ - useSelector: (selector: (state: { - userProfile: { id: string } - workspacePermissionKeys: string[] - isLoadingWorkspacePermissionKeys: boolean - }) => unknown) => { - return selector({ - userProfile: { id: mockCurrentUserId }, - workspacePermissionKeys: mockWorkspacePermissionKeys, - isLoadingWorkspacePermissionKeys: mockIsLoadingWorkspacePermissionKeys, - }) - }, -})) vi.mock('@/context/app-context-state', async (importOriginal) => { const { createDatasetAccessAtomMock } = await import('@/app/components/datasets/__tests__/mock-dataset-access') diff --git a/web/app/components/datasets/documents/__tests__/index.spec.tsx b/web/app/components/datasets/documents/__tests__/index.spec.tsx index de6e84e2ee5..072619bf6cd 100644 --- a/web/app/components/datasets/documents/__tests__/index.spec.tsx +++ b/web/app/components/datasets/documents/__tests__/index.spec.tsx @@ -47,14 +47,6 @@ vi.mock('@/context/provider-context', () => ({ })), })) -vi.mock('@/context/app-context', () => ({ - useSelector: (selector: (state: { userProfile: { id: string }, workspacePermissionKeys: string[] }) => unknown) => - selector({ - userProfile: { id: 'test-user' }, - workspacePermissionKeys: ['dataset.create_and_management'], - }), -})) - vi.mock('@/context/app-context-state', async (importOriginal) => { const { createDatasetAccessAtomMock } = await import('@/app/components/datasets/__tests__/mock-dataset-access') diff --git a/web/app/components/datasets/documents/components/document-list/__tests__/index.spec.tsx b/web/app/components/datasets/documents/components/document-list/__tests__/index.spec.tsx index 632e9b16fcb..fb14b1ec95d 100644 --- a/web/app/components/datasets/documents/components/document-list/__tests__/index.spec.tsx +++ b/web/app/components/datasets/documents/components/document-list/__tests__/index.spec.tsx @@ -34,14 +34,6 @@ vi.mock('@/context/dataset-detail', () => ({ }), })) -vi.mock('@/context/app-context', () => ({ - useSelector: (selector: (state: { userProfile: { id: string }, workspacePermissionKeys: string[] }) => unknown) => - selector({ - userProfile: { id: 'user-1' }, - workspacePermissionKeys: ['dataset.create_and_management'], - }), -})) - vi.mock('@/context/app-context-state', async (importOriginal) => { const { createDatasetAccessAtomMock } = await import('@/app/components/datasets/__tests__/mock-dataset-access') diff --git a/web/app/components/datasets/documents/create-from-pipeline/__tests__/index.spec.tsx b/web/app/components/datasets/documents/create-from-pipeline/__tests__/index.spec.tsx index 8e699008b3b..3c53226bb9c 100644 --- a/web/app/components/datasets/documents/create-from-pipeline/__tests__/index.spec.tsx +++ b/web/app/components/datasets/documents/create-from-pipeline/__tests__/index.spec.tsx @@ -49,19 +49,6 @@ vi.mock('@/context/provider-context', () => ({ let mockCurrentUserId = 'user-1' let mockWorkspacePermissionKeys = ['dataset.create_and_management'] let mockIsLoadingWorkspacePermissionKeys = false -vi.mock('@/context/app-context', () => ({ - useSelector: (selector: (state: { - userProfile: { id: string } - workspacePermissionKeys: string[] - isLoadingWorkspacePermissionKeys: boolean - }) => unknown) => { - return selector({ - userProfile: { id: mockCurrentUserId }, - workspacePermissionKeys: mockWorkspacePermissionKeys, - isLoadingWorkspacePermissionKeys: mockIsLoadingWorkspacePermissionKeys, - }) - }, -})) vi.mock('@/context/app-context-state', async (importOriginal) => { const { createDatasetAccessAtomMock } = await import('@/app/components/datasets/__tests__/mock-dataset-access') diff --git a/web/app/components/datasets/extra-info/api-access/__tests__/index.spec.tsx b/web/app/components/datasets/extra-info/api-access/__tests__/index.spec.tsx index 4c504ec4771..024616839c7 100644 --- a/web/app/components/datasets/extra-info/api-access/__tests__/index.spec.tsx +++ b/web/app/components/datasets/extra-info/api-access/__tests__/index.spec.tsx @@ -7,10 +7,6 @@ vi.mock('@/context/dataset-detail', () => ({ useDatasetDetailContextWithSelector: vi.fn(() => 'test-dataset-id'), })) -vi.mock('@/context/app-context', () => ({ - useSelector: vi.fn(() => true), -})) - vi.mock('@/hooks/use-api-access-url', () => ({ useDatasetApiAccessUrl: vi.fn(() => 'https://api.example.com/docs'), })) diff --git a/web/app/components/datasets/extra-info/service-api/__tests__/index.spec.tsx b/web/app/components/datasets/extra-info/service-api/__tests__/index.spec.tsx index 1a5ac70964a..418f3076ca9 100644 --- a/web/app/components/datasets/extra-info/service-api/__tests__/index.spec.tsx +++ b/web/app/components/datasets/extra-info/service-api/__tests__/index.spec.tsx @@ -10,11 +10,6 @@ import ServiceApi from '../index' let mockWorkspacePermissionKeys: string[] = ['dataset.api_key.manage'] -vi.mock('@/context/app-context', () => ({ - useSelector: (selector: (state: { workspacePermissionKeys: string[] }) => unknown) => - selector({ workspacePermissionKeys: mockWorkspacePermissionKeys }), -})) - vi.mock('@/context/app-context-state', async (importOriginal) => { const { createDatasetAccessAtomMock } = await import('@/app/components/datasets/__tests__/mock-dataset-access') diff --git a/web/app/components/datasets/hit-testing/__tests__/index.spec.tsx b/web/app/components/datasets/hit-testing/__tests__/index.spec.tsx index fa20d559603..4f1d4dc7bf8 100644 --- a/web/app/components/datasets/hit-testing/__tests__/index.spec.tsx +++ b/web/app/components/datasets/hit-testing/__tests__/index.spec.tsx @@ -79,10 +79,6 @@ vi.mock('@/context/dataset-detail', () => ({ ), })) -vi.mock('@/context/app-context', () => ({ - useSelector: (selector: (state: typeof mockAppContextState) => unknown) => selector(mockAppContextState), -})) - vi.mock('@/context/app-context-state', async (importOriginal) => { const { createDatasetAccessAtomMock } = await import('@/app/components/datasets/__tests__/mock-dataset-access') diff --git a/web/app/components/datasets/list/__tests__/index.spec.tsx b/web/app/components/datasets/list/__tests__/index.spec.tsx index 9b6a71a0407..f7b0906c58f 100644 --- a/web/app/components/datasets/list/__tests__/index.spec.tsx +++ b/web/app/components/datasets/list/__tests__/index.spec.tsx @@ -11,7 +11,6 @@ let mockAppContextState = { isCurrentWorkspaceOwner: true, workspacePermissionKeys: ['dataset.create_and_management', 'dataset.external.connect'], } -let mockIsCurrentWorkspaceOwner = true vi.mock('@/next/navigation', () => ({ useRouter: () => ({ push: mockPush, @@ -20,13 +19,6 @@ vi.mock('@/next/navigation', () => ({ })) // Mock app context -vi.mock('@/context/app-context', () => ({ - useAppContext: () => ({ - currentWorkspace: { role: 'admin' }, - isCurrentWorkspaceOwner: mockIsCurrentWorkspaceOwner, - }), - useSelector: (selector: (state: typeof mockAppContextState) => unknown) => selector(mockAppContextState), -})) vi.mock('@/context/app-context-state', async (importOriginal) => { const { createDatasetAccessAtomMock } = await import('@/app/components/datasets/__tests__/mock-dataset-access') @@ -148,7 +140,6 @@ describe('List', () => { isCurrentWorkspaceOwner: true, workspacePermissionKeys: ['dataset.create_and_management', 'dataset.external.connect'], } - mockIsCurrentWorkspaceOwner = true const { useDatasetList } = await import('@/service/knowledge/use-dataset') vi.mocked(useDatasetList).mockReturnValue({ data: { pages: [{ data: [], total: 1 }] }, @@ -375,19 +366,7 @@ describe('List', () => { describe('Branch Coverage', () => { it('should not redirect normal role users at component level', async () => { - // Re-mock useAppContext with normal role - vi.doMock('@/context/app-context', () => ({ - useAppContext: () => ({ - currentWorkspace: { role: 'normal' }, - isCurrentWorkspaceOwner: false, - }), - useSelector: (selector: (state: typeof mockAppContextState) => unknown) => selector({ - isCurrentWorkspaceEditor: false, - isCurrentWorkspaceManager: false, - isCurrentWorkspaceOwner: false, - workspacePermissionKeys: ['dataset.create_and_management', 'dataset.external.connect'], - }), - })) + // Re-mock app context state with normal role. // Clear module cache and re-import vi.resetModules() @@ -441,18 +420,6 @@ describe('List', () => { isCurrentWorkspaceOwner: true, workspacePermissionKeys: ['dataset.create_and_management'], } - vi.doMock('@/context/app-context', () => ({ - useAppContext: () => ({ - currentWorkspace: { role: 'admin' }, - isCurrentWorkspaceOwner: true, - }), - useSelector: (selector: (state: typeof mockAppContextState) => unknown) => selector({ - isCurrentWorkspaceEditor: true, - isCurrentWorkspaceManager: true, - isCurrentWorkspaceOwner: true, - workspacePermissionKeys: ['dataset.create_and_management'], - }), - })) vi.doMock('@/context/external-api-panel-context', () => ({ useExternalApiPanel: () => ({ showExternalApiPanel: true, @@ -469,18 +436,6 @@ describe('List', () => { }) it('should close ExternalAPIPanel when onClose is called', async () => { - vi.doMock('@/context/app-context', () => ({ - useAppContext: () => ({ - currentWorkspace: { role: 'admin' }, - isCurrentWorkspaceOwner: true, - }), - useSelector: (selector: (state: typeof mockAppContextState) => unknown) => selector({ - isCurrentWorkspaceEditor: true, - isCurrentWorkspaceManager: true, - isCurrentWorkspaceOwner: true, - workspacePermissionKeys: ['dataset.create_and_management', 'dataset.external.connect'], - }), - })) vi.doMock('@/context/external-api-panel-context', () => ({ useExternalApiPanel: () => ({ showExternalApiPanel: true, @@ -513,18 +468,6 @@ describe('List', () => { isCurrentWorkspaceOwner: false, workspacePermissionKeys: ['dataset.create_and_management', 'dataset.external.connect'], } - vi.doMock('@/context/app-context', () => ({ - useAppContext: () => ({ - currentWorkspace: { role: 'editor' }, - isCurrentWorkspaceOwner: false, - }), - useSelector: (selector: (state: typeof mockAppContextState) => unknown) => selector({ - isCurrentWorkspaceEditor: true, - isCurrentWorkspaceManager: true, - isCurrentWorkspaceOwner: false, - workspacePermissionKeys: ['dataset.create_and_management', 'dataset.external.connect'], - }), - })) vi.resetModules() const { default: ListComponent } = await import('../index') diff --git a/web/app/components/datasets/list/dataset-card/__tests__/index.spec.tsx b/web/app/components/datasets/list/dataset-card/__tests__/index.spec.tsx index d1735b299e0..06886b21bac 100644 --- a/web/app/components/datasets/list/dataset-card/__tests__/index.spec.tsx +++ b/web/app/components/datasets/list/dataset-card/__tests__/index.spec.tsx @@ -49,9 +49,6 @@ let mockAppContextState = { userProfile: { id: 'user-1' }, workspacePermissionKeys: [] as string[], } -vi.mock('@/context/app-context', () => ({ - useSelector: (selector: (state: typeof mockAppContextState) => unknown) => selector(mockAppContextState), -})) vi.mock('@/context/app-context-state', async (importOriginal) => { const { createDatasetAccessAtomMock } = await import('@/app/components/datasets/__tests__/mock-dataset-access') diff --git a/web/app/components/datasets/list/dataset-card/components/__tests__/operations-dropdown.spec.tsx b/web/app/components/datasets/list/dataset-card/components/__tests__/operations-dropdown.spec.tsx index 9620202a47a..a48126e2b8a 100644 --- a/web/app/components/datasets/list/dataset-card/components/__tests__/operations-dropdown.spec.tsx +++ b/web/app/components/datasets/list/dataset-card/components/__tests__/operations-dropdown.spec.tsx @@ -20,10 +20,6 @@ const render = (ui: Parameters[0]) => renderWit }, }) -vi.mock('@/context/app-context', () => ({ - useSelector: vi.fn((selector: (state: typeof mockAppContextState) => unknown) => selector(mockAppContextState)), -})) - vi.mock('@/context/app-context-state', async (importOriginal) => { const { createDatasetAccessAtomMock } = await import('@/app/components/datasets/__tests__/mock-dataset-access') diff --git a/web/app/components/datasets/settings/form/__tests__/index.spec.tsx b/web/app/components/datasets/settings/form/__tests__/index.spec.tsx index 64795665890..c3714c45a7f 100644 --- a/web/app/components/datasets/settings/form/__tests__/index.spec.tsx +++ b/web/app/components/datasets/settings/form/__tests__/index.spec.tsx @@ -37,16 +37,6 @@ vi.mock('@tanstack/react-query', async (importOriginal) => { } }) -vi.mock('@/context/app-context', () => ({ - useSelector: (selector: (state: unknown) => unknown) => { - const state = { - userProfile: mockUserProfile, - workspacePermissionKeys: mockWorkspacePermissionKeys, - } - return selector(state) - }, -})) - vi.mock('@/context/app-context-state', async (importOriginal) => { const { createDatasetAccessAtomMock } = await import('@/app/components/datasets/__tests__/mock-dataset-access') diff --git a/web/app/components/datasets/settings/form/components/__tests__/basic-info-section.spec.tsx b/web/app/components/datasets/settings/form/components/__tests__/basic-info-section.spec.tsx index 2466445435a..d1d83ceaafe 100644 --- a/web/app/components/datasets/settings/form/components/__tests__/basic-info-section.spec.tsx +++ b/web/app/components/datasets/settings/form/components/__tests__/basic-info-section.spec.tsx @@ -30,9 +30,6 @@ const mockAppContextState = vi.hoisted(() => ({ })) // Mock app-context -vi.mock('@/context/app-context', () => ({ - useSelector: () => mockAppContextState.userProfile, -})) vi.mock('@/context/app-context-state', async (importOriginal) => { const { createDatasetAccessAtomMock } = await import('@/app/components/datasets/__tests__/mock-dataset-access') diff --git a/web/app/components/datasets/settings/form/hooks/__tests__/use-form-state.spec.ts b/web/app/components/datasets/settings/form/hooks/__tests__/use-form-state.spec.ts index bd047dd469e..7172f218c84 100644 --- a/web/app/components/datasets/settings/form/hooks/__tests__/use-form-state.spec.ts +++ b/web/app/components/datasets/settings/form/hooks/__tests__/use-form-state.spec.ts @@ -16,13 +16,6 @@ const { mockToastSuccess, mockToastError } = vi.hoisted(() => ({ const mockMutateDatasets = vi.fn() const mockInvalidDatasetList = vi.fn() -vi.mock('@/context/app-context', () => ({ - useSelector: (selector: (value: { userProfile: { id: string }, workspacePermissionKeys: string[] }) => T) => selector({ - userProfile: { id: 'user-1' }, - workspacePermissionKeys: [], - }), -})) - vi.mock('@/context/app-context-state', async (importOriginal) => { const { createDatasetAccessAtomMock } = await import('@/app/components/datasets/__tests__/mock-dataset-access') diff --git a/web/app/components/develop/secret-key/__tests__/secret-key-modal.spec.tsx b/web/app/components/develop/secret-key/__tests__/secret-key-modal.spec.tsx index 206af53a0cd..bcce6ba7b58 100644 --- a/web/app/components/develop/secret-key/__tests__/secret-key-modal.spec.tsx +++ b/web/app/components/develop/secret-key/__tests__/secret-key-modal.spec.tsx @@ -27,14 +27,6 @@ const mockCurrentWorkspace = vi.fn().mockReturnValue({ const mockIsCurrentWorkspaceManager = vi.fn().mockReturnValue(true) const mockIsCurrentWorkspaceEditor = vi.fn().mockReturnValue(true) -vi.mock('@/context/app-context', () => ({ - useAppContext: () => ({ - currentWorkspace: mockCurrentWorkspace(), - isCurrentWorkspaceManager: mockIsCurrentWorkspaceManager(), - isCurrentWorkspaceEditor: mockIsCurrentWorkspaceEditor(), - }), -})) - vi.mock('@/context/app-context-state', async (importOriginal) => { const { createAppContextStateAtomMock } = await import('@/__tests__/utils/mock-app-context-state') diff --git a/web/app/components/explore/create-app-modal/__tests__/index.spec.tsx b/web/app/components/explore/create-app-modal/__tests__/index.spec.tsx index cb31c432de6..29c8228f08f 100644 --- a/web/app/components/explore/create-app-modal/__tests__/index.spec.tsx +++ b/web/app/components/explore/create-app-modal/__tests__/index.spec.tsx @@ -44,13 +44,6 @@ vi.mock('@/next/navigation', () => ({ useParams: () => ({}), })) -vi.mock('@/context/app-context', () => ({ - useAppContext: () => ({ - userProfile: { email: 'test@example.com' }, - langGeniusVersionInfo: { current_version: '0.0.0' }, - }), -})) - const createPlanInfo = (buildApps: number): UsagePlanInfo => ({ vectorSpace: 0, buildApps, diff --git a/web/app/components/header/account-dropdown/__tests__/index.spec.tsx b/web/app/components/header/account-dropdown/__tests__/index.spec.tsx index 051b5eca20a..787dc75645b 100644 --- a/web/app/components/header/account-dropdown/__tests__/index.spec.tsx +++ b/web/app/components/header/account-dropdown/__tests__/index.spec.tsx @@ -1,5 +1,5 @@ import type { GetSystemFeaturesResponse } from '@dify/contracts/api/console/system-features/types.gen' -import type { AppContextValue } from '@/context/app-context' +import type { AppContextStateMockState } from '@/__tests__/utils/mock-app-context-state' import type { ModalContextState } from '@/context/modal-context' import type { ProviderContextState } from '@/context/provider-context' import { fireEvent, screen, waitFor } from '@testing-library/react' @@ -43,7 +43,7 @@ const { mockSetTheme } = vi.hoisted(() => ({ mockSetTheme: vi.fn(), })) const mockAppContextState = vi.hoisted(() => ({ - current: undefined as AppContextValue | undefined, + current: undefined as AppContextStateMockState | undefined, })) const mockUseAppContext = vi.hoisted(() => vi.fn()) @@ -54,10 +54,6 @@ vi.mock('next-themes', () => ({ }), })) -vi.mock('@/context/app-context', () => ({ - useAppContext: mockUseAppContext, -})) - vi.mock('@/context/app-context-state', async (importOriginal) => { const { createAppContextStateAtomMock } = await import('@/__tests__/utils/mock-app-context-state') return createAppContextStateAtomMock(importOriginal, () => mockAppContextState.current ?? {}) @@ -122,7 +118,7 @@ vi.mock('@/config', async (importOriginal) => { }) vi.mock('@/env', () => mockEnv) -const baseAppContextValue: AppContextValue = { +const baseAppContextValue: AppContextStateMockState = { userProfile: { id: '1', name: 'Test User', @@ -158,13 +154,11 @@ const baseAppContextValue: AppContextValue = { version: '0.6.0', can_auto_update: false, }, - useSelector: vi.fn(), isLoadingCurrentWorkspace: false, - isValidatingCurrentWorkspace: false, workspacePermissionKeys: [], } -const setAppContextValue = (value: AppContextValue) => { +const setAppContextValue = (value: AppContextStateMockState) => { mockAppContextState.current = value mockUseAppContext.mockReturnValue(value) } diff --git a/web/app/components/header/account-setting/__tests__/index.spec.tsx b/web/app/components/header/account-setting/__tests__/index.spec.tsx index 5f0fc462f2b..4348797d3ec 100644 --- a/web/app/components/header/account-setting/__tests__/index.spec.tsx +++ b/web/app/components/header/account-setting/__tests__/index.spec.tsx @@ -1,5 +1,5 @@ import type { AccountSettingTab } from '../constants' -import type { AppContextValue } from '@/context/app-context' +import type { AppContextStateMockState } from '@/__tests__/utils/mock-app-context-state' import { fireEvent, screen } from '@testing-library/react' import { useState } from 'react' import { renderWithSystemFeatures } from '@/__tests__/utils/mock-system-features' @@ -22,15 +22,6 @@ vi.mock('@/context/provider-context', async (importOriginal) => { } }) -vi.mock('@/context/app-context', async (importOriginal) => { - const actual = await importOriginal() - return { - ...actual, - useAppContext: mockUseAppContext, - useSelector: vi.fn((selector: (state: unknown) => unknown) => selector(mockAppContextState.current)), - } -}) - vi.mock('@/context/app-context-state', async (importOriginal) => { const { createAppContextStateAtomMock } = await import('@/__tests__/utils/mock-app-context-state') return createAppContextStateAtomMock(importOriginal, () => mockAppContextState.current ?? {}) @@ -139,7 +130,7 @@ vi.mock('@/app/components/header/account-setting/access-rules-page', () => ({ default: () =>
, })) -const baseAppContextValue: AppContextValue = { +const baseAppContextValue: AppContextStateMockState = { userProfile: { id: '1', name: 'Test User', @@ -175,9 +166,7 @@ const baseAppContextValue: AppContextValue = { version: '0.1.0', can_auto_update: false, }, - useSelector: vi.fn(), isLoadingCurrentWorkspace: false, - isValidatingCurrentWorkspace: false, workspacePermissionKeys: [ 'workspace.member.manage', 'workspace.role.manage', @@ -381,7 +370,7 @@ describe('AccountSetting', () => { // Arrange const contextWithoutApiExtensionPermission = { ...baseAppContextValue, - workspacePermissionKeys: baseAppContextValue.workspacePermissionKeys.filter(key => key !== 'api_extension.manage'), + workspacePermissionKeys: baseAppContextValue.workspacePermissionKeys!.filter(key => key !== 'api_extension.manage'), } mockUseAppContext.mockReturnValue(contextWithoutApiExtensionPermission) mockAppContextState.current = contextWithoutApiExtensionPermission @@ -399,7 +388,7 @@ describe('AccountSetting', () => { // Arrange const contextWithoutCustomizationPermission = { ...baseAppContextValue, - workspacePermissionKeys: baseAppContextValue.workspacePermissionKeys.filter(key => key !== 'customization.manage'), + workspacePermissionKeys: baseAppContextValue.workspacePermissionKeys!.filter(key => key !== 'customization.manage'), } mockUseAppContext.mockReturnValue(contextWithoutCustomizationPermission) mockAppContextState.current = contextWithoutCustomizationPermission @@ -418,7 +407,7 @@ describe('AccountSetting', () => { // Arrange const contextWithoutRoleManagePermission = { ...baseAppContextValue, - workspacePermissionKeys: baseAppContextValue.workspacePermissionKeys.filter(key => key !== 'workspace.role.manage'), + workspacePermissionKeys: baseAppContextValue.workspacePermissionKeys!.filter(key => key !== 'workspace.role.manage'), } mockUseAppContext.mockReturnValue(contextWithoutRoleManagePermission) mockAppContextState.current = contextWithoutRoleManagePermission @@ -463,36 +452,6 @@ describe('AccountSetting', () => { // Act renderAccountSetting() - // Assert - // Assert - // Assert - // Assert - // Assert - // Assert - // Assert - // Assert - // Assert - // Assert - // Assert - // Assert - // Assert - // Assert - // Assert - // Assert - // Assert - // Assert - // Assert - // Assert - // Assert - // Assert - // Assert - // Assert - // Assert - // Assert - // Assert - // Assert - // Assert - // Assert // Assert // Assert expect(screen.queryByText('common.settings.billing')).not.toBeInTheDocument() @@ -503,7 +462,7 @@ describe('AccountSetting', () => { // Arrange const contextWithoutBillingViewPermission = { ...baseAppContextValue, - workspacePermissionKeys: baseAppContextValue.workspacePermissionKeys.filter(key => key !== 'billing.view'), + workspacePermissionKeys: baseAppContextValue.workspacePermissionKeys!.filter(key => key !== 'billing.view'), } mockUseAppContext.mockReturnValue(contextWithoutBillingViewPermission) mockAppContextState.current = contextWithoutBillingViewPermission @@ -519,7 +478,7 @@ describe('AccountSetting', () => { // Arrange const contextWithoutBillingViewPermission = { ...baseAppContextValue, - workspacePermissionKeys: baseAppContextValue.workspacePermissionKeys.filter(key => key !== 'billing.view'), + workspacePermissionKeys: baseAppContextValue.workspacePermissionKeys!.filter(key => key !== 'billing.view'), } mockUseAppContext.mockReturnValue(contextWithoutBillingViewPermission) mockAppContextState.current = contextWithoutBillingViewPermission diff --git a/web/app/components/header/account-setting/access-rules-page/__tests__/access-rule-section.spec.tsx b/web/app/components/header/account-setting/access-rules-page/__tests__/access-rule-section.spec.tsx index f2a8fbc8f4d..da2d87c56de 100644 --- a/web/app/components/header/account-setting/access-rules-page/__tests__/access-rule-section.spec.tsx +++ b/web/app/components/header/account-setting/access-rules-page/__tests__/access-rule-section.spec.tsx @@ -9,12 +9,6 @@ const mocks = vi.hoisted(() => ({ workspacePermissionKeys: [] as string[], })) -vi.mock('@/context/app-context', () => ({ - useSelector: vi.fn((selector: (state: { workspacePermissionKeys: string[] }) => unknown) => selector({ - workspacePermissionKeys: mocks.workspacePermissionKeys, - })), -})) - vi.mock('@/context/app-context-state', async (importOriginal) => { const { createAppContextStateAtomMock } = await import('@/__tests__/utils/mock-app-context-state') return createAppContextStateAtomMock(importOriginal, () => ({ diff --git a/web/app/components/header/account-setting/api-based-extension-page/__tests__/index.spec.tsx b/web/app/components/header/account-setting/api-based-extension-page/__tests__/index.spec.tsx index f5f475655e6..198385eb101 100644 --- a/web/app/components/header/account-setting/api-based-extension-page/__tests__/index.spec.tsx +++ b/web/app/components/header/account-setting/api-based-extension-page/__tests__/index.spec.tsx @@ -18,12 +18,6 @@ const { }, })) -vi.mock('@/context/app-context', () => ({ - useSelector: vi.fn((selector: (state: { workspacePermissionKeys: string[] }) => unknown) => selector({ - workspacePermissionKeys: mockWorkspacePermissionKeys.current, - })), -})) - vi.mock('@/context/app-context-state', async (importOriginal) => { const { createAppContextStateAtomMock } = await import('@/__tests__/utils/mock-app-context-state') return createAppContextStateAtomMock(importOriginal, () => ({ diff --git a/web/app/components/header/account-setting/data-source-page-new/__tests__/card.spec.tsx b/web/app/components/header/account-setting/data-source-page-new/__tests__/card.spec.tsx index 464e4d7f367..74daafa39c1 100644 --- a/web/app/components/header/account-setting/data-source-page-new/__tests__/card.spec.tsx +++ b/web/app/components/header/account-setting/data-source-page-new/__tests__/card.spec.tsx @@ -13,12 +13,6 @@ import { useDataSourceAuthUpdate } from '../hooks' let mockWorkspacePermissionKeys: string[] = ['credential.use', 'credential.create', 'credential.manage'] -vi.mock('@/context/app-context', () => ({ - useSelector: (selector: (state: { workspacePermissionKeys: string[] }) => unknown) => selector({ - workspacePermissionKeys: mockWorkspacePermissionKeys, - }), -})) - vi.mock('@/context/app-context-state', async (importOriginal) => { const { createAppContextStateAtomMock } = await import('@/__tests__/utils/mock-app-context-state') return createAppContextStateAtomMock(importOriginal, () => ({ diff --git a/web/app/components/header/account-setting/members-page/__tests__/index.spec.tsx b/web/app/components/header/account-setting/members-page/__tests__/index.spec.tsx index f1544cb097b..93955c446ee 100644 --- a/web/app/components/header/account-setting/members-page/__tests__/index.spec.tsx +++ b/web/app/components/header/account-setting/members-page/__tests__/index.spec.tsx @@ -1,4 +1,4 @@ -import type { AppContextValue } from '@/context/app-context' +import type { AppContextStateMockState } from '@/__tests__/utils/mock-app-context-state' import type { Role } from '@/models/access-control' import type { ICurrentWorkspace, Member } from '@/models/common' import { screen, within } from '@testing-library/react' @@ -14,13 +14,10 @@ import { useMembers } from '@/service/use-common' import MembersPage from '../index' const mockAppContextState = vi.hoisted(() => ({ - current: {} as Partial, + current: {} as Partial, })) const mockUseAppContext = vi.hoisted(() => vi.fn()) -vi.mock('@/context/app-context', () => ({ - useAppContext: mockUseAppContext, -})) vi.mock('@/context/app-context-state', async (importOriginal) => { const { createAppContextStateAtomMock } = await import('@/__tests__/utils/mock-app-context-state') return createAppContextStateAtomMock(importOriginal, () => mockAppContextState.current) @@ -55,7 +52,7 @@ const createRole = (overrides: Partial): Role => ({ ...overrides, }) -const setAppContextValue = (value: AppContextValue) => { +const setAppContextValue = (value: AppContextStateMockState) => { mockAppContextState.current = value mockUseAppContext.mockReturnValue(value) } @@ -206,7 +203,7 @@ describe('MembersPage', () => { isCurrentWorkspaceOwner: true, isCurrentWorkspaceManager: true, workspacePermissionKeys: ['workspace.member.manage'], - } as unknown as AppContextValue) + } as unknown as AppContextStateMockState) vi.mocked(useMembers).mockReturnValue({ data: { accounts: mockAccounts }, @@ -313,7 +310,7 @@ describe('MembersPage', () => { currentWorkspace: { name: 'Test Workspace', role: 'admin' } as ICurrentWorkspace, isCurrentWorkspaceOwner: false, isCurrentWorkspaceManager: false, - } as unknown as AppContextValue) + } as unknown as AppContextStateMockState) renderMembersPage() @@ -415,7 +412,7 @@ describe('MembersPage', () => { isCurrentWorkspaceOwner: false, isCurrentWorkspaceManager: true, workspacePermissionKeys: ['workspace.member.manage'], - } as unknown as AppContextValue) + } as unknown as AppContextStateMockState) renderMembersPage() @@ -430,7 +427,7 @@ describe('MembersPage', () => { isCurrentWorkspaceOwner: false, isCurrentWorkspaceManager: true, workspacePermissionKeys: ['workspace.member.manage'], - } as unknown as AppContextValue) + } as unknown as AppContextStateMockState) vi.mocked(useMembers).mockReturnValue({ data: { accounts: [ @@ -507,7 +504,7 @@ describe('MembersPage', () => { currentWorkspace: { name: 'Test Workspace', role: 'admin' } as ICurrentWorkspace, isCurrentWorkspaceOwner: false, isCurrentWorkspaceManager: false, - } as unknown as AppContextValue) + } as unknown as AppContextStateMockState) vi.mocked(useMembers).mockReturnValue({ data: { accounts: [{ ...mockAccounts[1], role: 'unknown_role' as Member['role'] }] }, refetch: mockRefetch, @@ -576,7 +573,7 @@ describe('MembersPage', () => { isCurrentWorkspaceOwner: false, isCurrentWorkspaceManager: true, workspacePermissionKeys: ['workspace.member.manage'], - } as unknown as AppContextValue) + } as unknown as AppContextStateMockState) renderMembersPage() diff --git a/web/app/components/header/account-setting/members-page/__tests__/invite-button.spec.tsx b/web/app/components/header/account-setting/members-page/__tests__/invite-button.spec.tsx index 10e50fc885e..359294a4b75 100644 --- a/web/app/components/header/account-setting/members-page/__tests__/invite-button.spec.tsx +++ b/web/app/components/header/account-setting/members-page/__tests__/invite-button.spec.tsx @@ -1,4 +1,4 @@ -import type { AppContextValue } from '@/context/app-context' +import type { AppContextStateMockState } from '@/__tests__/utils/mock-app-context-state' import type { ICurrentWorkspace } from '@/models/common' import { screen } from '@testing-library/react' import { vi } from 'vitest' @@ -8,9 +8,6 @@ import InviteButton from '../invite-button' const mockUseAppContext = vi.hoisted(() => vi.fn()) -vi.mock('@/context/app-context', () => ({ - useAppContext: mockUseAppContext, -})) vi.mock('@/context/app-context-state', async (importOriginal) => { const { createAppContextStateAtomMock } = await import('@/__tests__/utils/mock-app-context-state') return createAppContextStateAtomMock(importOriginal, () => ({ @@ -46,7 +43,7 @@ describe('InviteButton', () => { vi.clearAllMocks() mockUseAppContext.mockReturnValue({ currentWorkspace: { id: 'workspace-id' } as ICurrentWorkspace, - } as unknown as AppContextValue) + } as unknown as AppContextStateMockState) }) it('should show invite button when branding is disabled', () => { diff --git a/web/app/components/header/account-setting/members-page/edit-workspace-modal/__tests__/dialog.spec.tsx b/web/app/components/header/account-setting/members-page/edit-workspace-modal/__tests__/dialog.spec.tsx index f9bcf49335e..3ddb717f933 100644 --- a/web/app/components/header/account-setting/members-page/edit-workspace-modal/__tests__/dialog.spec.tsx +++ b/web/app/components/header/account-setting/members-page/edit-workspace-modal/__tests__/dialog.spec.tsx @@ -1,5 +1,5 @@ import type { ReactNode } from 'react' -import type { AppContextValue } from '@/context/app-context' +import type { AppContextStateMockState } from '@/__tests__/utils/mock-app-context-state' import { render } from '@testing-library/react' import EditWorkspaceModal from '../index' @@ -11,7 +11,7 @@ type DialogProps = { let latestOnOpenChange: DialogProps['onOpenChange'] const mockAppContextState = vi.hoisted(() => ({ - current: {} as Partial, + current: {} as Partial, })) const mockUseAppContext = vi.hoisted(() => vi.fn()) @@ -29,10 +29,6 @@ vi.mock('@langgenius/dify-ui/dialog', () => ({ ), })) -vi.mock('@/context/app-context', () => ({ - useAppContext: mockUseAppContext, -})) - vi.mock('@/context/app-context-state', async (importOriginal) => { const { createAppContextStateAtomMock } = await import('@/__tests__/utils/mock-app-context-state') return createAppContextStateAtomMock(importOriginal, () => mockAppContextState.current) diff --git a/web/app/components/header/account-setting/members-page/edit-workspace-modal/__tests__/index.spec.tsx b/web/app/components/header/account-setting/members-page/edit-workspace-modal/__tests__/index.spec.tsx index ff2457752bf..9a3c881f391 100644 --- a/web/app/components/header/account-setting/members-page/edit-workspace-modal/__tests__/index.spec.tsx +++ b/web/app/components/header/account-setting/members-page/edit-workspace-modal/__tests__/index.spec.tsx @@ -1,4 +1,4 @@ -import type { AppContextValue } from '@/context/app-context' +import type { AppContextStateMockState } from '@/__tests__/utils/mock-app-context-state' import type { ICurrentWorkspace } from '@/models/common' import { fireEvent, render, screen, waitFor } from '@testing-library/react' import userEvent from '@testing-library/user-event' @@ -10,15 +10,12 @@ const toastMocks = vi.hoisted(() => ({ mockNotify: vi.fn(), })) const mockAppContextState = vi.hoisted(() => ({ - current: {} as Partial, + current: {} as Partial, })) const mockUseAppContext = vi.hoisted(() => vi.fn()) const getSaveButton = () => screen.getByRole('button', { name: /operation\.(save|saving)/i }) -vi.mock('@/context/app-context', () => ({ - useAppContext: mockUseAppContext, -})) vi.mock('@/context/app-context-state', async (importOriginal) => { const { createAppContextStateAtomMock } = await import('@/__tests__/utils/mock-app-context-state') return createAppContextStateAtomMock(importOriginal, () => mockAppContextState.current) @@ -50,7 +47,7 @@ describe('EditWorkspaceModal', () => { const appContextValue = { currentWorkspace: { name: 'Test Workspace' } as ICurrentWorkspace, isCurrentWorkspaceOwner: true, - } as unknown as AppContextValue + } as unknown as AppContextStateMockState mockAppContextState.current = appContextValue mockUseAppContext.mockReturnValue(appContextValue) }) @@ -170,7 +167,7 @@ describe('EditWorkspaceModal', () => { mockUseAppContext.mockReturnValue({ currentWorkspace: { name: 'Test Workspace' } as ICurrentWorkspace, isCurrentWorkspaceOwner: false, - } as unknown as AppContextValue) + } as unknown as AppContextStateMockState) renderModal() diff --git a/web/app/components/header/account-setting/members-page/transfer-ownership-modal/__tests__/index.spec.tsx b/web/app/components/header/account-setting/members-page/transfer-ownership-modal/__tests__/index.spec.tsx index 855148af034..434a0f4415c 100644 --- a/web/app/components/header/account-setting/members-page/transfer-ownership-modal/__tests__/index.spec.tsx +++ b/web/app/components/header/account-setting/members-page/transfer-ownership-modal/__tests__/index.spec.tsx @@ -1,4 +1,4 @@ -import type { AppContextValue } from '@/context/app-context' +import type { AppContextStateMockState } from '@/__tests__/utils/mock-app-context-state' import type { ICurrentWorkspace } from '@/models/common' import { act, fireEvent, render, screen, waitFor } from '@testing-library/react' import userEvent from '@testing-library/user-event' @@ -11,13 +11,10 @@ const toastMocks = vi.hoisted(() => ({ mockNotify: vi.fn(), })) const mockAppContextState = vi.hoisted(() => ({ - current: {} as Partial, + current: {} as Partial, })) const mockUseAppContext = vi.hoisted(() => vi.fn()) -vi.mock('@/context/app-context', () => ({ - useAppContext: mockUseAppContext, -})) vi.mock('@/context/app-context-state', async (importOriginal) => { const { createAppContextStateAtomMock } = await import('@/__tests__/utils/mock-app-context-state') return createAppContextStateAtomMock(importOriginal, () => mockAppContextState.current) @@ -56,7 +53,7 @@ describe('TransferOwnershipModal', () => { const appContextValue = { currentWorkspace: { name: 'Test Workspace' } as ICurrentWorkspace, userProfile: { email: 'owner@example.com', id: 'owner-id' }, - } as unknown as AppContextValue + } as unknown as AppContextStateMockState mockAppContextState.current = appContextValue mockUseAppContext.mockReturnValue(appContextValue) diff --git a/web/app/components/header/account-setting/model-provider-page/model-auth/__tests__/add-credential-in-load-balancing.spec.tsx b/web/app/components/header/account-setting/model-provider-page/model-auth/__tests__/add-credential-in-load-balancing.spec.tsx index 499380c1e1a..e6da3be7181 100644 --- a/web/app/components/header/account-setting/model-provider-page/model-auth/__tests__/add-credential-in-load-balancing.spec.tsx +++ b/web/app/components/header/account-setting/model-provider-page/model-auth/__tests__/add-credential-in-load-balancing.spec.tsx @@ -7,12 +7,6 @@ const mockWorkspacePermissionKeys = vi.hoisted(() => ({ value: ['credential.use', 'credential.create', 'credential.manage'], })) -vi.mock('@/context/app-context', () => ({ - useSelector: (selector: (state: { workspacePermissionKeys: string[] }) => unknown) => selector({ - workspacePermissionKeys: mockWorkspacePermissionKeys.value, - }), -})) - vi.mock('@/context/app-context-state', async (importOriginal) => { const { createAppContextStateAtomMock } = await import('@/__tests__/utils/mock-app-context-state') return createAppContextStateAtomMock(importOriginal, () => ({ diff --git a/web/app/components/header/account-setting/model-provider-page/model-auth/__tests__/add-custom-model.spec.tsx b/web/app/components/header/account-setting/model-provider-page/model-auth/__tests__/add-custom-model.spec.tsx index 515081c22f8..8f75a0190ae 100644 --- a/web/app/components/header/account-setting/model-provider-page/model-auth/__tests__/add-custom-model.spec.tsx +++ b/web/app/components/header/account-setting/model-provider-page/model-auth/__tests__/add-custom-model.spec.tsx @@ -28,12 +28,6 @@ const mockWorkspacePermissionKeys = vi.hoisted(() => ({ value: ['credential.use', 'credential.create', 'credential.manage'], })) -vi.mock('@/context/app-context', () => ({ - useSelector: (selector: (state: { workspacePermissionKeys: string[] }) => unknown) => selector({ - workspacePermissionKeys: mockWorkspacePermissionKeys.value, - }), -})) - vi.mock('@/context/app-context-state', async (importOriginal) => { const { createAppContextStateAtomMock } = await import('@/__tests__/utils/mock-app-context-state') return createAppContextStateAtomMock(importOriginal, () => ({ diff --git a/web/app/components/header/account-setting/model-provider-page/model-auth/__tests__/switch-credential-in-load-balancing.spec.tsx b/web/app/components/header/account-setting/model-provider-page/model-auth/__tests__/switch-credential-in-load-balancing.spec.tsx index 902a2000425..f354f2d3aa0 100644 --- a/web/app/components/header/account-setting/model-provider-page/model-auth/__tests__/switch-credential-in-load-balancing.spec.tsx +++ b/web/app/components/header/account-setting/model-provider-page/model-auth/__tests__/switch-credential-in-load-balancing.spec.tsx @@ -8,12 +8,6 @@ const mockWorkspacePermissionKeys = vi.hoisted(() => ({ value: ['credential.use', 'credential.create', 'credential.manage'], })) -vi.mock('@/context/app-context', () => ({ - useSelector: (selector: (state: { workspacePermissionKeys: string[] }) => unknown) => selector({ - workspacePermissionKeys: mockWorkspacePermissionKeys.value, - }), -})) - vi.mock('@/context/app-context-state', async (importOriginal) => { const { createAppContextStateAtomMock } = await import('@/__tests__/utils/mock-app-context-state') return createAppContextStateAtomMock(importOriginal, () => ({ diff --git a/web/app/components/header/account-setting/model-provider-page/model-auth/authorized/__tests__/index.spec.tsx b/web/app/components/header/account-setting/model-provider-page/model-auth/authorized/__tests__/index.spec.tsx index bab7f605997..6f886a0d78f 100644 --- a/web/app/components/header/account-setting/model-provider-page/model-auth/authorized/__tests__/index.spec.tsx +++ b/web/app/components/header/account-setting/model-provider-page/model-auth/authorized/__tests__/index.spec.tsx @@ -13,12 +13,6 @@ let mockDeleteCredentialId: string | null = null let mockDoingAction = false let mockWorkspacePermissionKeys = ['credential.use', 'credential.create', 'credential.manage'] -vi.mock('@/context/app-context', () => ({ - useSelector: (selector: (state: { workspacePermissionKeys: string[] }) => unknown) => selector({ - workspacePermissionKeys: mockWorkspacePermissionKeys, - }), -})) - vi.mock('@/context/app-context-state', async (importOriginal) => { const { createAppContextStateAtomMock } = await import('@/__tests__/utils/mock-app-context-state') return createAppContextStateAtomMock(importOriginal, () => ({ diff --git a/web/app/components/header/account-setting/model-provider-page/model-modal/__tests__/dialog.spec.tsx b/web/app/components/header/account-setting/model-provider-page/model-modal/__tests__/dialog.spec.tsx index e1a8ac24cf2..ab2e04a0856 100644 --- a/web/app/components/header/account-setting/model-provider-page/model-modal/__tests__/dialog.spec.tsx +++ b/web/app/components/header/account-setting/model-provider-page/model-modal/__tests__/dialog.spec.tsx @@ -77,11 +77,6 @@ vi.mock('../../model-auth/hooks', () => ({ }), })) -vi.mock('@/context/app-context', () => ({ - useSelector: (selector: (state: { workspacePermissionKeys: string[] }) => unknown) => - selector({ workspacePermissionKeys: ['credential.use', 'credential.create', 'credential.manage'] }), -})) - vi.mock('@/hooks/use-i18n', () => ({ useRenderI18nObject: () => (value: Record) => value[mockLanguage] || value.en_US, })) diff --git a/web/app/components/header/account-setting/model-provider-page/model-modal/__tests__/index.spec.tsx b/web/app/components/header/account-setting/model-provider-page/model-modal/__tests__/index.spec.tsx index 655220ee6ac..5825a2d4211 100644 --- a/web/app/components/header/account-setting/model-provider-page/model-modal/__tests__/index.spec.tsx +++ b/web/app/components/header/account-setting/model-provider-page/model-modal/__tests__/index.spec.tsx @@ -75,11 +75,6 @@ vi.mock('../../model-auth/hooks', () => ({ }), })) -vi.mock('@/context/app-context', () => ({ - useSelector: (selector: (state: { workspacePermissionKeys: string[] }) => unknown) => - selector({ workspacePermissionKeys: mockState.workspacePermissionKeys }), -})) - vi.mock('@/context/app-context-state', async (importOriginal) => { const { createAppContextStateAtomMock } = await import('@/__tests__/utils/mock-app-context-state') return createAppContextStateAtomMock(importOriginal, () => ({ diff --git a/web/app/components/header/account-setting/model-provider-page/model-selector/__tests__/popup-item.spec.tsx b/web/app/components/header/account-setting/model-provider-page/model-selector/__tests__/popup-item.spec.tsx index 29d8f728693..4d894e80624 100644 --- a/web/app/components/header/account-setting/model-provider-page/model-selector/__tests__/popup-item.spec.tsx +++ b/web/app/components/header/account-setting/model-provider-page/model-selector/__tests__/popup-item.spec.tsx @@ -87,12 +87,6 @@ const mockUseAppContext = vi.hoisted(() => vi.fn()) const mockWorkspacePermissionKeys = vi.hoisted(() => ({ value: ['credential.use', 'credential.create', 'credential.manage'], })) -vi.mock('@/context/app-context', () => ({ - useAppContext: mockUseAppContext, - useSelector: (selector: (state: { workspacePermissionKeys: string[] }) => unknown) => selector({ - workspacePermissionKeys: mockWorkspacePermissionKeys.value, - }), -})) vi.mock('@/context/app-context-state', async (importOriginal) => { const { createAppContextStateAtomMock } = await import('@/__tests__/utils/mock-app-context-state') diff --git a/web/app/components/header/account-setting/model-provider-page/provider-added-card/__tests__/index.spec.tsx b/web/app/components/header/account-setting/model-provider-page/provider-added-card/__tests__/index.spec.tsx index 9aee6fd9ead..35395aa6e9f 100644 --- a/web/app/components/header/account-setting/model-provider-page/provider-added-card/__tests__/index.spec.tsx +++ b/web/app/components/header/account-setting/model-provider-page/provider-added-card/__tests__/index.spec.tsx @@ -34,15 +34,6 @@ vi.mock('@/service/client', () => ({ }, })) -vi.mock('@/context/app-context', () => ({ - useAppContext: () => ({ - isCurrentWorkspaceManager: mockIsCurrentWorkspaceManager, - }), - useSelector: (selector: (state: { workspacePermissionKeys: string[] }) => unknown) => selector({ - workspacePermissionKeys: mockWorkspacePermissionKeys, - }), -})) - vi.mock('@/context/app-context-state', async (importOriginal) => { const { createAppContextStateAtomMock } = await import('@/__tests__/utils/mock-app-context-state') return createAppContextStateAtomMock(importOriginal, () => ({ diff --git a/web/app/components/header/account-setting/model-provider-page/provider-added-card/__tests__/model-list-item.spec.tsx b/web/app/components/header/account-setting/model-provider-page/provider-added-card/__tests__/model-list-item.spec.tsx index 065baa2496f..0ba980b56ac 100644 --- a/web/app/components/header/account-setting/model-provider-page/provider-added-card/__tests__/model-list-item.spec.tsx +++ b/web/app/components/header/account-setting/model-provider-page/provider-added-card/__tests__/model-list-item.spec.tsx @@ -16,12 +16,6 @@ let mockModelLoadBalancingEnabled = false let mockPlanType: string = 'pro' let mockWorkspacePermissionKeys: string[] = ['plugin.model_config'] -vi.mock('@/context/app-context', () => ({ - useAppContext: () => ({ - workspacePermissionKeys: mockWorkspacePermissionKeys, - }), -})) - vi.mock('@/context/app-context-state', async (importOriginal) => { const { createAppContextStateAtomMock } = await import('@/__tests__/utils/mock-app-context-state') return createAppContextStateAtomMock(importOriginal, () => ({ diff --git a/web/app/components/header/account-setting/model-provider-page/provider-added-card/__tests__/model-list.spec.tsx b/web/app/components/header/account-setting/model-provider-page/provider-added-card/__tests__/model-list.spec.tsx index 1d5055a0741..c9111b67208 100644 --- a/web/app/components/header/account-setting/model-provider-page/provider-added-card/__tests__/model-list.spec.tsx +++ b/web/app/components/header/account-setting/model-provider-page/provider-added-card/__tests__/model-list.spec.tsx @@ -6,11 +6,6 @@ import ModelList from '../model-list' const mockSetShowModelLoadBalancingModal = vi.fn() let mockWorkspacePermissionKeys: string[] = ['plugin.model_config', 'credential.manage', 'credential.use'] -vi.mock('@/context/app-context', () => ({ - useSelector: (selector: (state: { workspacePermissionKeys: string[] }) => unknown) => - selector({ workspacePermissionKeys: mockWorkspacePermissionKeys }), -})) - vi.mock('@/context/app-context-state', async (importOriginal) => { const { createAppContextStateAtomMock } = await import('@/__tests__/utils/mock-app-context-state') return createAppContextStateAtomMock(importOriginal, () => ({ diff --git a/web/app/components/header/account-setting/model-provider-page/provider-added-card/model-auth-dropdown/__tests__/api-key-section.spec.tsx b/web/app/components/header/account-setting/model-provider-page/provider-added-card/model-auth-dropdown/__tests__/api-key-section.spec.tsx index 82e4477b4cf..c70159f9a38 100644 --- a/web/app/components/header/account-setting/model-provider-page/provider-added-card/model-auth-dropdown/__tests__/api-key-section.spec.tsx +++ b/web/app/components/header/account-setting/model-provider-page/provider-added-card/model-auth-dropdown/__tests__/api-key-section.spec.tsx @@ -3,12 +3,6 @@ import { fireEvent, render, screen } from '@testing-library/react' import { CustomConfigurationStatusEnum, PreferredProviderTypeEnum } from '../../../declarations' import ApiKeySection from '../api-key-section' -vi.mock('@/context/app-context', () => ({ - useSelector: (selector: (state: { workspacePermissionKeys: string[] }) => T): T => selector({ - workspacePermissionKeys: ['credential.use', 'credential.create', 'credential.manage'], - }), -})) - vi.mock('@/context/app-context-state', async (importOriginal) => { const { createAppContextStateAtomMock } = await import('@/__tests__/utils/mock-app-context-state') return createAppContextStateAtomMock(importOriginal, () => ({ diff --git a/web/app/components/header/account-setting/model-provider-page/provider-added-card/model-auth-dropdown/__tests__/dropdown-content.spec.tsx b/web/app/components/header/account-setting/model-provider-page/provider-added-card/model-auth-dropdown/__tests__/dropdown-content.spec.tsx index fe3f55e68dd..93cb654799e 100644 --- a/web/app/components/header/account-setting/model-provider-page/provider-added-card/model-auth-dropdown/__tests__/dropdown-content.spec.tsx +++ b/web/app/components/header/account-setting/model-provider-page/provider-added-card/model-auth-dropdown/__tests__/dropdown-content.spec.tsx @@ -35,12 +35,6 @@ vi.mock('../../../model-auth/hooks', () => ({ }), })) -vi.mock('@/context/app-context', () => ({ - useSelector: (selector: (state: { workspacePermissionKeys: string[] }) => unknown) => selector({ - workspacePermissionKeys: mockWorkspacePermissionKeys, - }), -})) - vi.mock('@/context/app-context-state', async (importOriginal) => { const { createAppContextStateAtomMock } = await import('@/__tests__/utils/mock-app-context-state') return createAppContextStateAtomMock(importOriginal, () => ({ diff --git a/web/app/components/header/account-setting/model-provider-page/system-model-selector/__tests__/index.spec.tsx b/web/app/components/header/account-setting/model-provider-page/system-model-selector/__tests__/index.spec.tsx index 4bbf4ec7bb6..4c0e14c3226 100644 --- a/web/app/components/header/account-setting/model-provider-page/system-model-selector/__tests__/index.spec.tsx +++ b/web/app/components/header/account-setting/model-provider-page/system-model-selector/__tests__/index.spec.tsx @@ -34,12 +34,6 @@ const mockModelSelectorProps = vi.hoisted(() => [] as Array<{ hideProviderSettin let mockWorkspacePermissionKeys = ['plugin.model_config'] -vi.mock('@/context/app-context', () => ({ - useAppContext: () => ({ - workspacePermissionKeys: mockWorkspacePermissionKeys, - }), -})) - vi.mock('@/context/app-context-state', async (importOriginal) => { const { createAppContextStateAtomMock } = await import('@/__tests__/utils/mock-app-context-state') return createAppContextStateAtomMock(importOriginal, () => ({ diff --git a/web/app/components/header/account-setting/permissions-page/__tests__/index.spec.tsx b/web/app/components/header/account-setting/permissions-page/__tests__/index.spec.tsx index c0c0efb4f95..d67ce0f2648 100644 --- a/web/app/components/header/account-setting/permissions-page/__tests__/index.spec.tsx +++ b/web/app/components/header/account-setting/permissions-page/__tests__/index.spec.tsx @@ -1,9 +1,7 @@ -import type { AppContextValue } from '@/context/app-context' import type { Role } from '@/models/access-control' import { toast } from '@langgenius/dify-ui/toast' import { render, screen, within } from '@testing-library/react' import userEvent from '@testing-library/user-event' -import { useSelector as useAppContextSelector } from '@/context/app-context' import { useCreateWorkspaceRole, useUpdateWorkspaceRole } from '@/service/access-control/use-workspace-roles' import { useRoleGroups } from '../hooks' import PermissionsPage from '../index' @@ -20,12 +18,6 @@ vi.mock('@langgenius/dify-ui/toast', () => ({ }, })) -vi.mock('@/context/app-context', () => ({ - useSelector: vi.fn((selector: (state: AppContextValue) => unknown) => selector({ - workspacePermissionKeys: mocks.workspacePermissionKeys, - } as AppContextValue)), -})) - vi.mock('@/context/app-context-state', async (importOriginal) => { const { createAppContextStateAtomMock } = await import('@/__tests__/utils/mock-app-context-state') return createAppContextStateAtomMock(importOriginal, () => ({ @@ -143,9 +135,6 @@ describe('PermissionsPage', () => { beforeEach(() => { vi.clearAllMocks() mocks.workspacePermissionKeys = [] - vi.mocked(useAppContextSelector).mockImplementation((selector: (state: AppContextValue) => unknown) => selector({ - workspacePermissionKeys: mocks.workspacePermissionKeys, - } as AppContextValue)) vi.mocked(useRoleGroups).mockReturnValue({ roleGroups: [{ id: 'global_custom', diff --git a/web/app/components/header/account-setting/permissions-page/role-list/__tests__/index.spec.tsx b/web/app/components/header/account-setting/permissions-page/role-list/__tests__/index.spec.tsx index c789b163b19..c1bf2f46dd4 100644 --- a/web/app/components/header/account-setting/permissions-page/role-list/__tests__/index.spec.tsx +++ b/web/app/components/header/account-setting/permissions-page/role-list/__tests__/index.spec.tsx @@ -6,12 +6,6 @@ const mockWorkspacePermissionKeys = vi.hoisted(() => ({ value: ['workspace.role.manage'] as string[], })) -vi.mock('@/context/app-context', () => ({ - useSelector: (selector: (state: { workspacePermissionKeys: string[] }) => T): T => selector({ - workspacePermissionKeys: mockWorkspacePermissionKeys.value, - }), -})) - vi.mock('@/service/access-control/use-workspace-roles', () => ({ useCopyWorkspaceRole: () => ({ mutateAsync: vi.fn(), diff --git a/web/app/components/header/account-setting/permissions-page/role-list/__tests__/row-menu.spec.tsx b/web/app/components/header/account-setting/permissions-page/role-list/__tests__/row-menu.spec.tsx index 46412f3f16f..6685ca0bb6c 100644 --- a/web/app/components/header/account-setting/permissions-page/role-list/__tests__/row-menu.spec.tsx +++ b/web/app/components/header/account-setting/permissions-page/role-list/__tests__/row-menu.spec.tsx @@ -30,12 +30,6 @@ const membersOfRoleQueryMock = vi.hoisted(() => { } }) -vi.mock('@/context/app-context', () => ({ - useSelector: (selector: (state: { workspacePermissionKeys: string[] }) => T): T => selector({ - workspacePermissionKeys: mockWorkspacePermissionKeys.value, - }), -})) - vi.mock('@/context/app-context-state', async (importOriginal) => { const { createAppContextStateAtomMock } = await import('@/__tests__/utils/mock-app-context-state') return createAppContextStateAtomMock(importOriginal, () => ({ diff --git a/web/app/components/header/account-setting/preference-page/__tests__/index.spec.tsx b/web/app/components/header/account-setting/preference-page/__tests__/index.spec.tsx index db47bfe571d..70a21125fcf 100644 --- a/web/app/components/header/account-setting/preference-page/__tests__/index.spec.tsx +++ b/web/app/components/header/account-setting/preference-page/__tests__/index.spec.tsx @@ -68,13 +68,6 @@ vi.mock('@/next/navigation', () => ({ useRouter: () => ({ refresh: mockRefresh }), })) -vi.mock('@/context/app-context', () => ({ - useAppContext: () => ({ - userProfile: mockUserProfile, - mutateUserProfile: mockMutateUserProfile, - }), -})) - vi.mock('@/context/app-context-state', async (importOriginal) => { const { createAppContextStateAtomMock } = await import('@/__tests__/utils/mock-app-context-state') return createAppContextStateAtomMock(importOriginal, () => ({ diff --git a/web/app/components/header/env-nav/__tests__/index.spec.tsx b/web/app/components/header/env-nav/__tests__/index.spec.tsx index 1a6e1bfe731..f4c3e5f4b4f 100644 --- a/web/app/components/header/env-nav/__tests__/index.spec.tsx +++ b/web/app/components/header/env-nav/__tests__/index.spec.tsx @@ -1,17 +1,13 @@ -import type { AppContextValue } from '@/context/app-context' +import type { AppContextStateMockState } from '@/__tests__/utils/mock-app-context-state' import { render, screen } from '@testing-library/react' import { vi } from 'vitest' import EnvNav from '../index' const mockAppContextState = vi.hoisted(() => ({ - current: {} as Partial, + current: {} as Partial, })) const mockUseAppContext = vi.hoisted(() => vi.fn()) -vi.mock('@/context/app-context', () => ({ - useAppContext: mockUseAppContext, -})) - vi.mock('@/context/app-context-state', async (importOriginal) => { const { createAppContextStateAtomMock } = await import('@/__tests__/utils/mock-app-context-state') return createAppContextStateAtomMock(importOriginal, () => mockAppContextState.current) @@ -32,7 +28,7 @@ describe('EnvNav', () => { langGeniusVersionInfo: { current_env: 'PRODUCTION', }, - } as unknown as AppContextValue + } as unknown as AppContextStateMockState mockAppContextState.current = appContextValue mockUseAppContext.mockReturnValue(appContextValue) @@ -45,7 +41,7 @@ describe('EnvNav', () => { langGeniusVersionInfo: { current_env: 'TESTING', }, - } as unknown as AppContextValue + } as unknown as AppContextStateMockState mockAppContextState.current = appContextValue mockUseAppContext.mockReturnValue(appContextValue) @@ -58,7 +54,7 @@ describe('EnvNav', () => { langGeniusVersionInfo: { current_env: 'DEVELOPMENT', }, - } as unknown as AppContextValue + } as unknown as AppContextStateMockState mockAppContextState.current = appContextValue mockUseAppContext.mockReturnValue(appContextValue) diff --git a/web/app/components/integrations/__tests__/page.spec.tsx b/web/app/components/integrations/__tests__/page.spec.tsx index 7e0ea144891..b8ceb670520 100644 --- a/web/app/components/integrations/__tests__/page.spec.tsx +++ b/web/app/components/integrations/__tests__/page.spec.tsx @@ -43,12 +43,6 @@ vi.mock('@/next/navigation', () => ({ }), })) -vi.mock('@/context/app-context', () => ({ - useSelector: (selector: (state: { workspacePermissionKeys: string[] }) => T): T => selector({ - workspacePermissionKeys: mockAppContextState.workspacePermissionKeys, - }), -})) - vi.mock('@/app/components/plugins/plugin-page/use-reference-setting', () => ({ usePluginSettingsAccess: () => ({ permission: mockReferenceSetting().permission, diff --git a/web/app/components/integrations/__tests__/tool-provider-list.spec.tsx b/web/app/components/integrations/__tests__/tool-provider-list.spec.tsx index c43d728916d..6abc46550e3 100644 --- a/web/app/components/integrations/__tests__/tool-provider-list.spec.tsx +++ b/web/app/components/integrations/__tests__/tool-provider-list.spec.tsx @@ -97,11 +97,6 @@ vi.mock('@/service/use-tools', () => ({ const mockAppContextState = vi.hoisted(() => ({ workspacePermissionKeys: ['tool.manage', 'mcp.manage'] as string[], })) -vi.mock('@/context/app-context', () => ({ - useSelector: (selector: (state: { workspacePermissionKeys: string[] }) => T): T => selector({ - workspacePermissionKeys: mockAppContextState.workspacePermissionKeys, - }), -})) vi.mock('@/context/app-context-state', async (importOriginal) => { const { createAppContextStateAtomMock } = await import('@/__tests__/utils/mock-app-context-state') diff --git a/web/app/components/main-nav/__tests__/index.spec.tsx b/web/app/components/main-nav/__tests__/index.spec.tsx index 527ec0e9e6e..f2d65d67c43 100644 --- a/web/app/components/main-nav/__tests__/index.spec.tsx +++ b/web/app/components/main-nav/__tests__/index.spec.tsx @@ -1,9 +1,9 @@ import type { ReactNode } from 'react' import type { Mock } from 'vitest' -import type { AppContextValue } from '@/context/app-context' +import type { AppContextStateMockState } from '@/__tests__/utils/mock-app-context-state' import type { ModalContextState } from '@/context/modal-context' import type { ProviderContextState } from '@/context/provider-context' -import type { IWorkspace } from '@/models/common' +import type { ICurrentWorkspace, IWorkspace } from '@/models/common' import type { InstalledApp } from '@/models/explore' import { fireEvent, screen, waitFor } from '@testing-library/react' import { createStore, Provider as JotaiProvider } from 'jotai' @@ -30,7 +30,7 @@ const { mockIsAgentV2Enabled, mockSwitchWorkspace, mockToastSuccess } = vi.hoist mockIsAgentV2Enabled: vi.fn(() => true), })) const mockAppContextState = vi.hoisted(() => ({ - current: undefined as AppContextValue | undefined, + current: undefined as AppContextStateMockState | undefined, })) vi.mock('@/features/agent-v2/feature-flag', () => ({ @@ -190,7 +190,7 @@ const createInstalledApp = (overrides: Partial = {}): InstalledApp }, }) -const appContextValue: AppContextValue = { +const appContextValue: AppContextStateMockState = { userProfile: { id: 'user-1', name: 'Evan Z', @@ -226,10 +226,8 @@ const appContextValue: AppContextValue = { version: '1.0.0', can_auto_update: false, }, - useSelector: vi.fn(), isLoadingCurrentWorkspace: false, isLoadingWorkspacePermissionKeys: false, - isValidatingCurrentWorkspace: false, workspacePermissionKeys: ownerWorkspacePermissionKeys, } @@ -247,7 +245,7 @@ const renderMainNav = ( const queryClient = createTestQueryClient() const currentAppContext = mockAppContextState.current ?? appContextValue mockAppContextState.current = currentAppContext - queryClient.setQueryData(consoleQuery.workspaces.current.post.queryKey(), currentAppContext.currentWorkspace) + queryClient.setQueryData(consoleQuery.workspaces.current.post.queryKey(), currentAppContext.currentWorkspace as ICurrentWorkspace) queryClient.setQueryData(consoleQuery.workspaces.get.queryKey(), { workspaces: mockWorkspaces }) const resolvedSystemFeatures = { ...defaultMainNavSystemFeatures, diff --git a/web/app/components/oauth-registration-analytics.tsx b/web/app/components/oauth-registration-analytics.tsx index 029586c715f..2c0d84edd52 100644 --- a/web/app/components/oauth-registration-analytics.tsx +++ b/web/app/components/oauth-registration-analytics.tsx @@ -49,7 +49,7 @@ export function OAuthRegistrationAnalytics() { const eventName = utmInfo ? 'user_registration_success_with_utm' : 'user_registration_success' // Defer the Amplitude event until the user ID is attached. It is flushed in - // AppContextProvider after setUserId runs. Firing it here would record it under an + // AppBootstrapEffects after setUserId runs. Firing it here would record it under an // anonymous Amplitude profile (no user ID set yet). rememberRegistrationSuccess({ method: 'oauth', utmInfo }) diff --git a/web/app/components/plugins/plugin-auth/__tests__/authorized-in-node.spec.tsx b/web/app/components/plugins/plugin-auth/__tests__/authorized-in-node.spec.tsx index ba542bdc9ed..4d756f6f2bc 100644 --- a/web/app/components/plugins/plugin-auth/__tests__/authorized-in-node.spec.tsx +++ b/web/app/components/plugins/plugin-auth/__tests__/authorized-in-node.spec.tsx @@ -36,15 +36,6 @@ vi.mock('@/service/use-tools', () => ({ })) const mockIsCurrentWorkspaceManager = vi.fn() -const mockUserProfile = { id: 'test-user', name: 'Test User', email: 'test@example.com', avatar_url: '' } -vi.mock('@/context/app-context', () => ({ - useAppContext: () => ({ - isCurrentWorkspaceManager: mockIsCurrentWorkspaceManager(), - }), - // Item renders useAppContextWithSelector(state => state.userProfile) - useSelector: (selector: (state: { userProfile: typeof mockUserProfile }) => unknown) => - selector({ userProfile: mockUserProfile }), -})) vi.mock('@/hooks/use-oauth', () => ({ openOAuthPopup: vi.fn(), diff --git a/web/app/components/plugins/plugin-auth/__tests__/plugin-auth-in-agent.spec.tsx b/web/app/components/plugins/plugin-auth/__tests__/plugin-auth-in-agent.spec.tsx index 43b9ddf62dc..2858aae7f8a 100644 --- a/web/app/components/plugins/plugin-auth/__tests__/plugin-auth-in-agent.spec.tsx +++ b/web/app/components/plugins/plugin-auth/__tests__/plugin-auth-in-agent.spec.tsx @@ -37,18 +37,6 @@ vi.mock('@/service/use-tools', () => ({ const mockIsCurrentWorkspaceManager = vi.fn() const mockUserProfile = { id: 'test-user', name: 'Test User', email: 'test@example.com', avatar_url: '' } -vi.mock('@/context/app-context', () => ({ - useAppContext: () => ({ - isCurrentWorkspaceManager: mockIsCurrentWorkspaceManager(), - }), - // Item renders useAppContextWithSelector(state => state.userProfile) for the - // borrowed-row heuristic. Provide a minimal stub so the selector runs. - useSelector: (selector: (state: { userProfile: typeof mockUserProfile, workspacePermissionKeys: string[] }) => unknown) => - selector({ - userProfile: mockUserProfile, - workspacePermissionKeys: ['credential.use', 'credential.create', 'credential.manage'], - }), -})) vi.mock('@/context/app-context-state', async (importOriginal) => { const { createAppContextStateAtomMock } = await import('@/__tests__/utils/mock-app-context-state') diff --git a/web/app/components/plugins/plugin-auth/__tests__/plugin-auth.spec.tsx b/web/app/components/plugins/plugin-auth/__tests__/plugin-auth.spec.tsx index a4775a37e41..9669186bcf6 100644 --- a/web/app/components/plugins/plugin-auth/__tests__/plugin-auth.spec.tsx +++ b/web/app/components/plugins/plugin-auth/__tests__/plugin-auth.spec.tsx @@ -23,13 +23,6 @@ vi.mock('../authorized', () => ({ ), })) -vi.mock('@/context/app-context', () => ({ - useSelector: (selector: (state: { workspacePermissionKeys: string[] }) => unknown) => - selector({ - workspacePermissionKeys: mockAppContext.workspacePermissionKeys, - }), -})) - vi.mock('@/context/app-context-state', async (importOriginal) => { const { createAppContextStateAtomMock } = await import('@/__tests__/utils/mock-app-context-state') return createAppContextStateAtomMock(importOriginal, () => ({ diff --git a/web/app/components/plugins/plugin-auth/authorize/__tests__/api-key-modal.spec.tsx b/web/app/components/plugins/plugin-auth/authorize/__tests__/api-key-modal.spec.tsx index 7b2df1f9918..cb211adffff 100644 --- a/web/app/components/plugins/plugin-auth/authorize/__tests__/api-key-modal.spec.tsx +++ b/web/app/components/plugins/plugin-auth/authorize/__tests__/api-key-modal.spec.tsx @@ -84,10 +84,6 @@ vi.mock('@/service/use-common', () => ({ })) // PermissionSelector also reads userProfile from app-context. -vi.mock('@/context/app-context', () => ({ - useSelector: (selector: (state: { userProfile: { id: string, name: string, email: string, avatar_url: string } }) => unknown) => - selector({ userProfile: { id: 'test-user', name: 'Test User', email: 'test@example.com', avatar_url: '' } }), -})) const basePayload = { category: AuthCategory.tool, diff --git a/web/app/components/plugins/plugin-auth/authorize/__tests__/index.spec.tsx b/web/app/components/plugins/plugin-auth/authorize/__tests__/index.spec.tsx index 1c1f56e0b74..842e063edfa 100644 --- a/web/app/components/plugins/plugin-auth/authorize/__tests__/index.spec.tsx +++ b/web/app/components/plugins/plugin-auth/authorize/__tests__/index.spec.tsx @@ -64,13 +64,6 @@ vi.mock('@/hooks/use-oauth', () => ({ openOAuthPopup: vi.fn(), })) -vi.mock('@/context/app-context', () => ({ - useSelector: (selector: (state: { workspacePermissionKeys: string[] }) => unknown) => - selector({ - workspacePermissionKeys: mockAppContext.workspacePermissionKeys, - }), -})) - vi.mock('@/context/app-context-state', async (importOriginal) => { const { createAppContextStateAtomMock } = await import('@/__tests__/utils/mock-app-context-state') return createAppContextStateAtomMock(importOriginal, () => ({ diff --git a/web/app/components/plugins/plugin-auth/authorized/__tests__/index.spec.tsx b/web/app/components/plugins/plugin-auth/authorized/__tests__/index.spec.tsx index 00a50f9b06d..ab725d66672 100644 --- a/web/app/components/plugins/plugin-auth/authorized/__tests__/index.spec.tsx +++ b/web/app/components/plugins/plugin-auth/authorized/__tests__/index.spec.tsx @@ -79,12 +79,6 @@ const mockAppContext = vi.hoisted(() => ({ userProfile: { id: 'test-user', name: 'Test User', email: 'test@example.com', avatar_url: '' }, workspacePermissionKeys: ['credential.use', 'credential.create', 'credential.manage'] as string[], })) -vi.mock('@/context/app-context', () => ({ - useSelector: (selector: (state: { - userProfile: typeof mockAppContext.userProfile - workspacePermissionKeys: string[] - }) => unknown) => selector(mockAppContext), -})) vi.mock('@/context/app-context-state', async (importOriginal) => { const { createAppContextStateAtomMock } = await import('@/__tests__/utils/mock-app-context-state') diff --git a/web/app/components/plugins/plugin-detail-panel/__tests__/detail-header.spec.tsx b/web/app/components/plugins/plugin-detail-panel/__tests__/detail-header.spec.tsx index 375f9f15b23..abf0ec57e95 100644 --- a/web/app/components/plugins/plugin-detail-panel/__tests__/detail-header.spec.tsx +++ b/web/app/components/plugins/plugin-detail-panel/__tests__/detail-header.spec.tsx @@ -75,12 +75,6 @@ vi.mock('ahooks', async () => { } }) -vi.mock('@/context/app-context', () => ({ - useAppContext: () => ({ - userProfile: { timezone: 'UTC' }, - }), -})) - vi.mock('@/hooks/use-theme', () => ({ default: () => ({ theme: 'light' }), })) diff --git a/web/app/components/plugins/plugin-detail-panel/detail-header/__tests__/index.spec.tsx b/web/app/components/plugins/plugin-detail-panel/detail-header/__tests__/index.spec.tsx index 3fdd82f7091..c663a91f5e2 100644 --- a/web/app/components/plugins/plugin-detail-panel/detail-header/__tests__/index.spec.tsx +++ b/web/app/components/plugins/plugin-detail-panel/detail-header/__tests__/index.spec.tsx @@ -21,12 +21,6 @@ const render = (ui: ReactElement) => { }) } -vi.mock('@/context/app-context', () => ({ - useAppContext: () => ({ - userProfile: { timezone: 'UTC' }, - }), -})) - vi.mock('@/context/i18n', () => ({ useGetLanguage: () => 'en_US', useLocale: () => 'en-US', diff --git a/web/app/components/plugins/plugin-page/__tests__/index.spec.tsx b/web/app/components/plugins/plugin-page/__tests__/index.spec.tsx index 80ea6e03ab4..4d36405ee5a 100644 --- a/web/app/components/plugins/plugin-page/__tests__/index.spec.tsx +++ b/web/app/components/plugins/plugin-page/__tests__/index.spec.tsx @@ -47,23 +47,6 @@ vi.mock('@/context/i18n', () => ({ useDocLink: () => (path: string) => `https://docs.example.com${path}`, })) -vi.mock('@/context/app-context', () => ({ - useAppContext: () => ({ - isCurrentWorkspaceManager: true, - isCurrentWorkspaceOwner: false, - langGeniusVersionInfo: { - current_env: 'CLOUD', - current_version: '1.0.0', - latest_version: '1.0.0', - version: '1.0.0', - release_date: '', - release_notes: '', - can_auto_update: false, - }, - workspacePermissionKeys: ['plugin.install', 'plugin.delete', 'plugin.debug', 'plugin.plugin_preferences'], - }), -})) - vi.mock('@/context/app-context-state', async (importOriginal) => { const { createAppContextStateAtomMock } = await import('@/__tests__/utils/mock-app-context-state') return createAppContextStateAtomMock(importOriginal, () => ({ diff --git a/web/app/components/plugins/reference-setting-modal/auto-update-setting/__tests__/index.spec.tsx b/web/app/components/plugins/reference-setting-modal/auto-update-setting/__tests__/index.spec.tsx index 4597948ef7a..b3ab7faaf33 100644 --- a/web/app/components/plugins/reference-setting-modal/auto-update-setting/__tests__/index.spec.tsx +++ b/web/app/components/plugins/reference-setting-modal/auto-update-setting/__tests__/index.spec.tsx @@ -33,13 +33,6 @@ dayjs.extend(timezone) // Mock app context const mockTimezone = 'America/New_York' -vi.mock('@/context/app-context', () => ({ - useAppContext: () => ({ - userProfile: { - timezone: mockTimezone, - }, - }), -})) // Mock modal context const mockSetShowAccountSettingModal = vi.fn() diff --git a/web/app/components/plugins/update-plugin/__tests__/index.spec.tsx b/web/app/components/plugins/update-plugin/__tests__/index.spec.tsx index 98642528405..063198d83f7 100644 --- a/web/app/components/plugins/update-plugin/__tests__/index.spec.tsx +++ b/web/app/components/plugins/update-plugin/__tests__/index.spec.tsx @@ -22,9 +22,6 @@ vi.mock('@/context/i18n', () => ({ })) // Mock app context for useGetIcon -vi.mock('@/context/app-context', () => ({ - useSelector: () => ({ id: 'test-workspace-id' }), -})) // Mock hooks/use-timestamp vi.mock('@/hooks/use-timestamp', () => ({ diff --git a/web/app/components/rag-pipeline/components/__tests__/conversion.spec.tsx b/web/app/components/rag-pipeline/components/__tests__/conversion.spec.tsx index 489fe005380..623b8d7c234 100644 --- a/web/app/components/rag-pipeline/components/__tests__/conversion.spec.tsx +++ b/web/app/components/rag-pipeline/components/__tests__/conversion.spec.tsx @@ -19,14 +19,6 @@ vi.mock('@/context/dataset-detail', () => ({ useDatasetDetailContextWithSelector: (selector: (state: typeof mockDatasetDetailState) => unknown) => selector(mockDatasetDetailState), })) -let mockAppContextState = { - userProfile: { id: 'user-1' }, - workspacePermissionKeys: [] as string[], -} -vi.mock('@/context/app-context', () => ({ - useSelector: (selector: (state: typeof mockAppContextState) => unknown) => selector(mockAppContextState), -})) - vi.mock('@/service/use-pipeline', () => ({ useConvertDatasetToPipeline: () => ({ mutateAsync: mockConvert, @@ -78,10 +70,6 @@ describe('Conversion', () => { maintainer: 'maintainer-id', }, } - mockAppContextState = { - userProfile: { id: 'user-1' }, - workspacePermissionKeys: [], - } }) afterEach(() => { diff --git a/web/app/components/rag-pipeline/components/__tests__/index.spec.tsx b/web/app/components/rag-pipeline/components/__tests__/index.spec.tsx index dc3df5a7a4e..132f1e0aec3 100644 --- a/web/app/components/rag-pipeline/components/__tests__/index.spec.tsx +++ b/web/app/components/rag-pipeline/components/__tests__/index.spec.tsx @@ -229,14 +229,6 @@ vi.mock('@/context/dataset-detail', () => ({ useDatasetDetailContextWithSelector: (selector: (state: typeof mockDatasetDetailState) => unknown) => selector(mockDatasetDetailState), })) -let mockAppContextState = { - userProfile: { id: 'user-1' }, - workspacePermissionKeys: [] as string[], -} -vi.mock('@/context/app-context', () => ({ - useSelector: (selector: (state: typeof mockAppContextState) => unknown) => selector(mockAppContextState), -})) - vi.mock('@/service/workflow', () => ({ fetchWorkflowDraft: vi.fn().mockResolvedValue({ graph: { nodes: [], edges: [], viewport: {} }, @@ -409,10 +401,6 @@ describe('Conversion', () => { maintainer: 'maintainer-id', }, } - mockAppContextState = { - userProfile: { id: 'user-1' }, - workspacePermissionKeys: [], - } }) describe('Rendering', () => { diff --git a/web/app/components/rag-pipeline/components/rag-pipeline-header/__tests__/index.spec.tsx b/web/app/components/rag-pipeline/components/rag-pipeline-header/__tests__/index.spec.tsx index 73230ec54b8..b125907ff34 100644 --- a/web/app/components/rag-pipeline/components/rag-pipeline-header/__tests__/index.spec.tsx +++ b/web/app/components/rag-pipeline/components/rag-pipeline-header/__tests__/index.spec.tsx @@ -147,16 +147,6 @@ vi.mock('@/context/dataset-detail', () => ({ }), })) -vi.mock('@/context/app-context', () => ({ - useSelector: (selector: (state: Record) => unknown) => selector({ - userProfile: { - id: mockCurrentUserId, - }, - isLoadingWorkspacePermissionKeys: mockIsLoadingWorkspacePermissionKeys, - workspacePermissionKeys: mockWorkspacePermissionKeys, - }), -})) - vi.mock('@/context/app-context-state', async (importOriginal) => { const { createAppContextStateAtomMock } = await import('@/__tests__/utils/mock-app-context-state') diff --git a/web/app/components/rag-pipeline/components/rag-pipeline-header/publisher/__tests__/index.spec.tsx b/web/app/components/rag-pipeline/components/rag-pipeline-header/publisher/__tests__/index.spec.tsx index e1fda0a0648..f269bdd63ce 100644 --- a/web/app/components/rag-pipeline/components/rag-pipeline-header/publisher/__tests__/index.spec.tsx +++ b/web/app/components/rag-pipeline/components/rag-pipeline-header/publisher/__tests__/index.spec.tsx @@ -139,16 +139,6 @@ vi.mock('@/context/dataset-detail', () => ({ }, })) -vi.mock('@/context/app-context', () => ({ - useSelector: (selector: (state: Record) => unknown) => selector({ - userProfile: { - id: mockCurrentUserId, - }, - isLoadingWorkspacePermissionKeys: mockIsLoadingWorkspacePermissionKeys, - workspacePermissionKeys: mockWorkspacePermissionKeys, - }), -})) - vi.mock('@/context/app-context-state', async (importOriginal) => { const { createAppContextStateAtomMock } = await import('@/__tests__/utils/mock-app-context-state') diff --git a/web/app/components/rag-pipeline/components/rag-pipeline-header/publisher/__tests__/popup.spec.tsx b/web/app/components/rag-pipeline/components/rag-pipeline-header/publisher/__tests__/popup.spec.tsx index 75353bb6598..95f7d36ee24 100644 --- a/web/app/components/rag-pipeline/components/rag-pipeline-header/publisher/__tests__/popup.spec.tsx +++ b/web/app/components/rag-pipeline/components/rag-pipeline-header/publisher/__tests__/popup.spec.tsx @@ -156,16 +156,6 @@ vi.mock('@/context/dataset-detail', () => ({ }), })) -vi.mock('@/context/app-context', () => ({ - useSelector: (selector: (state: Record) => unknown) => selector({ - userProfile: { - id: mockCurrentUserId, - }, - isLoadingWorkspacePermissionKeys: mockIsLoadingWorkspacePermissionKeys, - workspacePermissionKeys: mockWorkspacePermissionKeys, - }), -})) - vi.mock('@/context/app-context-state', async (importOriginal) => { const { createAppContextStateAtomMock } = await import('@/__tests__/utils/mock-app-context-state') diff --git a/web/app/components/snippet-list/__tests__/index.spec.tsx b/web/app/components/snippet-list/__tests__/index.spec.tsx index a73a8f3965f..173233f19fb 100644 --- a/web/app/components/snippet-list/__tests__/index.spec.tsx +++ b/web/app/components/snippet-list/__tests__/index.spec.tsx @@ -71,32 +71,6 @@ vi.mock('@/service/client', () => ({ const mockIsCurrentWorkspaceEditor = vi.fn(() => true) const mockIsCurrentWorkspaceDatasetOperator = vi.fn(() => false) const mockWorkspacePermissionKeys = vi.fn(() => ['snippets.create_and_modify']) -vi.mock('@/context/app-context', () => ({ - useAppContext: () => { - const state = { - isCurrentWorkspaceEditor: mockIsCurrentWorkspaceEditor(), - isCurrentWorkspaceDatasetOperator: mockIsCurrentWorkspaceDatasetOperator(), - isLoadingCurrentWorkspace: false, - userProfile: { id: 'creator-1' }, - workspacePermissionKeys: mockWorkspacePermissionKeys(), - } - - return state - }, - useSelector: (selector: (state: { - isCurrentWorkspaceEditor: boolean - isCurrentWorkspaceDatasetOperator: boolean - isLoadingCurrentWorkspace: boolean - userProfile: { id: string } - workspacePermissionKeys: string[] - }) => T): T => selector({ - isCurrentWorkspaceEditor: mockIsCurrentWorkspaceEditor(), - isCurrentWorkspaceDatasetOperator: mockIsCurrentWorkspaceDatasetOperator(), - isLoadingCurrentWorkspace: false, - userProfile: { id: 'creator-1' }, - workspacePermissionKeys: mockWorkspacePermissionKeys(), - }), -})) vi.mock('@/context/app-context-state', async (importOriginal) => { const { createAppContextStateAtomMock } = await import('@/__tests__/utils/mock-app-context-state') diff --git a/web/app/components/snippet-list/components/__tests__/snippet-card.spec.tsx b/web/app/components/snippet-list/components/__tests__/snippet-card.spec.tsx index 484faf1e13c..80c19ac7329 100644 --- a/web/app/components/snippet-list/components/__tests__/snippet-card.spec.tsx +++ b/web/app/components/snippet-list/components/__tests__/snippet-card.spec.tsx @@ -26,20 +26,6 @@ const { mockUpdateMutate: vi.fn(), })) -vi.mock('@/context/app-context', () => ({ - useAppContext: () => ({ - isCurrentWorkspaceEditor: mockIsCurrentWorkspaceEditor(), - workspacePermissionKeys: mockWorkspacePermissionKeys(), - }), - useSelector: (selector: (state: { - isCurrentWorkspaceEditor: boolean - workspacePermissionKeys: string[] - }) => T): T => selector({ - isCurrentWorkspaceEditor: mockIsCurrentWorkspaceEditor(), - workspacePermissionKeys: mockWorkspacePermissionKeys(), - }), -})) - vi.mock('@/context/app-context-state', async (importOriginal) => { const { createAppContextStateAtomMock } = await import('@/__tests__/utils/mock-app-context-state') diff --git a/web/app/components/snippet-list/components/__tests__/snippet-create-button.spec.tsx b/web/app/components/snippet-list/components/__tests__/snippet-create-button.spec.tsx index f1a717a7c4f..01961b45f6d 100644 --- a/web/app/components/snippet-list/components/__tests__/snippet-create-button.spec.tsx +++ b/web/app/components/snippet-list/components/__tests__/snippet-create-button.spec.tsx @@ -25,15 +25,6 @@ vi.mock('@langgenius/dify-ui/toast', () => ({ }, })) -vi.mock('@/context/app-context', () => ({ - useAppContext: () => ({ - workspacePermissionKeys: mockWorkspacePermissionKeys(), - }), - useSelector: (selector: (state: { workspacePermissionKeys: string[] }) => T): T => selector({ - workspacePermissionKeys: mockWorkspacePermissionKeys(), - }), -})) - vi.mock('@/context/app-context-state', async (importOriginal) => { const { createAppContextStateAtomMock } = await import('@/__tests__/utils/mock-app-context-state') diff --git a/web/app/components/snippets/__tests__/import-snippet-dsl-dialog.spec.tsx b/web/app/components/snippets/__tests__/import-snippet-dsl-dialog.spec.tsx index ccb1df06f82..7d8f4a76c38 100644 --- a/web/app/components/snippets/__tests__/import-snippet-dsl-dialog.spec.tsx +++ b/web/app/components/snippets/__tests__/import-snippet-dsl-dialog.spec.tsx @@ -24,15 +24,6 @@ vi.mock('@/next/navigation', () => ({ useRouter: () => routerMocks, })) -vi.mock('@/context/app-context', () => ({ - useAppContext: () => ({ - workspacePermissionKeys: contextMocks.workspacePermissionKeys, - }), - useSelector: (selector: (state: { workspacePermissionKeys: string[] }) => T): T => selector({ - workspacePermissionKeys: contextMocks.workspacePermissionKeys, - }), -})) - vi.mock('@/context/app-context-state', async (importOriginal) => { const { createAppContextStateAtomMock } = await import('@/__tests__/utils/mock-app-context-state') diff --git a/web/app/components/snippets/components/__tests__/snippet-main.spec.tsx b/web/app/components/snippets/components/__tests__/snippet-main.spec.tsx index 9b1b289531b..26a99f44473 100644 --- a/web/app/components/snippets/components/__tests__/snippet-main.spec.tsx +++ b/web/app/components/snippets/components/__tests__/snippet-main.spec.tsx @@ -52,12 +52,6 @@ vi.mock('@langgenius/dify-ui/toast', () => ({ }, })) -vi.mock('@/context/app-context', () => ({ - useSelector: (selector: (state: { workspacePermissionKeys: string[] }) => T): T => selector({ - workspacePermissionKeys: mockAppContext.workspacePermissionKeys, - }), -})) - vi.mock('@/context/app-context-state', async (importOriginal) => { const { createAppContextStateAtomMock } = await import('@/__tests__/utils/mock-app-context-state') diff --git a/web/app/components/snippets/hooks/__tests__/use-create-snippet.spec.tsx b/web/app/components/snippets/hooks/__tests__/use-create-snippet.spec.tsx index 4a80ccf7e6e..4ea1fdaa822 100644 --- a/web/app/components/snippets/hooks/__tests__/use-create-snippet.spec.tsx +++ b/web/app/components/snippets/hooks/__tests__/use-create-snippet.spec.tsx @@ -43,15 +43,6 @@ vi.mock('@/service/client', () => ({ }, })) -vi.mock('@/context/app-context', () => ({ - useAppContext: () => ({ - workspacePermissionKeys: mockWorkspacePermissionKeys(), - }), - useSelector: (selector: (state: { workspacePermissionKeys: string[] }) => T): T => selector({ - workspacePermissionKeys: mockWorkspacePermissionKeys(), - }), -})) - vi.mock('@/context/app-context-state', async (importOriginal) => { const { createAppContextStateAtomMock } = await import('@/__tests__/utils/mock-app-context-state') diff --git a/web/app/components/tools/mcp/__tests__/create-card.spec.tsx b/web/app/components/tools/mcp/__tests__/create-card.spec.tsx index daa2a273000..3a8650d9642 100644 --- a/web/app/components/tools/mcp/__tests__/create-card.spec.tsx +++ b/web/app/components/tools/mcp/__tests__/create-card.spec.tsx @@ -45,12 +45,6 @@ const mockAppContextState = vi.hoisted(() => ({ workspacePermissionKeysAtom: Symbol('workspacePermissionKeysAtom'), })) -vi.mock('@/context/app-context', () => ({ - useSelector: (selector: (state: { workspacePermissionKeys: string[] }) => unknown) => selector({ - workspacePermissionKeys: mockAppContextState.workspacePermissionKeys, - }), -})) - vi.mock('@/context/app-context-state', () => ({ workspacePermissionKeysAtom: mockAppContextState.workspacePermissionKeysAtom, })) diff --git a/web/app/components/tools/mcp/__tests__/index.spec.tsx b/web/app/components/tools/mcp/__tests__/index.spec.tsx index 0b55d4d4310..48a6e7e1388 100644 --- a/web/app/components/tools/mcp/__tests__/index.spec.tsx +++ b/web/app/components/tools/mcp/__tests__/index.spec.tsx @@ -31,12 +31,6 @@ vi.mock('@/service/use-tools', () => ({ }, })) -vi.mock('@/context/app-context', () => ({ - useSelector: (selector: (state: { workspacePermissionKeys: string[] }) => unknown) => selector({ - workspacePermissionKeys: mockAppContextState.workspacePermissionKeys, - }), -})) - vi.mock('@/context/app-context-state', () => ({ workspacePermissionKeysAtom: mockAppContextState.workspacePermissionKeysAtom, })) diff --git a/web/app/components/tools/mcp/__tests__/provider-card.spec.tsx b/web/app/components/tools/mcp/__tests__/provider-card.spec.tsx index a399057b08a..8069a5e9aa4 100644 --- a/web/app/components/tools/mcp/__tests__/provider-card.spec.tsx +++ b/web/app/components/tools/mcp/__tests__/provider-card.spec.tsx @@ -86,12 +86,6 @@ const mockAppContextState = vi.hoisted(() => ({ workspacePermissionKeysAtom: Symbol('workspacePermissionKeysAtom'), })) -vi.mock('@/context/app-context', () => ({ - useSelector: (selector: (state: { workspacePermissionKeys: string[] }) => unknown) => selector({ - workspacePermissionKeys: mockAppContextState.workspacePermissionKeys, - }), -})) - vi.mock('@/context/app-context-state', () => ({ workspacePermissionKeysAtom: mockAppContextState.workspacePermissionKeysAtom, })) diff --git a/web/app/components/tools/mcp/detail/__tests__/content.spec.tsx b/web/app/components/tools/mcp/detail/__tests__/content.spec.tsx index 5dc235a6683..78116a1c408 100644 --- a/web/app/components/tools/mcp/detail/__tests__/content.spec.tsx +++ b/web/app/components/tools/mcp/detail/__tests__/content.spec.tsx @@ -113,11 +113,6 @@ const mockAppContextState = vi.hoisted(() => ({ })) // Mock the app context -vi.mock('@/context/app-context', () => ({ - useSelector: (selector: (state: { workspacePermissionKeys: string[] }) => unknown) => selector({ - workspacePermissionKeys: mockAppContextState.workspacePermissionKeys, - }), -})) vi.mock('@/context/app-context-state', () => ({ workspacePermissionKeysAtom: mockAppContextState.workspacePermissionKeysAtom, diff --git a/web/app/components/tools/provider/__tests__/custom-create-card.spec.tsx b/web/app/components/tools/provider/__tests__/custom-create-card.spec.tsx index 948366f2eaa..d0e05c583c0 100644 --- a/web/app/components/tools/provider/__tests__/custom-create-card.spec.tsx +++ b/web/app/components/tools/provider/__tests__/custom-create-card.spec.tsx @@ -9,12 +9,6 @@ const mockAppContextState = vi.hoisted(() => ({ workspacePermissionKeysAtom: Symbol('workspacePermissionKeysAtom'), })) -vi.mock('@/context/app-context', () => ({ - useSelector: (selector: (state: { workspacePermissionKeys: string[] }) => T): T => selector({ - workspacePermissionKeys: mockAppContextState.workspacePermissionKeys, - }), -})) - vi.mock('@/context/app-context-state', () => ({ workspacePermissionKeysAtom: mockAppContextState.workspacePermissionKeysAtom, })) diff --git a/web/app/components/tools/provider/__tests__/detail.spec.tsx b/web/app/components/tools/provider/__tests__/detail.spec.tsx index 497df1398c9..06ad5afbfc8 100644 --- a/web/app/components/tools/provider/__tests__/detail.spec.tsx +++ b/web/app/components/tools/provider/__tests__/detail.spec.tsx @@ -12,19 +12,10 @@ vi.mock('@/i18n-config/language', () => ({ getLanguage: () => 'en_US', })) -const mockIsCurrentWorkspaceManager = vi.fn(() => true) const mockAppContextState = vi.hoisted(() => ({ workspacePermissionKeys: ['tool.manage', 'credential.use', 'credential.create', 'credential.manage'] as string[], workspacePermissionKeysAtom: Symbol('workspacePermissionKeysAtom'), })) -vi.mock('@/context/app-context', () => ({ - useAppContext: () => ({ - isCurrentWorkspaceManager: mockIsCurrentWorkspaceManager(), - }), - useSelector: (selector: (state: { workspacePermissionKeys: string[] }) => T): T => selector({ - workspacePermissionKeys: mockAppContextState.workspacePermissionKeys, - }), -})) vi.mock('@/context/app-context-state', () => ({ workspacePermissionKeysAtom: mockAppContextState.workspacePermissionKeysAtom, diff --git a/web/app/components/workflow-app/__tests__/index.spec.tsx b/web/app/components/workflow-app/__tests__/index.spec.tsx index 8c52460c485..29a9be085e3 100644 --- a/web/app/components/workflow-app/__tests__/index.spec.tsx +++ b/web/app/components/workflow-app/__tests__/index.spec.tsx @@ -84,10 +84,6 @@ vi.mock('@/app/components/workflow/store/trigger-status', () => ({ }), })) -vi.mock('@/context/app-context', () => ({ - useAppContext: () => appContextState, -})) - vi.mock('@/context/app-context-state', async (importOriginal) => { const { createAppContextStateAtomMock } = await import('@/__tests__/utils/mock-app-context-state') diff --git a/web/app/components/workflow-app/hooks/__tests__/use-workflow-init.spec.ts b/web/app/components/workflow-app/hooks/__tests__/use-workflow-init.spec.ts index 925dcf4ca88..fb5c2135924 100644 --- a/web/app/components/workflow-app/hooks/__tests__/use-workflow-init.spec.ts +++ b/web/app/components/workflow-app/hooks/__tests__/use-workflow-init.spec.ts @@ -46,14 +46,6 @@ vi.mock('@/app/components/app/store', () => ({ selector(appStoreState), })) -vi.mock('@/context/app-context', () => ({ - useSelector: (selector: (state: { userProfile: { id: string }, workspacePermissionKeys: string[] }) => T): T => - selector({ - userProfile: { id: 'user-1' }, - workspacePermissionKeys: ['app.create_and_management'], - }), -})) - vi.mock('@/context/app-context-state', async (importOriginal) => { const { createAppContextStateAtomMock } = await import('@/__tests__/utils/mock-app-context-state') diff --git a/web/app/components/workflow/__tests__/selection-contextmenu.spec.tsx b/web/app/components/workflow/__tests__/selection-contextmenu.spec.tsx index 422a602c2d8..bface11be0d 100644 --- a/web/app/components/workflow/__tests__/selection-contextmenu.spec.tsx +++ b/web/app/components/workflow/__tests__/selection-contextmenu.spec.tsx @@ -23,12 +23,6 @@ const mockWorkspacePermissionKeys = vi.hoisted(() => ({ value: ['snippets.create_and_modify'] as string[], })) -vi.mock('@/context/app-context', () => ({ - useSelector: (selector: (state: { workspacePermissionKeys: string[] }) => T): T => selector({ - workspacePermissionKeys: mockWorkspacePermissionKeys.value, - }), -})) - vi.mock('@/context/app-context-state', async (importOriginal) => { const { createAppContextStateAtomMock } = await import('@/__tests__/utils/mock-app-context-state') return createAppContextStateAtomMock(importOriginal, () => ({ diff --git a/web/app/components/workflow/block-selector/__tests__/tool-picker.spec.tsx b/web/app/components/workflow/block-selector/__tests__/tool-picker.spec.tsx index ff7e6db519d..be94e8fb143 100644 --- a/web/app/components/workflow/block-selector/__tests__/tool-picker.spec.tsx +++ b/web/app/components/workflow/block-selector/__tests__/tool-picker.spec.tsx @@ -63,12 +63,6 @@ vi.mock('@/config', async (importOriginal) => { } }) -vi.mock('@/context/app-context', () => ({ - useSelector: (selector: (state: { workspacePermissionKeys: string[] }) => T): T => selector({ - workspacePermissionKeys: mockWorkspacePermissionKeys, - }), -})) - vi.mock('@/context/app-context-state', async (importOriginal) => { const { createAppContextStateAtomMock } = await import('@/__tests__/utils/mock-app-context-state') return createAppContextStateAtomMock(importOriginal, () => ({ diff --git a/web/app/components/workflow/comment/comment-icon.spec.tsx b/web/app/components/workflow/comment/comment-icon.spec.tsx index 017c83b272b..db0b9a81066 100644 --- a/web/app/components/workflow/comment/comment-icon.spec.tsx +++ b/web/app/components/workflow/comment/comment-icon.spec.tsx @@ -29,15 +29,6 @@ vi.mock('reactflow', () => ({ }), })) -vi.mock('@/context/app-context', () => ({ - useAppContext: () => ({ - userProfile: { - ...mockAppContextState.userProfile, - id: mockUserId, - }, - }), -})) - vi.mock('@/context/app-context-state', async (importOriginal) => { const { createAppContextStateAtomMock } = await import('@/__tests__/utils/mock-app-context-state') return createAppContextStateAtomMock(importOriginal, () => ({ diff --git a/web/app/components/workflow/comment/comment-input.spec.tsx b/web/app/components/workflow/comment/comment-input.spec.tsx index 1696f85fa89..39b3b919095 100644 --- a/web/app/components/workflow/comment/comment-input.spec.tsx +++ b/web/app/components/workflow/comment/comment-input.spec.tsx @@ -32,12 +32,6 @@ vi.mock('react-i18next', () => ({ }), })) -vi.mock('@/context/app-context', () => ({ - useAppContext: () => ({ - userProfile: mockAppContextState.userProfile, - }), -})) - vi.mock('@/context/app-context-state', async (importOriginal) => { const { createAppContextStateAtomMock } = await import('@/__tests__/utils/mock-app-context-state') return createAppContextStateAtomMock(importOriginal, () => mockAppContextState) diff --git a/web/app/components/workflow/comment/thread.spec.tsx b/web/app/components/workflow/comment/thread.spec.tsx index 771443e37ff..12589787cb8 100644 --- a/web/app/components/workflow/comment/thread.spec.tsx +++ b/web/app/components/workflow/comment/thread.spec.tsx @@ -38,12 +38,6 @@ vi.mock('@/hooks/use-format-time-from-now', () => ({ }), })) -vi.mock('@/context/app-context', () => ({ - useAppContext: () => ({ - userProfile: mockAppContextState.userProfile, - }), -})) - vi.mock('@/context/app-context-state', async (importOriginal) => { const { createAppContextStateAtomMock } = await import('@/__tests__/utils/mock-app-context-state') return createAppContextStateAtomMock(importOriginal, () => mockAppContextState) diff --git a/web/app/components/workflow/hooks/__tests__/use-node-plugin-installation.spec.ts b/web/app/components/workflow/hooks/__tests__/use-node-plugin-installation.spec.ts index 9e80fb40f8a..11ec795db5f 100644 --- a/web/app/components/workflow/hooks/__tests__/use-node-plugin-installation.spec.ts +++ b/web/app/components/workflow/hooks/__tests__/use-node-plugin-installation.spec.ts @@ -15,12 +15,6 @@ const mockInvalidateTriggers = vi.fn() const mockInvalidDataSourceList = vi.fn() let mockWorkspacePermissionKeys = ['plugin.install'] -vi.mock('@/context/app-context', () => ({ - useAppContext: () => ({ - workspacePermissionKeys: mockWorkspacePermissionKeys, - }), -})) - vi.mock('@/context/app-context-state', async (importOriginal) => { const { createAppContextStateAtomMock } = await import('@/__tests__/utils/mock-app-context-state') return createAppContextStateAtomMock(importOriginal, () => ({ diff --git a/web/app/components/workflow/hooks/__tests__/use-workflow-comment.spec.ts b/web/app/components/workflow/hooks/__tests__/use-workflow-comment.spec.ts index 548ec5eef25..834527abd2a 100644 --- a/web/app/components/workflow/hooks/__tests__/use-workflow-comment.spec.ts +++ b/web/app/components/workflow/hooks/__tests__/use-workflow-comment.spec.ts @@ -49,12 +49,6 @@ vi.mock('@/next/navigation', () => ({ useParams: () => ({ appId: 'app-1' }), })) -vi.mock('@/context/app-context', () => ({ - useAppContext: () => ({ - userProfile: mockAppContextState.userProfile, - }), -})) - vi.mock('@/context/app-context-state', async (importOriginal) => { const { createAppContextStateAtomMock } = await import('@/__tests__/utils/mock-app-context-state') return createAppContextStateAtomMock(importOriginal, () => mockAppContextState) diff --git a/web/app/components/workflow/nodes/human-input/components/delivery-method/__tests__/email-configure-modal.spec.tsx b/web/app/components/workflow/nodes/human-input/components/delivery-method/__tests__/email-configure-modal.spec.tsx index 7ba7347869f..0c88cde561d 100644 --- a/web/app/components/workflow/nodes/human-input/components/delivery-method/__tests__/email-configure-modal.spec.tsx +++ b/web/app/components/workflow/nodes/human-input/components/delivery-method/__tests__/email-configure-modal.spec.tsx @@ -15,11 +15,6 @@ vi.mock('@langgenius/dify-ui/toast', () => ({ }, })) -vi.mock('@/context/app-context', () => ({ - useSelector: (selector: (state: { userProfile: { email: string } }) => string) => - selector({ userProfile: mockAppContextState.userProfile }), -})) - vi.mock('@/context/app-context-state', async (importOriginal) => { const { createAppContextStateAtomMock } = await import('@/__tests__/utils/mock-app-context-state') return createAppContextStateAtomMock(importOriginal, () => mockAppContextState) diff --git a/web/app/components/workflow/nodes/human-input/components/delivery-method/__tests__/method-item.spec.tsx b/web/app/components/workflow/nodes/human-input/components/delivery-method/__tests__/method-item.spec.tsx index e9d6d32ddc2..5b9dd7c5494 100644 --- a/web/app/components/workflow/nodes/human-input/components/delivery-method/__tests__/method-item.spec.tsx +++ b/web/app/components/workflow/nodes/human-input/components/delivery-method/__tests__/method-item.spec.tsx @@ -26,11 +26,6 @@ const mockAppContextState = vi.hoisted(() => ({ }, })) -vi.mock('@/context/app-context', () => ({ - useSelector: (selector: (state: { userProfile: { email: string } }) => string) => - selector({ userProfile: mockAppContextState.userProfile }), -})) - vi.mock('@/context/app-context-state', async (importOriginal) => { const { createAppContextStateAtomMock } = await import('@/__tests__/utils/mock-app-context-state') return createAppContextStateAtomMock(importOriginal, () => mockAppContextState) diff --git a/web/app/components/workflow/nodes/human-input/components/delivery-method/__tests__/test-email-sender.spec.tsx b/web/app/components/workflow/nodes/human-input/components/delivery-method/__tests__/test-email-sender.spec.tsx index 9c32cd592e4..24d0e1a446b 100644 --- a/web/app/components/workflow/nodes/human-input/components/delivery-method/__tests__/test-email-sender.spec.tsx +++ b/web/app/components/workflow/nodes/human-input/components/delivery-method/__tests__/test-email-sender.spec.tsx @@ -1,4 +1,3 @@ -/* eslint-disable react/no-context-provider -- use-context-selector contexts require .Provider in tests. */ import type { ReactNode } from 'react' import type { EmailConfig, FormInputItem, ParagraphFormInput, SelectFormInput } from '../../../types' import type { CodeNodeType } from '@/app/components/workflow/nodes/code/types' @@ -12,7 +11,6 @@ import { HooksStoreContext } from '@/app/components/workflow/hooks-store/provide import { createHooksStore } from '@/app/components/workflow/hooks-store/store' import { CodeLanguage } from '@/app/components/workflow/nodes/code/types' import { BlockEnum, InputVarType, VarType } from '@/app/components/workflow/types' -import { AppContext, initialLangGeniusVersionInfo, initialWorkspaceInfo, userProfilePlaceholder } from '@/context/app-context' import EmailSenderModal from '../test-email-sender' vi.mock('@langgenius/dify-ui/toast', () => ({ @@ -66,53 +64,9 @@ const renderWithProviders = (ui: ReactNode) => { return render( - selector({ - userProfile: { - ...userProfilePlaceholder, - ...mockAppContextState.userProfile, - }, - currentWorkspace: { - ...initialWorkspaceInfo, - ...mockAppContextState.currentWorkspace, - }, - isCurrentWorkspaceManager: true, - isCurrentWorkspaceOwner: true, - isCurrentWorkspaceEditor: true, - isCurrentWorkspaceDatasetOperator: true, - mutateUserProfile: vi.fn(), - mutateCurrentWorkspace: vi.fn(), - langGeniusVersionInfo: initialLangGeniusVersionInfo, - useSelector: vi.fn(), - isLoadingCurrentWorkspace: false, - isValidatingCurrentWorkspace: false, - workspacePermissionKeys: [], - }), - isLoadingCurrentWorkspace: false, - isValidatingCurrentWorkspace: false, - workspacePermissionKeys: [], - }} - > - - {ui} - - + + {ui} + , ) } diff --git a/web/app/components/workflow/nodes/human-input/components/delivery-method/recipient/__tests__/index.spec.tsx b/web/app/components/workflow/nodes/human-input/components/delivery-method/recipient/__tests__/index.spec.tsx index ad386679b18..feaeabddf61 100644 --- a/web/app/components/workflow/nodes/human-input/components/delivery-method/recipient/__tests__/index.spec.tsx +++ b/web/app/components/workflow/nodes/human-input/components/delivery-method/recipient/__tests__/index.spec.tsx @@ -13,10 +13,6 @@ vi.mock('react-i18next', () => ({ useTranslation: () => mockUseTranslation(), })) -vi.mock('@/context/app-context', () => ({ - useAppContext: () => mockUseAppContext(), -})) - vi.mock('@/context/app-context-state', async (importOriginal) => { const { createAppContextStateAtomMock } = await import('@/__tests__/utils/mock-app-context-state') return createAppContextStateAtomMock(importOriginal, () => mockAppContextState) diff --git a/web/app/components/workflow/nodes/knowledge-retrieval/__tests__/integration.spec.tsx b/web/app/components/workflow/nodes/knowledge-retrieval/__tests__/integration.spec.tsx index 5b2ffed90db..f08d672fc82 100644 --- a/web/app/components/workflow/nodes/knowledge-retrieval/__tests__/integration.spec.tsx +++ b/web/app/components/workflow/nodes/knowledge-retrieval/__tests__/integration.spec.tsx @@ -129,18 +129,6 @@ const createCondition = (overrides: Partial = {}): M ...overrides, }) -vi.mock('@/context/app-context', () => ({ - useSelector: (selector: (state: { userProfile: { id: string }, workspacePermissionKeys: string[] }) => unknown) => selector({ - userProfile: { id: 'user-1' }, - workspacePermissionKeys: [], - }), - useAppContext: () => ({ - userProfile: { - timezone: 'UTC', - }, - }), -})) - const mockAppContextState = vi.hoisted(() => ({ userProfile: { id: 'user-1' }, workspacePermissionKeys: [] as string[], diff --git a/web/app/components/workflow/nodes/trigger-schedule/__tests__/use-config.spec.ts b/web/app/components/workflow/nodes/trigger-schedule/__tests__/use-config.spec.ts index bc445f4211d..08ea8d7720e 100644 --- a/web/app/components/workflow/nodes/trigger-schedule/__tests__/use-config.spec.ts +++ b/web/app/components/workflow/nodes/trigger-schedule/__tests__/use-config.spec.ts @@ -17,10 +17,6 @@ vi.mock('@/app/components/workflow/nodes/_base/hooks/use-node-crud', () => ({ default: vi.fn(), })) -vi.mock('@/context/app-context', () => ({ - useAppContext: mockUseAppContext, -})) - const mockUseNodesReadOnly = vi.mocked(useNodesReadOnly) const mockUseNodeCrud = vi.mocked(useNodeCrud) diff --git a/web/app/components/workflow/panel/__tests__/human-input-form-list.spec.tsx b/web/app/components/workflow/panel/__tests__/human-input-form-list.spec.tsx index 962ff86d98a..9b0e1cff6b9 100644 --- a/web/app/components/workflow/panel/__tests__/human-input-form-list.spec.tsx +++ b/web/app/components/workflow/panel/__tests__/human-input-form-list.spec.tsx @@ -22,12 +22,6 @@ vi.mock('reactflow', () => ({ }), })) -vi.mock('@/context/app-context', () => ({ - useSelector: (selector: (state: { userProfile: { email: string } }) => T) => selector({ - userProfile: { email: 'debug@example.com' }, - }), -})) - vi.mock('@/context/i18n', () => ({ useLocale: () => 'en-US', })) diff --git a/web/app/components/workflow/panel/comments-panel/__tests__/index.spec.tsx b/web/app/components/workflow/panel/comments-panel/__tests__/index.spec.tsx index ffeb138a013..fadf667628e 100644 --- a/web/app/components/workflow/panel/comments-panel/__tests__/index.spec.tsx +++ b/web/app/components/workflow/panel/comments-panel/__tests__/index.spec.tsx @@ -71,12 +71,6 @@ vi.mock('@/hooks/use-format-time-from-now', () => ({ }), })) -vi.mock('@/context/app-context', () => ({ - useAppContext: () => ({ - userProfile: mockAppContextState.userProfile, - }), -})) - vi.mock('@/context/app-context-state', async (importOriginal) => { const { createAppContextStateAtomMock } = await import('@/__tests__/utils/mock-app-context-state') return createAppContextStateAtomMock(importOriginal, () => mockAppContextState) diff --git a/web/app/components/workflow/panel/version-history-panel/__tests__/index.spec.tsx b/web/app/components/workflow/panel/version-history-panel/__tests__/index.spec.tsx index 0760c0449f7..3f17277dcbc 100644 --- a/web/app/components/workflow/panel/version-history-panel/__tests__/index.spec.tsx +++ b/web/app/components/workflow/panel/version-history-panel/__tests__/index.spec.tsx @@ -65,10 +65,6 @@ type MockVersionHistoryItemProps = { handleClickActionMenuItem: (operation: VersionHistoryContextMenuOptions) => void } -vi.mock('@/context/app-context', () => ({ - useSelector: () => mockAppContextState.userProfile, -})) - vi.mock('@/context/app-context-state', async (importOriginal) => { const { createAppContextStateAtomMock } = await import('@/__tests__/utils/mock-app-context-state') return createAppContextStateAtomMock(importOriginal, () => mockAppContextState) diff --git a/web/app/components/workflow/run/agent-log/__tests__/agent-log-item.spec.tsx b/web/app/components/workflow/run/agent-log/__tests__/agent-log-item.spec.tsx index 50ac08b682c..6dbe4aa4c17 100644 --- a/web/app/components/workflow/run/agent-log/__tests__/agent-log-item.spec.tsx +++ b/web/app/components/workflow/run/agent-log/__tests__/agent-log-item.spec.tsx @@ -1,13 +1,6 @@ -import type { AppContextValue } from '@/context/app-context' import type { AgentLogItemWithChildren } from '@/types/workflow' import { render, screen } from '@testing-library/react' import userEvent from '@testing-library/user-event' -import { - AppContext, - initialLangGeniusVersionInfo, - initialWorkspaceInfo, - userProfilePlaceholder, -} from '@/context/app-context' import AgentLogItem from '../agent-log-item' const createLogItem = (overrides: Partial = {}): AgentLogItemWithChildren => ({ @@ -24,33 +17,6 @@ const createLogItem = (overrides: Partial = {}): Agent ...overrides, }) -const createAppContextValue = (): AppContextValue => { - let value!: AppContextValue - const base = { - userProfile: userProfilePlaceholder, - mutateUserProfile: vi.fn(), - currentWorkspace: { - ...initialWorkspaceInfo, - id: 'workspace-1', - }, - isCurrentWorkspaceManager: false, - isCurrentWorkspaceOwner: false, - isCurrentWorkspaceEditor: false, - isCurrentWorkspaceDatasetOperator: false, - mutateCurrentWorkspace: vi.fn(), - langGeniusVersionInfo: initialLangGeniusVersionInfo, - isLoadingCurrentWorkspace: false, - isValidatingCurrentWorkspace: false, - workspacePermissionKeys: [], - } - const useSelector: AppContextValue['useSelector'] = selector => selector(value) - value = { - ...base, - useSelector, - } - return value -} - describe('AgentLogItem', () => { beforeEach(() => { vi.clearAllMocks() @@ -65,12 +31,10 @@ describe('AgentLogItem', () => { }) render( - - - , + , ) expect(screen.getByText('Planner')).toBeInTheDocument() diff --git a/web/app/components/workflow/run/agent-log/__tests__/agent-result-panel.spec.tsx b/web/app/components/workflow/run/agent-log/__tests__/agent-result-panel.spec.tsx index 7953bfc52a1..3fd64d5fdc8 100644 --- a/web/app/components/workflow/run/agent-log/__tests__/agent-result-panel.spec.tsx +++ b/web/app/components/workflow/run/agent-log/__tests__/agent-result-panel.spec.tsx @@ -1,13 +1,6 @@ -import type { AppContextValue } from '@/context/app-context' import type { AgentLogItemWithChildren } from '@/types/workflow' import { render, screen } from '@testing-library/react' import userEvent from '@testing-library/user-event' -import { - AppContext, - initialLangGeniusVersionInfo, - initialWorkspaceInfo, - userProfilePlaceholder, -} from '@/context/app-context' import AgentResultPanel from '../agent-result-panel' const createLogItem = (overrides: Partial = {}): AgentLogItemWithChildren => ({ @@ -21,33 +14,6 @@ const createLogItem = (overrides: Partial = {}): Agent ...overrides, }) -const createAppContextValue = (): AppContextValue => { - let value!: AppContextValue - const base = { - userProfile: userProfilePlaceholder, - mutateUserProfile: vi.fn(), - currentWorkspace: { - ...initialWorkspaceInfo, - id: 'workspace-1', - }, - isCurrentWorkspaceManager: false, - isCurrentWorkspaceOwner: false, - isCurrentWorkspaceEditor: false, - isCurrentWorkspaceDatasetOperator: false, - mutateCurrentWorkspace: vi.fn(), - langGeniusVersionInfo: initialLangGeniusVersionInfo, - isLoadingCurrentWorkspace: false, - isValidatingCurrentWorkspace: false, - workspacePermissionKeys: [], - } - const useSelector: AppContextValue['useSelector'] = selector => selector(value) - value = { - ...base, - useSelector, - } - return value -} - describe('AgentResultPanel', () => { beforeEach(() => { vi.clearAllMocks() @@ -65,13 +31,11 @@ describe('AgentResultPanel', () => { const top = createLogItem({ message_id: 'top', label: 'Top', hasCircle: true }) render( - - - , + , ) expect(screen.getByText('runLog.circularInvocationTip')).toBeInTheDocument() diff --git a/web/app/signup/set-password/page.tsx b/web/app/signup/set-password/page.tsx index d1b5adc29ab..f0087156a85 100644 --- a/web/app/signup/set-password/page.tsx +++ b/web/app/signup/set-password/page.tsx @@ -79,7 +79,7 @@ const ChangePasswordForm = () => { const utmInfo = parseUtmInfo() rememberCreateAppExternalAttribution({ utmInfo }) // Defer the Amplitude event until the user ID is attached. It is flushed in - // AppContextProvider after setUserId runs once the redirect lands on /apps. + // AppBootstrapEffects after setUserId runs once the redirect lands on /apps. // Firing it here would record it under an anonymous Amplitude profile. rememberRegistrationSuccess({ method: 'email', utmInfo }) diff --git a/web/context/__tests__/app-context-provider.spec.tsx b/web/context/__tests__/app-bootstrap-effects.spec.tsx similarity index 83% rename from web/context/__tests__/app-context-provider.spec.tsx rename to web/context/__tests__/app-bootstrap-effects.spec.tsx index 54bd312a03a..108c2ecf618 100644 --- a/web/context/__tests__/app-context-provider.spec.tsx +++ b/web/context/__tests__/app-bootstrap-effects.spec.tsx @@ -1,17 +1,27 @@ import type { ReactNode } from 'react' import { QueryClient, QueryClientProvider } from '@tanstack/react-query' import { fireEvent, render, screen, waitFor } from '@testing-library/react' -import { Provider as JotaiProvider } from 'jotai' +import { Provider as JotaiProvider, useAtomValue, useSetAtom } from 'jotai' import { queryClientAtom } from 'jotai-tanstack-query' import { useHydrateAtoms } from 'jotai/react/utils' import { Suspense } from 'react' -import { useContext } from 'use-context-selector' import { setUserId, setUserProperties } from '@/app/components/base/amplitude' import { flushRegistrationSuccess } from '@/app/components/base/amplitude/registration-tracking' import { setZendeskConversationFields } from '@/app/components/base/zendesk/utils' import { ZENDESK_FIELD_IDS } from '@/config' -import { AppContext, initialWorkspaceInfo, useSelector } from '../app-context' -import { AppContextProvider } from '../app-context-provider' +import { AppBootstrapEffects } from '../app-bootstrap-effects' +import { initialWorkspaceInfo } from '../app-context-defaults' +import { + currentWorkspaceAtom, + currentWorkspaceLoadingAtom, + langGeniusVersionInfoAtom, + refreshCurrentWorkspaceAtom, + refreshUserProfileAtom, + userProfileAtom, + workspacePermissionKeysAtom, + workspacePermissionKeysLoadingAtom, + workspaceRoleFlagsAtom, +} from '../app-context-state' const mockGetRequest = vi.hoisted(() => vi.fn()) const mockPermissionKeysState = vi.hoisted(() => ({ @@ -158,65 +168,68 @@ vi.mock('@/app/components/header/maintenance-notice', () => ({ })) function AppContextProbe() { - const context = useContext(AppContext) - const selectedWorkspacePermissionKeys = useSelector(state => state.workspacePermissionKeys) + const userProfile = useAtomValue(userProfileAtom) + const currentWorkspace = useAtomValue(currentWorkspaceAtom) + const roleFlags = useAtomValue(workspaceRoleFlagsAtom) + const workspacePermissionKeys = useAtomValue(workspacePermissionKeysAtom) + const isLoadingWorkspacePermissionKeys = useAtomValue(workspacePermissionKeysLoadingAtom) + const isLoadingCurrentWorkspace = useAtomValue(currentWorkspaceLoadingAtom) + const langGeniusVersionInfo = useAtomValue(langGeniusVersionInfoAtom) + const refreshUserProfile = useSetAtom(refreshUserProfileAtom) + const refreshCurrentWorkspace = useSetAtom(refreshCurrentWorkspaceAtom) return ( <> keys: - {selectedWorkspacePermissionKeys.join(',')} + {workspacePermissionKeys.join(',')} permission loading: - {String(context.isLoadingWorkspacePermissionKeys)} + {String(isLoadingWorkspacePermissionKeys)} workspace loading: - {String(context.isLoadingCurrentWorkspace)} - - - workspace validating: - {String(context.isValidatingCurrentWorkspace)} + {String(isLoadingCurrentWorkspace)} user: - {context.userProfile.email} + {userProfile.email} workspace: - {context.currentWorkspace.name} + {currentWorkspace.name} role: - {context.currentWorkspace.role} + {currentWorkspace.role} manager: - {String(context.isCurrentWorkspaceManager)} + {String(roleFlags.isCurrentWorkspaceManager)} owner: - {String(context.isCurrentWorkspaceOwner)} + {String(roleFlags.isCurrentWorkspaceOwner)} editor: - {String(context.isCurrentWorkspaceEditor)} + {String(roleFlags.isCurrentWorkspaceEditor)} dataset operator: - {String(context.isCurrentWorkspaceDatasetOperator)} + {String(roleFlags.isCurrentWorkspaceDatasetOperator)} version: - {context.langGeniusVersionInfo.current_version} + {langGeniusVersionInfo.current_version} / - {context.langGeniusVersionInfo.latest_version} + {langGeniusVersionInfo.latest_version} / - {context.langGeniusVersionInfo.current_env} + {langGeniusVersionInfo.current_env} - - + + ) } @@ -244,16 +257,15 @@ function createTestQueryClient() { }) } -function renderProvider() { +function renderBootstrapEffects() { const queryClient = createTestQueryClient() const view = render( loading}> - - - + + @@ -266,7 +278,7 @@ function renderProvider() { } } -describe('AppContextProvider', () => { +describe('AppBootstrapEffects', () => { beforeEach(() => { vi.clearAllMocks() mockPermissionKeysState.isPending = false @@ -325,16 +337,15 @@ describe('AppContextProvider', () => { }) }) - describe('Context compatibility values', () => { + describe('Bootstrap atoms', () => { it('should provide profile, workspace, permissions, loading state, and version metadata', async () => { - renderProvider() + renderBootstrapEffects() expect(await screen.findByText('user:user@example.com')).toBeInTheDocument() expect(await screen.findByText('workspace:Workspace')).toBeInTheDocument() expect(await screen.findByText('keys:app.create_and_management')).toBeInTheDocument() expect(screen.getByText('permission loading:false')).toBeInTheDocument() expect(screen.getByText('workspace loading:false')).toBeInTheDocument() - expect(screen.getByText('workspace validating:false')).toBeInTheDocument() expect(await screen.findByText('version:1.0.0/1.0.1/cloud')).toBeInTheDocument() }) @@ -349,7 +360,7 @@ describe('AppContextProvider', () => { mockPermissionKeysState.permissionKeys = [] mockLangGeniusVersionState.data = undefined - renderProvider() + renderBootstrapEffects() expect(await screen.findByText('user:')).toBeInTheDocument() expect(screen.getByText(`workspace:${initialWorkspaceInfo.name}`)).toBeInTheDocument() @@ -364,7 +375,7 @@ describe('AppContextProvider', () => { role: 'unsupported-role', } - renderProvider() + renderBootstrapEffects() expect(await screen.findByText(`role:${initialWorkspaceInfo.role}`)).toBeInTheDocument() }) @@ -375,7 +386,7 @@ describe('AppContextProvider', () => { role: 'owner', } - renderProvider() + renderBootstrapEffects() expect(await screen.findByText('manager:true')).toBeInTheDocument() expect(screen.getByText('owner:true')).toBeInTheDocument() @@ -383,21 +394,20 @@ describe('AppContextProvider', () => { expect(screen.getByText('dataset operator:false')).toBeInTheDocument() }) - it('should expose query loading and validating state', async () => { + it('should expose query loading state', async () => { mockPermissionKeysState.isPending = true mockCurrentWorkspaceQueryState.isPending = true - renderProvider() + renderBootstrapEffects() expect(await screen.findByText('workspace loading:true')).toBeInTheDocument() - expect(screen.getByText('workspace validating:true')).toBeInTheDocument() expect(screen.getByText('permission loading:true')).toBeInTheDocument() }) }) describe('Refresh actions', () => { it('should invalidate the source queries when refresh actions are called', async () => { - const { queryClient } = renderProvider() + const { queryClient } = renderBootstrapEffects() const invalidateQueriesSpy = vi.spyOn(queryClient, 'invalidateQueries') fireEvent.click(await screen.findByRole('button', { name: /refresh user/i })) @@ -410,7 +420,7 @@ describe('AppContextProvider', () => { describe('External side effects', () => { it('should sync Zendesk fields and Amplitude identity when bootstrap data is available', async () => { - renderProvider() + renderBootstrapEffects() await waitFor(() => { expect(setZendeskConversationFields).toHaveBeenCalledWith([{ @@ -459,7 +469,7 @@ describe('AppContextProvider', () => { }, } - renderProvider() + renderBootstrapEffects() await screen.findByText('user:') expect(setUserId).not.toHaveBeenCalled() diff --git a/web/context/app-bootstrap-effects.tsx b/web/context/app-bootstrap-effects.tsx new file mode 100644 index 00000000000..0493cfffc99 --- /dev/null +++ b/web/context/app-bootstrap-effects.tsx @@ -0,0 +1,13 @@ +'use client' + +import { + useSyncAmplitudeIdentity, + useSyncZendeskFields, +} from './app-context-effects' + +export function AppBootstrapEffects() { + useSyncZendeskFields() + useSyncAmplitudeIdentity() + + return null +} diff --git a/web/context/app-context-normalizers.ts b/web/context/app-context-normalizers.ts index 244d88fa682..d0fc0faca84 100644 --- a/web/context/app-context-normalizers.ts +++ b/web/context/app-context-normalizers.ts @@ -1,6 +1,6 @@ import type { PostWorkspacesCurrentResponse } from '@dify/contracts/api/console/workspaces/types.gen' import type { ICurrentWorkspace, LangGeniusVersionResponse } from '@/models/common' -import { initialLangGeniusVersionInfo, initialWorkspaceInfo } from './app-context' +import { initialLangGeniusVersionInfo, initialWorkspaceInfo } from './app-context-defaults' const workspaceRoles = new Set(['owner', 'admin', 'editor', 'dataset_operator', 'normal']) diff --git a/web/context/app-context-provider.tsx b/web/context/app-context-provider.tsx deleted file mode 100644 index 64dda2cc753..00000000000 --- a/web/context/app-context-provider.tsx +++ /dev/null @@ -1,68 +0,0 @@ -'use client' - -import type { ReactNode } from 'react' -import { useAtomValue, useSetAtom } from 'jotai' -import { - AppContext, - useSelector, -} from '@/context/app-context' -import { - currentWorkspaceAtom, - currentWorkspaceLoadingAtom, - currentWorkspaceValidatingAtom, - langGeniusVersionInfoAtom, - refreshCurrentWorkspaceAtom, - refreshUserProfileAtom, - userProfileAtom, - workspacePermissionKeysAtom, - workspacePermissionKeysLoadingAtom, - workspaceRoleFlagsAtom, -} from '@/context/app-context-state' -import { - useSyncAmplitudeIdentity, - useSyncZendeskFields, -} from './app-context-effects' - -type AppContextProviderProps = { - children: ReactNode -} - -export function AppContextProvider({ children }: AppContextProviderProps) { - const userProfile = useAtomValue(userProfileAtom) - const currentWorkspace = useAtomValue(currentWorkspaceAtom) - const roleFlags = useAtomValue(workspaceRoleFlagsAtom) - const workspacePermissionKeys = useAtomValue(workspacePermissionKeysAtom) - const langGeniusVersionInfo = useAtomValue(langGeniusVersionInfoAtom) - const isLoadingCurrentWorkspace = useAtomValue(currentWorkspaceLoadingAtom) - const isValidatingCurrentWorkspace = useAtomValue(currentWorkspaceValidatingAtom) - const isLoadingWorkspacePermissionKeys = useAtomValue(workspacePermissionKeysLoadingAtom) - - const refreshUserProfile = useSetAtom(refreshUserProfileAtom) - const refreshCurrentWorkspace = useSetAtom(refreshCurrentWorkspaceAtom) - - useSyncZendeskFields() - useSyncAmplitudeIdentity() - - return ( - { - refreshUserProfile() - }, - langGeniusVersionInfo, - useSelector, - currentWorkspace, - ...roleFlags, - mutateCurrentWorkspace: () => { - refreshCurrentWorkspace() - }, - isLoadingCurrentWorkspace, - isLoadingWorkspacePermissionKeys, - isValidatingCurrentWorkspace, - workspacePermissionKeys, - }} - > - {children} - - ) -} diff --git a/web/context/app-context-state.ts b/web/context/app-context-state.ts index 03081fc1108..a9050275a7b 100644 --- a/web/context/app-context-state.ts +++ b/web/context/app-context-state.ts @@ -119,10 +119,6 @@ export const datasetRbacEnabledAtom = atom((get) => { return get(systemFeaturesAtom).rbac_enabled }) -export const currentWorkspaceValidatingAtom = atom((get) => { - return get(currentWorkspaceQueryAtom).isFetching -}) - const versionQueryAtom = atomWithQuery((get) => { const meta = get(profileMetaAtom) const systemFeaturesQuery = get(systemFeaturesQueryAtom) as SuspenseQueryResult diff --git a/web/context/app-context.ts b/web/context/app-context.ts deleted file mode 100644 index 7606542170b..00000000000 --- a/web/context/app-context.ts +++ /dev/null @@ -1,55 +0,0 @@ -'use client' - -import type { GetAccountProfileResponse } from '@dify/contracts/api/console/account/types.gen' -import type { ICurrentWorkspace, LangGeniusVersionResponse } from '@/models/common' -import { noop } from 'es-toolkit/function' -import { createContext, useContextSelector } from 'use-context-selector' -import { - initialLangGeniusVersionInfo as defaultLangGeniusVersionInfo, - userProfilePlaceholder as defaultUserProfilePlaceholder, - initialWorkspaceInfo as defaultWorkspaceInfo, -} from './app-context-defaults' - -export type AppContextValue = { - userProfile: GetAccountProfileResponse - mutateUserProfile: VoidFunction - currentWorkspace: ICurrentWorkspace - isCurrentWorkspaceManager: boolean - isCurrentWorkspaceOwner: boolean - isCurrentWorkspaceEditor: boolean - isCurrentWorkspaceDatasetOperator: boolean - mutateCurrentWorkspace: VoidFunction - langGeniusVersionInfo: LangGeniusVersionResponse - useSelector: typeof useSelector - isLoadingCurrentWorkspace: boolean - isLoadingWorkspacePermissionKeys?: boolean - isValidatingCurrentWorkspace: boolean - workspacePermissionKeys: string[] -} - -export const userProfilePlaceholder = defaultUserProfilePlaceholder - -export const initialLangGeniusVersionInfo = defaultLangGeniusVersionInfo - -export const initialWorkspaceInfo = defaultWorkspaceInfo - -export const AppContext = createContext({ - userProfile: userProfilePlaceholder, - currentWorkspace: initialWorkspaceInfo, - isCurrentWorkspaceManager: false, - isCurrentWorkspaceOwner: false, - isCurrentWorkspaceEditor: false, - isCurrentWorkspaceDatasetOperator: false, - mutateUserProfile: noop, - mutateCurrentWorkspace: noop, - langGeniusVersionInfo: initialLangGeniusVersionInfo, - useSelector, - isLoadingCurrentWorkspace: false, - isLoadingWorkspacePermissionKeys: false, - isValidatingCurrentWorkspace: false, - workspacePermissionKeys: [], -}) - -export function useSelector(selector: (value: AppContextValue) => T): T { - return useContextSelector(AppContext, selector) -} diff --git a/web/context/modal-context.test.tsx b/web/context/modal-context.test.tsx index 3ff7480a6d5..30879b6c05e 100644 --- a/web/context/modal-context.test.tsx +++ b/web/context/modal-context.test.tsx @@ -48,9 +48,6 @@ vi.mock('@/context/provider-context', () => ({ })) const mockUseAppContext = vi.fn() -vi.mock('@/context/app-context', () => ({ - useAppContext: () => mockUseAppContext(), -})) vi.mock('@/context/app-context-state', async (importOriginal) => { const { createAppContextStateAtomMock } = await import('@/__tests__/utils/mock-app-context-state') diff --git a/web/features/agent-v2/agent-detail/access/components/__tests__/access-surface-cards.spec.tsx b/web/features/agent-v2/agent-detail/access/components/__tests__/access-surface-cards.spec.tsx index 9af16c2a58f..32cb20138bb 100644 --- a/web/features/agent-v2/agent-detail/access/components/__tests__/access-surface-cards.spec.tsx +++ b/web/features/agent-v2/agent-detail/access/components/__tests__/access-surface-cards.spec.tsx @@ -43,14 +43,6 @@ vi.mock('@/app/components/base/chat/embedded-chatbot/theme/theme-context', () => }), })) -vi.mock('@/context/app-context', () => ({ - useAppContext: () => ({ - langGeniusVersionInfo: { - current_env: 'PRODUCTION', - }, - }), -})) - vi.mock('@/context/app-context-state', async (importOriginal) => { const { createAppContextStateAtomMock } = await import('@/__tests__/utils/mock-app-context-state') diff --git a/web/features/tag-management/__tests__/tag-filter.spec.tsx b/web/features/tag-management/__tests__/tag-filter.spec.tsx index dd2e31b74e5..bb9e0c058b4 100644 --- a/web/features/tag-management/__tests__/tag-filter.spec.tsx +++ b/web/features/tag-management/__tests__/tag-filter.spec.tsx @@ -15,12 +15,6 @@ vi.mock('@tanstack/react-query', () => ({ useQuery: () => ({ data: mockUseQueryData.current }), })) -vi.mock('@/context/app-context', () => ({ - useSelector: (selector: (state: { workspacePermissionKeys: string[] }) => unknown) => selector({ - workspacePermissionKeys: mockWorkspacePermissionKeys.value, - }), -})) - vi.mock('@/context/app-context-state', async (importOriginal) => { const { createAppContextStateAtomMock } = await import('@/__tests__/utils/mock-app-context-state') diff --git a/web/features/tag-management/__tests__/tag-management-modal.spec.tsx b/web/features/tag-management/__tests__/tag-management-modal.spec.tsx index a3b91cae337..ed5534ea741 100644 --- a/web/features/tag-management/__tests__/tag-management-modal.spec.tsx +++ b/web/features/tag-management/__tests__/tag-management-modal.spec.tsx @@ -44,12 +44,6 @@ vi.mock('@tanstack/react-query', () => ({ }), })) -vi.mock('@/context/app-context', () => ({ - useSelector: (selector: (state: { workspacePermissionKeys: string[] }) => T): T => selector({ - workspacePermissionKeys: mockWorkspacePermissionKeys.value, - }), -})) - vi.mock('@/context/app-context-state', async (importOriginal) => { const { createAppContextStateAtomMock } = await import('@/__tests__/utils/mock-app-context-state') diff --git a/web/features/tag-management/__tests__/tag-search-content.spec.tsx b/web/features/tag-management/__tests__/tag-search-content.spec.tsx index 7b5f482c768..8f682a58640 100644 --- a/web/features/tag-management/__tests__/tag-search-content.spec.tsx +++ b/web/features/tag-management/__tests__/tag-search-content.spec.tsx @@ -15,12 +15,6 @@ const mockWorkspacePermissionKeys = vi.hoisted(() => ({ value: ['app.tag.manage', 'dataset.tag.manage'] as string[], })) -vi.mock('@/context/app-context', () => ({ - useSelector: (selector: (state: { workspacePermissionKeys: string[] }) => unknown) => selector({ - workspacePermissionKeys: mockWorkspacePermissionKeys.value, - }), -})) - vi.mock('@/context/app-context-state', async (importOriginal) => { const { createAppContextStateAtomMock } = await import('@/__tests__/utils/mock-app-context-state') diff --git a/web/features/tag-management/__tests__/tag-selector.spec.tsx b/web/features/tag-management/__tests__/tag-selector.spec.tsx index cabdb86b6ec..819e25a517e 100644 --- a/web/features/tag-management/__tests__/tag-selector.spec.tsx +++ b/web/features/tag-management/__tests__/tag-selector.spec.tsx @@ -33,12 +33,6 @@ const mockWorkspacePermissionKeys = vi.hoisted(() => ({ value: ['app.tag.manage', 'dataset.tag.manage', 'snippets.create_and_modify'] as string[], })) -vi.mock('@/context/app-context', () => ({ - useSelector: (selector: (state: { workspacePermissionKeys: string[] }) => T): T => selector({ - workspacePermissionKeys: mockWorkspacePermissionKeys.value, - }), -})) - vi.mock('@/context/app-context-state', async (importOriginal) => { const { createAppContextStateAtomMock } = await import('@/__tests__/utils/mock-app-context-state') diff --git a/web/hooks/use-timestamp.spec.ts b/web/hooks/use-timestamp.spec.ts index ab8127b88ce..98c0587f4c8 100644 --- a/web/hooks/use-timestamp.spec.ts +++ b/web/hooks/use-timestamp.spec.ts @@ -6,25 +6,6 @@ import { userProfileQueryOptions } from '@/features/account-profile/client' import { createAccountProfileQueryWrapper } from '@/test/account-profile-query' import useTimestamp from './use-timestamp' -vi.mock('@/context/app-context', () => ({ - useAppContext: vi.fn(() => ({ - userProfile: { - id: '8b18e24b-1ac8-4262-aa5c-e9aa95c76846', - name: 'test', - avatar: null, - avatar_url: null, - email: 'test@dify.ai', - is_password_set: false, - interface_language: 'zh-Hans', - interface_theme: 'light', - timezone: 'Asia/Shanghai', - last_login_at: 1744188761, - last_login_ip: '127.0.0.1', - created_at: 1728444483, - }, - })), -})) - const createEmptyQueryWrapper = () => { const queryClient = new QueryClient({ defaultOptions: {