aboutsummaryrefslogtreecommitdiffziptar.gz
path: root/viewer/tests/urlstate.test.mjs
diff options
context:
space:
mode:
Diffstat (limited to 'viewer/tests/urlstate.test.mjs')
-rw-r--r--viewer/tests/urlstate.test.mjs77
1 files changed, 77 insertions, 0 deletions
diff --git a/viewer/tests/urlstate.test.mjs b/viewer/tests/urlstate.test.mjs
new file mode 100644
index 0000000..f32656e
--- /dev/null
+++ b/viewer/tests/urlstate.test.mjs
@@ -0,0 +1,77 @@
+import './_planet.mjs';
+import { test } from 'node:test';
+import assert from 'node:assert/strict';
+import { parse, serialize, DEFAULT, carryHash } from '../js/urlstate.js';
+
+test('round trip', () => {
+ const s = { ...DEFAULT, layer: 'biomes', view: 'equal_earth', lat: 40.5, lon: -10.25, alt: 0.5, zoom: 3, overlays: ['coast', 'pins'] };
+ assert.deepEqual(parse(serialize(s)), s);
+ const t = { ...s, over: 'biomes', op: 0.35, sky: true, day: 100, mo: 12345, alt: 0.0004, zoom: 20000 };
+ assert.deepEqual(parse(serialize(t)), t);
+});
+
+test('new keys clamp and default', () => {
+ const s = parse('#op=7&day=300&mo=-5&sky=maybe&alt=0.00001&zoom=1e9');
+ assert.equal(s.op, 1);
+ assert.equal(s.day, 215);
+ assert.equal(s.mo, 0);
+ assert.equal(s.sky, false);
+ assert.equal(s.alt, 0.00001); // above the 20 m floor now
+ assert.equal(s.zoom, 20000);
+ assert.equal(s.over, '');
+});
+
+test('garbage and out-of-range values fall back or clamp', () => {
+ const s = parse('#view=nope&lat=abc&lon=200&alt=99&zoom=0');
+ assert.equal(s.view, DEFAULT.view);
+ assert.equal(s.lat, DEFAULT.lat);
+ assert.equal(s.lon, -160);
+ assert.equal(s.alt, 5);
+ assert.equal(s.zoom, 1);
+ assert.deepEqual(parse(''), DEFAULT);
+});
+
+test('clamps come from the shared view limits', async () => {
+ const { MIN_ALT, MAX_ALT, MAX_ZOOM } = await import('../js/limits.js');
+ const s = parse('#alt=1e-9&zoom=1e12');
+ assert.equal(s.alt, MIN_ALT);
+ assert.equal(s.zoom, MAX_ZOOM);
+ assert.equal(parse('#alt=1e9').alt, MAX_ALT);
+});
+
+test('tilt and 3D: round trip, clamps, only written when they differ from the default', () => {
+ const s = { ...DEFAULT, alt: 0.001, hd: 30.5, pt: 45, terrain: 2.5 };
+ assert.deepEqual(parse(serialize(s)), s);
+ assert.deepEqual(parse(serialize({ ...DEFAULT, terrain: 0 })), { ...DEFAULT, terrain: 0 });
+ assert.ok(!/hd=|pt=|3d=/.test(serialize(DEFAULT)));
+ assert.ok(!/hd=|pt=/.test(serialize({ ...DEFAULT, view: 'equal_earth', hd: 30, pt: 40 })), 'flat views have no tilt');
+ const c = parse('#hd=-90&pt=95&3d=9');
+ assert.deepEqual([c.hd, c.pt, c.terrain], [270, 80, 5]);
+ assert.equal(parse('#3d=0.4').terrain, 1);
+ assert.equal(parse('#3d=-2').terrain, 0);
+ assert.equal(parse('#3d=abc').terrain, 1);
+});
+
+test('era and water round-trip; defaults stay out of the URL', () => {
+ const s = { ...DEFAULT, era: 'age-of-legends', water: false };
+ assert.deepEqual(parse(serialize(s)), s);
+ assert.doesNotMatch(serialize(DEFAULT), /era=|water=/);
+ assert.equal(parse('#water=1').water, true);
+ assert.equal(parse('#era=').era, '');
+});
+
+test('the sea floor replaces relief only on the 3D globe with the water off', async () => {
+ const { drawnLayer } = await import('../js/urlstate.js');
+ const s = { ...DEFAULT, water: false };
+ assert.equal(drawnLayer(s, 'globe'), 'seafloor');
+ assert.equal(drawnLayer({ ...s, terrain: 0 }, 'globe'), 'relief', '3D off: the water toggle is hidden');
+ assert.equal(drawnLayer(s, 'equal_earth'), 'relief');
+ assert.equal(drawnLayer({ ...s, layer: 'biomes' }, 'globe'), 'biomes');
+ assert.equal(drawnLayer(DEFAULT, 'globe'), 'relief');
+});
+
+test('carryHash keeps the view, drops era and time', () => {
+ assert.equal(carryHash('#layer=ground&view=globe&lat=10&era=high-fantasy&sky=1&day=50&mo=9'), '#layer=ground&view=globe&lat=10&sky=1');
+ assert.equal(carryHash('#era=x'), '');
+ assert.equal(carryHash(''), '');
+});