Merge pull request #27355 from Julien-Hery/fix/displayNameSearch

fix(catalog): fix search by `displayName` when searching User and Group entities in the catalog table
This commit is contained in:
Vincenzo Scamporlino
2024-11-18 12:33:17 +01:00
committed by GitHub
3 changed files with 64 additions and 2 deletions
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-catalog-backend': patch
---
Fixed bug when searching an entity by `spec.profile.displayName` in the catalog on the frontend. Text filter fields were not applied correctly to the database query resulting in empty results.
@@ -1183,7 +1183,6 @@ describe('DefaultEntitiesCatalog', () => {
const request: QueryEntitiesInitialRequest = {
filter,
limit: 100,
orderFields: [{ field: 'metadata.name', order: 'asc' }],
fullTextFilter: { term: 'cAt ' },
credentials: mockCredentials.none(),
@@ -1200,6 +1199,60 @@ describe('DefaultEntitiesCatalog', () => {
},
);
it.each(databases.eachSupportedId())(
'should filter the results when query is provided with fullTextFilter for camelCase fields, %p',
async databaseId => {
await createDatabase(databaseId);
const entities: Entity[] = [
{
apiVersion: 'a',
kind: 'k',
metadata: {
name: 'camelCase',
},
spec: {
shouldSearchCamelCase: 'searched',
},
},
];
const notFoundEntities: Entity[] = [
{
apiVersion: 'a',
kind: 'k',
metadata: { name: 'something' },
spec: {},
},
];
await Promise.all(
entities.concat(notFoundEntities).map(e => addEntityToSearch(e)),
);
const catalog = new DefaultEntitiesCatalog({
database: knex,
logger: mockServices.logger.mock(),
stitcher,
});
const request: QueryEntitiesInitialRequest = {
limit: 100,
orderFields: [{ field: 'metadata.name', order: 'asc' }],
fullTextFilter: {
term: 'sear',
fields: ['spec.shouldSearchCamelCase'],
},
credentials: mockCredentials.none(),
};
const response = await catalog.queryEntities(request);
expect(response.items).toEqual(entities);
expect(response.pageInfo.nextCursor).toBeUndefined();
expect(response.pageInfo.prevCursor).toBeUndefined();
expect(response.totalItems).toBe(1);
},
);
it.each(databases.eachSupportedId())(
'should filter the text results when sortOrder is not provided, %p',
async databaseId => {
@@ -411,7 +411,11 @@ export class DefaultEntitiesCatalog implements EntitiesCatalog {
} else {
const matchQuery = db<DbSearchRow>('search')
.select('search.entity_id')
.whereIn('key', textFilterFields)
// textFilterFields must be lowercased to match searchable keys in database, i.e. spec.profile.displayName -> spec.profile.displayname
.whereIn(
'key',
textFilterFields.map(field => field.toLocaleLowerCase('en-US')),
)
.andWhere(function keyFilter() {
this.andWhereRaw(
'value like ?',