From e4e90f28115835b83e5c6bb408d4fc1d07317c2a Mon Sep 17 00:00:00 2001 From: Laura Martinez Garcia Date: Mon, 11 Nov 2024 14:04:32 +0100 Subject: [PATCH 1/2] feat: add lang parameter to the queriesPreview hash --- .../__tests__/query-preview.spec.ts | 25 ++++++------ .../components/query-preview-list.vue | 9 ++++- .../components/query-preview.vue | 4 +- .../store/__tests__/actions.spec.ts | 38 +++++++++++++------ .../fetch-and-save-query-preview.action.ts | 3 +- .../x-modules/queries-preview/store/module.ts | 4 +- .../utils/__tests__/utils.spec.ts | 15 +++++--- .../utils/get-hash-from-query-preview.ts | 16 ++++++-- 8 files changed, 76 insertions(+), 38 deletions(-) diff --git a/packages/x-components/src/x-modules/queries-preview/components/__tests__/query-preview.spec.ts b/packages/x-components/src/x-modules/queries-preview/components/__tests__/query-preview.spec.ts index 90a9afa6af..d443248194 100644 --- a/packages/x-components/src/x-modules/queries-preview/components/__tests__/query-preview.spec.ts +++ b/packages/x-components/src/x-modules/queries-preview/components/__tests__/query-preview.spec.ts @@ -64,11 +64,12 @@ async function render({ } ); - const queryPreviewInfoHash = getHashFromQueryPreviewInfo(queryPreviewInfo); + const queryPreviewInfoHash = getHashFromQueryPreviewInfo(queryPreviewInfo, 'en'); queryPreviewInState.request = { query: queryPreviewInfo.query }; resetXQueriesPreviewStateWith(store, { queriesPreview: { [queryPreviewInfoHash]: queryPreviewInState } }); + store.commit('x/queriesPreview/setParams', { lang: 'en' }); await nextTick(); const queryPreviewRequestUpdatedSpy = jest.fn(); @@ -118,7 +119,7 @@ describe('query preview', () => { filters: ['fit:regular'] } }); - const query = getHashFromQueryPreviewInfo(queryPreviewInfo); + const query = getHashFromQueryPreviewInfo(queryPreviewInfo, 'en'); expect(queryPreviewRequestUpdatedSpy).toHaveBeenCalledTimes(0); expect(queryPreviewWrapper.emitted('load')?.length).toEqual(1); @@ -167,7 +168,8 @@ describe('query preview', () => { expect(queryPreviewRequestUpdatedSpy).toHaveBeenCalledTimes(1); expect(queryPreviewRequestUpdatedSpy).toHaveBeenCalledWith({ extraParams: { - directory: 'Magrathea' + directory: 'Magrathea', + lang: 'en' }, filters: { fit: [{ id: 'fit:regular', modelName: 'RawFilter', selected: true }] @@ -185,7 +187,8 @@ describe('query preview', () => { expect(queryPreviewRequestUpdatedSpy).toHaveBeenNthCalledWith(2, { extraParams: { - directory: 'Magrathea' + directory: 'Magrathea', + lang: 'en' }, filters: { fit: [{ id: 'fit:regular', modelName: 'RawFilter', selected: true }] @@ -222,7 +225,7 @@ describe('query preview', () => { jest.advanceTimersToNextTimer(); expect(queryPreviewRequestUpdatedSpy).toHaveBeenNthCalledWith(1, { - extraParams: {}, + extraParams: { lang: 'en' }, filters: undefined, origin: 'query_suggestion:predictive_layer', query: 'shoes', @@ -318,7 +321,7 @@ describe('query preview', () => { totalResults: 100 } }); - const query = getHashFromQueryPreviewInfo(queryPreviewInfo); + const query = getHashFromQueryPreviewInfo(queryPreviewInfo, 'en'); await flushPromises(); @@ -340,7 +343,7 @@ describe('query preview', () => { instances: 1 } }); - const query = getHashFromQueryPreviewInfo(queryPreviewInfo); + const query = getHashFromQueryPreviewInfo(queryPreviewInfo, 'en'); await flushPromises(); @@ -363,7 +366,7 @@ describe('query preview', () => { totalResults: 100 } }); - const query = getHashFromQueryPreviewInfo({ query: 'milk' }); + const query = getHashFromQueryPreviewInfo({ query: 'milk' }, 'en'); await flushPromises(); @@ -384,7 +387,7 @@ describe('query preview', () => { expect(queryPreviewRequestUpdatedSpy).toHaveBeenCalledTimes(1); expect(queryPreviewRequestUpdatedSpy).toHaveBeenNthCalledWith(1, { - extraParams: {}, + extraParams: { lang: 'en' }, query: 'bull', rows: 24 }); @@ -402,7 +405,7 @@ describe('query preview', () => { jest.advanceTimersByTime(1); // 250ms since mounting the component, the debounce tested expect(queryPreviewRequestUpdatedSpy).toHaveBeenCalledTimes(1); expect(queryPreviewRequestUpdatedSpy).toHaveBeenNthCalledWith(1, { - extraParams: {}, + extraParams: { lang: 'en' }, query: 'bull', rows: 24 }); @@ -424,7 +427,7 @@ describe('query preview', () => { jest.advanceTimersByTime(251); expect(queryPreviewRequestUpdatedSpy).toHaveBeenCalledTimes(2); expect(queryPreviewRequestUpdatedSpy).toHaveBeenNthCalledWith(2, { - extraParams: {}, + extraParams: { lang: 'en' }, query: 'secallona', rows: 24 }); diff --git a/packages/x-components/src/x-modules/queries-preview/components/query-preview-list.vue b/packages/x-components/src/x-modules/queries-preview/components/query-preview-list.vue index 2c4ba1a512..b2b8348381 100644 --- a/packages/x-components/src/x-modules/queries-preview/components/query-preview-list.vue +++ b/packages/x-components/src/x-modules/queries-preview/components/query-preview-list.vue @@ -29,6 +29,7 @@ import { QueryPreviewInfo } from '../store/types'; import { getHashFromQueryPreviewInfo } from '../utils/get-hash-from-query-preview'; import { AnimationProp, QueryFeature } from '../../../types'; + import { useState } from '../../../composables/index'; import QueryPreview from './query-preview.vue'; interface QueryPreviewStatusRecord { @@ -100,6 +101,8 @@ } }, setup(props) { + const { params } = useState('queriesPreview', ['params']); + /** * Contains the status of the preview requests, indexed by query. */ @@ -112,7 +115,9 @@ * @internal */ const queries = computed((): string[] => - props.queriesPreviewInfo.map(item => getHashFromQueryPreviewInfo(item)) + props.queriesPreviewInfo.map(item => + getHashFromQueryPreviewInfo(item, params.value.lang as string) + ) ); /** @@ -123,7 +128,7 @@ */ const renderedQueryPreviews = computed((): QueryPreviewInfo[] => { return props.queriesPreviewInfo.filter(item => { - const queryPreviewHash = getHashFromQueryPreviewInfo(item); + const queryPreviewHash = getHashFromQueryPreviewInfo(item, params.value.lang as string); return ( queriesStatus.value[queryPreviewHash] === 'success' || queriesStatus.value[queryPreviewHash] === 'loading' diff --git a/packages/x-components/src/x-modules/queries-preview/components/query-preview.vue b/packages/x-components/src/x-modules/queries-preview/components/query-preview.vue index 5563bd6883..fc24612c60 100644 --- a/packages/x-components/src/x-modules/queries-preview/components/query-preview.vue +++ b/packages/x-components/src/x-modules/queries-preview/components/query-preview.vue @@ -121,7 +121,9 @@ * * @returns The query hash. */ - const queryPreviewHash = computed(() => getHashFromQueryPreviewInfo(props.queryPreviewInfo)); + const queryPreviewHash = computed(() => + getHashFromQueryPreviewInfo(props.queryPreviewInfo, params.value.lang as string) + ); provide('queryPreviewHash', queryPreviewHash); diff --git a/packages/x-components/src/x-modules/queries-preview/store/__tests__/actions.spec.ts b/packages/x-components/src/x-modules/queries-preview/store/__tests__/actions.spec.ts index 5d1c4323b3..2546c253e9 100644 --- a/packages/x-components/src/x-modules/queries-preview/store/__tests__/actions.spec.ts +++ b/packages/x-components/src/x-modules/queries-preview/store/__tests__/actions.spec.ts @@ -88,7 +88,10 @@ describe('testing queries preview module actions', () => { const request = getQueryPreviewRequest(queryPreview.query); await nextTick(); const stateResults = store.state.queriesPreview; - const queryId = getHashFromQueryPreviewInfo(queryPreview); + const queryId = getHashFromQueryPreviewInfo( + queryPreview, + request.extraParams?.lang as string + ); const expectedResults: QueryPreviewItem = { totalResults: mockedSearchResponse.totalResults, results: mockedSearchResponse.results, @@ -133,7 +136,10 @@ describe('testing queries preview module actions', () => { adapter.search.mockRejectedValueOnce('Generic error'); const queryPreview: QueryPreviewInfo = { query: 'sandals' }; const request = getQueryPreviewRequest(queryPreview.query); - const queryId = getHashFromQueryPreviewInfo(queryPreview); + const queryId = getHashFromQueryPreviewInfo( + queryPreview, + request.extraParams?.lang as string + ); await store.dispatch('fetchAndSaveQueryPreview', request); expect(store.state.queriesPreview[queryId].status).toEqual('error'); @@ -141,16 +147,24 @@ describe('testing queries preview module actions', () => { it('should send multiple requests if the queries are different', async () => { const { store } = renderQueryPreviewActions(); - const firstQuery = getHashFromQueryPreviewInfo({ query: 'milk' }); - const secondQuery = getHashFromQueryPreviewInfo({ query: 'cookies' }); - const firstRequest = store.dispatch( - 'fetchAndSaveQueryPreview', - getQueryPreviewRequest('milk') - ); - const secondRequest = store.dispatch( - 'fetchAndSaveQueryPreview', - getQueryPreviewRequest('cookies') - ); + const firstQuery = getHashFromQueryPreviewInfo({ query: 'milk' }, 'en'); + const secondQuery = getHashFromQueryPreviewInfo({ query: 'cookies' }, 'en'); + const firstRequest = store.dispatch('fetchAndSaveQueryPreview', { + query: 'milk', + rows: 3, + extraParams: { + extraParam: 'extra param', + lang: 'en' + } + }); + const secondRequest = store.dispatch('fetchAndSaveQueryPreview', { + query: 'cookies', + rows: 3, + extraParams: { + extraParam: 'extra param', + lang: 'en' + } + }); await Promise.all([firstRequest, secondRequest]); diff --git a/packages/x-components/src/x-modules/queries-preview/store/actions/fetch-and-save-query-preview.action.ts b/packages/x-components/src/x-modules/queries-preview/store/actions/fetch-and-save-query-preview.action.ts index 702bc57e0c..362079c72a 100644 --- a/packages/x-components/src/x-modules/queries-preview/store/actions/fetch-and-save-query-preview.action.ts +++ b/packages/x-components/src/x-modules/queries-preview/store/actions/fetch-and-save-query-preview.action.ts @@ -45,7 +45,8 @@ export const fetchAndSaveQueryPreview: QueriesPreviewXStoreModule['actions']['fe .catch(error => { // eslint-disable-next-line no-console console.error(error); - const queryPreviewHash = getHashFromQueryPreviewItem(queryPreviewItem); + const lang = request.extraParams ? request.extraParams.lang : ''; + const queryPreviewHash = getHashFromQueryPreviewItem(queryPreviewItem, lang as string); commit('setStatus', { queryPreviewHash, status: 'error' }); }); }; diff --git a/packages/x-components/src/x-modules/queries-preview/store/module.ts b/packages/x-components/src/x-modules/queries-preview/store/module.ts index de9fc645eb..45f3aaf91d 100644 --- a/packages/x-components/src/x-modules/queries-preview/store/module.ts +++ b/packages/x-components/src/x-modules/queries-preview/store/module.ts @@ -32,7 +32,9 @@ export const queriesPreviewXStoreModule: QueriesPreviewXStoreModule = { state.params = params; }, setQueryPreviewCached(state, queryPreview) { - state.queriesPreview[getHashFromQueryPreviewItem(queryPreview)] = queryPreview; + state.queriesPreview[ + getHashFromQueryPreviewItem(queryPreview, queryPreview.request.extraParams?.lang as string) + ] = queryPreview; }, setStatus(state, { queryPreviewHash, status }) { state.queriesPreview[queryPreviewHash].status = status; diff --git a/packages/x-components/src/x-modules/queries-preview/utils/__tests__/utils.spec.ts b/packages/x-components/src/x-modules/queries-preview/utils/__tests__/utils.spec.ts index 51b562190d..c892d6af0a 100644 --- a/packages/x-components/src/x-modules/queries-preview/utils/__tests__/utils.spec.ts +++ b/packages/x-components/src/x-modules/queries-preview/utils/__tests__/utils.spec.ts @@ -70,10 +70,13 @@ describe('testing queries preview module utils', () => { } ] }, - rows: 3 + rows: 3, + extraParams: { + lang: 'en' + } } }; - const queryHash = getHashFromQueryPreviewItem(queryPreviewItem); + const queryHash = getHashFromQueryPreviewItem(queryPreviewItem, 'en'); await store.dispatch('fetchAndSaveQueryPreview', queryPreviewItem.request); @@ -83,9 +86,9 @@ describe('testing queries preview module utils', () => { it('should check if a query hash from a QueryPreviewInfo is created correctly', () => { const queryPreviewInfo: QueryPreviewInfo = { query: 'tshirt', filters: ['fit:regular'] }; - const queryPreviewHash = getHashFromQueryPreviewInfo(queryPreviewInfo); + const queryPreviewHash = getHashFromQueryPreviewInfo(queryPreviewInfo, 'en'); - expect(queryPreviewHash).toBe('ba83786514cc76ebfd00da880b8068b2'); + expect(queryPreviewHash).toBe('3ed535c606cfe71ff84ebd2c4271fb9c'); }); // eslint-disable-next-line max-len @@ -110,10 +113,10 @@ describe('testing queries preview module utils', () => { rows: 3 } }; - const queryPreviewItemHash = getHashFromQueryPreviewItem(queryPreviewItem); + const queryPreviewItemHash = getHashFromQueryPreviewItem(queryPreviewItem, 'en'); const queryPreviewInfo: QueryPreviewInfo = { query: 'tshirt', filters: ['fit:regular'] }; - const queryPreviewInfoHash = getHashFromQueryPreviewInfo(queryPreviewInfo); + const queryPreviewInfoHash = getHashFromQueryPreviewInfo(queryPreviewInfo, 'en'); expect(queryPreviewItemHash).toBe(queryPreviewInfoHash); }); diff --git a/packages/x-components/src/x-modules/queries-preview/utils/get-hash-from-query-preview.ts b/packages/x-components/src/x-modules/queries-preview/utils/get-hash-from-query-preview.ts index a9de4b717c..e0251b44db 100644 --- a/packages/x-components/src/x-modules/queries-preview/utils/get-hash-from-query-preview.ts +++ b/packages/x-components/src/x-modules/queries-preview/utils/get-hash-from-query-preview.ts @@ -6,9 +6,13 @@ import { QueryPreviewInfo, QueryPreviewItem } from '../store/index'; * with different filters can be saved more than once in the state. * * @param queryPreview - The {@link QueryPreviewItem | QueryPreviewItem} used in the request. + * @param lang - The language used in the request. * @returns A unique id that will be used as a key to store the QueryPreviewItem in the state. */ -export const getHashFromQueryPreviewItem = (queryPreview: QueryPreviewItem): string => { +export const getHashFromQueryPreviewItem = ( + queryPreview: QueryPreviewItem, + lang: string +): string => { const queryPreviewFilters = queryPreview.request.filters ? Object.values(queryPreview.request.filters) .flat() @@ -16,17 +20,21 @@ export const getHashFromQueryPreviewItem = (queryPreview: QueryPreviewItem): str .join('-') : ''; - return md5(queryPreview.request.query.concat(queryPreviewFilters)); + return md5(queryPreview.request.query.concat(queryPreviewFilters).concat(lang)); }; /** * Creates a query hash to check if a QueryPreview has already been saved in the state. * * @param queryPreviewInfo - The {@link QueryPreviewInfo | QueryPreviewInfo} of a QueryPreview. + * @param lang - The language used in the request. * @returns A unique id that will be used as a key to check the QueryPreview in the state. */ -export const getHashFromQueryPreviewInfo = (queryPreviewInfo: QueryPreviewInfo): string => { +export const getHashFromQueryPreviewInfo = ( + queryPreviewInfo: QueryPreviewInfo, + lang: string +): string => { const queryPreviewFilters = queryPreviewInfo.filters ? queryPreviewInfo.filters.join('-') : ''; - return md5(queryPreviewInfo.query.concat(queryPreviewFilters)); + return md5(queryPreviewInfo.query.concat(queryPreviewFilters).concat(lang)); }; From 1560fbc8a0c06bdcfebde261d1b20cee5c800493 Mon Sep 17 00:00:00 2001 From: Laura Martinez Garcia Date: Tue, 12 Nov 2024 13:20:13 +0100 Subject: [PATCH 2/2] feat: add a query preview test --- .../components/__tests__/query-preview.spec.ts | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/packages/x-components/src/x-modules/queries-preview/components/__tests__/query-preview.spec.ts b/packages/x-components/src/x-modules/queries-preview/components/__tests__/query-preview.spec.ts index d443248194..ca949a4b04 100644 --- a/packages/x-components/src/x-modules/queries-preview/components/__tests__/query-preview.spec.ts +++ b/packages/x-components/src/x-modules/queries-preview/components/__tests__/query-preview.spec.ts @@ -215,6 +215,18 @@ describe('query preview', () => { }); }); + it('sends the `QueryPreviewRequestUpdated` event when the application language changes', async () => { + const { queryPreviewRequestUpdatedSpy, updateExtraParams } = await render({ + queryPreviewInfo: { query: 'shoes' }, + location: 'predictive_layer' + }); + + await updateExtraParams({ lang: 'es' }); + jest.advanceTimersToNextTimer(); + + expect(queryPreviewRequestUpdatedSpy).toHaveBeenCalledTimes(1); + }); + it('sends the `QueryPreviewRequestUpdated` event with the correct location provided', async () => { const { queryPreviewRequestUpdatedSpy, wrapper } = await render({ queryPreviewInfo: { query: 'shoes' },