diff --git a/plugins/home/README.md b/plugins/home/README.md index fdc5ce833b..066e637725 100644 --- a/plugins/home/README.md +++ b/plugins/home/README.md @@ -353,7 +353,7 @@ home: value: ``` -Filters that are not defined according to the docs will be ignored. +`filterBy` configs that are not defined in the above format will be ignored. In order to validate the config you can use `backstage/cli config:check` diff --git a/plugins/home/src/api/config.test.ts b/plugins/home/src/api/config.test.ts index c2b715ec08..178287bb3d 100644 --- a/plugins/home/src/api/config.test.ts +++ b/plugins/home/src/api/config.test.ts @@ -33,15 +33,14 @@ describe('config', () => { }); }); - it('throws an error for invalid filter', async () => { - const mockConfig = new MockConfigApi({ + it('returns undefined for invalid filter', async () => { + const mockInvalidConfig = new MockConfigApi({ myField: 'pathname', operator: '==', value: '3', }); - expect(() => readFilterConfig(mockConfig)).toThrow( - "Invalid config, Error: Missing required config value at 'field'", - ); + const res = readFilterConfig(mockInvalidConfig); + expect(res).toEqual(undefined); }); }); @@ -67,22 +66,22 @@ describe('config', () => { ]); }); - it('return undefined for invalid filter', async () => { - const mockConfig1 = new MockConfigApi({ + it('returns only invalid filters', async () => { + const mockValidConfig = new MockConfigApi({ field: 'id', operator: '==', value: '3', }); - const mockConfig2 = new MockConfigApi({ + const mockInvalidConfig = new MockConfigApi({ myField: 'pathname', operator: '==', value: 'path', }); const res = createFilterByQueryParamFromConfig([ - mockConfig1, - mockConfig2, + mockValidConfig, + mockInvalidConfig, ]); - expect(res).toEqual(undefined); + expect(res).toEqual([{ field: 'id', operator: '==', value: '3' }]); }); }); }); diff --git a/plugins/home/src/api/config.ts b/plugins/home/src/api/config.ts index a8af29fc9e..3cc6d93f24 100644 --- a/plugins/home/src/api/config.ts +++ b/plugins/home/src/api/config.ts @@ -24,11 +24,13 @@ import { Config } from '@backstage/config'; * * @public */ -export function readFilterConfig(config: Config): { - field: keyof Visit; - operator: '<' | '<=' | '==' | '!=' | '>' | '>=' | 'contains'; - value: string | number; -} { +export function readFilterConfig(config: Config): + | { + field: keyof Visit; + operator: '<' | '<=' | '==' | '!=' | '>' | '>=' | 'contains'; + value: string | number; + } + | undefined { try { const field = config.getString('field') as keyof Visit; const operator = config.getString('operator') as @@ -42,7 +44,8 @@ export function readFilterConfig(config: Config): { const value = config.getString('value'); return { field, operator, value }; } catch (error) { - throw new Error(`Invalid config, ${error}`); + // invalid filter config - ignore filter + return undefined; } } @@ -57,7 +60,9 @@ export function createFilterByQueryParamFromConfig( configs: Config[], ): VisitsApiQueryParams['filterBy'] | undefined { try { - return configs.map(readFilterConfig); + return configs + .map(readFilterConfig) + .filter(Boolean) as VisitsApiQueryParams['filterBy']; } catch { return undefined; } diff --git a/plugins/home/src/homePageComponents/VisitedByType/Content.test.tsx b/plugins/home/src/homePageComponents/VisitedByType/Content.test.tsx index 1234291f1a..2a7a6481ba 100644 --- a/plugins/home/src/homePageComponents/VisitedByType/Content.test.tsx +++ b/plugins/home/src/homePageComponents/VisitedByType/Content.test.tsx @@ -43,12 +43,21 @@ const visits = [ }, ]; -const mockVisitsApi = { +let mockVisitsApi = { save: async () => visits[0], list: async () => visits, }; describe('', () => { + beforeEach(() => { + mockVisitsApi = { + save: async () => visits[0], + list: async () => visits, + }; + }); + + afterEach(() => jest.resetAllMocks()); + it('renders', async () => { const { getByText } = await renderInTestApp( @@ -207,6 +216,11 @@ describe('', () => { operator: '==', value: '/tech-radar', }, + { + field: 'pathname', + operator: '==', + value: '/explore', + }, ], }, }, @@ -235,12 +249,28 @@ describe('', () => { field: 'timestamp', }, ], + filterBy: [ + { + field: 'pathname', + operator: '==', + value: '/explore', + }, + ], }); }); }); }); describe('', () => { + beforeEach(() => { + mockVisitsApi = { + save: async () => visits[0], + list: async () => visits, + }; + }); + + afterEach(() => jest.resetAllMocks()); + it('renders', async () => { const { getByText } = await renderInTestApp(