143 lines
3.8 KiB
JavaScript
143 lines
3.8 KiB
JavaScript
import { module, test } from 'qunit';
|
|
import {
|
|
visit,
|
|
click,
|
|
fillIn,
|
|
triggerEvent,
|
|
currentURL,
|
|
} from '@ember/test-helpers';
|
|
import { setupApplicationTest } from 'marco/tests/helpers';
|
|
import Service from '@ember/service';
|
|
import { Promise } from 'rsvp';
|
|
|
|
class MockPhotonService extends Service {
|
|
cancelAll() {}
|
|
|
|
async search(query) {
|
|
// Simulate network delay
|
|
await new Promise((resolve) => setTimeout(resolve, 50));
|
|
if (query === 'slow') {
|
|
await new Promise((resolve) => setTimeout(resolve, 200));
|
|
}
|
|
return [
|
|
{
|
|
title: 'Test Place',
|
|
lat: 1,
|
|
lon: 1,
|
|
osmId: '123',
|
|
osmType: 'node',
|
|
},
|
|
];
|
|
}
|
|
}
|
|
|
|
class MockOsmService extends Service {
|
|
cancelAll() {}
|
|
|
|
async getCategoryPois(bounds, category) {
|
|
await new Promise((resolve) => setTimeout(resolve, 50));
|
|
if (category === 'slow_category') {
|
|
await new Promise((resolve) => setTimeout(resolve, 200));
|
|
}
|
|
return [];
|
|
}
|
|
async getNearbyPois() {
|
|
return [];
|
|
}
|
|
}
|
|
|
|
module('Acceptance | search loading', function (hooks) {
|
|
setupApplicationTest(hooks);
|
|
|
|
hooks.beforeEach(function () {
|
|
this.owner.register('service:photon', MockPhotonService);
|
|
this.owner.register('service:osm', MockOsmService);
|
|
});
|
|
|
|
test('search shows loading indicator but nearby search does not', async function (assert) {
|
|
const mapUi = this.owner.lookup('service:map-ui');
|
|
|
|
// 1. Text Search
|
|
// Start a search and check for loading state immediately
|
|
const searchPromise = visit('/search?q=slow');
|
|
|
|
// We can't easily check the DOM mid-transition in acceptance tests without complicated helpers,
|
|
// so we check the service state which drives the UI.
|
|
// Wait a tiny bit for the route to start processing
|
|
await new Promise((r) => setTimeout(r, 10));
|
|
|
|
assert.deepEqual(
|
|
mapUi.loadingState,
|
|
{ type: 'text', value: 'slow' },
|
|
'Loading state is set for text search'
|
|
);
|
|
|
|
await searchPromise;
|
|
assert.strictEqual(
|
|
mapUi.loadingState,
|
|
null,
|
|
'Loading state is cleared after text search'
|
|
);
|
|
|
|
// 2. Category Search
|
|
const catPromise = visit('/search?category=slow_category&lat=1&lon=1');
|
|
await new Promise((r) => setTimeout(r, 10));
|
|
|
|
assert.deepEqual(
|
|
mapUi.loadingState,
|
|
{ type: 'category', value: 'slow_category' },
|
|
'Loading state is set for category search'
|
|
);
|
|
|
|
await catPromise;
|
|
assert.strictEqual(
|
|
mapUi.loadingState,
|
|
null,
|
|
'Loading state is cleared after category search'
|
|
);
|
|
|
|
// 3. Nearby Search
|
|
await visit('/search?lat=1&lon=1');
|
|
assert.strictEqual(
|
|
mapUi.loadingState,
|
|
null,
|
|
'Loading state is NOT set for nearby search'
|
|
);
|
|
});
|
|
|
|
test('clearing search stops loading indicator', async function (assert) {
|
|
const mapUi = this.owner.lookup('service:map-ui');
|
|
|
|
// 1. Start from index
|
|
await visit('/');
|
|
|
|
// 2. Type "slow" to trigger autocomplete (which is async)
|
|
await fillIn('.search-input', 'slow');
|
|
|
|
// 3. Submit search to trigger route loading
|
|
click('.search-submit-btn'); // Intentionally no await to not block on transition
|
|
|
|
// Wait for loading state to activate
|
|
await new Promise((r) => setTimeout(r, 100));
|
|
|
|
assert.deepEqual(
|
|
mapUi.loadingState,
|
|
{ type: 'text', value: 'slow' },
|
|
'Loading state is set'
|
|
);
|
|
|
|
// 4. Click the clear button (should be visible since input has value)
|
|
await click('.search-clear-btn');
|
|
|
|
// Verify loading state is cleared immediately
|
|
assert.strictEqual(
|
|
mapUi.loadingState,
|
|
null,
|
|
'Loading state is cleared immediately after clicking clear'
|
|
);
|
|
|
|
// Verify we are back on index (or at least query is gone)
|
|
assert.strictEqual(currentURL(), '/', 'Navigated to index');
|
|
});
|
|
});
|