refactor(web): remove app context provider (#38568)

This commit is contained in:
Stephen Zhou 2026-07-08 21:52:45 +08:00 committed by GitHub
parent eb3362e646
commit 23b936aeb5
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
171 changed files with 182 additions and 1669 deletions

View File

@ -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: <T,>(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()

View File

@ -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<string, string>) => {
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()

View File

@ -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()

View File

@ -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)

View File

@ -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')

View File

@ -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)

View File

@ -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)

View File

@ -20,10 +20,6 @@ let mockAppCtx: Record<string, unknown> = {}
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)

View File

@ -28,16 +28,6 @@ const mockMutateDatasets = vi.fn()
const mockInvalidDatasetList = vi.fn()
const mockUpdateDatasetSetting = vi.fn().mockResolvedValue({})
vi.mock('@/context/app-context', () => ({
useSelector: <T,>(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),
}))

View File

@ -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}`),

View File

@ -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}`),

View File

@ -118,11 +118,6 @@ vi.mock('@/service/client', () => ({
},
}))
vi.mock('@/context/app-context', () => ({
useAppContext: mockUseAppContext,
useSelector: <T,>(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')

View File

@ -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)

View File

@ -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(' '),
}))

View File

@ -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, () => ({

View File

@ -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: [

View File

@ -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(),

View File

@ -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, () => ({

View File

@ -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<ICurrentWorkspace>) | null
isCurrentWorkspaceManager?: boolean
isCurrentWorkspaceOwner?: boolean
isCurrentWorkspaceEditor?: boolean
@ -25,6 +25,8 @@ export type AppContextStateMockState = {
langGeniusVersionInfo?: Partial<LangGeniusVersionResponse>
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,
})

View File

@ -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,
}))

View File

@ -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: () => <div>api key info panel</div>,
}))

View File

@ -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: {

View File

@ -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')

View File

@ -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')

View File

@ -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({
<NextRouteStateBridge>
<div className="flex h-full flex-col overflow-hidden">
<MaintenanceNotice />
<AppContextProvider>
<EventEmitterContextProvider>
<ProviderContextProvider>
<ModalContextProvider>
<MainNavLayout detailSidebar={detailSidebar}>
{children}
</MainNavLayout>
<CommonLayoutGlobalMounts />
</ModalContextProvider>
</ProviderContextProvider>
</EventEmitterContextProvider>
</AppContextProvider>
<AppBootstrapEffects />
<EventEmitterContextProvider>
<ProviderContextProvider>
<ModalContextProvider>
<MainNavLayout detailSidebar={detailSidebar}>
{children}
</MainNavLayout>
<CommonLayoutGlobalMounts />
</ModalContextProvider>
</ProviderContextProvider>
</EventEmitterContextProvider>
</div>
</NextRouteStateBridge>
</CommonLayoutHydrationBoundary>

View File

@ -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 })

View File

@ -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()

View File

@ -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 }
<CommonLayoutHydrationBoundary>
<div className="flex h-full flex-col overflow-hidden bg-background-body">
<MaintenanceNotice />
<AppContextProvider>
<EventEmitterContextProvider>
<ProviderContextProvider>
<ModalContextProvider>
<HeaderWrapper>
<Header />
</HeaderWrapper>
<div className="relative flex h-0 min-h-0 shrink-0 grow flex-col overflow-y-auto bg-components-panel-bg">
{children}
</div>
</ModalContextProvider>
</ProviderContextProvider>
</EventEmitterContextProvider>
</AppContextProvider>
<AppBootstrapEffects />
<EventEmitterContextProvider>
<ProviderContextProvider>
<ModalContextProvider>
<HeaderWrapper>
<Header />
</HeaderWrapper>
<div className="relative flex h-0 min-h-0 shrink-0 grow flex-col overflow-y-auto bg-components-panel-bg">
{children}
</div>
</ModalContextProvider>
</ProviderContextProvider>
</EventEmitterContextProvider>
</div>
</CommonLayoutHydrationBoundary>
</React.Fragment>

View File

@ -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')

View File

