[ACS-10514] ADW Search not working for some scenario tocken creation issue (#4891)

* [ACS-10514] improve search term extractrion from query

* [ACS-10514] handle other search types, unit tests, docs

* [ACS-10515] fix sonar issue

* [ACS-10514] format table
This commit is contained in:
Grzegorz Jaśkowski
2025-11-21 11:33:02 +01:00
committed by GitHub
parent 5fdd2202e2
commit 8ee33bc944
3 changed files with 91 additions and 31 deletions
@@ -54,6 +54,11 @@ describe('SearchUtils', () => {
expect(isOperator(null)).toBeFalse();
expect(isOperator(undefined)).toBeFalse();
});
it('should treat lowercase operators as search terms', () => {
expect(isOperator('and')).toBeFalse();
expect(isOperator('or')).toBeFalse();
});
});
describe('formatSearchTermByFields', () => {
@@ -109,8 +114,8 @@ describe('SearchUtils', () => {
});
it('should support exact term matching with operators', () => {
expect(formatSearchTerm('=test1.pdf or =test2.pdf', ['cm:name', 'cm:title'])).toBe(
`(=cm:name:"test1.pdf" OR =cm:title:"test1.pdf") or (=cm:name:"test2.pdf" OR =cm:title:"test2.pdf")`
expect(formatSearchTerm('=test1.pdf OR =test2.pdf', ['cm:name', 'cm:title'])).toBe(
`(=cm:name:"test1.pdf" OR =cm:title:"test1.pdf") OR (=cm:name:"test2.pdf" OR =cm:title:"test2.pdf")`
);
});
});
@@ -145,9 +150,9 @@ describe('SearchUtils', () => {
expect(extractSearchedWordFromEncodedQuery(encodeQuery(query))).toBe('test');
});
it('should properly extract search term for custom search', () => {
it('should preserve quotes in search term for custom search', () => {
const query = { userQuery: '"test"' };
expect(extractSearchedWordFromEncodedQuery(encodeQuery(query))).toBe('test');
expect(extractSearchedWordFromEncodedQuery(encodeQuery(query))).toBe('"test"');
});
it('should properly extract search term when userQuery does not contain quotes', () => {
@@ -164,6 +169,25 @@ describe('SearchUtils', () => {
const query = { userQuery: 'cm:name:"quoted term" AND TEXT:unquoted' };
expect(extractSearchedWordFromEncodedQuery(encodeQuery(query))).toBe('quoted term TEXT:unquoted');
});
it('should handle complex search query', () => {
const query = {
userQuery: `((cm:name:"a*" OR cm:title:"a*" OR cm:description:"a*" OR TEXT:"a*" OR TAG:"a*") AND
(cm:name:"b*" OR cm:title:"b*" OR cm:description:"b*" OR TEXT:"b*" OR TAG:"b*") OR
(cm:name:"c*" OR cm:title:"c*" OR cm:description:"c*" OR TEXT:"c*" OR TAG:"c*"))`
};
expect(extractSearchedWordFromEncodedQuery(encodeQuery(query))).toBe('a b OR c');
});
it('should not treat operator as a searched word', () => {
const query = { userQuery: 'AND' };
expect(extractSearchedWordFromEncodedQuery(encodeQuery(query))).toBe('');
});
it('should not unquote when searching for phrase', () => {
const query = { userQuery: '"exact phrase search"' };
expect(extractSearchedWordFromEncodedQuery(encodeQuery(query))).toBe('"exact phrase search"');
});
});
describe('extractFiltersFromEncodedQuery', () => {
@@ -30,10 +30,8 @@
*/
export function isOperator(input: string): boolean {
if (input) {
input = input.trim().toUpperCase();
const operators = ['AND', 'OR'];
return operators.includes(input);
return operators.includes(input.trim());
}
return false;
}
@@ -111,17 +109,54 @@ export function extractUserQueryFromEncodedQuery(encodedQuery: string): string {
* @returns string
*/
export function extractSearchedWordFromEncodedQuery(encodedQuery: string): string {
if (encodedQuery) {
const userQuery = extractUserQueryFromEncodedQuery(encodedQuery);
return userQuery !== '' && userQuery !== undefined
? userQuery
.split('AND')
.map((searchCondition) => {
const searchTerm = searchCondition.includes('"') ? searchCondition.split('"')[1] : searchCondition.trim();
return searchTerm?.endsWith('*') && searchTerm !== '*' ? searchTerm.slice(0, -1) : searchTerm;
})
.join(' ')
: '';
if (!encodedQuery) {
return '';
}
const userQuery = extractUserQueryFromEncodedQuery(encodedQuery);
if (!userQuery) {
return '';
}
const tokenRegex = /\(([^()]+)\)|\b(AND|OR)\b/g;
const fragments: string[] = [];
let match: RegExpExecArray | null;
while ((match = tokenRegex.exec(userQuery))) {
if (match[1]) {
fragments.push(extractWordFromQuery(match[1]));
} else if (match[2] === 'OR') {
fragments.push('OR');
}
}
if (fragments.length === 0) {
return userQuery
.split(/\bAND\b|\bOR\b/)
.map((part) => extractWordFromQuery(part))
.filter(Boolean)
.join(' ')
.trim();
}
return fragments.join(' ').trim();
}
/**
* Extracts the searched word from a part of search query
*
* @param queryPart encoded query
* @returns searched word
*/
function extractWordFromQuery(queryPart: string): string {
const regex = /:"([^"]+)"/;
const quoted = regex.exec(queryPart);
if (quoted) {
return quoted[1].replace(/\*$/, '');
}
const trimmedPart = queryPart.trim();
if (trimmedPart && !isOperator(trimmedPart)) {
return trimmedPart;
}
return '';
}