feat: add configurable timeline range

This commit is contained in:
2026-08-14 15:40:54 +02:00
parent b284275e98
commit 45c7c6a292
15 changed files with 121 additions and 14 deletions
+11
View File
@@ -68,6 +68,7 @@ suite('level persistence API', () => {
expect(createResponse.status).toBe(201)
const state = await createResponse.json() as CaseState
state.viewport = { x: 91, y: -42, zoom: 0.85 }
state.timelineRange = { start: '2021-04-01', end: '2021-04-30' }
const documentId = randomUUID()
const folderId = randomUUID()
const noteId = randomUUID()
@@ -96,12 +97,20 @@ suite('level persistence API', () => {
const loaded = await (await fetch(`${baseUrl}/api/levels/${state.id}?edit=1`)).json() as CaseState
expect(loaded.viewport).toEqual(state.viewport)
expect(loaded.timelineRange).toEqual(state.timelineRange)
expect(loaded.evidence[0]).toMatchObject({ id: folderId, x: 685, y: 417, config: { open: true } })
expect(loaded.relations[0]).toMatchObject({ id: `contains:${folderId}:${documentId}`, config: { x: 1051, y: 417 } })
expect(loaded.brief.concepts).toEqual(expect.arrayContaining([
expect.objectContaining({ label: 'Ada Lovelace', expectedPartyKind: 'person' }),
expect.objectContaining({ label: 'Analytical Engines Ltd', expectedPartyKind: 'organization' }),
]))
const legacyClientState = structuredClone(loaded)
delete legacyClientState.timelineRange
const legacySave = await fetch(`${baseUrl}/api/levels/${state.id}`, {
method: 'PUT', headers: { 'content-type': 'application/json' }, body: JSON.stringify(legacyClientState),
})
expect(legacySave.ok).toBe(true)
expect((await (await fetch(`${baseUrl}/api/levels/${state.id}`)).json() as CaseState).timelineRange).toEqual(state.timelineRange)
const upload = new FormData()
upload.append('file', new Blob(['OSINT smoke evidence'], { type: 'text/plain' }), 'smoke-evidence.txt')
@@ -177,6 +186,7 @@ suite('level persistence API', () => {
expect(resetResponse.ok).toBe(true)
const resetState = await resetResponse.json() as CaseState
expect(resetState.viewport).toEqual(playerState.viewport)
expect(resetState.timelineRange).toEqual(state.timelineRange)
expect(resetState.evidence[0]).toMatchObject({ id: folderId, x: 812, y: 533 })
const templateResponse = await fetch(`${baseUrl}/api/levels/${state.id}/templates?edit=1`, {
@@ -200,6 +210,7 @@ suite('level persistence API', () => {
expect(cloneResponse.status).toBe(201)
const clone = await cloneResponse.json() as CaseState
expect(clone).toMatchObject({ id: 'smoke-template-copy', title: 'Playable copy', sourceTemplateVersionId: expect.any(String) })
expect(clone.timelineRange).toEqual(state.timelineRange)
expect(clone.evidence.find(item => item.type === 'folder')).toMatchObject({ x: 812, y: 533 })
expect(clone.documents.find(item => item.title === 'Renamed smoke evidence')?.assetId).toBe(uploaded.assetId)
expect(clone.documents[0].id).not.toBe(savedPlayerState.documents[0].id)