feat(ui): refine governed workbench and dual-screen flows
This commit is contained in:
@@ -3,6 +3,8 @@ import { beforeEach, describe, expect, it, vi } from 'vitest'
|
||||
import type { JobRead, SegmentationRead, SegmentationRunRead } from '../types'
|
||||
|
||||
const mocks = vi.hoisted(() => ({
|
||||
rasterInspect: vi.fn(),
|
||||
rasterTile: vi.fn(),
|
||||
listModels: vi.fn(),
|
||||
runAsync: vi.fn(),
|
||||
listRuns: vi.fn(),
|
||||
@@ -13,6 +15,10 @@ const mocks = vi.hoisted(() => ({
|
||||
}))
|
||||
|
||||
vi.mock('../services/api', () => ({
|
||||
datasetsApi: {
|
||||
rasterInspect: mocks.rasterInspect,
|
||||
rasterTile: mocks.rasterTile,
|
||||
},
|
||||
segmentationApi: {
|
||||
listModels: mocks.listModels,
|
||||
runAsync: mocks.runAsync,
|
||||
@@ -60,6 +66,7 @@ function renderWorkflow(selectedProjectId = projectId) {
|
||||
selectedProjectId,
|
||||
rasterDatasets: [],
|
||||
qaIouThreshold: 0.5,
|
||||
maxInferenceTiles: 100,
|
||||
loadProjectData,
|
||||
loadQualityChecks,
|
||||
}))
|
||||
@@ -87,6 +94,20 @@ describe('useSegmentationWorkflow GPU execution', () => {
|
||||
mocks.getRun.mockResolvedValue(persistedRun)
|
||||
mocks.listSegmentations.mockResolvedValue({ items: [], total: 0, truncated: false })
|
||||
mocks.getRunGeoJson.mockResolvedValue({ type: 'FeatureCollection', features: [] })
|
||||
mocks.rasterInspect.mockResolvedValue({
|
||||
dataset_id: datasetId,
|
||||
ready: true,
|
||||
metadata: { width: 512, height: 512 },
|
||||
})
|
||||
mocks.rasterTile.mockResolvedValue({
|
||||
id: 'tile-job-1',
|
||||
job_type: 'raster.tile',
|
||||
status: 'success',
|
||||
project_id: projectId,
|
||||
dataset_id: datasetId,
|
||||
parameters_json: {},
|
||||
result_json: { manifest_path: '/tiles/generated-manifest.json' },
|
||||
})
|
||||
})
|
||||
|
||||
it('queues, follows and reconciles a persisted segmentation result', async () => {
|
||||
@@ -118,15 +139,41 @@ describe('useSegmentationWorkflow GPU execution', () => {
|
||||
expect(loadProjectData).toHaveBeenCalledWith(projectId)
|
||||
})
|
||||
|
||||
it('does not queue a configured model without a tile manifest', async () => {
|
||||
it('prepares a server manifest before queueing when no manifest is supplied', async () => {
|
||||
const { result } = renderWorkflow()
|
||||
await act(async () => { await result.current.loadSegmentationModels() })
|
||||
act(() => { result.current.setSelectedSegmentationDatasetId(datasetId) })
|
||||
|
||||
await act(async () => { await result.current.runSegmentation() })
|
||||
|
||||
expect(mocks.rasterInspect).toHaveBeenCalledWith(projectId, datasetId)
|
||||
expect(mocks.rasterTile).toHaveBeenCalledWith(projectId, datasetId, {
|
||||
tile_size: 512,
|
||||
overlap: 64,
|
||||
})
|
||||
expect(mocks.runAsync).toHaveBeenCalledWith(expect.objectContaining({
|
||||
tile_manifest_path: '/tiles/generated-manifest.json',
|
||||
}))
|
||||
expect(result.current.segmentationTileManifestPath).toBe('/tiles/generated-manifest.json')
|
||||
expect(result.current.segmentationRunError).toBeNull()
|
||||
})
|
||||
|
||||
it('uses the backend-reported inference limit and refuses tiling before writes', async () => {
|
||||
mocks.rasterInspect.mockResolvedValueOnce({
|
||||
dataset_id: datasetId,
|
||||
ready: true,
|
||||
metadata: { width: 5376, height: 4480 },
|
||||
})
|
||||
const { result } = renderWorkflow()
|
||||
await act(async () => { await result.current.loadSegmentationModels() })
|
||||
act(() => { result.current.setSelectedSegmentationDatasetId(datasetId) })
|
||||
|
||||
await act(async () => { await result.current.runSegmentation() })
|
||||
|
||||
expect(mocks.rasterTile).not.toHaveBeenCalled()
|
||||
expect(mocks.runAsync).not.toHaveBeenCalled()
|
||||
expect(result.current.segmentationRunError).toContain('beeldtegelmanifest')
|
||||
expect(result.current.segmentationRunError).toContain('120 beeldtegels')
|
||||
expect(result.current.segmentationRunError).toContain('maximum is 100')
|
||||
})
|
||||
|
||||
it('ignores a late run list after the active project changes', async () => {
|
||||
@@ -142,6 +189,7 @@ describe('useSegmentationWorkflow GPU execution', () => {
|
||||
selectedProjectId,
|
||||
rasterDatasets: [],
|
||||
qaIouThreshold: 0.5,
|
||||
maxInferenceTiles: 100,
|
||||
loadProjectData,
|
||||
loadQualityChecks,
|
||||
}),
|
||||
@@ -185,6 +233,7 @@ describe('useSegmentationWorkflow GPU execution', () => {
|
||||
selectedProjectId,
|
||||
rasterDatasets: [],
|
||||
qaIouThreshold: 0.5,
|
||||
maxInferenceTiles: 100,
|
||||
loadProjectData,
|
||||
loadQualityChecks,
|
||||
}),
|
||||
|
||||
Reference in New Issue
Block a user