import { render, screen, waitFor } from '@testing-library/react'; import { beforeEach, describe, expect, it, vi } from 'vitest'; import { MemoryRouter, Outlet } from 'react-router-dom'; import App from '@/App'; import { useAuthStore } from '@/stores/auth'; import { useProviderStore } from '@/stores/providers'; import { useSettingsStore } from '@/stores/settings'; import { useUserSyncStore } from '@/stores/user-sync'; vi.mock('@/components/layout/MainLayout', () => ({ MainLayout: () => , })); vi.mock('@/pages/AiHardware', () => ({ AiHardware: () =>
Robot workspace
, })); vi.mock('@/pages/ImageCanvas', () => ({ ImageCanvas: () =>
Canvas workspace
, })); vi.mock('@/pages/Chat', () => ({ Chat: () =>
Programming workspace
, })); vi.mock('@/pages/ModuleSelection', () => ({ ModuleSelection: () =>
Module chooser
, })); describe('App programming provider initialization gate', () => { const initProviders = vi.fn(); beforeEach(() => { vi.clearAllMocks(); window.electron.imageWorkspaceLocalDevelopment = false; useSettingsStore.setState({ setupComplete: true, init: vi.fn(), }); useProviderStore.setState({ init: initProviders }); useAuthStore.setState({ initialized: true, accessToken: 'access-token', expiresAt: Date.now() + 60_000, user: { username: 'robot-tester', userId: '1', tenantId: null, deptId: null, authorities: [], }, moduleAccess: { programming: true, design: true, learning: true, robot: true, }, init: vi.fn(), }); useUserSyncStore.setState({ bootstrap: vi.fn().mockResolvedValue(undefined) }); }); async function renderAt(pathname: string) { render( , ); await waitFor(() => expect(useSettingsStore.getState().init).toHaveBeenCalled()); } it.each(['/ai-hardware', '/image-canvas', '/module-select'])( 'does not initialize programming providers at %s', async (pathname) => { await renderAt(pathname); expect(initProviders).not.toHaveBeenCalled(); }, ); it('initializes programming providers at the explicit programming route', async () => { await renderAt('/opencode-chat'); await waitFor(() => expect(initProviders).toHaveBeenCalledTimes(1)); }); it.each([ ['/opencode-chat', 'programming'], ['/image-canvas', 'design'], ['/learning', 'learning'], ['/ai-hardware', 'robot'], ] as const)('redirects disabled %s routes before mounting their module', async (pathname, accessKey) => { useAuthStore.setState({ moduleAccess: { programming: true, design: true, learning: true, robot: true, [accessKey]: false, }, }); await renderAt(pathname); expect(await screen.findByText('Module chooser')).toBeInTheDocument(); if (accessKey === 'programming') { expect(initProviders).not.toHaveBeenCalled(); } }); });