From cc60b02d28e7a65bc1219d852f3a21f73a8e5f97 Mon Sep 17 00:00:00 2001 From: Felix Sommer Date: Tue, 1 Oct 2024 13:24:14 +0200 Subject: [PATCH 1/6] PB-951: do not store swisssearch param in url --- .../menu/components/search/SearchBar.vue | 26 +++++++++------- .../storeSync/SearchParamConfig.class.js | 30 +++++++++++++++++-- .../cypress/tests-e2e/legacyParamImport.cy.js | 4 +-- .../tests-e2e/search/search-results.cy.js | 22 +++++++++----- 4 files changed, 59 insertions(+), 23 deletions(-) diff --git a/src/modules/menu/components/search/SearchBar.vue b/src/modules/menu/components/search/SearchBar.vue index a907f2898..8410e61a6 100644 --- a/src/modules/menu/components/search/SearchBar.vue +++ b/src/modules/menu/components/search/SearchBar.vue @@ -9,7 +9,7 @@ const dispatcher = { dispatcher: 'SearchBar' } const store = useStore() -const isPristine = ref(true) +const isPristine = ref(true) // if search bar is not yet modified by the user const showResults = ref(false) const searchInput = ref(null) const searchValue = ref('') @@ -20,16 +20,20 @@ const searchQuery = computed(() => store.state.search.query) const hasResults = computed(() => store.state.search.results.length > 0) const isPhoneMode = computed(() => store.getters.isPhoneMode) -watch(hasResults, (newValue) => { - // if an entry has been selected from the list, do not show the list again - // because the list has been hidden by onEntrySelected. Also if the search bar is pristine (not - // yet modified by the user) we don't want to show the result (e.g. at startup with a swisssearch - // query param) - if (!selectedEntry.value && !isPristine.value) { - log.debug(`Search has result changed to ${newValue}, change the show result to ${newValue}`) - showResults.value = newValue - } -}) +watch( + hasResults, + (newValue) => { + // if an entry has been selected from the list, do not show the list again + // because the list has been hidden by onEntrySelected. + if (!selectedEntry.value) { + log.debug( + `Search has result changed to ${newValue}, change the show result to ${newValue}` + ) + showResults.value = newValue + } + }, + { immediate: true } +) watch(showResults, (newValue) => { if (newValue && isPhoneMode.value && store.state.ui.showMenu) { diff --git a/src/router/storeSync/SearchParamConfig.class.js b/src/router/storeSync/SearchParamConfig.class.js index 47923fc50..071b8f15d 100644 --- a/src/router/storeSync/SearchParamConfig.class.js +++ b/src/router/storeSync/SearchParamConfig.class.js @@ -2,6 +2,7 @@ import AbstractParamConfig, { STORE_DISPATCHER_ROUTER_PLUGIN, } from '@/router/storeSync/abstractParamConfig.class' +const URL_PARAM_NAME = 'swisssearch' /** * The goal is to stop centering on the search when sharing a position. When we share a position, * both the center and the crosshair are sets. @@ -16,15 +17,38 @@ function dispatchSearchFromUrl(to, store, urlParamValue) { shouldCenter: !(to.query.crosshair && to.query.center), dispatcher: STORE_DISPATCHER_ROUTER_PLUGIN, }) + removeQueryParamFromHref(URL_PARAM_NAME) +} + +/** + * This will remove the query param from the URL It is necessary to do this in vanilla JS because + * the router does not provide a way to remove a query without reloading the page which then removes + * the value from the store + * + * @param {Object} key The key to remove from the URL + */ +function removeQueryParamFromHref(key) { + const [baseUrl, queryString] = window.location.href.split('?') + if (!queryString) { + return + } + + const params = new URLSearchParams(queryString) + if (!params.has(key)) { + return + } + params.delete(key) + + const newQueryString = params.toString() + const newUrl = newQueryString ? `${baseUrl}?${newQueryString}` : baseUrl + window.history.replaceState({}, document.title, newUrl) } export default class SearchParamConfig extends AbstractParamConfig { constructor() { super({ - urlParamName: 'swisssearch', - mutationsToWatch: ['setSearchQuery'], + urlParamName: URL_PARAM_NAME, setValuesInStore: dispatchSearchFromUrl, - extractValueFromStore: (store) => store.state.search.query, keepInUrlWhenDefault: false, valueType: String, defaultValue: '', diff --git a/tests/cypress/tests-e2e/legacyParamImport.cy.js b/tests/cypress/tests-e2e/legacyParamImport.cy.js index 98e4d6411..f3bfcd636 100644 --- a/tests/cypress/tests-e2e/legacyParamImport.cy.js +++ b/tests/cypress/tests-e2e/legacyParamImport.cy.js @@ -268,9 +268,9 @@ describe('Test on legacy param import', () => { false ) cy.readStoreValue('state.search.query').should('eq', '1530 Payerne') - cy.url().should('include', 'swisssearch=1530+Payerne') + cy.url().should('not.contain', 'swisssearch') cy.get('[data-cy="searchbar"]').click() - cy.get('[data-cy="search-results-locations"]').should('be.visible') + cy.get('[data-cy="search-results-locations"]').should('not.be.visible') }) it('External WMS layer', () => { const layerName = 'OpenData-AV' diff --git a/tests/cypress/tests-e2e/search/search-results.cy.js b/tests/cypress/tests-e2e/search/search-results.cy.js index 12ea2502d..3d112e0dd 100644 --- a/tests/cypress/tests-e2e/search/search-results.cy.js +++ b/tests/cypress/tests-e2e/search/search-results.cy.js @@ -165,18 +165,14 @@ describe('Test the search bar result handling', () => { .invoke('text') .should('eq', expectedLocationLabel.replaceAll(/<\/?b>/g, '')) - cy.log('Checking that it adds the search query as swisssearch URL param') - cy.url().should('contain', 'swisssearch=test') + cy.log('Checking that it does not add the search query as swisssearch URL param') + cy.url().should('not.contain', 'swisssearch') cy.log( 'Checking that it reads the swisssearch URL param at startup and launch a search with its content' ) - cy.reload() - cy.waitMapIsReady() - cy.wait(['@search-locations', '@search-layers']) + cy.readStoreValue('state.search.query').should('eq', 'test') - cy.get('@locationSearchResults').should('not.be.visible') - cy.get(searchbarSelector).click() cy.get('@locationSearchResults').should('be.visible') cy.log('Checking that it displays layer results with info-buttons') @@ -379,5 +375,17 @@ describe('Test the search bar result handling', () => { cy.wait(['@search-locations', '@search-layers', '@search-layer-features']) cy.get('@layerFeatureSearchCategory').should('be.visible') + + cy.get(searchbarSelector).click() + cy.get('@locationSearchResults').should('not.be.visible') + + cy.log('Checking that the swisssearch url param is not present after reloading the page') + cy.reload() + cy.waitMapIsReady() + cy.wait(['@search-locations', '@search-layers']) + + cy.url().should('not.contain', 'swisssearch') + cy.readStoreValue('state.search.query').should('equal', '') + cy.get('@locationSearchResults').should('not.exist') }) }) From 8860d8b6ea81344ced3efcaa90522c53f4d02ef5 Mon Sep 17 00:00:00 2001 From: Felix Sommer Date: Tue, 1 Oct 2024 18:04:35 +0200 Subject: [PATCH 2/6] PB-951: add after set values in store function --- .../storeSync/SearchParamConfig.class.js | 2 +- .../storeSync/abstractParamConfig.class.js | 24 +++++++++++++++++++ .../storeSync/storeSync.routerPlugin.js | 1 + 3 files changed, 26 insertions(+), 1 deletion(-) diff --git a/src/router/storeSync/SearchParamConfig.class.js b/src/router/storeSync/SearchParamConfig.class.js index 071b8f15d..92ed3b83c 100644 --- a/src/router/storeSync/SearchParamConfig.class.js +++ b/src/router/storeSync/SearchParamConfig.class.js @@ -17,7 +17,6 @@ function dispatchSearchFromUrl(to, store, urlParamValue) { shouldCenter: !(to.query.crosshair && to.query.center), dispatcher: STORE_DISPATCHER_ROUTER_PLUGIN, }) - removeQueryParamFromHref(URL_PARAM_NAME) } /** @@ -49,6 +48,7 @@ export default class SearchParamConfig extends AbstractParamConfig { super({ urlParamName: URL_PARAM_NAME, setValuesInStore: dispatchSearchFromUrl, + afterSetValuesInStore: () => removeQueryParamFromHref(URL_PARAM_NAME), keepInUrlWhenDefault: false, valueType: String, defaultValue: '', diff --git a/src/router/storeSync/abstractParamConfig.class.js b/src/router/storeSync/abstractParamConfig.class.js index e9f4db7c0..71c3f9d97 100644 --- a/src/router/storeSync/abstractParamConfig.class.js +++ b/src/router/storeSync/abstractParamConfig.class.js @@ -37,6 +37,7 @@ export default class AbstractParamConfig { valueType = String, defaultValue = null, validateUrlInput = null, + afterSetValuesInStore = null, } = {}) { this.urlParamName = urlParamName this.mutationsToWatch = mutationsToWatch @@ -51,6 +52,7 @@ export default class AbstractParamConfig { this.defaultValue = false } this.validateUrlInput = validateUrlInput + this.afterSetValuesInStore = afterSetValuesInStore } /** @@ -201,4 +203,26 @@ export default class AbstractParamConfig { } }) } + + /** + * Triggers an action after the store has been populated with the query value. Returns a promise + * + * @returns {Promise} + */ + afterPopulateStore() { + return new Promise((resolve, reject) => { + if (this.afterSetValuesInStore) { + const promiseAfterSetValuesInStore = this.afterSetValuesInStore() + if (promiseAfterSetValuesInStore) { + promiseAfterSetValuesInStore.then(() => { + resolve() + }) + } else { + resolve() + } + } else { + reject('After query, store or setter functions is not set') + } + }) + } } diff --git a/src/router/storeSync/storeSync.routerPlugin.js b/src/router/storeSync/storeSync.routerPlugin.js index f8cad089a..f2c048e1f 100644 --- a/src/router/storeSync/storeSync.routerPlugin.js +++ b/src/router/storeSync/storeSync.routerPlugin.js @@ -122,6 +122,7 @@ function urlQueryWatcher(store, to, from) { const setValueInStore = async (paramConfig, store, value) => { await paramConfig.populateStoreWithQueryValue(to, store, value) + await paramConfig.afterPopulateStoreWithQueryValue() } if ( From 4757612b4f3c9b736f0ee6fbfd62e5dc286e62fe Mon Sep 17 00:00:00 2001 From: Felix Sommer Date: Fri, 4 Oct 2024 13:23:32 +0200 Subject: [PATCH 3/6] PB-951: after set value in abstract param config --- .../menu/components/search/SearchBar.vue | 1 + .../storeSync/SearchParamConfig.class.js | 3 ++- .../storeSync/abstractParamConfig.class.js | 23 ++++++++++--------- .../storeSync/storeSync.routerPlugin.js | 2 +- 4 files changed, 16 insertions(+), 13 deletions(-) diff --git a/src/modules/menu/components/search/SearchBar.vue b/src/modules/menu/components/search/SearchBar.vue index 8410e61a6..ed48a1270 100644 --- a/src/modules/menu/components/search/SearchBar.vue +++ b/src/modules/menu/components/search/SearchBar.vue @@ -26,6 +26,7 @@ watch( // if an entry has been selected from the list, do not show the list again // because the list has been hidden by onEntrySelected. if (!selectedEntry.value) { + // if (!selectedEntry.value) { log.debug( `Search has result changed to ${newValue}, change the show result to ${newValue}` ) diff --git a/src/router/storeSync/SearchParamConfig.class.js b/src/router/storeSync/SearchParamConfig.class.js index 92ed3b83c..f81810c56 100644 --- a/src/router/storeSync/SearchParamConfig.class.js +++ b/src/router/storeSync/SearchParamConfig.class.js @@ -22,7 +22,7 @@ function dispatchSearchFromUrl(to, store, urlParamValue) { /** * This will remove the query param from the URL It is necessary to do this in vanilla JS because * the router does not provide a way to remove a query without reloading the page which then removes - * the value from the store + * the value from the store. * * @param {Object} key The key to remove from the URL */ @@ -47,6 +47,7 @@ export default class SearchParamConfig extends AbstractParamConfig { constructor() { super({ urlParamName: URL_PARAM_NAME, + mutationsToWatch: [], setValuesInStore: dispatchSearchFromUrl, afterSetValuesInStore: () => removeQueryParamFromHref(URL_PARAM_NAME), keepInUrlWhenDefault: false, diff --git a/src/router/storeSync/abstractParamConfig.class.js b/src/router/storeSync/abstractParamConfig.class.js index 71c3f9d97..7f1e01659 100644 --- a/src/router/storeSync/abstractParamConfig.class.js +++ b/src/router/storeSync/abstractParamConfig.class.js @@ -27,12 +27,14 @@ export default class AbstractParamConfig { * added to the URL even though its value is set to the default value of the param. * @param {NumberConstructor | StringConstructor | BooleanConstructor, ObjectConstructor} valueType * @param {Boolean | Number | String | null} defaultValue + * @param {Function} afterSetValuesInStore A function that will be called after the store values + * have been set */ constructor({ urlParamName, mutationsToWatch, setValuesInStore, - extractValueFromStore, + extractValueFromStore = (_) => '', keepInUrlWhenDefault = true, valueType = String, defaultValue = null, @@ -210,18 +212,17 @@ export default class AbstractParamConfig { * @returns {Promise} */ afterPopulateStore() { - return new Promise((resolve, reject) => { - if (this.afterSetValuesInStore) { - const promiseAfterSetValuesInStore = this.afterSetValuesInStore() - if (promiseAfterSetValuesInStore) { - promiseAfterSetValuesInStore.then(() => { - resolve() - }) - } else { + return new Promise((resolve) => { + if (!this.afterSetValuesInStore) { + resolve() + } + const promiseAfterSetValuesInStore = this.afterSetValuesInStore() + if (promiseAfterSetValuesInStore) { + promiseAfterSetValuesInStore.then(() => { resolve() - } + }) } else { - reject('After query, store or setter functions is not set') + resolve() } }) } diff --git a/src/router/storeSync/storeSync.routerPlugin.js b/src/router/storeSync/storeSync.routerPlugin.js index f2c048e1f..39c6d11cf 100644 --- a/src/router/storeSync/storeSync.routerPlugin.js +++ b/src/router/storeSync/storeSync.routerPlugin.js @@ -122,7 +122,7 @@ function urlQueryWatcher(store, to, from) { const setValueInStore = async (paramConfig, store, value) => { await paramConfig.populateStoreWithQueryValue(to, store, value) - await paramConfig.afterPopulateStoreWithQueryValue() + await paramConfig.afterPopulateStore() } if ( From 82a4443adc7b386401b9aecedf6104197863fc6d Mon Sep 17 00:00:00 2001 From: Felix Sommer Date: Wed, 16 Oct 2024 13:02:39 +0200 Subject: [PATCH 4/6] PB-877: add limit to swisssearch url param --- src/api/search.api.js | 25 +++++++++++++------ .../menu/components/search/SearchBar.vue | 10 +++++++- .../storeSync/SearchParamConfig.class.js | 1 + src/store/modules/search.store.js | 25 ++++++++++++++++++- .../plugins/redo-search-when-needed.plugin.js | 1 + 5 files changed, 53 insertions(+), 9 deletions(-) diff --git a/src/api/search.api.js b/src/api/search.api.js index c76cd8f15..2d67d665e 100644 --- a/src/api/search.api.js +++ b/src/api/search.api.js @@ -181,13 +181,14 @@ function parseLocationResult(result, outputProjection) { } } -async function searchLayers(queryString, lang, cancelToken) { +async function searchLayers(queryString, lang, cancelToken, limit = 0) { try { const layerResponse = await generateAxiosSearchRequest( queryString, lang, 'layers', - cancelToken.token + cancelToken.token, + { limit } ) // checking that there is something of interest to parse const resultWithAttrs = layerResponse?.data.results?.filter((result) => result.attrs) @@ -206,15 +207,17 @@ async function searchLayers(queryString, lang, cancelToken) { * @param queryString * @param lang * @param cancelToken + * @param limit * @returns {Promise} */ -async function searchLocation(outputProjection, queryString, lang, cancelToken) { +async function searchLocation(outputProjection, queryString, lang, cancelToken, limit = 0) { try { const locationResponse = await generateAxiosSearchRequest( queryString, lang, 'locations', - cancelToken.token + cancelToken.token, + { limit } ) // checking that there is something of interest to parse const resultWithAttrs = locationResponse?.data.results?.filter((result) => result.attrs) @@ -280,10 +283,17 @@ let cancelToken = null * @param {String} config.lang The lang ISO code in which the search must be conducted * @param {GeoAdminLayer[]} [config.layersToSearch=[]] List of searchable layers for which to fire * search requests. Default is `[]` + * @param {number} config.limit The maximum number of results to return * @returns {Promise} */ export default async function search(config) { - const { outputProjection = null, queryString = null, lang = null, layersToSearch = [] } = config + const { + outputProjection = null, + queryString = null, + lang = null, + layersToSearch = [], + limit = 0, + } = config if (!(outputProjection instanceof CoordinateSystem)) { const errorMessage = `A valid output projection is required to start a search request` log.error(errorMessage) @@ -307,10 +317,11 @@ export default async function search(config) { /** @type {Promise[]} */ const allRequests = [ - searchLayers(queryString, lang, cancelToken), - searchLocation(outputProjection, queryString, lang, cancelToken), + searchLayers(queryString, lang, cancelToken, limit), + searchLocation(outputProjection, queryString, lang, cancelToken, limit), ] + // TODO limit also in the local kml and gpx files ? if (layersToSearch.some((layer) => layer.searchable)) { allRequests.push( ...layersToSearch diff --git a/src/modules/menu/components/search/SearchBar.vue b/src/modules/menu/components/search/SearchBar.vue index ed48a1270..5582d2960 100644 --- a/src/modules/menu/components/search/SearchBar.vue +++ b/src/modules/menu/components/search/SearchBar.vue @@ -18,19 +18,27 @@ const selectedEntry = ref(null) const searchQuery = computed(() => store.state.search.query) const hasResults = computed(() => store.state.search.results.length > 0) +const hasResultsOne = computed(() => store.state.search.results.length === 1) const isPhoneMode = computed(() => store.getters.isPhoneMode) +let isImmediateTrigger = true watch( hasResults, (newValue) => { // if an entry has been selected from the list, do not show the list again // because the list has been hidden by onEntrySelected. + + // to prevent the list from being shown when the page with swisssearch is loaded and only one result is available and selected + if (isImmediateTrigger && hasResultsOne.value) { + isImmediateTrigger = false + return + } if (!selectedEntry.value) { - // if (!selectedEntry.value) { log.debug( `Search has result changed to ${newValue}, change the show result to ${newValue}` ) showResults.value = newValue + isImmediateTrigger = false } }, { immediate: true } diff --git a/src/router/storeSync/SearchParamConfig.class.js b/src/router/storeSync/SearchParamConfig.class.js index f81810c56..1946ed1e6 100644 --- a/src/router/storeSync/SearchParamConfig.class.js +++ b/src/router/storeSync/SearchParamConfig.class.js @@ -16,6 +16,7 @@ function dispatchSearchFromUrl(to, store, urlParamValue) { query: urlParamValue, shouldCenter: !(to.query.crosshair && to.query.center), dispatcher: STORE_DISPATCHER_ROUTER_PLUGIN, + originUrlParam: true, }) } diff --git a/src/store/modules/search.store.js b/src/store/modules/search.store.js index 749b9b02c..efaee9dba 100644 --- a/src/store/modules/search.store.js +++ b/src/store/modules/search.store.js @@ -27,6 +27,19 @@ const state = { const getters = {} +function extractLimitNumber(query) { + const regex = / limit: \d+/ + const match = query.match(regex) + + if (match) { + return { + limit: parseInt(match[0].split(':')[1].trim()), + extractedQuery: query.replace(match[0], ''), + } + } + return { limit: 0, extractedQuery: query } +} + const actions = { /** * @param {vuex} vuex @@ -35,10 +48,12 @@ const actions = { */ setSearchQuery: async ( { commit, rootState, dispatch, getters }, - { query = '', shouldCenter = true, dispatcher } + { query = '', originUrlParam = false, shouldCenter = true, dispatcher } ) => { let results = [] commit('setSearchQuery', { query, dispatcher }) + const { limit, extractedQuery } = extractLimitNumber(query) + query = extractedQuery // only firing search if query is longer than or equal to 2 chars if (query.length >= 2) { const currentProjection = rootState.position.projection @@ -129,7 +144,14 @@ const actions = { queryString: query, lang: rootState.i18n.lang, layersToSearch: getters.visibleLayers, + limit, }) + if (originUrlParam && results.length === 1) { + dispatch('selectResultEntry', { + dispatcher: `${dispatcher}/setSearchQuery`, + entry: results[0], + }) + } } catch (error) { log.error(`Search failed`, error) } @@ -147,6 +169,7 @@ const actions = { * @param {SearchResult} entry */ selectResultEntry: ({ dispatch, getters, rootState }, { entry, dispatcher }) => { + console.log('selectResultEntry', entry) const dispatcherSelectResultEntry = `${dispatcher}/search.store/selectResultEntry` switch (entry.resultType) { case SearchResultTypes.LAYER: diff --git a/src/store/plugins/redo-search-when-needed.plugin.js b/src/store/plugins/redo-search-when-needed.plugin.js index 18835dce4..c70fc62b3 100644 --- a/src/store/plugins/redo-search-when-needed.plugin.js +++ b/src/store/plugins/redo-search-when-needed.plugin.js @@ -12,6 +12,7 @@ const redoSearchWhenNeeded = (store) => { query: store.state.search.query, // we don't center on the search query when redoing a search if there is a crosshair shouldCenter: store.state.position.crossHair === null, + originUrlParam: true, // necessary to select the first result if there is only one else it will not be because this redo search is done every time the page loaded }) } } From bd83db6d0e52dfe3f570bc2fe3ce482e6af76be7 Mon Sep 17 00:00:00 2001 From: Felix Sommer Date: Wed, 16 Oct 2024 15:00:38 +0200 Subject: [PATCH 5/6] PB-877: remove prevent search list show --- src/modules/menu/components/search/SearchBar.vue | 9 --------- 1 file changed, 9 deletions(-) diff --git a/src/modules/menu/components/search/SearchBar.vue b/src/modules/menu/components/search/SearchBar.vue index 5582d2960..8410e61a6 100644 --- a/src/modules/menu/components/search/SearchBar.vue +++ b/src/modules/menu/components/search/SearchBar.vue @@ -18,27 +18,18 @@ const selectedEntry = ref(null) const searchQuery = computed(() => store.state.search.query) const hasResults = computed(() => store.state.search.results.length > 0) -const hasResultsOne = computed(() => store.state.search.results.length === 1) const isPhoneMode = computed(() => store.getters.isPhoneMode) -let isImmediateTrigger = true watch( hasResults, (newValue) => { // if an entry has been selected from the list, do not show the list again // because the list has been hidden by onEntrySelected. - - // to prevent the list from being shown when the page with swisssearch is loaded and only one result is available and selected - if (isImmediateTrigger && hasResultsOne.value) { - isImmediateTrigger = false - return - } if (!selectedEntry.value) { log.debug( `Search has result changed to ${newValue}, change the show result to ${newValue}` ) showResults.value = newValue - isImmediateTrigger = false } }, { immediate: true } From ffa41526da334e18a9f7846c85a6f9ee4d2c6c84 Mon Sep 17 00:00:00 2001 From: Felix Sommer Date: Wed, 16 Oct 2024 15:01:01 +0200 Subject: [PATCH 6/6] PB-877: test limit parameter --- .../cypress/tests-e2e/legacyParamImport.cy.js | 56 ++++++++++++++++++- 1 file changed, 55 insertions(+), 1 deletion(-) diff --git a/tests/cypress/tests-e2e/legacyParamImport.cy.js b/tests/cypress/tests-e2e/legacyParamImport.cy.js index f3bfcd636..9cc30701b 100644 --- a/tests/cypress/tests-e2e/legacyParamImport.cy.js +++ b/tests/cypress/tests-e2e/legacyParamImport.cy.js @@ -249,6 +249,7 @@ describe('Test on legacy param import', () => { cy.intercept('**/rest/services/ech/SearchServer*?type=layers*', { body: { results: [] }, }).as('search-layers') + const coordinates = [2598633.75, 1200386.75] cy.intercept('**/rest/services/ech/SearchServer*?type=locations*', { body: { results: [ @@ -256,6 +257,10 @@ describe('Test on legacy param import', () => { attrs: { detail: '1530 payerne 5822 payerne ch vd', label: ' 1530 Payerne', + lat: 46.954559326171875, + lon: 7.420684814453125, + y: coordinates[0], + x: coordinates[1], }, }, ], @@ -267,11 +272,60 @@ describe('Test on legacy param import', () => { }, false ) - cy.readStoreValue('state.search.query').should('eq', '1530 Payerne') + cy.readStoreValue('state.search.query').should('eq', ' 1530 Payerne') cy.url().should('not.contain', 'swisssearch') cy.get('[data-cy="searchbar"]').click() + const acceptableDelta = 0.25 + + // selects the result if it is only one + cy.readStoreValue('state.map.pinnedLocation').should((feature) => { + expect(feature).to.not.be.null + expect(feature).to.be.a('array').that.is.not.empty + expect(feature[0]).to.be.approximately(coordinates[0], acceptableDelta) + expect(feature[1]).to.be.approximately(coordinates[1], acceptableDelta) + }) cy.get('[data-cy="search-results-locations"]').should('not.be.visible') }) + it('limits the swisssearch with legacy parameter limit', () => { + cy.intercept('**/rest/services/ech/SearchServer*?type=layers*', { + body: { results: [] }, + }).as('search-layers') + const coordinates = [2598633.75, 1200386.75] + cy.intercept('**/rest/services/ech/SearchServer*?type=locations*', { + body: { + results: [ + { + attrs: { + detail: '1530 payerne 5822 payerne ch vd', + label: ' 1530 Payerne', + lat: 46.954559326171875, + lon: 7.420684814453125, + y: coordinates[0], + x: coordinates[1], + }, + }, + { + attrs: { + detail: '1530 payerne 5822 payerne ch vd 2', + label: ' 1530 Payerne 2', + lat: 46.954559326171875, + lon: 7.420684814453125, + y: coordinates[0], + x: coordinates[1], + }, + }, + ], + }, + }).as('search-locations') + cy.goToMapView( + { + swisssearch: '1530 Payerne limit: 2', + }, + false + ) + cy.readStoreValue('state.search.query').should('eq', '1530 Payerne limit: 2') + cy.url().should('not.contain', 'swisssearch') + }) it('External WMS layer', () => { const layerName = 'OpenData-AV' const layerId = 'ch.swisstopo-vd.official-survey'