dify/web/app/components/plugins/plugin-page/context.spec.tsx
yyh 915a6cc090
refactor!: replace Zustand global store with TanStack Query for systemFeatures
Follow-up to SSR prefetch migration. Eliminates the Zustand middleman
that was syncing TanStack Query data into a separate store.

- Remove useGlobalPublicStore Zustand store entirely
- Create hooks/use-global-public.ts with useSystemFeatures,
  useSystemFeaturesQuery, useIsSystemFeaturesPending, useSetupStatusQuery
- Migrate all consumers to import from @/hooks/use-global-public
- Simplify global-public-context.tsx to a thin provider component
- Update test files to mock the new hook interface
- Fix SetupStatusResponse.setup_at type from Date to string (JSON)
- Fix setup-status.spec.ts mock target to match consoleClient
- Regenerate eslint-suppressions.json for main branch

BREAKING CHANGE: useGlobalPublicStore is removed. Use useSystemFeatures()
from @/hooks/use-global-public instead.
2026-02-01 19:14:58 +08:00

123 lines
3.7 KiB
TypeScript

import { render, screen } from '@testing-library/react'
import { beforeEach, describe, expect, it, vi } from 'vitest'
// Import mocks
import { useSystemFeatures } from '@/hooks/use-global-public'
import { PluginPageContext, PluginPageContextProvider, usePluginPageContext } from './context'
// Mock dependencies
vi.mock('nuqs', () => ({
useQueryState: vi.fn(() => ['plugins', vi.fn()]),
}))
vi.mock('@/context/global-public-context', () => ({
useSystemFeatures: vi.fn(),
}))
vi.mock('../hooks', () => ({
PLUGIN_PAGE_TABS_MAP: {
plugins: 'plugins',
marketplace: 'discover',
},
usePluginPageTabs: () => [
{ value: 'plugins', text: 'Plugins' },
{ value: 'discover', text: 'Explore Marketplace' },
],
}))
// Helper function to mock useSystemFeatures with marketplace setting
const mockGlobalPublicStore = (enableMarketplace: boolean) => {
vi.mocked(useSystemFeatures).mockReturnValue({
enable_marketplace: enableMarketplace,
} as ReturnType<typeof useSystemFeatures>)
}
// Test component that uses the context
const TestConsumer = () => {
const containerRef = usePluginPageContext(v => v.containerRef)
const options = usePluginPageContext(v => v.options)
const activeTab = usePluginPageContext(v => v.activeTab)
return (
<div>
<span data-testid="has-container-ref">{containerRef ? 'true' : 'false'}</span>
<span data-testid="options-count">{options.length}</span>
<span data-testid="active-tab">{activeTab}</span>
{options.map((opt: { value: string, text: string }) => (
<span key={opt.value} data-testid={`option-${opt.value}`}>{opt.text}</span>
))}
</div>
)
}
describe('PluginPageContext', () => {
beforeEach(() => {
vi.clearAllMocks()
})
describe('PluginPageContextProvider', () => {
it('should provide context values to children', () => {
mockGlobalPublicStore(true)
render(
<PluginPageContextProvider>
<TestConsumer />
</PluginPageContextProvider>,
)
expect(screen.getByTestId('has-container-ref')).toHaveTextContent('true')
expect(screen.getByTestId('options-count')).toHaveTextContent('2')
})
it('should include marketplace tab when enable_marketplace is true', () => {
mockGlobalPublicStore(true)
render(
<PluginPageContextProvider>
<TestConsumer />
</PluginPageContextProvider>,
)
expect(screen.getByTestId('option-plugins')).toBeInTheDocument()
expect(screen.getByTestId('option-discover')).toBeInTheDocument()
})
it('should filter out marketplace tab when enable_marketplace is false', () => {
mockGlobalPublicStore(false)
render(
<PluginPageContextProvider>
<TestConsumer />
</PluginPageContextProvider>,
)
expect(screen.getByTestId('option-plugins')).toBeInTheDocument()
expect(screen.queryByTestId('option-discover')).not.toBeInTheDocument()
expect(screen.getByTestId('options-count')).toHaveTextContent('1')
})
})
describe('usePluginPageContext', () => {
it('should select specific context values', () => {
mockGlobalPublicStore(true)
render(
<PluginPageContextProvider>
<TestConsumer />
</PluginPageContextProvider>,
)
// activeTab should be 'plugins' from the mock
expect(screen.getByTestId('active-tab')).toHaveTextContent('plugins')
})
})
describe('Default Context Values', () => {
it('should have empty options by default from context', () => {
// Test that the context has proper default values by checking the exported constant
// The PluginPageContext is created with default values including empty options array
expect(PluginPageContext).toBeDefined()
})
})
})