UNPKG

mod-arch-shared

Version:

Shared library for modular architecture micro-frontend projects

167 lines 10.3 kB
import '@testing-library/jest-dom'; import * as React from 'react'; import { render, screen, act } from '@testing-library/react'; import useNamespaces from '../../hooks/useNamespaces'; import { useModularArchContext } from '../../hooks/useModularArchContext'; import { ModularArchContext } from '../../context/ModularArchContext'; import { NamespaceSelectorContext, NamespaceSelectorContextProvider, } from '../../context/NamespaceSelectorContext'; import { DeploymentMode, PlatformMode } from '../../utilities'; // Mock the hooks and utilities jest.mock('~/hooks/useNamespaces'); jest.mock('~/hooks/useModularArchContext'); // jest.mock('~/utilities/const'); // Ensure this old mock is removed or commented out const mockNamespaces = [{ name: 'namespace-2' }, { name: 'namespace-3' }, { name: 'namespace-1' }]; // Helper component to provide ModularArchContext const MockModularArchContextProvider = ({ deploymentMode, platformMode, children }) => { const mockContextValue = React.useMemo(() => ({ config: { deploymentMode, platformMode, URL_PREFIX: 'model-registry', BFF_API_VERSION: 'v1', }, }), [deploymentMode, platformMode]); // Mock the hook to return just the config, not the entire context useModularArchContext.mockReturnValue(mockContextValue.config); return (React.createElement(ModularArchContext.Provider, { value: mockContextValue }, children)); }; describe('NamespaceSelectorContext', () => { const TestConsumer = () => { const { namespaces, namespacesLoaded, namespacesLoadError, preferredNamespace, initializationError, } = React.useContext(NamespaceSelectorContext); return (React.createElement("div", null, React.createElement("div", { "data-testid": "loading-state" }, namespacesLoaded.toString()), React.createElement("div", { "data-testid": "error-state" }, namespacesLoadError?.message || 'no-error'), React.createElement("div", { "data-testid": "init-error" }, initializationError?.message || 'no-init-error'), React.createElement("div", { "data-testid": "namespaces" }, namespaces.map((ns) => ns.name).join(',')), React.createElement("div", { "data-testid": "preferred" }, preferredNamespace?.name || 'none'))); }; beforeEach(() => { jest.clearAllMocks(); // Reset global window.centraldashboard delete global.window.centraldashboard; }); it('should provide initial empty state', () => { useNamespaces.mockReturnValue([[], true, undefined]); render(React.createElement(MockModularArchContextProvider, { deploymentMode: DeploymentMode.Standalone, platformMode: PlatformMode.Default }, React.createElement(NamespaceSelectorContextProvider, null, React.createElement(TestConsumer, null)))); expect(screen.getByTestId('loading-state')).toHaveTextContent('true'); expect(screen.getByTestId('error-state')).toHaveTextContent('no-error'); expect(screen.getByTestId('namespaces')).toHaveTextContent(''); expect(screen.getByTestId('preferred')).toHaveTextContent('none'); }); it('should load namespaces and set first namespace as preferred when not integrated', () => { useNamespaces.mockReturnValue([mockNamespaces, true, undefined]); render(React.createElement(MockModularArchContextProvider, { deploymentMode: DeploymentMode.Standalone, platformMode: PlatformMode.Default }, React.createElement(NamespaceSelectorContextProvider, null, React.createElement(TestConsumer, null)))); expect(screen.getByTestId('loading-state')).toHaveTextContent('true'); expect(screen.getByTestId('error-state')).toHaveTextContent('no-error'); expect(screen.getByTestId('namespaces')).toHaveTextContent('namespace-1,namespace-2,namespace-3'); expect(screen.getByTestId('preferred')).toHaveTextContent('namespace-1'); }); it('should handle errors during namespace loading', () => { const error = new Error('Failed to load namespaces'); useNamespaces.mockReturnValue([[], true, error]); render(React.createElement(MockModularArchContextProvider, { deploymentMode: DeploymentMode.Standalone, platformMode: PlatformMode.Default }, React.createElement(NamespaceSelectorContextProvider, null, React.createElement(TestConsumer, null)))); expect(screen.getByTestId('loading-state')).toHaveTextContent('true'); expect(screen.getByTestId('error-state')).toHaveTextContent('Failed to load namespaces'); expect(screen.getByTestId('namespaces')).toHaveTextContent(''); expect(screen.getByTestId('preferred')).toHaveTextContent('none'); }); it('should initialize central dashboard client when integrated', () => { useNamespaces.mockReturnValue([mockNamespaces, true, undefined]); // Mock window.centraldashboard before rendering const mockInit = jest.fn((callback) => { // Simulate the callback being called callback({ onNamespaceSelected: jest.fn(), }); }); global.window.centraldashboard = { CentralDashboardEventHandler: { init: mockInit, }, }; render(React.createElement(MockModularArchContextProvider, { deploymentMode: DeploymentMode.Integrated, platformMode: PlatformMode.Kubeflow }, React.createElement(NamespaceSelectorContextProvider, null, React.createElement(TestConsumer, null)))); expect(mockInit).toHaveBeenCalled(); expect(screen.getByTestId('preferred')).toHaveTextContent('namespace-1'); }); it('should update preferred namespace when selected', () => { useNamespaces.mockReturnValue([mockNamespaces, true, undefined]); const TestUpdater = () => { const { updatePreferredNamespace } = React.useContext(NamespaceSelectorContext); React.useEffect(() => { act(() => { updatePreferredNamespace({ name: 'namespace-2' }); }); }, [updatePreferredNamespace]); return null; }; render(React.createElement(MockModularArchContextProvider, { deploymentMode: DeploymentMode.Standalone, platformMode: PlatformMode.Default }, React.createElement(NamespaceSelectorContextProvider, null, React.createElement(TestConsumer, null), React.createElement(TestUpdater, null)))); expect(screen.getByTestId('preferred')).toHaveTextContent('namespace-2'); }); it('should handle central dashboard initialization failure gracefully', () => { useNamespaces.mockReturnValue([mockNamespaces, true, undefined]); // Mock console.error to avoid test output noise const consoleSpy = jest.spyOn(console, 'error').mockImplementation(); // Mock window.centraldashboard with an init function that throws an error BEFORE rendering const error = new Error('Central dashboard initialization failed'); global.window.centraldashboard = { CentralDashboardEventHandler: { init: () => { throw error; }, }, }; render(React.createElement(MockModularArchContextProvider, { deploymentMode: DeploymentMode.Integrated, platformMode: PlatformMode.Kubeflow }, React.createElement(NamespaceSelectorContextProvider, null, React.createElement(TestConsumer, null)))); expect(consoleSpy).toHaveBeenCalledWith('Failed to initialize central dashboard client', error); expect(screen.getByTestId('init-error')).toHaveTextContent('Central dashboard initialization failed'); expect(screen.getByTestId('preferred')).toHaveTextContent('namespace-1'); consoleSpy.mockRestore(); }); it('should reflect loading state changes', async () => { // Start with loading state useNamespaces.mockReturnValue([[], false, undefined]); const { rerender } = render(React.createElement(MockModularArchContextProvider, { deploymentMode: DeploymentMode.Standalone, platformMode: PlatformMode.Default }, React.createElement(NamespaceSelectorContextProvider, null, React.createElement(TestConsumer, null)))); expect(screen.getByTestId('loading-state')).toHaveTextContent('false'); // Update to loaded state useNamespaces.mockReturnValue([mockNamespaces, true, undefined]); rerender(React.createElement(MockModularArchContextProvider, { deploymentMode: DeploymentMode.Standalone, platformMode: PlatformMode.Default }, React.createElement(NamespaceSelectorContextProvider, null, React.createElement(TestConsumer, null)))); expect(screen.getByTestId('loading-state')).toHaveTextContent('true'); expect(screen.getByTestId('namespaces')).toHaveTextContent('namespace-1,namespace-2,namespace-3'); }); it('should handle multiple namespace updates correctly', () => { useNamespaces.mockReturnValue([mockNamespaces, true, undefined]); const TestMultipleUpdates = () => { const { updatePreferredNamespace } = React.useContext(NamespaceSelectorContext); React.useEffect(() => { act(() => { updatePreferredNamespace({ name: 'namespace-2' }); updatePreferredNamespace({ name: 'namespace-3' }); updatePreferredNamespace({ name: 'namespace-1' }); }); }, [updatePreferredNamespace]); return null; }; render(React.createElement(MockModularArchContextProvider, { deploymentMode: DeploymentMode.Standalone, platformMode: PlatformMode.Default }, React.createElement(NamespaceSelectorContextProvider, null, React.createElement(TestConsumer, null), React.createElement(TestMultipleUpdates, null)))); expect(screen.getByTestId('preferred')).toHaveTextContent('namespace-1'); }); }); //# sourceMappingURL=NamespaceSelectorContext.test.js.map