forked from OurHike/OurHike
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathviewerController.test.ts
More file actions
116 lines (97 loc) · 3.81 KB
/
Copy pathviewerController.test.ts
File metadata and controls
116 lines (97 loc) · 3.81 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
// Tests for viewerController.ts - what dropping files does to the map and
// the status line. openArchive is mocked here (its own tests run it against
// real archive bytes); what is under test is the orchestration.
import { describe, it, expect, vi, beforeEach } from 'vitest'
import { Protocol } from 'pmtiles'
import { createViewerController } from './viewerController'
import { openArchive, type OpenedArchive } from './viewerArchives'
import { LIVE_TOPO_LAYER_IDS } from '../map/liveTopo'
import { MockMap, resetMapLibreMock } from '../test/mocks/maplibre-gl'
vi.mock('./viewerArchives', async (importOriginal) => ({
...(await importOriginal<typeof import('./viewerArchives')>()),
openArchive: vi.fn(),
}))
const HEADER = {
tileType: 1,
minZoom: 0,
maxZoom: 14,
minLon: -80,
minLat: 34,
maxLon: -68,
maxLat: 46,
}
function opened(slot: OpenedArchive['slot'], fileName: string): OpenedArchive {
return {
slot,
url: `pmtiles://viewer:${slot}`,
header: HEADER,
fileName,
sizeBytes: 532_400_000,
}
}
function file(name: string): File {
return new File(['bytes'], name)
}
function makeController() {
const map = new MockMap({})
const statuses: string[] = []
const controller = createViewerController({
map,
protocol: new Protocol(),
onStatus: (text) => statuses.push(text),
})
return { map, statuses, controller }
}
beforeEach(() => {
vi.mocked(openArchive).mockReset()
resetMapLibreMock()
})
describe('createViewerController', () => {
it('renders a dropped basemap with the live sheet layers and fits its bounds', async () => {
vi.mocked(openArchive).mockResolvedValue(opened('basemap', 'at.pmtiles'))
const { map, statuses, controller } = makeController()
await controller.handleFiles([file('at.pmtiles')])
const style = map.styles.at(-1) as { layers: Array<{ id: string }> }
expect(style.layers.map((l) => l.id)).toContain(LIVE_TOPO_LAYER_IDS.wood)
expect(map.cameraMoves[0]).toMatchObject({
fitBounds: [
[-80, 34],
[-68, 46],
],
})
expect(statuses.at(-1)).toContain('at.pmtiles')
expect(statuses.at(-1)).toContain('z0–14')
})
it('a second drop composes with the first and leaves the camera alone', async () => {
vi.mocked(openArchive)
.mockResolvedValueOnce(opened('basemap', 'at.pmtiles'))
.mockResolvedValueOnce(opened('dem', 'dem.pmtiles'))
const { map, statuses, controller } = makeController()
await controller.handleFiles([file('at.pmtiles')])
await controller.handleFiles([file('dem.pmtiles')])
const style = map.styles.at(-1) as { layers: Array<{ id: string }> }
expect(style.layers.map((l) => l.id)).toContain(LIVE_TOPO_LAYER_IDS.hillshade)
expect(map.cameraMoves).toHaveLength(1)
expect(statuses.at(-1)).toContain('at.pmtiles')
expect(statuses.at(-1)).toContain('dem.pmtiles')
})
it('one unreadable file reports itself and does not cost the archives already shown', async () => {
vi.mocked(openArchive)
.mockResolvedValueOnce(opened('basemap', 'at.pmtiles'))
.mockRejectedValueOnce(new Error('not a PMTiles archive'))
const { map, statuses, controller } = makeController()
await controller.handleFiles([file('at.pmtiles')])
const stylesBefore = map.styles.length
await controller.handleFiles([file('junk.bin')])
expect(statuses).toContain('not a PMTiles archive')
// The style is rebuilt from what is open - the basemap survives.
expect(map.styles.length).toBeGreaterThan(stylesBefore)
expect(controller.opened.has('basemap')).toBe(true)
})
it('nothing openable means no style write at all', async () => {
vi.mocked(openArchive).mockRejectedValue(new Error('nope'))
const { map, controller } = makeController()
await controller.handleFiles([file('junk.bin')])
expect(map.styles).toHaveLength(0)
})
})