From 623674b6d64d0f03a129651fdfa859b570baff54 Mon Sep 17 00:00:00 2001 From: Livia Rett <30511433+liviarett@users.noreply.github.com> Date: Tue, 21 Jun 2022 11:00:00 -0300 Subject: [PATCH] fix(headless): update recent queries only when query has results (#2110) * feat(atomic): update recent queries only when query has results https://coveord.atlassian.net/browse/KIT-1751 * update quantic tests https://coveord.atlassian.net/browse/KIT-1751 --- .../recent-queries-slice.test.ts | 47 ++++++++++++++----- .../recent-queries/recent-queries-slice.ts | 3 +- .../recent-queries-list.cypress.ts | 36 ++++++++++++-- .../quantic/cypress/page-objects/search.ts | 13 +++++ 4 files changed, 84 insertions(+), 15 deletions(-) diff --git a/packages/headless/src/features/recent-queries/recent-queries-slice.test.ts b/packages/headless/src/features/recent-queries/recent-queries-slice.test.ts index 6e94edce547..7cc9b45e076 100644 --- a/packages/headless/src/features/recent-queries/recent-queries-slice.test.ts +++ b/packages/headless/src/features/recent-queries/recent-queries-slice.test.ts @@ -11,6 +11,14 @@ import { getRecentQueriesInitialState, RecentQueriesState, } from './recent-queries-state'; +import {Result} from '../../api/search/search/result'; + +function withResult(rest = {}) { + return { + results: [{title: 'result'} as Result], + ...rest, + }; +} describe('recent-queries-slice', () => { let state: RecentQueriesState; @@ -62,9 +70,11 @@ describe('recent-queries-slice', () => { const searchAction = executeSearch.fulfilled( buildMockSearch({ queryExecuted: testQuery, - response: buildMockSearchResponse({ - queryCorrections: [{correctedQuery: 'foo', wordCorrections: []}], - }), + response: buildMockSearchResponse( + withResult({ + queryCorrections: [{correctedQuery: 'foo', wordCorrections: []}], + }) + ), }), '', logSearchEvent({evt: 'foo'}) @@ -82,9 +92,11 @@ describe('recent-queries-slice', () => { const searchAction = executeSearch.fulfilled( buildMockSearch({ queryExecuted: otherTestQuery, - response: buildMockSearchResponse({ - queryCorrections: [{correctedQuery: 'foo', wordCorrections: []}], - }), + response: buildMockSearchResponse( + withResult({ + queryCorrections: [{correctedQuery: 'foo', wordCorrections: []}], + }) + ), }), '', logSearchEvent({evt: 'foo'}) @@ -102,7 +114,7 @@ describe('recent-queries-slice', () => { const searchAction = executeSearch.fulfilled( buildMockSearch({ queryExecuted: '6', - response: buildMockSearchResponse({}), + response: buildMockSearchResponse(withResult()), }), '', logSearchEvent({evt: 'foo'}) @@ -118,14 +130,14 @@ describe('recent-queries-slice', () => { }); it('should not add new recent query on search fulfilled if queue already contains the query', () => { - const duplicates = ['what is a query', ' what is a query ']; + const duplicates = [testQuery, ` ${testQuery} `]; for (const i in duplicates) { state.queries = testQueries; state.maxLength = 10; const searchAction = executeSearch.fulfilled( buildMockSearch({ queryExecuted: duplicates[i], - response: buildMockSearchResponse({}), + response: buildMockSearchResponse(withResult()), }), '', logSearchEvent({evt: 'foo'}) @@ -137,13 +149,26 @@ describe('recent-queries-slice', () => { } }); + it('should not add new recent query on search fulfilled if there are no results', () => { + const searchAction = executeSearch.fulfilled( + buildMockSearch({ + queryExecuted: 'bloobloo', + response: buildMockSearchResponse({}), + }), + '', + logSearchEvent({evt: 'foo'}) + ); + + expect(recentQueriesReducer(state, searchAction).queries).toEqual([]); + }); + it('should not add an empty query to the list', () => { const emptyQueries = ['', ' ']; for (const i in emptyQueries) { const searchAction = executeSearch.fulfilled( buildMockSearch({ queryExecuted: emptyQueries[i], - response: buildMockSearchResponse({}), + response: buildMockSearchResponse(withResult()), }), '', logSearchEvent({evt: 'foo'}) @@ -161,7 +186,7 @@ describe('recent-queries-slice', () => { const searchAction = executeSearch.fulfilled( buildMockSearch({ queryExecuted: '3', - response: buildMockSearchResponse({}), + response: buildMockSearchResponse(withResult()), }), '', logSearchEvent({evt: 'foo'}) diff --git a/packages/headless/src/features/recent-queries/recent-queries-slice.ts b/packages/headless/src/features/recent-queries/recent-queries-slice.ts index fa341d6c041..648acfa1c56 100644 --- a/packages/headless/src/features/recent-queries/recent-queries-slice.ts +++ b/packages/headless/src/features/recent-queries/recent-queries-slice.ts @@ -22,7 +22,8 @@ export const recentQueriesReducer = createReducer( }) .addCase(executeSearch.fulfilled, (state, action) => { const query = action.payload.queryExecuted.trim(); - if (!query.length) { + const results = action.payload.response.results; + if (!query.length || !results.length) { return; } state.queries = state.queries.filter((q) => q !== query); diff --git a/packages/quantic/cypress/integration/recent-queries-list/recent-queries-list.cypress.ts b/packages/quantic/cypress/integration/recent-queries-list/recent-queries-list.cypress.ts index 01d6ded0b09..d9b692ae956 100644 --- a/packages/quantic/cypress/integration/recent-queries-list/recent-queries-list.cypress.ts +++ b/packages/quantic/cypress/integration/recent-queries-list/recent-queries-list.cypress.ts @@ -1,5 +1,10 @@ import {configure} from '../../page-objects/configurator'; -import {InterceptAliases, interceptSearch} from '../../page-objects/search'; +import { + InterceptAliases, + interceptSearch, + mockSearchNoResults, + mockSearchWithResults, +} from '../../page-objects/search'; import {RecentQueriesListExpectations as Expect} from './recent-queries-list-expectations'; import {scope} from '../../reporters/detailed-collector'; import { @@ -32,8 +37,16 @@ describe('quantic-recent-queries-list', () => { const pageUrl = 's/quantic-recent-queries-list'; const defaultMaxLength = 10; - function visitRecentQueries(options: Partial = {}) { + function visitRecentQueries( + options: Partial = {}, + returnResults = true + ) { interceptSearch(); + if (returnResults) { + mockSearchWithResults(); + } else { + mockSearchNoResults(); + } cy.visit(pageUrl); configure(options); } @@ -41,7 +54,7 @@ describe('quantic-recent-queries-list', () => { urlHash: string, options: Partial = {} ) { - interceptSearch(); + mockSearchWithResults(); cy.visit(`${pageUrl}#${urlHash}`); configure(options); cy.wait(InterceptAliases.Search); @@ -110,6 +123,23 @@ describe('quantic-recent-queries-list', () => { }); }); + describe('when there are no results', () => { + it('should work as expected', () => { + visitRecentQueries({}, false); + + scope('when searching new queries', () => { + createRandomQueriesList(2).forEach((query) => { + setQuery(query); + performSearch().wait(InterceptAliases.Search); + + Expect.displayQueries(false); + Expect.displayEmptyList(true); + clearInput(); + }); + }); + }); + }); + describe('with custom #maxLength', () => { const customMaxLength = 3; diff --git a/packages/quantic/cypress/page-objects/search.ts b/packages/quantic/cypress/page-objects/search.ts index f4145274d8e..c469764e0be 100644 --- a/packages/quantic/cypress/page-objects/search.ts +++ b/packages/quantic/cypress/page-objects/search.ts @@ -156,6 +156,19 @@ export function mockSearchNoResults() { }).as(InterceptAliases.Search.substring(1)); } +export function mockSearchWithResults() { + cy.intercept(routeMatchers.search, (req) => { + req.continue((res) => { + res.body.results = [ + {title: 'Result', uri: 'uri', raw: {urihash: 'resulthash'}}, + ]; + res.body.totalCount = 1; + res.body.totalCountFiltered = 1; + res.send(); + }); + }).as(InterceptAliases.Search.substring(1)); +} + export function interceptResultHtmlContent() { cy.intercept('POST', routeMatchers.html).as( InterceptAliases.ResultHtml.substring(1)