@ -23,19 +23,6 @@ const intersectionObserverMocks = vi.hoisted(() => ({
callback: null as null | ((entries: Array<{ isIntersecting: boolean }>) => void),
}))
vi.mock('@/context/app-context', () => ({
useSelector: <T,>(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),

View File

@ -10,14 +10,6 @@ const intersectionObserverMocks = vi.hoisted(() => ({
callback: null as null | ((entries: Array<{ isIntersecting: boolean }>) => void),
}))
vi.mock('@/context/app-context', () => ({
useSelector: <T,>(selector: (value: { userProfile: { email: string } }) => T) => selector({
userProfile: {
email: 'member@example.com',
},
}),
}))
vi.mock('@/service/access-control', () => ({
useSearchForWhiteListCandidates: (...args: unknown[]) => mockUseSearchForWhiteListCandidates(...args),
}))

View File

@ -107,15 +107,6 @@ vi.mock('@/service/use-tools', () => ({
useInvalidateWorkflowToolDetailByAppID: () => vi.fn(),
}))
vi.mock('@/context/app-context', () => ({
useAppContext: () => ({
isCurrentWorkspaceManager: true,
}),
useSelector: <T,>(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, () => ({

View File

@ -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')

View File

@ -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')

View File

@ -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: <T,>(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,

View File

@ -29,10 +29,6 @@ let capturedChatProps: {
let eventSubscriptionCallback: ((v: { type: string, payload?: Record<string, unknown> }) => void) | null = null
vi.mock('@/context/app-context', () => ({
useAppContext: () => mockUseAppContext(),
}))
vi.mock('@/context/debug-configuration', () => ({
useDebugConfigurationContext: () => mockUseDebugConfigurationContext(),
}))

View File

@ -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[] }

View File

@ -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')

View File

@ -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(<Apps />)
@ -239,7 +229,6 @@ describe('Apps', () => {
})
it('does not allow template creation when app.create_and_management permission is missing', () => {
mockIsCurrentWorkspaceEditor = true
mockWorkspacePermissionKeys = []
render(<Apps />)

View File

@ -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')

View File

@ -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')

View File

@ -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}`,

View File

@ -14,16 +14,6 @@ vi.mock('react-i18next', () => ({
}),
}))
vi.mock('@/context/app-context', () => ({
useAppContext: () => ({
isCurrentWorkspaceEditor: true,
}),
useSelector: <T,>(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}`,
}))

View File

@ -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

View File

@ -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,

View File

@ -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 }) => (

View File

@ -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')

View File

@ -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')

View File

@ -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')

View File

@ -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')

View File

@ -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<string, unknown> | null },

View File

@ -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<typeof import('@/context/app-context')>()
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', () => {

View File

@ -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<ProviderContextState> = {}): Pr
...overrides,
})
const buildAppContext = (overrides: Partial<AppContextValue> = {}): AppContextValue => {
const buildAppContext = (overrides: Partial<AppContextStateMockState> = {}): AppContextStateMockState => {
const userProfile: GetAccountProfileResponse = {
id: 'user-id',
name: 'Test User',
@ -109,7 +105,7 @@ const buildAppContext = (overrides: Partial<AppContextValue> = {}): AppContextVa
version: '',
can_auto_update: false,
}
const base: Omit<AppContextValue, 'useSelector'> = {
const base: AppContextStateMockState = {
userProfile,
currentWorkspace,
isCurrentWorkspaceManager: false,
@ -120,13 +116,10 @@ const buildAppContext = (overrides: Partial<AppContextValue> = {}): AppContextVa
mutateCurrentWorkspace: vi.fn(),
langGeniusVersionInfo,
isLoadingCurrentWorkspace: false,
isValidatingCurrentWorkspace: false,
workspacePermissionKeys: [],
}
const useSelector: AppContextValue['useSelector'] = selector => selector({ ...base, useSelector })
return {
...base,
useSelector,
...overrides,
}
}

View File

@ -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, () => ({

View File

@ -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, () => ({

View File

@ -44,10 +44,6 @@ vi.mock('../footer', () => ({
default: () => <div>footer</div>,
}))
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)

View File

@ -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)

View File

@ -14,10 +14,6 @@ import CloudPlanItem from '../index'
let mockAppCtx: Record<string, unknown> = {}
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)

View File

@ -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)

View File

@ -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<typeof import('@/context/app-context')>()
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: [],
})

View File

@ -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<typeof import('@/context/app-context')>()
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> = {}): AppContextValue => {
const createAppContextValue = (overrides: Partial<AppContextStateMockState> = {}): AppContextStateMockState => {
const { currentWorkspace: currentWorkspaceOverride, ...restOverrides } = overrides
const workspaceOverrides: Partial<AppContextValue['currentWorkspace']> = currentWorkspaceOverride ?? {}
const workspaceOverrides: Partial<AppContextStateMockState['currentWorkspace']> = currentWorkspaceOverride ?? {}
const currentWorkspace = {
...initialWorkspaceInfo,
...workspaceOverrides,
@ -125,17 +119,15 @@ const createAppContextValue = (overrides: Partial<AppContextValue> = {}): 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')

View File

@ -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')

View File

@ -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')

View File

@ -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')

View File

@ -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')

View File

@ -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')

View File

@ -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'),
}))

View File

@ -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')

View File

@ -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')

View File

@ -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')

View File

@ -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')

View File

@ -20,10 +20,6 @@ const render = (ui: Parameters<typeof renderWithSystemFeatures>[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')

View File

@ -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')

View File

@ -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')

View File

@ -16,13 +16,6 @@ const { mockToastSuccess, mockToastError } = vi.hoisted(() => ({
const mockMutateDatasets = vi.fn()
const mockInvalidDatasetList = vi.fn()
vi.mock('@/context/app-context', () => ({
useSelector: <T>(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')

View File

@ -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')

View File

@ -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,

View File

@ -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)
}

View File

@ -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<typeof import('@/context/app-context')>()
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: () => <div data-testid="access-rules-page" />,
}))
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

View File

@ -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, () => ({

View File

@ -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, () => ({

View File

@ -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, () => ({

View File

@ -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<AppContextValue>,
current: {} as Partial<AppContextStateMockState>,
}))
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>): 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()

View File

@ -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', () => {

View File

@ -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<AppContextValue>,
current: {} as Partial<AppContextStateMockState>,
}))
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)

View File

@ -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<AppContextValue>,
current: {} as Partial<AppContextStateMockState>,
}))
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()

View File

@ -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<AppContextValue>,
current: {} as Partial<AppContextStateMockState>,
}))
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)

View File

@ -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, () => ({

View File

@ -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, () => ({

View File

@ -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, () => ({

View File

@ -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, () => ({

View File

@ -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<string, string>) => value[mockLanguage] || value.en_US,
}))

View File

@ -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, () => ({

View File

@ -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')

View File

@ -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, () => ({

View File

@ -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, () => ({

View File

@ -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, () => ({

View File

@ -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: <T,>(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, () => ({

View File

@ -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, () => ({

View File

@ -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, () => ({

Some files were not shown because too many files have changed in this diff Show More