Files
marco/tests/acceptance/map-search-reset-test.js

183 lines
4.8 KiB
JavaScript

import { module, test } from 'qunit';
import { visit, currentURL, waitFor, triggerEvent } from '@ember/test-helpers';
import { setupApplicationTest } from 'marco/tests/helpers';
import Service from '@ember/service';
import sinon from 'sinon';
module('Acceptance | map search reset', function (hooks) {
setupApplicationTest(hooks);
hooks.beforeEach(function () {
// Seed localStorage with a high zoom level to ensure map is interactive
const highZoomState = {
center: [13.4, 52.5],
zoom: 18,
};
window.localStorage.setItem(
'marco:map-view',
JSON.stringify(highZoomState)
);
// Stub window.fetch using Sinon
// We want to intercept map style requests and let everything else through
this.fetchStub = sinon.stub(window, 'fetch');
this.fetchStub.callsFake(async (input, init) => {
let url = input;
if (typeof input === 'object' && input !== null && 'url' in input) {
url = input.url;
}
if (
typeof url === 'string' &&
url.includes('tiles.openfreemap.org/styles/liberty')
) {
return {
ok: true,
status: 200,
json: async () => ({
version: 8,
name: 'Liberty',
sources: {
openmaptiles: {
type: 'vector',
url: 'https://tiles.openfreemap.org/planet',
},
},
layers: [
{
id: 'background',
type: 'background',
paint: {
'background-color': '#123456',
},
},
],
glyphs:
'https://tiles.openfreemap.org/fonts/{fontstack}/{range}.pbf',
sprite: 'https://tiles.openfreemap.org/sprites/liberty',
}),
};
}
// Pass through to the original implementation
return this.fetchStub.wrappedMethod(input, init);
});
});
hooks.afterEach(function () {
window.localStorage.removeItem('marco:map-view');
// Restore the original fetch
this.fetchStub.restore();
});
test('clicking the map clears the category search parameter', async function (assert) {
// Mock OSM Service
class MockOsmService extends Service {
async getCategoryPois() {
return [
{
title: 'Cafe Test',
lat: 52.52,
lon: 13.405,
osmId: '123',
osmType: 'N',
},
];
}
async getNearbyPois() {
return [];
}
}
this.owner.register('service:osm', MockOsmService);
// Mock Storage
this.owner.register(
'service:storage',
class extends Service {
rs = { on: () => {} };
placesInView = [];
savedPlaces = [];
loadPlacesInBounds() {
return Promise.resolve();
}
findPlaceById() {
return null;
}
}
);
// 1. Visit a category search URL
await visit('/search?category=coffee&lat=52.52&lon=13.405');
assert.dom('.sidebar-header').includesText('Results');
assert.ok(
currentURL().includes('category=coffee'),
'URL should have category param'
);
// 2. Click the map (First click closes sidebar)
await waitFor('canvas', { timeout: 2000 });
const canvas = document.querySelector('canvas');
if (canvas) {
// First Click (Close Sidebar)
await triggerEvent(canvas, 'pointerdown', {
clientX: 200,
clientY: 200,
button: 0,
isPrimary: true,
});
await triggerEvent(canvas, 'pointerup', {
clientX: 200,
clientY: 200,
button: 0,
isPrimary: true,
});
await triggerEvent(canvas, 'click', {
clientX: 200,
clientY: 200,
bubbles: true,
});
// Wait for transition to index
await new Promise((r) => setTimeout(r, 500));
assert.strictEqual(
currentURL(),
'/',
'Should have transitioned to index (closed sidebar)'
);
// Second Click (Start new search)
// Click slightly differently to ensure fresh event
await triggerEvent(canvas, 'pointerdown', {
clientX: 250,
clientY: 250,
button: 0,
isPrimary: true,
});
await triggerEvent(canvas, 'pointerup', {
clientX: 250,
clientY: 250,
button: 0,
isPrimary: true,
});
await triggerEvent(canvas, 'click', {
clientX: 250,
clientY: 250,
bubbles: true,
});
}
// 3. Wait for transition
await new Promise((r) => setTimeout(r, 1000));
const newUrl = currentURL();
assert.notOk(
newUrl.includes('category=coffee'),
`New URL ${newUrl} should not contain category param`
);
assert.ok(newUrl.includes('/search'), 'Should be on search route');
});
});