import { renderHook } from '@testing-library/react' import { waitFor } from '@testing-library/dom' import { describe, expect, it, vi } from 'vitest' import { useWorkbenchBootstrap } from './useWorkbenchBootstrap' function action() { return vi.fn().mockResolvedValue(undefined) } function options(selectedProjectId: string | null, activeWorkspace = 'map') { return { activeWorkspace, selectedProjectId, selectedDetectionRunId: '', detectionClassFilter: '', detectionMinConfidenceFilter: 0, selectedSegmentationRunId: '', segmentationClassFilter: '', segmentationMinConfidenceFilter: 0, loadProjects: action(), loadCapabilities: action(), loadDetectionModels: action(), loadSegmentationModels: action(), loadProjectData: action(), loadDetectionRuns: action(), loadSegmentationRuns: action(), loadQualityChecks: action(), loadExports: action(), loadDetectionResults: action(), loadSegmentationResults: action(), resetProjectData: vi.fn(), resetDatasetForProject: vi.fn(), resetDetectionForProject: vi.fn(), resetSegmentationForProject: vi.fn(), resetExportsForProject: vi.fn(), } } describe('useWorkbenchBootstrap', () => { it('haalt zonder project alleen de werkruimtes op en wist projectgebonden state', async () => { const state = options(null) renderHook(() => useWorkbenchBootstrap(state)) await waitFor(() => expect(state.loadProjects).toHaveBeenCalledOnce()) expect(state.resetProjectData).toHaveBeenCalledOnce() expect(state.resetDatasetForProject).toHaveBeenCalledOnce() expect(state.loadProjectData).not.toHaveBeenCalled() }) it('laadt op het kaartwerkblad de gebieden en bronnen, en verder niets', async () => { const state = options('project-1') renderHook(() => useWorkbenchBootstrap(state)) await waitFor(() => expect(state.loadProjectData).toHaveBeenCalledWith('project-1')) expect(state.resetProjectData).toHaveBeenCalledOnce() expect(state.resetDatasetForProject).toHaveBeenCalledOnce() expect(state.resetDetectionForProject).toHaveBeenCalledOnce() expect(state.resetSegmentationForProject).toHaveBeenCalledOnce() expect(state.resetExportsForProject).toHaveBeenCalledOnce() // Alles wat bij een ander werkblad hoort blijft liggen tot dat werkblad // geopend wordt. Voorheen ging dit alles bij het opstarten de deur uit, // ook voor werkbladen die de gebruiker nooit opende. expect(state.loadCapabilities).not.toHaveBeenCalled() expect(state.loadDetectionModels).not.toHaveBeenCalled() expect(state.loadSegmentationModels).not.toHaveBeenCalled() expect(state.loadDetectionRuns).not.toHaveBeenCalled() expect(state.loadSegmentationRuns).not.toHaveBeenCalled() expect(state.loadQualityChecks).not.toHaveBeenCalled() expect(state.loadExports).not.toHaveBeenCalled() }) it('haalt de beeldanalysegegevens op zodra dat werkblad open staat', async () => { const state = options('project-1', 'ai') renderHook(() => useWorkbenchBootstrap(state)) await waitFor(() => expect(state.loadDetectionModels).toHaveBeenCalledOnce()) expect(state.loadSegmentationModels).toHaveBeenCalledOnce() expect(state.loadDetectionRuns).toHaveBeenCalledWith('project-1') expect(state.loadSegmentationRuns).toHaveBeenCalledWith('project-1') expect(state.loadDetectionResults).toHaveBeenCalledOnce() expect(state.loadSegmentationResults).toHaveBeenCalledOnce() expect(state.loadExports).not.toHaveBeenCalled() }) it('haalt kwaliteit, downloads en bronkoppelingen op hun eigen werkblad', async () => { const kwaliteit = options('project-1', 'analysis') renderHook(() => useWorkbenchBootstrap(kwaliteit)) await waitFor(() => expect(kwaliteit.loadQualityChecks).toHaveBeenCalledWith('project-1')) const downloads = options('project-1', 'exports') renderHook(() => useWorkbenchBootstrap(downloads)) await waitFor(() => expect(downloads.loadExports).toHaveBeenCalledWith('project-1')) const systeem = options('project-1', 'system') renderHook(() => useWorkbenchBootstrap(systeem)) await waitFor(() => expect(systeem.loadCapabilities).toHaveBeenCalledOnce()) }) it('herlaadt bezochte werkbladen niet wanneer een ander werkblad opent', async () => { const state = options('project-1', 'ai') const { rerender } = renderHook((props: { werkblad: string }) => useWorkbenchBootstrap({ ...state, activeWorkspace: props.werkblad }), { initialProps: { werkblad: 'ai' }, }) await waitFor(() => expect(state.loadDetectionRuns).toHaveBeenCalledWith('project-1')) const detectionRunCalls = state.loadDetectionRuns.mock.calls.length const detectionResultCalls = state.loadDetectionResults.mock.calls.length rerender({ werkblad: 'map' }) rerender({ werkblad: 'exports' }) await waitFor(() => expect(state.loadExports).toHaveBeenCalledOnce()) rerender({ werkblad: 'analysis' }) await waitFor(() => expect(state.loadQualityChecks).toHaveBeenCalledOnce()) expect(state.loadDetectionRuns).toHaveBeenCalledTimes(detectionRunCalls) expect(state.loadDetectionResults).toHaveBeenCalledTimes(detectionResultCalls) expect(state.loadExports).toHaveBeenCalledOnce() }) it('meldt een mislukte laadactie in plaats van haar weg te slikken', async () => { const state = options('project-1') state.loadProjectData = vi.fn().mockRejectedValue(new Error('netwerk weg')) const gemeld: string[] = [] renderHook(() => useWorkbenchBootstrap({ ...state, onLoadError: (onderdeel) => gemeld.push(onderdeel) })) await waitFor(() => expect(gemeld).toContain('gebieden en bronnen')) }) it('laadt voor een gast hetzelfde als voor een operator', async () => { const state = { ...options('project-1', 'ai'), restrictedMode: true } renderHook(() => useWorkbenchBootstrap(state)) await waitFor(() => expect(state.loadProjectData).toHaveBeenCalledWith('project-1')) expect(state.loadDetectionModels).toHaveBeenCalledOnce() expect(state.loadDetectionRuns).toHaveBeenCalledWith('project-1') }) })