Skip to content

Commit 8e3d9eb

Browse files
fix(search-service): fix global search issue
fix global search issue GH-2553
1 parent f5ecddf commit 8e3d9eb

2 files changed

Lines changed: 58 additions & 7 deletions

File tree

services/search-service/src/__tests__/unit/psql/query.builder.unit.ts

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,55 @@ import {buildTestsRunner} from '../runner';
66
import {PsqlQueryBuilder} from '../../../classes';
77
import {expect} from '@loopback/testlab';
88
import {testModelList, testModelListWithIdentifier} from '../..';
9+
import {AnyObject} from '@loopback/repository';
910

1011
describe('PostgreSQL QueryBuilder', () => {
1112
const queryPart =
1213
" from public.TestSearchedCustom where to_tsvector(public.f_concat_ws(' ', about, identifier)) @@ to_tsquery($1))";
14+
15+
describe('_formatAndSanitize', () => {
16+
it('should preserve dots in search terms', () => {
17+
const builder = new PsqlQueryBuilder({match: 'Deal 10.1'});
18+
const result = (builder as AnyObject)._formatAndSanitize('Deal 10.1');
19+
expect(result).to.equal('Deal:*<->10.1:*');
20+
});
21+
22+
it('should handle project names with dots', () => {
23+
const builder = new PsqlQueryBuilder({match: 'test'});
24+
const result = (builder as AnyObject)._formatAndSanitize('testlift.QA');
25+
expect(result).to.equal('testlift.QA:*');
26+
});
27+
28+
it('should handle IP addresses', () => {
29+
const builder = new PsqlQueryBuilder({match: 'test'});
30+
const result = (builder as AnyObject)._formatAndSanitize('192.168.1.1');
31+
expect(result).to.equal('192.168.1.1:*');
32+
});
33+
34+
it('should handle multiple dots in different positions', () => {
35+
const builder = new PsqlQueryBuilder({match: 'test'});
36+
const result = (builder as AnyObject)._formatAndSanitize(
37+
'Project.Alpha.Beta',
38+
);
39+
expect(result).to.equal('Project.Alpha.Beta:*');
40+
});
41+
42+
it('should handle mix of dots and special characters', () => {
43+
const builder = new PsqlQueryBuilder({match: 'test'});
44+
const result = (builder as AnyObject)._formatAndSanitize(
45+
'Deal.10 & Test.1.5',
46+
);
47+
expect(result).to.equal('Deal.10:*<->Test.1.5:*');
48+
});
49+
50+
it('should handle complex search with dots and spaces', () => {
51+
const builder = new PsqlQueryBuilder({match: 'test'});
52+
const result = (builder as AnyObject)._formatAndSanitize(
53+
'Version 2.5 (Release)',
54+
);
55+
expect(result).to.equal('Version:*<->2.5:*<->Release:*');
56+
});
57+
});
1358
describe(
1459
'with match parameter',
1560
buildTestsRunner(

services/search-service/src/classes/psql/query.builder.ts

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -78,11 +78,17 @@ export class PsqlQueryBuilder<T extends Model> extends SearchQueryBuilder<T> {
7878
}
7979

8080
_formatAndSanitize(param: string) {
81-
return param
82-
.replace(/[^A-Za-z\s0-9]/g, ' ')
83-
.split(' ')
84-
.filter(p => p)
85-
.map(p => `${p}:*`)
86-
.join('<->');
87-
}
81+
    let result = param;
82+
    while (result.endsWith('.')) {
83+
      result = result.slice(0, -1);
84+
    }
85+
86+
    return result
87+
      .replace(/[!&|<>():'"]/g, ' ')
88+
      .replace(/[^A-Za-z0-9.\s]/g, ' ')
89+
      .split(' ')
90+
      .filter(p => p && p !== '.')
91+
      .map(p => `${p}:*`)
92+
      .join('<->');
93+
  }
8894
}

0 commit comments

Comments
 (0)