parent
348b721876
commit
59e3d91071
@ -56,6 +56,8 @@ export default class PlaceRoute extends Route {
|
||||
deactivate() {
|
||||
// Clear the pin when leaving the route
|
||||
this.mapUi.clearSelection();
|
||||
// Reset the "return to search" flag so it doesn't persist to subsequent navigations
|
||||
this.mapUi.returnToSearch = false;
|
||||
}
|
||||
|
||||
async loadOsmPlace(id, type = null) {
|
||||
|
||||
@ -6,6 +6,7 @@ export default class MapUiService extends Service {
|
||||
@tracked isSearching = false;
|
||||
@tracked isCreating = false;
|
||||
@tracked creationCoordinates = null;
|
||||
@tracked returnToSearch = false;
|
||||
|
||||
selectPlace(place) {
|
||||
this.selectedPlace = place;
|
||||
|
||||
@ -77,11 +77,11 @@ export default class PlaceTemplate extends Component {
|
||||
navigateBack(place) {
|
||||
// The sidebar calls this with null when "Back" is clicked.
|
||||
if (place === null) {
|
||||
// If we have history, go back (preserves search state)
|
||||
if (window.history.length > 1) {
|
||||
// If we came from search results, go back in history
|
||||
if (this.mapUi.returnToSearch) {
|
||||
window.history.back();
|
||||
} else {
|
||||
// Fallback if opened directly
|
||||
// Otherwise just close the sidebar (return to map index)
|
||||
this.router.transitionTo('index');
|
||||
}
|
||||
} else {
|
||||
|
||||
@ -5,10 +5,12 @@ import { action } from '@ember/object';
|
||||
|
||||
export default class SearchTemplate extends Component {
|
||||
@service router;
|
||||
@service mapUi;
|
||||
|
||||
@action
|
||||
selectPlace(place) {
|
||||
if (place) {
|
||||
this.mapUi.returnToSearch = true;
|
||||
this.router.transitionTo('place', place);
|
||||
}
|
||||
}
|
||||
|
||||
106
tests/acceptance/navigation-test.js
Normal file
106
tests/acceptance/navigation-test.js
Normal file
@ -0,0 +1,106 @@
|
||||
import { module, test } from 'qunit';
|
||||
import { visit, currentURL, click, settled } from '@ember/test-helpers';
|
||||
import { setupApplicationTest } from 'marco/tests/helpers';
|
||||
import Service from '@ember/service';
|
||||
import sinon from 'sinon';
|
||||
|
||||
class MockOsmService extends Service {
|
||||
async getNearbyPois() {
|
||||
return [
|
||||
{
|
||||
osmId: '123',
|
||||
lat: 1,
|
||||
lon: 1,
|
||||
osmTags: { name: 'Test Place', amenity: 'cafe' },
|
||||
osmType: 'node',
|
||||
},
|
||||
];
|
||||
}
|
||||
async getPoiById() {
|
||||
return {
|
||||
osmId: '123',
|
||||
lat: 1,
|
||||
lon: 1,
|
||||
osmTags: { name: 'Test Place', amenity: 'cafe' },
|
||||
osmType: 'node',
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
class MockStorageService extends Service {
|
||||
savedPlaces = [];
|
||||
findPlaceById() {
|
||||
return null;
|
||||
}
|
||||
loadPlacesInBounds() {
|
||||
return [];
|
||||
}
|
||||
get placesInView() {
|
||||
return [];
|
||||
}
|
||||
rs = {
|
||||
on: () => {},
|
||||
};
|
||||
}
|
||||
|
||||
module('Acceptance | navigation', function (hooks) {
|
||||
setupApplicationTest(hooks);
|
||||
|
||||
hooks.beforeEach(function () {
|
||||
this.owner.register('service:osm', MockOsmService);
|
||||
this.owner.register('service:storage', MockStorageService);
|
||||
});
|
||||
|
||||
test('navigating from search results to place and back uses history', async function (assert) {
|
||||
const mapUi = this.owner.lookup('service:map-ui');
|
||||
const backStub = sinon.stub(window.history, 'back');
|
||||
|
||||
try {
|
||||
await visit('/search?lat=1&lon=1');
|
||||
assert.strictEqual(currentURL(), '/search?lat=1&lon=1');
|
||||
|
||||
await click('.place-item');
|
||||
assert.ok(currentURL().includes('/place/'), 'Navigated to place');
|
||||
assert.true(mapUi.returnToSearch, 'Flag returnToSearch is set');
|
||||
|
||||
// Click the back button in the sidebar
|
||||
await click('.back-btn');
|
||||
|
||||
assert.true(backStub.calledOnce, 'window.history.back() was called');
|
||||
} finally {
|
||||
backStub.restore();
|
||||
}
|
||||
});
|
||||
|
||||
test('closing the sidebar resets the returnToSearch flag', async function (assert) {
|
||||
const mapUi = this.owner.lookup('service:map-ui');
|
||||
|
||||
await visit('/search?lat=1&lon=1');
|
||||
await click('.place-item'); // Sets returnToSearch = true
|
||||
|
||||
assert.true(mapUi.returnToSearch, 'Flag is set upon entering place');
|
||||
|
||||
// Click the Close (X) button
|
||||
await click('.close-btn');
|
||||
await settled();
|
||||
|
||||
assert.strictEqual(currentURL(), '/', 'Returned to index');
|
||||
assert.false(mapUi.returnToSearch, 'Flag is reset after closing sidebar');
|
||||
});
|
||||
|
||||
test('navigating directly to place and back closes sidebar', async function (assert) {
|
||||
const backStub = sinon.stub(window.history, 'back');
|
||||
try {
|
||||
await visit('/place/osm:node:123');
|
||||
assert.ok(currentURL().includes('/place/'), 'Visited place directly');
|
||||
|
||||
await click('.back-btn');
|
||||
await settled();
|
||||
|
||||
assert.strictEqual(currentURL(), '/', 'Returned to index/map');
|
||||
assert.true(backStub.notCalled, 'window.history.back() was NOT called');
|
||||
} finally {
|
||||
backStub.restore();
|
||||
}
|
||||
});
|
||||
});
|
||||
Loading…
x
Reference in New Issue
Block a user