Return undefined for invalid filters + fix README.md

Signed-off-by: shmaram <shaharshmaram@gmail.com>
This commit is contained in:
shmaram
2024-01-25 23:10:30 +02:00
parent 7944df5ae4
commit c57d61f0a9
4 changed files with 54 additions and 20 deletions
+1 -1
View File
@@ -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`
+10 -11
View File
@@ -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' }]);
});
});
});
+12 -7
View File
@@ -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;
}
@@ -43,12 +43,21 @@ const visits = [
},
];
const mockVisitsApi = {
let mockVisitsApi = {
save: async () => visits[0],
list: async () => visits,
};
describe('<Content kind="recent"/>', () => {
beforeEach(() => {
mockVisitsApi = {
save: async () => visits[0],
list: async () => visits,
};
});
afterEach(() => jest.resetAllMocks());
it('renders', async () => {
const { getByText } = await renderInTestApp(
<TestApiProvider apis={[[visitsApiRef, mockVisitsApi]]}>
@@ -207,6 +216,11 @@ describe('<Content kind="recent"/>', () => {
operator: '==',
value: '/tech-radar',
},
{
field: 'pathname',
operator: '==',
value: '/explore',
},
],
},
},
@@ -235,12 +249,28 @@ describe('<Content kind="recent"/>', () => {
field: 'timestamp',
},
],
filterBy: [
{
field: 'pathname',
operator: '==',
value: '/explore',
},
],
});
});
});
});
describe('<Content kind="top"/>', () => {
beforeEach(() => {
mockVisitsApi = {
save: async () => visits[0],
list: async () => visits,
};
});
afterEach(() => jest.resetAllMocks());
it('renders', async () => {
const { getByText } = await renderInTestApp(
<TestApiProvider apis={[[visitsApiRef, mockVisitsApi]]}>