@basemaps/lambda-tiler 6.31.0 → 6.32.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +21 -0
- package/build/__tests__/config.data.d.ts +6 -1
- package/build/__tests__/config.data.d.ts.map +1 -1
- package/build/__tests__/config.data.js +33 -2
- package/build/__tests__/config.data.js.map +1 -1
- package/build/__tests__/index.test.js +3 -13
- package/build/__tests__/index.test.js.map +1 -1
- package/build/__tests__/xyz.util.d.ts +7 -9
- package/build/__tests__/xyz.util.d.ts.map +1 -1
- package/build/__tests__/xyz.util.js +14 -20
- package/build/__tests__/xyz.util.js.map +1 -1
- package/build/index.d.ts +0 -2
- package/build/index.d.ts.map +1 -1
- package/build/index.js +57 -26
- package/build/index.js.map +1 -1
- package/build/routes/__tests__/attribution.test.js +350 -400
- package/build/routes/__tests__/attribution.test.js.map +1 -1
- package/build/routes/__tests__/fonts.test.js +11 -5
- package/build/routes/__tests__/fonts.test.js.map +1 -1
- package/build/routes/__tests__/health.test.js +16 -13
- package/build/routes/__tests__/health.test.js.map +1 -1
- package/build/routes/__tests__/sprites.test.js +6 -0
- package/build/routes/__tests__/sprites.test.js.map +1 -1
- package/build/routes/__tests__/tile.json.test.d.ts +2 -0
- package/build/routes/__tests__/tile.json.test.d.ts.map +1 -0
- package/build/routes/__tests__/tile.json.test.js +124 -0
- package/build/routes/__tests__/tile.json.test.js.map +1 -0
- package/build/routes/__tests__/tile.style.json.test.d.ts +2 -0
- package/build/routes/__tests__/tile.style.json.test.d.ts.map +1 -0
- package/build/routes/__tests__/tile.style.json.test.js +95 -0
- package/build/routes/__tests__/tile.style.json.test.js.map +1 -0
- package/build/routes/__tests__/wmts.test.js +5 -44
- package/build/routes/__tests__/wmts.test.js.map +1 -1
- package/build/{__tests__ → routes/__tests__}/xyz.test.d.ts +0 -0
- package/build/routes/__tests__/xyz.test.d.ts.map +1 -0
- package/build/routes/__tests__/xyz.test.js +99 -0
- package/build/routes/__tests__/xyz.test.js.map +1 -0
- package/build/routes/attribution.d.ts +7 -5
- package/build/routes/attribution.d.ts.map +1 -1
- package/build/routes/attribution.js +43 -81
- package/build/routes/attribution.js.map +1 -1
- package/build/routes/fonts.d.ts +1 -1
- package/build/routes/fonts.d.ts.map +1 -1
- package/build/routes/fonts.js +30 -15
- package/build/routes/fonts.js.map +1 -1
- package/build/routes/health.d.ts +3 -3
- package/build/routes/health.d.ts.map +1 -1
- package/build/routes/health.js +15 -13
- package/build/routes/health.js.map +1 -1
- package/build/routes/imagery.d.ts.map +1 -1
- package/build/routes/imagery.js +11 -10
- package/build/routes/imagery.js.map +1 -1
- package/build/routes/ping.d.ts +3 -0
- package/build/routes/ping.d.ts.map +1 -0
- package/build/routes/ping.js +7 -0
- package/build/routes/ping.js.map +1 -0
- package/build/routes/sprites.d.ts.map +1 -1
- package/build/routes/sprites.js +16 -10
- package/build/routes/sprites.js.map +1 -1
- package/build/routes/tile.json.d.ts +7 -1
- package/build/routes/tile.json.d.ts.map +1 -1
- package/build/routes/tile.json.js +18 -21
- package/build/routes/tile.json.js.map +1 -1
- package/build/routes/tile.style.json.d.ts +6 -1
- package/build/routes/tile.style.json.d.ts.map +1 -1
- package/build/routes/tile.style.json.js +10 -13
- package/build/routes/tile.style.json.js.map +1 -1
- package/build/routes/tile.wmts.d.ts +9 -3
- package/build/routes/tile.wmts.d.ts.map +1 -1
- package/build/routes/tile.wmts.js +26 -35
- package/build/routes/tile.wmts.js.map +1 -1
- package/build/routes/tile.xyz.d.ts +14 -4
- package/build/routes/tile.xyz.d.ts.map +1 -1
- package/build/routes/tile.xyz.js +21 -17
- package/build/routes/tile.xyz.js.map +1 -1
- package/build/routes/tile.xyz.raster.d.ts +11 -0
- package/build/routes/tile.xyz.raster.d.ts.map +1 -0
- package/build/routes/tile.xyz.raster.js +90 -0
- package/build/routes/tile.xyz.raster.js.map +1 -0
- package/build/routes/tile.xyz.vector.d.ts +8 -0
- package/build/routes/tile.xyz.vector.d.ts.map +1 -0
- package/build/routes/tile.xyz.vector.js +46 -0
- package/build/routes/tile.xyz.vector.js.map +1 -0
- package/build/routes/version.d.ts +3 -0
- package/build/routes/version.d.ts.map +1 -0
- package/build/routes/version.js +9 -0
- package/build/routes/version.js.map +1 -0
- package/build/util/__test__/validate.test.d.ts +2 -0
- package/build/util/__test__/validate.test.d.ts.map +1 -0
- package/build/util/__test__/validate.test.js +66 -0
- package/build/util/__test__/validate.test.js.map +1 -0
- package/build/{cotar.cache.d.ts → util/cotar.serve.d.ts} +3 -8
- package/build/util/cotar.serve.d.ts.map +1 -0
- package/build/util/cotar.serve.js +41 -0
- package/build/util/cotar.serve.js.map +1 -0
- package/build/util/etag.d.ts +6 -0
- package/build/util/etag.d.ts.map +1 -0
- package/build/util/etag.js +20 -0
- package/build/util/etag.js.map +1 -0
- package/build/util/response.d.ts +4 -0
- package/build/util/response.d.ts.map +1 -0
- package/build/util/response.js +4 -0
- package/build/util/response.js.map +1 -0
- package/build/util/source.cache.d.ts +28 -0
- package/build/util/source.cache.d.ts.map +1 -0
- package/build/util/source.cache.js +53 -0
- package/build/util/source.cache.js.map +1 -0
- package/build/{source.tracer.d.ts → util/source.tracer.d.ts} +1 -0
- package/build/util/source.tracer.d.ts.map +1 -0
- package/build/{source.tracer.js → util/source.tracer.js} +3 -0
- package/build/util/source.tracer.js.map +1 -0
- package/build/util/swapping.lru.d.ts +21 -0
- package/build/util/swapping.lru.d.ts.map +1 -0
- package/build/util/swapping.lru.js +56 -0
- package/build/util/swapping.lru.js.map +1 -0
- package/build/util/validate.d.ts +46 -0
- package/build/util/validate.d.ts.map +1 -0
- package/build/util/validate.js +107 -0
- package/build/util/validate.js.map +1 -0
- package/build/wmts.capability.d.ts +1 -1
- package/build/wmts.capability.d.ts.map +1 -1
- package/dist/index.js +62 -60
- package/dist/node_modules/.package-lock.json +1 -1
- package/dist/package-lock.json +2 -2
- package/dist/package.json +1 -1
- package/package.json +6 -6
- package/src/__tests__/config.data.ts +41 -3
- package/src/__tests__/index.test.ts +3 -19
- package/src/__tests__/xyz.util.ts +18 -21
- package/src/index.ts +66 -29
- package/src/routes/__tests__/attribution.test.ts +356 -403
- package/src/routes/__tests__/fonts.test.ts +11 -5
- package/src/routes/__tests__/health.test.ts +17 -13
- package/src/routes/__tests__/sprites.test.ts +6 -1
- package/src/routes/__tests__/tile.json.test.ts +145 -0
- package/src/routes/__tests__/tile.style.json.test.ts +105 -0
- package/src/routes/__tests__/wmts.test.ts +5 -55
- package/src/routes/__tests__/xyz.test.ts +119 -0
- package/src/routes/attribution.ts +53 -99
- package/src/routes/fonts.ts +29 -15
- package/src/routes/health.ts +17 -16
- package/src/routes/imagery.ts +10 -9
- package/src/routes/ping.ts +8 -0
- package/src/routes/sprites.ts +16 -10
- package/src/routes/tile.json.ts +24 -18
- package/src/routes/tile.style.json.ts +15 -12
- package/src/routes/tile.wmts.ts +30 -31
- package/src/routes/tile.xyz.raster.ts +106 -0
- package/src/routes/tile.xyz.ts +31 -16
- package/src/routes/tile.xyz.vector.ts +47 -0
- package/src/routes/version.ts +8 -0
- package/src/util/__test__/validate.test.ts +74 -0
- package/src/util/cotar.serve.ts +46 -0
- package/src/util/etag.ts +20 -0
- package/src/util/response.ts +4 -0
- package/src/util/source.cache.ts +71 -0
- package/src/{source.tracer.ts → util/source.tracer.ts} +4 -0
- package/src/util/swapping.lru.ts +63 -0
- package/src/util/validate.ts +126 -0
- package/src/wmts.capability.ts +1 -1
- package/tsconfig.tsbuildinfo +1 -1
- package/build/__tests__/route.test.d.ts +0 -2
- package/build/__tests__/route.test.d.ts.map +0 -1
- package/build/__tests__/route.test.js +0 -21
- package/build/__tests__/route.test.js.map +0 -1
- package/build/__tests__/tiff.cache.test.d.ts +0 -2
- package/build/__tests__/tiff.cache.test.d.ts.map +0 -1
- package/build/__tests__/tiff.cache.test.js +0 -59
- package/build/__tests__/tiff.cache.test.js.map +0 -1
- package/build/__tests__/tile.cache.key.test.d.ts +0 -2
- package/build/__tests__/tile.cache.key.test.d.ts.map +0 -1
- package/build/__tests__/tile.cache.key.test.js +0 -49
- package/build/__tests__/tile.cache.key.test.js.map +0 -1
- package/build/__tests__/tile.set.cache.test.d.ts +0 -2
- package/build/__tests__/tile.set.cache.test.d.ts.map +0 -1
- package/build/__tests__/tile.set.cache.test.js +0 -72
- package/build/__tests__/tile.set.cache.test.js.map +0 -1
- package/build/__tests__/tile.set.test.d.ts +0 -2
- package/build/__tests__/tile.set.test.d.ts.map +0 -1
- package/build/__tests__/tile.set.test.js +0 -12
- package/build/__tests__/tile.set.test.js.map +0 -1
- package/build/__tests__/xyz.test.d.ts.map +0 -1
- package/build/__tests__/xyz.test.js +0 -275
- package/build/__tests__/xyz.test.js.map +0 -1
- package/build/api.key.d.ts +0 -2
- package/build/api.key.d.ts.map +0 -1
- package/build/api.key.js +0 -24
- package/build/api.key.js.map +0 -1
- package/build/cli/dump.d.ts +0 -2
- package/build/cli/dump.d.ts.map +0 -1
- package/build/cli/dump.js +0 -48
- package/build/cli/dump.js.map +0 -1
- package/build/cli/tile.set.local.d.ts +0 -12
- package/build/cli/tile.set.local.d.ts.map +0 -1
- package/build/cli/tile.set.local.js +0 -40
- package/build/cli/tile.set.local.js.map +0 -1
- package/build/cotar.cache.d.ts.map +0 -1
- package/build/cotar.cache.js +0 -50
- package/build/cotar.cache.js.map +0 -1
- package/build/router.d.ts +0 -15
- package/build/router.d.ts.map +0 -1
- package/build/router.js +0 -50
- package/build/router.js.map +0 -1
- package/build/routes/api.d.ts +0 -4
- package/build/routes/api.d.ts.map +0 -1
- package/build/routes/api.js +0 -14
- package/build/routes/api.js.map +0 -1
- package/build/routes/esri/rest.d.ts +0 -10
- package/build/routes/esri/rest.d.ts.map +0 -1
- package/build/routes/esri/rest.js +0 -88
- package/build/routes/esri/rest.js.map +0 -1
- package/build/routes/response.d.ts +0 -4
- package/build/routes/response.d.ts.map +0 -1
- package/build/routes/response.js +0 -4
- package/build/routes/response.js.map +0 -1
- package/build/routes/tile.d.ts +0 -3
- package/build/routes/tile.d.ts.map +0 -1
- package/build/routes/tile.etag.d.ts +0 -11
- package/build/routes/tile.etag.d.ts.map +0 -1
- package/build/routes/tile.etag.js +0 -30
- package/build/routes/tile.etag.js.map +0 -1
- package/build/routes/tile.js +0 -28
- package/build/routes/tile.js.map +0 -1
- package/build/source.tracer.d.ts.map +0 -1
- package/build/source.tracer.js.map +0 -1
- package/build/tiff.cache.d.ts +0 -17
- package/build/tiff.cache.d.ts.map +0 -1
- package/build/tiff.cache.js +0 -46
- package/build/tiff.cache.js.map +0 -1
- package/build/tile.set.cache.d.ts +0 -20
- package/build/tile.set.cache.d.ts.map +0 -1
- package/build/tile.set.cache.js +0 -72
- package/build/tile.set.cache.js.map +0 -1
- package/build/tile.set.d.ts +0 -4
- package/build/tile.set.d.ts.map +0 -1
- package/build/tile.set.js +0 -2
- package/build/tile.set.js.map +0 -1
- package/build/tile.set.raster.d.ts +0 -49
- package/build/tile.set.raster.d.ts.map +0 -1
- package/build/tile.set.raster.js +0 -189
- package/build/tile.set.raster.js.map +0 -1
- package/build/tile.set.vector.d.ts +0 -18
- package/build/tile.set.vector.d.ts.map +0 -1
- package/build/tile.set.vector.js +0 -54
- package/build/tile.set.vector.js.map +0 -1
- package/build/validate.d.ts +0 -16
- package/build/validate.d.ts.map +0 -1
- package/build/validate.js +0 -32
- package/build/validate.js.map +0 -1
- package/src/__tests__/route.test.ts +0 -24
- package/src/__tests__/tiff.cache.test.ts +0 -73
- package/src/__tests__/tile.cache.key.test.ts +0 -56
- package/src/__tests__/tile.set.cache.test.ts +0 -80
- package/src/__tests__/tile.set.test.ts +0 -12
- package/src/__tests__/xyz.test.ts +0 -318
- package/src/api.key.ts +0 -23
- package/src/cli/dump.ts +0 -61
- package/src/cli/tile.set.local.ts +0 -51
- package/src/cotar.cache.ts +0 -54
- package/src/router.ts +0 -58
- package/src/routes/api.ts +0 -15
- package/src/routes/esri/rest.ts +0 -90
- package/src/routes/response.ts +0 -4
- package/src/routes/tile.etag.ts +0 -36
- package/src/routes/tile.ts +0 -23
- package/src/tiff.cache.ts +0 -51
- package/src/tile.set.cache.ts +0 -84
- package/src/tile.set.raster.ts +0 -230
- package/src/tile.set.ts +0 -4
- package/src/tile.set.vector.ts +0 -61
- package/src/validate.ts +0 -32
|
@@ -33,14 +33,16 @@ o.spec('/v1/fonts', () => {
|
|
|
33
33
|
});
|
|
34
34
|
|
|
35
35
|
o('should return empty list if no fonts found', async () => {
|
|
36
|
-
const res = await fontList();
|
|
36
|
+
const res = await fontList(mockRequest('/v1/fonts.json'));
|
|
37
37
|
o(res.status).equals(200);
|
|
38
38
|
o(res.body).equals('[]');
|
|
39
|
+
o(res.header('etag')).notEquals(undefined);
|
|
40
|
+
o(res.header('cache-control')).equals('public, max-age=604800, stale-while-revalidate=86400');
|
|
39
41
|
});
|
|
40
42
|
|
|
41
43
|
o('should return 404 if no assets defined', async () => {
|
|
42
44
|
delete process.env[Env.AssetLocation];
|
|
43
|
-
const res = await fontList();
|
|
45
|
+
const res = await fontList(mockRequest('/v1/fonts.json'));
|
|
44
46
|
o(res.status).equals(404);
|
|
45
47
|
});
|
|
46
48
|
|
|
@@ -50,7 +52,7 @@ o.spec('/v1/fonts', () => {
|
|
|
50
52
|
fsa.write('memory://fonts/Roboto Thin/256-512.pbf', Buffer.from('')),
|
|
51
53
|
fsa.write('memory://fonts/Roboto Black/0-255.pbf', Buffer.from('')),
|
|
52
54
|
]);
|
|
53
|
-
const res = await fontList();
|
|
55
|
+
const res = await fontList(mockRequest('/v1/fonts.json'));
|
|
54
56
|
o(res.status).equals(200);
|
|
55
57
|
o(res.header('content-type')).equals('application/json');
|
|
56
58
|
o(res.header('content-encoding')).equals(undefined);
|
|
@@ -60,10 +62,12 @@ o.spec('/v1/fonts', () => {
|
|
|
60
62
|
o('should get the correct font', async () => {
|
|
61
63
|
await fsa.write('memory://fonts/Roboto Thin/0-255.pbf', Buffer.from(''));
|
|
62
64
|
|
|
63
|
-
const res255 = await handler.router.handle(mockRequest(
|
|
65
|
+
const res255 = await handler.router.handle(mockRequest('/v1/fonts/Roboto Thin/0-255.pbf'));
|
|
64
66
|
o(res255.status).equals(200);
|
|
65
67
|
o(res255.header('content-type')).equals('application/x-protobuf');
|
|
66
68
|
o(res255.header('content-encoding')).equals(undefined);
|
|
69
|
+
o(res255.header('etag')).notEquals(undefined);
|
|
70
|
+
o(res255.header('cache-control')).equals('public, max-age=604800, stale-while-revalidate=86400');
|
|
67
71
|
|
|
68
72
|
const res404 = await handler.router.handle(mockRequest('/v1/fonts/Roboto Thin/256-512.pbf'));
|
|
69
73
|
o(res404.status).equals(404);
|
|
@@ -72,9 +76,11 @@ o.spec('/v1/fonts', () => {
|
|
|
72
76
|
o('should get the correct utf8 font', async () => {
|
|
73
77
|
await fsa.write('memory://fonts/🦄 🌈/0-255.pbf', Buffer.from(''));
|
|
74
78
|
|
|
75
|
-
const res255 = await handler.router.handle(mockRequest(
|
|
79
|
+
const res255 = await handler.router.handle(mockRequest('/v1/fonts/🦄 🌈/0-255.pbf'));
|
|
76
80
|
o(res255.status).equals(200);
|
|
77
81
|
o(res255.header('content-type')).equals('application/x-protobuf');
|
|
78
82
|
o(res255.header('content-encoding')).equals(undefined);
|
|
83
|
+
o(res255.header('etag')).notEquals(undefined);
|
|
84
|
+
o(res255.header('cache-control')).equals('public, max-age=604800, stale-while-revalidate=86400');
|
|
79
85
|
});
|
|
80
86
|
});
|
|
@@ -1,12 +1,13 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Config, ConfigProviderMemory } from '@basemaps/config';
|
|
2
2
|
import { LogConfig } from '@basemaps/shared';
|
|
3
3
|
import { LambdaAlbRequest, LambdaHttpRequest, LambdaHttpResponse } from '@linzjs/lambda';
|
|
4
4
|
import { Context } from 'aws-lambda';
|
|
5
5
|
import o from 'ospec';
|
|
6
6
|
import sinon from 'sinon';
|
|
7
|
-
import {
|
|
8
|
-
|
|
9
|
-
import { getTestBuffer,
|
|
7
|
+
import { FakeData } from '../../__tests__/config.data.js';
|
|
8
|
+
|
|
9
|
+
import { getTestBuffer, healthGet, TestTiles } from '../health.js';
|
|
10
|
+
import { TileXyzRaster } from '../tile.xyz.raster.js';
|
|
10
11
|
|
|
11
12
|
const ctx: LambdaHttpRequest = new LambdaAlbRequest(
|
|
12
13
|
{
|
|
@@ -20,13 +21,16 @@ const ctx: LambdaHttpRequest = new LambdaAlbRequest(
|
|
|
20
21
|
LogConfig.get(),
|
|
21
22
|
);
|
|
22
23
|
|
|
23
|
-
o.spec('health', async () => {
|
|
24
|
+
o.spec('/v1/health', async () => {
|
|
24
25
|
o.specTimeout(1000);
|
|
25
26
|
const sandbox = sinon.createSandbox();
|
|
27
|
+
const config = new ConfigProviderMemory();
|
|
26
28
|
|
|
27
|
-
const
|
|
29
|
+
const fakeTileSet = FakeData.tileSetRaster('health');
|
|
28
30
|
o.beforeEach(() => {
|
|
29
|
-
|
|
31
|
+
config.objects.clear();
|
|
32
|
+
Config.setConfigProvider(config);
|
|
33
|
+
config.put(fakeTileSet);
|
|
30
34
|
});
|
|
31
35
|
|
|
32
36
|
o.afterEach(() => {
|
|
@@ -36,10 +40,10 @@ o.spec('health', async () => {
|
|
|
36
40
|
o('Should return bad response', async () => {
|
|
37
41
|
// Given ... a bad get tile response
|
|
38
42
|
const BadResponse = new LambdaHttpResponse(500, 'Can not get Tile Set.');
|
|
39
|
-
sandbox.stub(
|
|
43
|
+
sandbox.stub(TileXyzRaster, 'tile').resolves(BadResponse);
|
|
40
44
|
|
|
41
45
|
// When ...
|
|
42
|
-
const res = await
|
|
46
|
+
const res = await healthGet(ctx);
|
|
43
47
|
|
|
44
48
|
// Then ...
|
|
45
49
|
o(res.status).equals(500);
|
|
@@ -59,12 +63,12 @@ o.spec('health', async () => {
|
|
|
59
63
|
|
|
60
64
|
o('Should give a 200 response', async () => {
|
|
61
65
|
// Given ... a series good get tile response
|
|
62
|
-
const callback = sandbox.stub(
|
|
66
|
+
const callback = sandbox.stub(TileXyzRaster, 'tile');
|
|
63
67
|
callback.onCall(0).resolves(Response1);
|
|
64
68
|
callback.onCall(1).resolves(Response2);
|
|
65
69
|
|
|
66
70
|
// When ...
|
|
67
|
-
const res = await
|
|
71
|
+
const res = await healthGet(ctx);
|
|
68
72
|
|
|
69
73
|
// Then ...
|
|
70
74
|
o(res.status).equals(200);
|
|
@@ -73,12 +77,12 @@ o.spec('health', async () => {
|
|
|
73
77
|
|
|
74
78
|
o('Should return mis-match tile response', async () => {
|
|
75
79
|
// Given ... a bad get tile response for second get tile
|
|
76
|
-
const callback = sandbox.stub(
|
|
80
|
+
const callback = sandbox.stub(TileXyzRaster, 'tile');
|
|
77
81
|
callback.onCall(0).resolves(Response1);
|
|
78
82
|
callback.onCall(1).resolves(Response1);
|
|
79
83
|
|
|
80
84
|
// When ...
|
|
81
|
-
const res = await
|
|
85
|
+
const res = await healthGet(ctx);
|
|
82
86
|
|
|
83
87
|
// Then ...
|
|
84
88
|
o(res.status).equals(500);
|
|
@@ -36,6 +36,8 @@ o.spec('/v1/sprites', () => {
|
|
|
36
36
|
o(res.status).equals(200);
|
|
37
37
|
o(res.header('content-type')).equals('application/json');
|
|
38
38
|
o(res.header('content-encoding')).equals(undefined);
|
|
39
|
+
o(res.header('etag')).notEquals(undefined);
|
|
40
|
+
o(res.header('cache-control')).equals('public, max-age=604800, stale-while-revalidate=86400');
|
|
39
41
|
|
|
40
42
|
o(JSON.parse(Buffer.from(res.body, 'base64').toString())).deepEquals({ test: true });
|
|
41
43
|
});
|
|
@@ -48,6 +50,8 @@ o.spec('/v1/sprites', () => {
|
|
|
48
50
|
const res = await handler.router.handle(mockRequest('/v1/sprites/topographic@2x.png'));
|
|
49
51
|
o(res.status).equals(200);
|
|
50
52
|
o(res.header('content-type')).equals('image/png');
|
|
53
|
+
o(res.header('etag')).notEquals(undefined);
|
|
54
|
+
o(res.header('cache-control')).equals('public, max-age=604800, stale-while-revalidate=86400');
|
|
51
55
|
});
|
|
52
56
|
|
|
53
57
|
o('should detect gziped files and set content-encoding', async () => {
|
|
@@ -58,7 +62,8 @@ o.spec('/v1/sprites', () => {
|
|
|
58
62
|
o(res.status).equals(200);
|
|
59
63
|
o(res.header('content-type')).equals('application/json');
|
|
60
64
|
o(res.header('content-encoding')).equals('gzip');
|
|
61
|
-
|
|
65
|
+
o(res.header('etag')).notEquals(undefined);
|
|
66
|
+
o(res.header('cache-control')).equals('public, max-age=604800, stale-while-revalidate=86400');
|
|
62
67
|
o(JSON.parse(gunzipSync(Buffer.from(res.body, 'base64')).toString())).deepEquals({ test: true });
|
|
63
68
|
});
|
|
64
69
|
});
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
import { Config, ConfigProviderMemory } from '@basemaps/config';
|
|
2
|
+
import { Env } from '@basemaps/shared';
|
|
3
|
+
import o from 'ospec';
|
|
4
|
+
import { handler } from '../../index.js';
|
|
5
|
+
import { CoSources } from '../../util/source.cache.js';
|
|
6
|
+
import { FakeData } from '../../__tests__/config.data.js';
|
|
7
|
+
import { Api, mockRequest, mockUrlRequest } from '../../__tests__/xyz.util.js';
|
|
8
|
+
|
|
9
|
+
o.spec('/v1/tiles/:tileSet/:tileMatrix/tile.json', () => {
|
|
10
|
+
const config = new ConfigProviderMemory();
|
|
11
|
+
o.before(() => {
|
|
12
|
+
process.env[Env.PublicUrlBase] = 'https://tiles.test';
|
|
13
|
+
Config.setConfigProvider(config);
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
o.beforeEach(() => {
|
|
17
|
+
config.objects.clear();
|
|
18
|
+
CoSources.cache.clear();
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
o('should 404 if invalid url is given', async () => {
|
|
22
|
+
const request = mockRequest('/v1/tiles/tile.json', 'get', Api.header);
|
|
23
|
+
|
|
24
|
+
const res = await handler.router.handle(request);
|
|
25
|
+
o(res.status).equals(404);
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
o('should support utf8 tilesets', async () => {
|
|
29
|
+
const request = mockUrlRequest('/v1/tiles/🦄 🌈/NZTM2000Quad/tile.json', `api=${Api.key}`);
|
|
30
|
+
o(request.path).equals('/v1/tiles/%F0%9F%A6%84%20%F0%9F%8C%88/NZTM2000Quad/tile.json');
|
|
31
|
+
|
|
32
|
+
const fakeTileSet = FakeData.tileSetRaster('🦄 🌈');
|
|
33
|
+
config.put(fakeTileSet);
|
|
34
|
+
|
|
35
|
+
const res = await handler.router.handle(request);
|
|
36
|
+
o(res.status).equals(200);
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
o('should serve tile json for tile_set', async () => {
|
|
40
|
+
const request = mockRequest('/v1/tiles/aerial/NZTM2000Quad/tile.json', 'get', Api.header);
|
|
41
|
+
const fakeTileSet = FakeData.tileSetRaster('aerial');
|
|
42
|
+
config.put(fakeTileSet);
|
|
43
|
+
|
|
44
|
+
const res = await handler.router.handle(request);
|
|
45
|
+
o(res.status).equals(200);
|
|
46
|
+
o(res.header('cache-control')).equals('no-store');
|
|
47
|
+
|
|
48
|
+
const body = Buffer.from(res.body ?? '', 'base64').toString();
|
|
49
|
+
o(JSON.parse(body)).deepEquals({
|
|
50
|
+
tiles: [`https://tiles.test/v1/tiles/aerial/NZTM2000Quad/{z}/{x}/{y}.webp?api=${Api.key}`],
|
|
51
|
+
tilejson: '3.0.0',
|
|
52
|
+
});
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
o('should use the correct format', async () => {
|
|
56
|
+
const request = mockRequest('/v1/tiles/aerial/NZTM2000Quad/tile.json', 'get', Api.header);
|
|
57
|
+
request.query.set('format', 'jpeg');
|
|
58
|
+
|
|
59
|
+
const fakeTileSet = FakeData.tileSetRaster('aerial');
|
|
60
|
+
config.put(fakeTileSet);
|
|
61
|
+
|
|
62
|
+
const res = await handler.router.handle(request);
|
|
63
|
+
o(res.status).equals(200);
|
|
64
|
+
o(res.header('cache-control')).equals('no-store');
|
|
65
|
+
|
|
66
|
+
const body = Buffer.from(res.body ?? '', 'base64').toString();
|
|
67
|
+
o(JSON.parse(body)).deepEquals({
|
|
68
|
+
tiles: [`https://tiles.test/v1/tiles/aerial/NZTM2000Quad/{z}/{x}/{y}.jpeg?api=${Api.key}`],
|
|
69
|
+
tilejson: '3.0.0',
|
|
70
|
+
});
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
o('should use the correct format when multiple set', async () => {
|
|
74
|
+
const request = mockRequest('/v1/tiles/aerial/NZTM2000Quad/tile.json', 'get', Api.header);
|
|
75
|
+
request.query.append('format', 'png');
|
|
76
|
+
request.query.append('format', 'jpeg');
|
|
77
|
+
|
|
78
|
+
const fakeTileSet = FakeData.tileSetRaster('aerial');
|
|
79
|
+
config.put(fakeTileSet);
|
|
80
|
+
|
|
81
|
+
const res = await handler.router.handle(request);
|
|
82
|
+
o(res.status).equals(200);
|
|
83
|
+
o(res.header('cache-control')).equals('no-store');
|
|
84
|
+
|
|
85
|
+
const body = Buffer.from(res.body ?? '', 'base64').toString();
|
|
86
|
+
o(JSON.parse(body)).deepEquals({
|
|
87
|
+
tiles: [`https://tiles.test/v1/tiles/aerial/NZTM2000Quad/{z}/{x}/{y}.png?api=${Api.key}`],
|
|
88
|
+
tilejson: '3.0.0',
|
|
89
|
+
});
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
o('should serve vector tiles', async () => {
|
|
93
|
+
const request = mockRequest('/v1/tiles/topographic/EPSG:3857/tile.json', 'get', Api.header);
|
|
94
|
+
const fakeTileSet = FakeData.tileSetVector('topographic');
|
|
95
|
+
config.put(fakeTileSet);
|
|
96
|
+
|
|
97
|
+
const res = await handler.router.handle(request);
|
|
98
|
+
o(res.status).equals(200);
|
|
99
|
+
|
|
100
|
+
const body = Buffer.from(res.body ?? '', 'base64').toString();
|
|
101
|
+
o(JSON.parse(body)).deepEquals({
|
|
102
|
+
tiles: [`https://tiles.test/v1/tiles/topographic/WebMercatorQuad/{z}/{x}/{y}.pbf?api=${Api.key}`],
|
|
103
|
+
tilejson: '3.0.0',
|
|
104
|
+
});
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
o('should serve vector tiles with min/max zoom', async () => {
|
|
108
|
+
const fakeTileSet = FakeData.tileSetVector('fake-vector');
|
|
109
|
+
fakeTileSet.maxZoom = 15;
|
|
110
|
+
fakeTileSet.minZoom = 3;
|
|
111
|
+
config.put(fakeTileSet);
|
|
112
|
+
const request = mockRequest('/v1/tiles/fake-vector/WebMercatorQuad/tile.json', 'get', Api.header);
|
|
113
|
+
|
|
114
|
+
const res = await handler.router.handle(request);
|
|
115
|
+
o(res.status).equals(200);
|
|
116
|
+
|
|
117
|
+
const body = Buffer.from(res.body ?? '', 'base64').toString();
|
|
118
|
+
o(JSON.parse(body)).deepEquals({
|
|
119
|
+
tiles: [`https://tiles.test/v1/tiles/fake-vector/WebMercatorQuad/{z}/{x}/{y}.pbf?api=${Api.key}`],
|
|
120
|
+
maxzoom: 15,
|
|
121
|
+
minzoom: 3,
|
|
122
|
+
tilejson: '3.0.0',
|
|
123
|
+
});
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
o('should serve convert zoom to tile matrix', async () => {
|
|
127
|
+
const fakeTileSet = FakeData.tileSetVector('fake-vector');
|
|
128
|
+
fakeTileSet.maxZoom = 15;
|
|
129
|
+
fakeTileSet.minZoom = 1;
|
|
130
|
+
config.put(fakeTileSet);
|
|
131
|
+
|
|
132
|
+
const request = mockRequest('/v1/tiles/fake-vector/NZTM2000Quad/tile.json', 'get', Api.header);
|
|
133
|
+
|
|
134
|
+
const res = await handler.router.handle(request);
|
|
135
|
+
o(res.status).equals(200);
|
|
136
|
+
|
|
137
|
+
const body = Buffer.from(res.body ?? '', 'base64').toString();
|
|
138
|
+
o(JSON.parse(body)).deepEquals({
|
|
139
|
+
tiles: [`https://tiles.test/v1/tiles/fake-vector/NZTM2000Quad/{z}/{x}/{y}.pbf?api=${Api.key}`],
|
|
140
|
+
maxzoom: 13,
|
|
141
|
+
minzoom: 0,
|
|
142
|
+
tilejson: '3.0.0',
|
|
143
|
+
});
|
|
144
|
+
});
|
|
145
|
+
});
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import { Config, StyleJson } from '@basemaps/config';
|
|
2
|
+
import { Env } from '@basemaps/shared';
|
|
3
|
+
import o from 'ospec';
|
|
4
|
+
import { createSandbox } from 'sinon';
|
|
5
|
+
import { handler } from '../../index.js';
|
|
6
|
+
import { Api, mockRequest } from '../../__tests__/xyz.util.js';
|
|
7
|
+
|
|
8
|
+
o.spec('/v1/styles', () => {
|
|
9
|
+
const host = 'https://tiles.test';
|
|
10
|
+
const sandbox = createSandbox();
|
|
11
|
+
|
|
12
|
+
o.before(() => {
|
|
13
|
+
process.env[Env.PublicUrlBase] = host;
|
|
14
|
+
});
|
|
15
|
+
// o.beforeEach(() => {});
|
|
16
|
+
o.afterEach(() => sandbox.restore());
|
|
17
|
+
o('should not found style json', async () => {
|
|
18
|
+
const request = mockRequest('/v1/tiles/topographic/Google/style/topographic.json', 'get', Api.header);
|
|
19
|
+
|
|
20
|
+
sandbox.stub(Config.Style, 'get').resolves(null);
|
|
21
|
+
|
|
22
|
+
const res = await handler.router.handle(request);
|
|
23
|
+
o(res.status).equals(404);
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
o('should serve style json', async () => {
|
|
27
|
+
const request = mockRequest('/v1/tiles/topographic/Google/style/topographic.json', 'get', Api.header);
|
|
28
|
+
|
|
29
|
+
const fakeStyle: StyleJson = {
|
|
30
|
+
version: 8,
|
|
31
|
+
id: 'test',
|
|
32
|
+
name: 'topographic',
|
|
33
|
+
sources: {
|
|
34
|
+
basemaps_vector: {
|
|
35
|
+
type: 'vector',
|
|
36
|
+
url: `/vector`,
|
|
37
|
+
},
|
|
38
|
+
basemaps_raster: {
|
|
39
|
+
type: 'raster',
|
|
40
|
+
tiles: [`/raster`],
|
|
41
|
+
},
|
|
42
|
+
basemaps_raster_encode: {
|
|
43
|
+
type: 'raster',
|
|
44
|
+
tiles: [`/raster/{z}/{x}/{y}.webp`], // Shouldn't encode the {}
|
|
45
|
+
},
|
|
46
|
+
test_vector: {
|
|
47
|
+
type: 'vector',
|
|
48
|
+
url: 'vector.url.co.nz',
|
|
49
|
+
},
|
|
50
|
+
test_raster: {
|
|
51
|
+
type: 'raster',
|
|
52
|
+
tiles: ['raster.url.co.nz'],
|
|
53
|
+
},
|
|
54
|
+
},
|
|
55
|
+
layers: [
|
|
56
|
+
{
|
|
57
|
+
layout: {
|
|
58
|
+
visibility: 'visible',
|
|
59
|
+
},
|
|
60
|
+
paint: {
|
|
61
|
+
'background-color': 'rgba(206, 229, 242, 1)',
|
|
62
|
+
},
|
|
63
|
+
id: 'Background',
|
|
64
|
+
type: 'background',
|
|
65
|
+
minzoom: 0,
|
|
66
|
+
},
|
|
67
|
+
],
|
|
68
|
+
glyphs: '/glyphs',
|
|
69
|
+
sprite: '/sprite',
|
|
70
|
+
metadata: { id: 'test' },
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
const fakeRecord = {
|
|
74
|
+
id: 'st_topographic_production',
|
|
75
|
+
name: 'topographic',
|
|
76
|
+
style: fakeStyle,
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
sandbox.stub(Config.Style, 'get').resolves(fakeRecord as any);
|
|
80
|
+
|
|
81
|
+
const res = await handler.router.handle(request);
|
|
82
|
+
o(res.status).equals(200);
|
|
83
|
+
o(res.header('content-type')).equals('application/json');
|
|
84
|
+
o(res.header('cache-control')).equals('no-store');
|
|
85
|
+
|
|
86
|
+
const body = Buffer.from(res.body ?? '', 'base64').toString();
|
|
87
|
+
fakeStyle.sources.basemaps_vector = {
|
|
88
|
+
type: 'vector',
|
|
89
|
+
url: `${host}/vector?api=${Api.key}`,
|
|
90
|
+
};
|
|
91
|
+
fakeStyle.sources.basemaps_raster = {
|
|
92
|
+
type: 'raster',
|
|
93
|
+
tiles: [`${host}/raster?api=${Api.key}`],
|
|
94
|
+
};
|
|
95
|
+
fakeStyle.sources.basemaps_raster_encode = {
|
|
96
|
+
type: 'raster',
|
|
97
|
+
tiles: [`${host}/raster/{z}/{x}/{y}.webp?api=${Api.key}`],
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
fakeStyle.sprite = `${host}/sprite`;
|
|
101
|
+
fakeStyle.glyphs = `${host}/glyphs`;
|
|
102
|
+
|
|
103
|
+
o(JSON.parse(body)).deepEquals(fakeStyle);
|
|
104
|
+
});
|
|
105
|
+
});
|
|
@@ -1,59 +1,9 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { Config, LogConfig } from '@basemaps/shared';
|
|
3
|
-
import { LambdaHttpRequest, LambdaUrlRequest } from '@linzjs/lambda';
|
|
4
|
-
import { Context } from 'aws-lambda';
|
|
1
|
+
import { Config } from '@basemaps/shared';
|
|
5
2
|
import o from 'ospec';
|
|
6
|
-
import { handleRequest } from '../../index.js';
|
|
7
|
-
import { ulid } from 'ulid';
|
|
8
|
-
import { getImageFormats } from '../tile.wmts.js';
|
|
9
3
|
import { createSandbox } from 'sinon';
|
|
4
|
+
import { handler } from '../../index.js';
|
|
10
5
|
import { Imagery2193, Imagery3857, Provider, TileSetAerial } from '../../__tests__/config.data.js';
|
|
11
|
-
|
|
12
|
-
function newRequest(path: string, query: string): LambdaHttpRequest {
|
|
13
|
-
return new LambdaUrlRequest(
|
|
14
|
-
{
|
|
15
|
-
requestContext: { http: { method: 'GET' } },
|
|
16
|
-
headers: {},
|
|
17
|
-
rawPath: path,
|
|
18
|
-
rawQueryString: query,
|
|
19
|
-
isBase64Encoded: false,
|
|
20
|
-
} as any,
|
|
21
|
-
{} as Context,
|
|
22
|
-
LogConfig.get(),
|
|
23
|
-
);
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
o.spec('GetImageFormats', () => {
|
|
27
|
-
o('should parse all formats', () => {
|
|
28
|
-
const req = newRequest('/v1/blank', 'format=png&format=jpeg');
|
|
29
|
-
const formats = getImageFormats(req);
|
|
30
|
-
o(formats).deepEquals([ImageFormat.Png, ImageFormat.Jpeg]);
|
|
31
|
-
});
|
|
32
|
-
|
|
33
|
-
o('should ignore bad formats', () => {
|
|
34
|
-
const req = newRequest('/v1/blank', 'format=fake&format=mvt');
|
|
35
|
-
const formats = getImageFormats(req);
|
|
36
|
-
o(formats).equals(undefined);
|
|
37
|
-
});
|
|
38
|
-
|
|
39
|
-
o('should de-dupe formats', () => {
|
|
40
|
-
const req = newRequest('/v1/blank', 'format=png&format=jpeg&format=png&format=jpeg&format=png&format=jpeg');
|
|
41
|
-
const formats = getImageFormats(req);
|
|
42
|
-
o(formats).deepEquals([ImageFormat.Png, ImageFormat.Jpeg]);
|
|
43
|
-
});
|
|
44
|
-
|
|
45
|
-
o('should support "tileFormat" Alias all formats', () => {
|
|
46
|
-
const req = newRequest('/v1/blank', 'tileFormat=png&format=jpeg');
|
|
47
|
-
const formats = getImageFormats(req);
|
|
48
|
-
o(formats).deepEquals([ImageFormat.Jpeg, ImageFormat.Png]);
|
|
49
|
-
});
|
|
50
|
-
|
|
51
|
-
o('should not duplicate "tileFormat" alias all formats', () => {
|
|
52
|
-
const req = newRequest('/v1/blank', 'tileFormat=jpeg&format=jpeg');
|
|
53
|
-
const formats = getImageFormats(req);
|
|
54
|
-
o(formats).deepEquals([ImageFormat.Jpeg]);
|
|
55
|
-
});
|
|
56
|
-
});
|
|
6
|
+
import { Api, mockUrlRequest } from '../../__tests__/xyz.util.js';
|
|
57
7
|
|
|
58
8
|
o.spec('WMTSRouting', () => {
|
|
59
9
|
const sandbox = createSandbox();
|
|
@@ -70,8 +20,8 @@ o.spec('WMTSRouting', () => {
|
|
|
70
20
|
const imageryStub = sandbox.stub(Config.Imagery, 'getAll').returns(Promise.resolve(imagery));
|
|
71
21
|
const providerStub = sandbox.stub(Config.Provider, 'get').returns(Promise.resolve(Provider));
|
|
72
22
|
|
|
73
|
-
const req =
|
|
74
|
-
const res = await
|
|
23
|
+
const req = mockUrlRequest('/v1/tiles/WMTSCapabilities.xml', `format=png&api=${Api.key}`);
|
|
24
|
+
const res = await handler.router.handle(req);
|
|
75
25
|
|
|
76
26
|
o(tileSetStub.calledOnce).equals(true);
|
|
77
27
|
o(tileSetStub.args[0][0]).equals('ts_aerial');
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import { Config, ConfigProviderMemory } from '@basemaps/config';
|
|
2
|
+
import { LogConfig } from '@basemaps/shared';
|
|
3
|
+
import { round } from '@basemaps/test/build/rounding.js';
|
|
4
|
+
import o from 'ospec';
|
|
5
|
+
import sinon from 'sinon';
|
|
6
|
+
import { handler } from '../../index.js';
|
|
7
|
+
import { Etag } from '../../util/etag.js';
|
|
8
|
+
import { FakeData } from '../../__tests__/config.data.js';
|
|
9
|
+
import { Api, mockRequest } from '../../__tests__/xyz.util.js';
|
|
10
|
+
|
|
11
|
+
const sandbox = sinon.createSandbox();
|
|
12
|
+
|
|
13
|
+
const TileSetNames = ['aerial', 'aerial:ōtorohanga_urban_2021_0-1m_RGB', '01FYWKAJ86W9P7RWM1VB62KD0H'];
|
|
14
|
+
o.spec('/v1/tiles', () => {
|
|
15
|
+
const config = new ConfigProviderMemory();
|
|
16
|
+
|
|
17
|
+
o.beforeEach(() => {
|
|
18
|
+
LogConfig.get().level = 'silent';
|
|
19
|
+
Config.setConfigProvider(config);
|
|
20
|
+
config.objects.clear();
|
|
21
|
+
|
|
22
|
+
for (const tileSetName of TileSetNames) config.put(FakeData.tileSetRaster(tileSetName));
|
|
23
|
+
|
|
24
|
+
sandbox.stub(Etag, 'key').returns('fakeEtag');
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
o.afterEach(() => {
|
|
28
|
+
sandbox.restore();
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
o('should export handler', async () => {
|
|
32
|
+
const base = await import('../../index.js');
|
|
33
|
+
o(typeof base.handler).equals('function');
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
TileSetNames.forEach((tileSetName) => {
|
|
37
|
+
o(`should generate a tile/v1/tiles/${tileSetName}/global-mercator/0/0/0.png`, async () => {
|
|
38
|
+
const request = mockRequest(`/v1/tiles/${tileSetName}/global-mercator/0/0/0.png`, 'get', Api.header);
|
|
39
|
+
const res = await handler.router.handle(request);
|
|
40
|
+
o(res.status).equals(200);
|
|
41
|
+
o(res.header('content-type')).equals('image/png');
|
|
42
|
+
o(res.header('eTaG')).equals('fakeEtag');
|
|
43
|
+
|
|
44
|
+
// Validate the session information has been set correctly
|
|
45
|
+
o(request.logContext['tileSet']).equals(tileSetName);
|
|
46
|
+
o(request.logContext['xyz']).deepEquals({ x: 0, y: 0, z: 0 });
|
|
47
|
+
o(round(request.logContext['location'])).deepEquals({ lat: 0, lon: 0 });
|
|
48
|
+
});
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
o('should generate a tile 0,0,0 for webp', async () => {
|
|
52
|
+
const request = mockRequest('/v1/tiles/aerial/3857/0/0/0.webp', 'get', Api.header);
|
|
53
|
+
const res = await handler.router.handle(request);
|
|
54
|
+
o(res.status).equals(200);
|
|
55
|
+
o(res.header('content-type')).equals('image/webp');
|
|
56
|
+
o(res.header('eTaG')).equals('fakeEtag');
|
|
57
|
+
// o(res.body).equals(rasterMockBuffer.toString('base64'));
|
|
58
|
+
|
|
59
|
+
// Validate the session information has been set correctly
|
|
60
|
+
o(request.logContext['xyz']).deepEquals({ x: 0, y: 0, z: 0 });
|
|
61
|
+
o(round(request.logContext['location'])).deepEquals({ lat: 0, lon: 0 });
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
['png', 'webp', 'jpeg', 'avif'].forEach((fmt) => {
|
|
65
|
+
o(`should 200 with empty ${fmt} if a tile is out of bounds`, async () => {
|
|
66
|
+
// tiler.tile = async () => [];
|
|
67
|
+
const res = await handler.router.handle(
|
|
68
|
+
mockRequest(`/v1/tiles/aerial/global-mercator/0/0/0.${fmt}`, 'get', Api.header),
|
|
69
|
+
);
|
|
70
|
+
o(res.status).equals(200);
|
|
71
|
+
o(res.header('content-type')).equals(`image/${fmt}`);
|
|
72
|
+
o(res.header('etag')).notEquals(undefined);
|
|
73
|
+
o(res.header('cache-control')).equals('public, max-age=604800, stale-while-revalidate=86400');
|
|
74
|
+
// o(rasterMock.calls.length).equals(1);
|
|
75
|
+
});
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
o('should 304 if a tile is not modified', async () => {
|
|
79
|
+
const key = 'fakeEtag';
|
|
80
|
+
const request = mockRequest('/v1/tiles/aerial/global-mercator/0/0/0.png', 'get', {
|
|
81
|
+
'if-none-match': key,
|
|
82
|
+
...Api.header,
|
|
83
|
+
});
|
|
84
|
+
const res = await handler.router.handle(request);
|
|
85
|
+
o(res.status).equals(304);
|
|
86
|
+
o(res.header('eTaG')).equals(undefined);
|
|
87
|
+
|
|
88
|
+
o(request.logContext['cache']).deepEquals({ match: key, hit: true });
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
o('should 404 if a tile is outside of the range', async () => {
|
|
92
|
+
const res = await handler.router.handle(
|
|
93
|
+
mockRequest('/v1/tiles/aerial/global-mercator/25/0/0.png', 'get', Api.header),
|
|
94
|
+
);
|
|
95
|
+
o(res.status).equals(404);
|
|
96
|
+
|
|
97
|
+
const resB = await handler.router.handle(mockRequest('/v1/tiles/aerial/2193/17/0/0.png', 'get', Api.header));
|
|
98
|
+
o(resB.status).equals(404);
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
o('should support utf8 tilesets', async () => {
|
|
102
|
+
const fakeTileSet = FakeData.tileSetRaster('🦄 🌈');
|
|
103
|
+
config.put(fakeTileSet);
|
|
104
|
+
const req = mockRequest('/v1/tiles/🦄 🌈/global-mercator/0/0/0.png', 'get', Api.header);
|
|
105
|
+
o(req.path).equals('/v1/tiles/%F0%9F%A6%84%20%F0%9F%8C%88/global-mercator/0/0/0.png');
|
|
106
|
+
const res = await handler.router.handle(req);
|
|
107
|
+
o(res.status).equals(200);
|
|
108
|
+
o(res.header('content-type')).equals('image/png');
|
|
109
|
+
o(res.header('etag')).notEquals(undefined);
|
|
110
|
+
o(res.header('cache-control')).equals('public, max-age=604800, stale-while-revalidate=86400');
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
['/favicon.ico', '/index.html', '/foo/bar'].forEach((path) => {
|
|
114
|
+
o('should 404 on invalid paths: ' + path, async () => {
|
|
115
|
+
const res = await handler.router.handle(mockRequest(path, 'get', Api.header));
|
|
116
|
+
o(res.status).equals(404);
|
|
117
|
+
});
|
|
118
|
+
});
|
|
119
|
+
});
|