From 52201bcd13612d7fa05384f0dae6ac011eb5db95 Mon Sep 17 00:00:00 2001 From: Aleksander Sklorz Date: Wed, 1 Oct 2025 08:36:58 +0200 Subject: [PATCH 1/2] [ACS-10384] Fixed error when using non-latina characters in search --- .../src/lib/search/services/base-query-builder.service.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/content-services/src/lib/search/services/base-query-builder.service.ts b/lib/content-services/src/lib/search/services/base-query-builder.service.ts index b24377cad9..6d838d1389 100644 --- a/lib/content-services/src/lib/search/services/base-query-builder.service.ts +++ b/lib/content-services/src/lib/search/services/base-query-builder.service.ts @@ -582,7 +582,7 @@ export abstract class BaseQueryBuilderService { */ encodeQuery() { try { - this.encodedQuery = btoa(JSON.stringify(this.filterRawParams)); + this.encodedQuery = btoa(String.fromCharCode(...new TextEncoder().encode(JSON.stringify(this.filterRawParams)))); } catch (error) { console.error('Failed to encode query parameters:', error); this.encodedQuery = ''; From 3d78e9a214a0b266867e53e246f9fee60be9424d Mon Sep 17 00:00:00 2001 From: Aleksander Sklorz Date: Thu, 2 Oct 2025 12:58:25 +0200 Subject: [PATCH 2/2] [ACS-10384] Unit tests --- ...earch-header-query-builder.service.spec.ts | 45 +++++++++++++++++++ .../search-query-builder.service.spec.ts | 39 ++++++++++++++++ 2 files changed, 84 insertions(+) diff --git a/lib/content-services/src/lib/search/services/search-header-query-builder.service.spec.ts b/lib/content-services/src/lib/search/services/search-header-query-builder.service.spec.ts index 7af5968c1c..49cf94bc8c 100644 --- a/lib/content-services/src/lib/search/services/search-header-query-builder.service.spec.ts +++ b/lib/content-services/src/lib/search/services/search-header-query-builder.service.spec.ts @@ -21,12 +21,18 @@ import { SearchHeaderQueryBuilderService } from './search-header-query-builder.s import { TestBed } from '@angular/core/testing'; import { ContentTestingModule } from '../../testing/content.testing.module'; import { AlfrescoApiService } from '../../services/alfresco-api.service'; +import { ActivatedRoute, Router } from '@angular/router'; describe('SearchHeaderQueryBuilderService', () => { + let activatedRoute: ActivatedRoute; + let router: Router; + beforeEach(() => { TestBed.configureTestingModule({ imports: [ContentTestingModule] }); + router = TestBed.inject(Router); + activatedRoute = TestBed.inject(ActivatedRoute); }); const buildConfig = (searchSettings): AppConfigService => { @@ -142,4 +148,43 @@ describe('SearchHeaderQueryBuilderService', () => { expect(searchHeaderService.activeFilters.length).toBe(1); }); }); + + describe('updateSearchQueryParams', () => { + it('should use properly encoded query containing non-latin character when calls router.navigate', () => { + spyOn(router, 'navigate'); + spyOn(console, 'error'); + const service = TestBed.inject(SearchHeaderQueryBuilderService); + service.filterRawParams = { userQuery: '((cm:name:"wąż*" OR cm:title:"wąż*" OR cm:description:"wąż*" OR TEXT:"wąż*" OR TAG:"wąż*"))' }; + + service.updateSearchQueryParams(); + expect(console.error).not.toHaveBeenCalled(); + expect(router.navigate).toHaveBeenCalledWith([], { + relativeTo: activatedRoute, + queryParams: { + q: 'eyJ1c2VyUXVlcnkiOiIoKGNtOm5hbWU6XCJ3xIXFvCpcIiBPUiBjbTp0aXRsZTpcInfEhcW8KlwiIE9SIGNtOmRlc2NyaXB0aW9uOlwid8SFxbwqXCIgT1IgVEVYVDpcInfEhcW8KlwiIE9SIFRBRzpcInfEhcW8KlwiKSkifQ==' + }, + queryParamsHandling: 'merge' + }); + }); + }); + + describe('navigateToSearch', () => { + it('should use properly encoded query containing non-latin character when calls router.navigate', async () => { + spyOn(router, 'navigate'); + spyOn(console, 'error'); + const searchUrl = 'search'; + const service = TestBed.inject(SearchHeaderQueryBuilderService); + service.filterRawParams = { userQuery: '((cm:name:"wąż*" OR cm:title:"wąż*" OR cm:description:"wąż*" OR TEXT:"wąż*" OR TAG:"wąż*"))' }; + service.encodeQuery(); + + await service.navigateToSearch('', searchUrl); + expect(console.error).not.toHaveBeenCalled(); + expect(router.navigate).toHaveBeenCalledWith([searchUrl], { + queryParams: { + q: 'eyJ1c2VyUXVlcnkiOiIoKGNtOm5hbWU6XCJ3xIXFvCpcIiBPUiBjbTp0aXRsZTpcInfEhcW8KlwiIE9SIGNtOmRlc2NyaXB0aW9uOlwid8SFxbwqXCIgT1IgVEVYVDpcInfEhcW8KlwiIE9SIFRBRzpcInfEhcW8KlwiKSkifQ==' + }, + queryParamsHandling: 'merge' + }); + }); + }); }); diff --git a/lib/content-services/src/lib/search/services/search-query-builder.service.spec.ts b/lib/content-services/src/lib/search/services/search-query-builder.service.spec.ts index 19581f400c..bb3c7d6c6c 100644 --- a/lib/content-services/src/lib/search/services/search-query-builder.service.spec.ts +++ b/lib/content-services/src/lib/search/services/search-query-builder.service.spec.ts @@ -801,4 +801,43 @@ describe('SearchQueryBuilder', () => { }); }); }); + + describe('updateSearchQueryParams', () => { + it('should use properly encoded query containing non-latin character when calls router.navigate', () => { + spyOn(router, 'navigate'); + spyOn(console, 'error'); + const service = TestBed.inject(SearchQueryBuilderService); + service.filterRawParams = { userQuery: '((cm:name:"wąż*" OR cm:title:"wąż*" OR cm:description:"wąż*" OR TEXT:"wąż*" OR TAG:"wąż*"))' }; + + service.updateSearchQueryParams(); + expect(console.error).not.toHaveBeenCalled(); + expect(router.navigate).toHaveBeenCalledWith([], { + relativeTo: activatedRoute, + queryParams: { + q: 'eyJ1c2VyUXVlcnkiOiIoKGNtOm5hbWU6XCJ3xIXFvCpcIiBPUiBjbTp0aXRsZTpcInfEhcW8KlwiIE9SIGNtOmRlc2NyaXB0aW9uOlwid8SFxbwqXCIgT1IgVEVYVDpcInfEhcW8KlwiIE9SIFRBRzpcInfEhcW8KlwiKSkifQ==' + }, + queryParamsHandling: 'merge' + }); + }); + }); + + describe('navigateToSearch', () => { + it('should use properly encoded query containing non-latin character when calls router.navigate', async () => { + spyOn(router, 'navigate'); + spyOn(console, 'error'); + const searchUrl = 'search'; + const service = TestBed.inject(SearchQueryBuilderService); + service.filterRawParams = { userQuery: '((cm:name:"wąż*" OR cm:title:"wąż*" OR cm:description:"wąż*" OR TEXT:"wąż*" OR TAG:"wąż*"))' }; + service.encodeQuery(); + + await service.navigateToSearch('', searchUrl); + expect(console.error).not.toHaveBeenCalled(); + expect(router.navigate).toHaveBeenCalledWith([searchUrl], { + queryParams: { + q: 'eyJ1c2VyUXVlcnkiOiIoKGNtOm5hbWU6XCJ3xIXFvCpcIiBPUiBjbTp0aXRsZTpcInfEhcW8KlwiIE9SIGNtOmRlc2NyaXB0aW9uOlwid8SFxbwqXCIgT1IgVEVYVDpcInfEhcW8KlwiIE9SIFRBRzpcInfEhcW8KlwiKSkifQ==' + }, + queryParamsHandling: 'merge' + }); + }); + }); });