diff --git a/THIRD-PARTY-NOTICES b/THIRD-PARTY-NOTICES index ede2848a..d71b2a88 100644 --- a/THIRD-PARTY-NOTICES +++ b/THIRD-PARTY-NOTICES @@ -1,9 +1,8 @@ -The following NPM packages may be included in this product: +The following NPM package may be included in this product: - - @babel/runtime-corejs3@7.15.4 - @babel/runtime@7.14.6 -These packages each contain the following license and notice below: +This package contains the following license and notice below: MIT License @@ -60,12 +59,11 @@ SOFTWARE. ----------- -The following NPM packages may be included in this product: +The following NPM package may be included in this product: - - @yext/answers-core@1.3.2 - @yext/answers-headless@0.1.0-beta.4 -These packages each contain the following license and notice below: +This package contains the following license and notice below: BSD 3-Clause License @@ -99,64 +97,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ----------- -The following NPM package may be included in this product: - - - core-js-pure@3.17.3 - -This package contains the following license and notice below: - -Copyright (c) 2014-2021 Denis Pushkarev - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - ------------ - -The following NPM package may be included in this product: - - - cross-fetch@3.1.4 - -This package contains the following license and notice below: - -The MIT License (MIT) - -Copyright (c) 2017 Leonardo Quixadá - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - ------------ - The following NPM package may be included in this product: - immer@9.0.6 @@ -217,36 +157,6 @@ SOFTWARE. ----------- -The following NPM package may be included in this product: - - - node-fetch@2.6.1 - -This package contains the following license and notice below: - -The MIT License (MIT) - -Copyright (c) 2016 David Frank - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - ------------ - The following NPM packages may be included in this product: - redux-thunk@2.3.0 diff --git a/package-lock.json b/package-lock.json index 0f3421d8..1d565fc2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,7 +10,7 @@ "license": "ISC", "dependencies": { "@reduxjs/toolkit": "^1.6.0", - "@yext/answers-core": "^1.3.2", + "@yext/answers-core": "file:~/answers-core", "js-levenshtein": "^1.1.6", "redux-thunk": "^2.3.0" }, @@ -20,6 +20,7 @@ "@types/jest": "^26.0.24", "@types/lodash": "^4.14.175", "@types/node": "^14.14.28", + "@types/uuid": "^8.3.3", "@typescript-eslint/eslint-plugin": "^4.28.2", "@typescript-eslint/parser": "^4.28.2", "@yext/eslint-plugin-export-star": "^1.0.0", @@ -32,6 +33,38 @@ "typescript": "^4.1.5" } }, + "../answers-core": { + "name": "@yext/answers-core", + "version": "1.5.0-beta.1", + "license": "BSD-3-Clause", + "dependencies": { + "@babel/runtime-corejs3": "^7.12.5", + "cross-fetch": "^3.1.4" + }, + "devDependencies": { + "@babel/core": "^7.12.3", + "@babel/plugin-transform-runtime": "^7.12.10", + "@babel/preset-env": "^7.12.1", + "@babel/preset-typescript": "^7.12.1", + "@microsoft/api-documenter": "^7.11.3", + "@microsoft/api-extractor": "^7.12.0", + "@types/jest": "^26.0.15", + "@typescript-eslint/eslint-plugin": "^4.6.0", + "@typescript-eslint/parser": "^4.6.0", + "babel-jest": "^26.6.1", + "babel-loader": "^8.2.2", + "eslint": "^7.11.0", + "generate-license-file": "^1.1.0", + "jest": "^26.6.0", + "ts-loader": "^8.0.14", + "typescript": "^4.0.3", + "webpack": "^5.18.0", + "webpack-cli": "^4.4.0" + }, + "engines": { + "node": ">=12" + } + }, "node_modules/@babel/code-frame": { "version": "7.14.5", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.14.5.tgz", @@ -1660,18 +1693,6 @@ "node": ">=6.9.0" } }, - "node_modules/@babel/runtime-corejs3": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.15.4.tgz", - "integrity": "sha512-lWcAqKeB624/twtTc3w6w/2o9RqJPaNBhPGK6DKLSiwuVWC7WFkypWyNg+CpZoyJH0jVzv1uMtXZ/5/lQOLtCg==", - "dependencies": { - "core-js-pure": "^3.16.0", - "regenerator-runtime": "^0.13.4" - }, - "engines": { - "node": ">=6.9.0" - } - }, "node_modules/@babel/template": { "version": "7.14.5", "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.14.5.tgz", @@ -2335,6 +2356,12 @@ "integrity": "sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==", "dev": true }, + "node_modules/@types/uuid": { + "version": "8.3.3", + "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-8.3.3.tgz", + "integrity": "sha512-0LbEEx1zxrYB3pgpd1M5lEhLcXjKJnYghvhTRgaBeUivLHMDM1TzF3IJ6hXU2+8uA4Xz+5BA63mtZo5DjVT8iA==", + "dev": true + }, "node_modules/@types/yargs": { "version": "16.0.4", "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz", @@ -2555,16 +2582,8 @@ } }, "node_modules/@yext/answers-core": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/@yext/answers-core/-/answers-core-1.3.2.tgz", - "integrity": "sha512-hZO5XigSH3n5FtLYjhAAlvcBFVe0rQOv30BlbXr4cgGTR5+0w2D7c+Lu+N9RaGTuec7lcwFYIDLSeDAh/mZDRw==", - "dependencies": { - "@babel/runtime-corejs3": "^7.12.5", - "cross-fetch": "^3.1.4" - }, - "engines": { - "node": ">=0.12" - } + "resolved": "../answers-core", + "link": true }, "node_modules/@yext/eslint-plugin-export-star": { "version": "1.0.0", @@ -3402,30 +3421,12 @@ "semver": "bin/semver.js" } }, - "node_modules/core-js-pure": { - "version": "3.17.3", - "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.17.3.tgz", - "integrity": "sha512-YusrqwiOTTn8058JDa0cv9unbXdIiIgcgI9gXso0ey4WgkFLd3lYlV9rp9n7nDCsYxXsMDTjA4m1h3T348mdlQ==", - "hasInstallScript": true, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/core-js" - } - }, "node_modules/create-require": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", "dev": true }, - "node_modules/cross-fetch": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.4.tgz", - "integrity": "sha512-1eAtFWdIubi6T4XPy6ei9iUFoKpUkIF971QLN8lIvvvwueI65+Nw5haMNKUwfJxabqlIIDODJKGrQ66gxC0PbQ==", - "dependencies": { - "node-fetch": "2.6.1" - } - }, "node_modules/cross-spawn": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", @@ -6440,14 +6441,6 @@ "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", "dev": true }, - "node_modules/node-fetch": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz", - "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==", - "engines": { - "node": "4.x || >=6.0.0" - } - }, "node_modules/node-int64": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", @@ -9367,15 +9360,6 @@ "regenerator-runtime": "^0.13.4" } }, - "@babel/runtime-corejs3": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.15.4.tgz", - "integrity": "sha512-lWcAqKeB624/twtTc3w6w/2o9RqJPaNBhPGK6DKLSiwuVWC7WFkypWyNg+CpZoyJH0jVzv1uMtXZ/5/lQOLtCg==", - "requires": { - "core-js-pure": "^3.16.0", - "regenerator-runtime": "^0.13.4" - } - }, "@babel/template": { "version": "7.14.5", "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.14.5.tgz", @@ -9922,6 +9906,12 @@ "integrity": "sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==", "dev": true }, + "@types/uuid": { + "version": "8.3.3", + "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-8.3.3.tgz", + "integrity": "sha512-0LbEEx1zxrYB3pgpd1M5lEhLcXjKJnYghvhTRgaBeUivLHMDM1TzF3IJ6hXU2+8uA4Xz+5BA63mtZo5DjVT8iA==", + "dev": true + }, "@types/yargs": { "version": "16.0.4", "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz", @@ -10053,12 +10043,28 @@ } }, "@yext/answers-core": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/@yext/answers-core/-/answers-core-1.3.2.tgz", - "integrity": "sha512-hZO5XigSH3n5FtLYjhAAlvcBFVe0rQOv30BlbXr4cgGTR5+0w2D7c+Lu+N9RaGTuec7lcwFYIDLSeDAh/mZDRw==", + "version": "file:../answers-core", "requires": { + "@babel/core": "^7.12.3", + "@babel/plugin-transform-runtime": "^7.12.10", + "@babel/preset-env": "^7.12.1", + "@babel/preset-typescript": "^7.12.1", "@babel/runtime-corejs3": "^7.12.5", - "cross-fetch": "^3.1.4" + "@microsoft/api-documenter": "^7.11.3", + "@microsoft/api-extractor": "^7.12.0", + "@types/jest": "^26.0.15", + "@typescript-eslint/eslint-plugin": "^4.6.0", + "@typescript-eslint/parser": "^4.6.0", + "babel-jest": "^26.6.1", + "babel-loader": "^8.2.2", + "cross-fetch": "^3.1.4", + "eslint": "^7.11.0", + "generate-license-file": "^1.1.0", + "jest": "^26.6.0", + "ts-loader": "^8.0.14", + "typescript": "^4.0.3", + "webpack": "^5.18.0", + "webpack-cli": "^4.4.0" } }, "@yext/eslint-plugin-export-star": { @@ -10681,25 +10687,12 @@ } } }, - "core-js-pure": { - "version": "3.17.3", - "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.17.3.tgz", - "integrity": "sha512-YusrqwiOTTn8058JDa0cv9unbXdIiIgcgI9gXso0ey4WgkFLd3lYlV9rp9n7nDCsYxXsMDTjA4m1h3T348mdlQ==" - }, "create-require": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", "dev": true }, - "cross-fetch": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.4.tgz", - "integrity": "sha512-1eAtFWdIubi6T4XPy6ei9iUFoKpUkIF971QLN8lIvvvwueI65+Nw5haMNKUwfJxabqlIIDODJKGrQ66gxC0PbQ==", - "requires": { - "node-fetch": "2.6.1" - } - }, "cross-spawn": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", @@ -13013,11 +13006,6 @@ "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", "dev": true }, - "node-fetch": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz", - "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==" - }, "node-int64": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", diff --git a/package.json b/package.json index 5b31d92d..23fcf8d4 100644 --- a/package.json +++ b/package.json @@ -18,7 +18,7 @@ }, "dependencies": { "@reduxjs/toolkit": "^1.6.0", - "@yext/answers-core": "^1.3.2", + "@yext/answers-core": "file:~/answers-core", "js-levenshtein": "^1.1.6", "redux-thunk": "^2.3.0" }, @@ -28,6 +28,7 @@ "@types/jest": "^26.0.24", "@types/lodash": "^4.14.175", "@types/node": "^14.14.28", + "@types/uuid": "^8.3.3", "@typescript-eslint/eslint-plugin": "^4.28.2", "@typescript-eslint/parser": "^4.28.2", "@yext/eslint-plugin-export-star": "^1.0.0", diff --git a/src/answers-headless.ts b/src/answers-headless.ts index 7b0f334a..bb9ccda9 100644 --- a/src/answers-headless.ts +++ b/src/answers-headless.ts @@ -16,7 +16,7 @@ import { FilterSearchResponse, UniversalLimit, VerticalSearchResponse -} from '@yext/answers-core'; +} from '../../answers-core/lib/esm'; import StateListener from './models/state-listener'; import { State } from './models/state'; @@ -48,6 +48,10 @@ export default class AnswersHeadless { this.stateManager.dispatchEvent('query/setSource', source); } + setAutocompleteSessionId(uuid: string): void { + this.stateManager.dispatchEvent('query/setAutocompleteSessionId', uuid); + } + setVerticalKey(verticalKey: string): void { this.stateManager.dispatchEvent('vertical/setVerticalKey', verticalKey); } @@ -134,6 +138,7 @@ export default class AnswersHeadless { const sessionId = this.state.sessionTracking.sessionId; const { referrerPageUrl, context } = this.state.meta; const { userLocation } = this.state.location; + const autocompleteSessionId = this.state.query.autocompleteSessionId; const response = await this.core.universalSearch({ query: input || '', @@ -145,7 +150,8 @@ export default class AnswersHeadless { limit, location: userLocation, context, - referrerPageUrl + referrerPageUrl, + ...(autocompleteSessionId && { autocompleteSessionId }) }); const latestResponseId = this.httpManager.getLatestResponseId('universalQuery'); @@ -191,6 +197,7 @@ export default class AnswersHeadless { const sortBys = this.state.filters?.sortBys; const { referrerPageUrl, context } = this.state.meta; const { userLocation } = this.state.location; + const autocompleteSessionId = this.state.query.autocompleteSessionId; const facetsToApply = facets?.map(facet => { return { @@ -215,7 +222,8 @@ export default class AnswersHeadless { location: userLocation, sortBys, context, - referrerPageUrl + referrerPageUrl, + ...(autocompleteSessionId && { autocompleteSessionId }) }; const response = await this.core.verticalSearch(request); const latestResponseId = this.httpManager.getLatestResponseId('verticalQuery'); diff --git a/src/index.ts b/src/index.ts index bdcb2ea0..cfffa0ef 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,4 +1,4 @@ -import { provideCore, AnswersConfig } from '@yext/answers-core'; +import { provideCore, AnswersConfig } from '../../answers-core/lib/esm'; import HttpManager from './http-manager'; import ReduxStateManager from './redux-state-manager'; import AnswersHeadless from './answers-headless'; @@ -10,9 +10,7 @@ import { SessionTrackingState } from './models/slices/sessiontracking'; export * from '@yext/answers-core'; export * from './utils/filter-creators'; -export interface HeadlessConfig extends AnswersConfig { - headlessId?: string -} +type HeadlessConfig = AnswersConfig & { headlessId?: string } let firstHeadlessInstance: AnswersHeadless; const store = createBaseStore(); diff --git a/src/models/slices/query.ts b/src/models/slices/query.ts index 6f7ef91f..e4f4e9bc 100644 --- a/src/models/slices/query.ts +++ b/src/models/slices/query.ts @@ -6,5 +6,6 @@ export interface QueryState { queryTrigger?: QueryTrigger, querySource?: QuerySource, mostRecentSearch?: string, - searchIntents?: SearchIntent[] + searchIntents?: SearchIntent[], + autocompleteSessionId?: string } \ No newline at end of file diff --git a/src/models/state.ts b/src/models/state.ts index 49b67dfc..5b73dda4 100644 --- a/src/models/state.ts +++ b/src/models/state.ts @@ -25,7 +25,7 @@ export interface State { filters: FiltersState, searchStatus: SearchStatusState, spellCheck: SpellCheckState, - sessionTracking: SessionTrackingState + sessionTracking: SessionTrackingState, meta: MetaState, location: LocationState, } diff --git a/src/slices/query.ts b/src/slices/query.ts index 81a6a2af..7990e1ac 100644 --- a/src/slices/query.ts +++ b/src/slices/query.ts @@ -5,22 +5,25 @@ import { QueryState } from '../models/slices/query'; const initialState: QueryState = {}; const reducers = { - setInput: (state, action: PayloadAction) => { + setInput: (state: QueryState, action: PayloadAction) => { state.input = action.payload; }, - setTrigger: (state, action: PayloadAction) => { + setTrigger: (state: QueryState, action: PayloadAction) => { state.queryTrigger = action.payload; }, - setSource: (state, action: PayloadAction) => { + setSource: (state: QueryState, action: PayloadAction) => { state.querySource = action.payload; }, - setQueryId: (state, action: PayloadAction) => { + setQueryId: (state: QueryState, action: PayloadAction) => { state.queryId = action.payload; }, - setMostRecentSearch: (state, action: PayloadAction) => { + setAutocompleteSessionId: (state: QueryState, action: PayloadAction) => { + state.autocompleteSessionId = action.payload; + }, + setMostRecentSearch: (state: QueryState, action: PayloadAction) => { state.mostRecentSearch = action.payload; }, - setSearchIntents: (state, action: PayloadAction) => { + setSearchIntents: (state: QueryState, action: PayloadAction) => { state.searchIntents = action.payload; } }; diff --git a/tests/integration/query.ts b/tests/integration/query.ts index f5b8892b..f39eccb6 100644 --- a/tests/integration/query.ts +++ b/tests/integration/query.ts @@ -24,6 +24,36 @@ it('vertical searches set search intents', async () => { expect(answers.state.query.searchIntents).toEqual(['NEAR_ME']); }); +it('related query search a grouped with updated uuid', async () => { + const mockUniversalSearch = jest.fn().mockReturnValue(Promise.resolve({})); + const mockVerticalSearch = jest.fn().mockReturnValue(Promise.resolve({})); + const answers = createMockedAnswersHeadless({ + universalSearch: mockUniversalSearch, + verticalSearch: mockVerticalSearch + }); + answers.setVerticalKey('vertical-key'); + + answers.setAutocompleteSessionId('some-uuid-value'); + await answers.executeUniversalQuery(); + await answers.executeVerticalQuery(); + expect(mockUniversalSearch).toHaveBeenLastCalledWith( + expect.objectContaining({ autocompleteSessionId: 'some-uuid-value' }) + ); + expect(mockVerticalSearch).toHaveBeenLastCalledWith( + expect.objectContaining({ autocompleteSessionId: 'some-uuid-value' }) + ); + + answers.setAutocompleteSessionId('different-uuid-value'); + await answers.executeUniversalQuery(); + await answers.executeVerticalQuery(); + expect(mockUniversalSearch).toHaveBeenLastCalledWith( + expect.objectContaining({ autocompleteSessionId: 'different-uuid-value' }) + ); + expect(mockVerticalSearch).toHaveBeenLastCalledWith( + expect.objectContaining({ autocompleteSessionId: 'different-uuid-value' }) + ); +}); + it('universal searches set search intents', async () => { const mockSearch = jest.fn((_request: UniversalSearchRequest) => Promise.resolve({ searchIntents: [SearchIntent.NearMe] diff --git a/tests/unit/answers-headless.ts b/tests/unit/answers-headless.ts index e0270c2a..7d483660 100644 --- a/tests/unit/answers-headless.ts +++ b/tests/unit/answers-headless.ts @@ -229,6 +229,17 @@ describe('setters work as expected', () => { expect(dispatchEventCalls[0][0]).toBe('vertical/setOffset'); expect(dispatchEventCalls[0][1]).toBe(offset); }); + + it('setAutocompleteSessionId works as expected', () => { + answers.setAutocompleteSessionId('some-uuid-value'); + + const dispatchEventCalls = + mockedStateManager.dispatchEvent.mock.calls; + + expect(dispatchEventCalls.length).toBe(1); + expect(dispatchEventCalls[0][0]).toBe('query/setAutocompleteSessionId'); + expect(dispatchEventCalls[0][1]).toBe('some-uuid-value'); + }); }); describe('filter functions work as expected', () => { diff --git a/tests/unit/slices/query.ts b/tests/unit/slices/query.ts index 5be826cd..4d83b760 100644 --- a/tests/unit/slices/query.ts +++ b/tests/unit/slices/query.ts @@ -2,7 +2,13 @@ import { QuerySource, QueryTrigger } from '@yext/answers-core'; import createQuerySlice from '../../../src/slices/query'; const { reducer, actions } = createQuerySlice(''); -const { setInput, setQueryId, setSource, setTrigger } = actions; +const { + setInput, + setQueryId, + setSource, + setTrigger, + setAutocompleteSessionId +} = actions; describe('query slice reducer works as expected', () => { it('setQuery action is handled properly', () => { @@ -36,4 +42,15 @@ describe('query slice reducer works as expected', () => { expect(actualState).toEqual(expectedState); }); + + it('setAutocompleteSessionId action is handled properly', () => { + const initalState = { + autocompleteSessionId: 'very-old-uuid-value' + }; + const expectedState = { + autocompleteSessionId: 'some-uuid-value' + }; + const actualState = reducer(initalState, setAutocompleteSessionId('some-uuid-value')); + expect(actualState).toEqual(expectedState); + }); }); \ No newline at end of file