Skip to content

Commit

Permalink
Merge pull request #873 from a13o/clear-stale-search-results
Browse files Browse the repository at this point in the history
Clear stale search results when version is changed
  • Loading branch information
MinThaMie authored Jul 27, 2023
2 parents e9683b3 + ac3f44d commit 65735b1
Show file tree
Hide file tree
Showing 5 changed files with 210 additions and 3 deletions.
7 changes: 7 additions & 0 deletions app/components/search-input.js
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,13 @@ export default class SearchInput extends Component {
}

@action onfocus() {
if (this.query.length > 0 && this.searchService.hasStaleResults()) {
// clearing the results avoids a flash of stale content while the search
// is performed
this.searchService.clearResults();
this.searchService.search.perform(this.query);
}

this._focused = true;
}

Expand Down
22 changes: 22 additions & 0 deletions app/services/search.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ export default Service.extend({
_projectService: service('project'),
_projectVersion: alias('_projectService.version'),

/** @type {?string} */
_lastQueriedProjectVersion: null,

results: emberArray(),

search: task(function* (query) {
Expand All @@ -30,6 +33,8 @@ export default Service.extend({
query,
};

this._lastQueriedProjectVersion = projectVersion;

return set(this, 'results', yield this.doSearch(searchObj, params));
}).restartable(),

Expand All @@ -38,4 +43,21 @@ export default Service.extend({
.search(searchObj, params)
.then((results) => results.hits);
},

/**
* Whenever the version changes in service:project, the results in this
* service become stale. Presenting them any further could allow the user to
* undo their version change by clicking a stale link.
* @returns {boolean}
*/
hasStaleResults() {
return (
this._lastQueriedProjectVersion !== null &&
this._projectVersion !== this._lastQueriedProjectVersion
);
},

clearResults() {
set(this, 'results', emberArray());
},
});
40 changes: 37 additions & 3 deletions tests/acceptance/search-test.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import { module, test } from 'qunit';
import { visit, currentURL, fillIn, click } from '@ember/test-helpers';
import { visit, currentURL, fillIn, click, focus } from '@ember/test-helpers';
import { selectChoose } from 'ember-power-select/test-support';
import { setupApplicationTest } from 'ember-qunit';

import searchResults from 'ember-api-docs/tests/fixtures/searchresult';
import searchResultsV4_1 from 'ember-api-docs/tests/fixtures/searchresult-v-4-1';
import searchResultsV5_1 from 'ember-api-docs/tests/fixtures/searchresult-v-5-1';

module('Acceptance | search', function (hooks) {
setupApplicationTest(hooks);
Expand All @@ -13,7 +15,7 @@ module('Acceptance | search', function (hooks) {
const algoliaService = this.owner.lookup('service:algolia');

algoliaService.search = async () => {
return searchResults;
return searchResultsV4_1;
};

await fillIn('[data-test-search-input]', 'forEach');
Expand All @@ -25,4 +27,36 @@ module('Acceptance | search', function (hooks) {
'/ember/4.1/classes/EmberArray/methods/forEach?anchor=forEach'
);
});

test('discard stale search results when version changes', async function (assert) {
await visit('/');

const algoliaService = this.owner.lookup('service:algolia');

algoliaService.search = async () => {
return searchResultsV4_1;
};

await selectChoose('.ember-power-select-trigger', '4.1');

await fillIn('[data-test-search-input]', 'forEach');

// the url contains /ember/4.1/
assert
.dom('[data-test-search-result]')
.hasAttribute('href', /\/ember\/4\.1\//);

algoliaService.search = async () => {
return searchResultsV5_1;
};

await selectChoose('.ember-power-select-trigger', '5.1');

await focus('[data-test-search-input]');

// the url contains /ember/5.1/
assert
.dom('[data-test-search-result]')
.hasAttribute('href', /\/ember\/5\.1\//);
});
});
File renamed without changes.
144 changes: 144 additions & 0 deletions tests/fixtures/searchresult-v-5-1.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
export default {
hits: [
{
file: 'packages/@ember/array/index.ts',
line: 447,
module: '@ember/array',
class: 'EmberArray',
name: 'forEach',
access: 'public',
_tags: ['module:@ember/array', 'version:5.1.2'],
hierarchy: { lvl0: '@ember/array', lvl1: 'EmberArray', lvl2: 'forEach' },
objectID: '5215324000',
_highlightResult: {
name: {
value: '<em>forEach</em>',
matchLevel: 'full',
fullyHighlighted: true,
matchedWords: ['foreach'],
},
hierarchy: {
lvl0: { value: '@ember/array', matchLevel: 'none', matchedWords: [] },
lvl1: { value: 'EmberArray', matchLevel: 'none', matchedWords: [] },
lvl2: {
value: '<em>forEach</em>',
matchLevel: 'full',
fullyHighlighted: true,
matchedWords: ['foreach'],
},
},
},
},
{
file: 'packages/@ember/array/index.ts',
line: 447,
module: '@ember/array',
class: 'MutableArray',
name: 'forEach',
access: 'public',
_tags: ['module:@ember/array', 'version:5.1.2'],
hierarchy: {
lvl0: '@ember/array',
lvl1: 'MutableArray',
lvl2: 'forEach',
},
objectID: '5215295000',
_highlightResult: {
name: {
value: '<em>forEach</em>',
matchLevel: 'full',
fullyHighlighted: true,
matchedWords: ['foreach'],
},
hierarchy: {
lvl0: { value: '@ember/array', matchLevel: 'none', matchedWords: [] },
lvl1: { value: 'MutableArray', matchLevel: 'none', matchedWords: [] },
lvl2: {
value: '<em>forEach</em>',
matchLevel: 'full',
fullyHighlighted: true,
matchedWords: ['foreach'],
},
},
},
},
{
file: 'packages/@ember/array/index.ts',
line: 447,
module: '@ember/array',
class: 'Ember.NativeArray',
name: 'forEach',
access: 'public',
_tags: ['module:@ember/array', 'version:5.1.2'],
hierarchy: {
lvl0: '@ember/array',
lvl1: 'Ember.NativeArray',
lvl2: 'forEach',
},
objectID: '5215250000',
_highlightResult: {
name: {
value: '<em>forEach</em>',
matchLevel: 'full',
fullyHighlighted: true,
matchedWords: ['foreach'],
},
hierarchy: {
lvl0: { value: '@ember/array', matchLevel: 'none', matchedWords: [] },
lvl1: {
value: 'Ember.NativeArray',
matchLevel: 'none',
matchedWords: [],
},
lvl2: {
value: '<em>forEach</em>',
matchLevel: 'full',
fullyHighlighted: true,
matchedWords: ['foreach'],
},
},
},
},
{
file: 'packages/@ember/array/index.ts',
line: 447,
module: '@ember/array',
class: 'ArrayProxy',
name: 'forEach',
access: 'public',
_tags: ['module:@ember/array', 'version:5.1.2'],
hierarchy: { lvl0: '@ember/array', lvl1: 'ArrayProxy', lvl2: 'forEach' },
objectID: '5215191000',
_highlightResult: {
name: {
value: '<em>forEach</em>',
matchLevel: 'full',
fullyHighlighted: true,
matchedWords: ['foreach'],
},
hierarchy: {
lvl0: { value: '@ember/array', matchLevel: 'none', matchedWords: [] },
lvl1: { value: 'ArrayProxy', matchLevel: 'none', matchedWords: [] },
lvl2: {
value: '<em>forEach</em>',
matchLevel: 'full',
fullyHighlighted: true,
matchedWords: ['foreach'],
},
},
},
},
],
nbHits: 4,
page: 0,
nbPages: 1,
hitsPerPage: 15,
exhaustiveNbHits: true,
exhaustiveTypo: true,
exhaustive: { nbHits: true, typo: true },
query: 'forEach',
params:
'query=forEach&hitsPerPage=15&restrictSearchableAttributes=%5B%22hierarchy.lvl0%22%2C%22hierarchy.lvl1%22%2C%22hierarchy.lvl2%22%5D&tagFilters=%5B%22version%3A5.1.2%22%5D&facetFilters=%5B%22access%3A-private%22%5D',
processingTimeMS: 1,
processingTimingsMS: { request: { roundTrip: 22 } },
};

0 comments on commit 65735b1

Please sign in to comment.