config-loader: add visibility filtering tests + fix filtering logic
This commit is contained in:
@@ -0,0 +1,105 @@
|
||||
/*
|
||||
* Copyright 2020 Spotify AB
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { JsonObject } from '@backstage/config';
|
||||
import { ConfigVisibility } from './types';
|
||||
import { filterByVisibility } from './filtering';
|
||||
|
||||
const data = {
|
||||
arr: ['f', 'b', 's'],
|
||||
objArr: [
|
||||
{ f: 1, b: 2, s: 3 },
|
||||
{ f: 4, b: 5, s: 6 },
|
||||
],
|
||||
obj: {
|
||||
f: 'a',
|
||||
b: {
|
||||
s: true,
|
||||
},
|
||||
},
|
||||
arrF: [{ never: 'here' }],
|
||||
arrB: [{ never: 'here' }],
|
||||
arrS: [{ never: 'here' }],
|
||||
objF: { never: 'here' },
|
||||
objB: { never: 'here' },
|
||||
objS: { never: 'here' },
|
||||
};
|
||||
|
||||
const visibilities = new Map<string, ConfigVisibility>(
|
||||
Object.entries({
|
||||
'/arr/0': 'frontend',
|
||||
'/arr/1': 'backend',
|
||||
'/arr/2': 'secret',
|
||||
'/obj/f': 'frontend',
|
||||
'/obj/b': 'backend',
|
||||
'/obj/b/s': 'secret',
|
||||
'/objArr/0/f': 'frontend',
|
||||
'/objArr/0/b': 'backend',
|
||||
'/objArr/0/s': 'secret',
|
||||
'/objArr/1/f': 'frontend',
|
||||
'/objArr/1/b': 'backend',
|
||||
'/objArr/1/s': 'secret',
|
||||
'/arrF': 'frontend',
|
||||
'/arrB': 'backend',
|
||||
'/arrS': 'secret',
|
||||
'/objF': 'frontend',
|
||||
'/objB': 'backend',
|
||||
'/objS': 'secret',
|
||||
}),
|
||||
);
|
||||
|
||||
describe('filterByVisibility', () => {
|
||||
test.each<[ConfigVisibility[], JsonObject]>([
|
||||
[[], {}],
|
||||
[
|
||||
['frontend'],
|
||||
{
|
||||
arr: ['f'],
|
||||
objArr: [{ f: 1 }, { f: 4 }],
|
||||
obj: { f: 'a' },
|
||||
arrF: [],
|
||||
objF: {},
|
||||
},
|
||||
],
|
||||
[
|
||||
['backend'],
|
||||
{
|
||||
arr: ['b'],
|
||||
objArr: [{ b: 2 }, { b: 5 }],
|
||||
obj: { b: {} },
|
||||
arrF: [{ never: 'here' }],
|
||||
arrB: [{ never: 'here' }],
|
||||
arrS: [{ never: 'here' }],
|
||||
objF: { never: 'here' },
|
||||
objB: { never: 'here' },
|
||||
objS: { never: 'here' },
|
||||
},
|
||||
],
|
||||
[
|
||||
['secret'],
|
||||
{
|
||||
arr: ['s'],
|
||||
objArr: [{ s: 3 }, { s: 6 }],
|
||||
obj: { b: { s: true } },
|
||||
arrS: [],
|
||||
objS: {},
|
||||
},
|
||||
],
|
||||
[['frontend', 'backend', 'secret'], data],
|
||||
])('should filter correctly with %p', (filter, expected) => {
|
||||
expect(filterByVisibility(data, filter, visibilities)).toEqual(expected);
|
||||
});
|
||||
});
|
||||
@@ -23,13 +23,12 @@ export function filterByVisibility(
|
||||
visibilityByPath: Map<string, ConfigVisibility>,
|
||||
): JsonObject {
|
||||
function transform(jsonVal: JsonValue, path: string): JsonValue | undefined {
|
||||
const isVisible = includeVisibilities.includes(
|
||||
visibilityByPath.get(path) ?? DEFAULT_CONFIG_VISIBILITY,
|
||||
);
|
||||
|
||||
if (typeof jsonVal !== 'object') {
|
||||
const visibility =
|
||||
visibilityByPath.get(path) ?? DEFAULT_CONFIG_VISIBILITY;
|
||||
if (includeVisibilities.includes(visibility)) {
|
||||
return jsonVal;
|
||||
}
|
||||
return undefined;
|
||||
return isVisible ? jsonVal : undefined;
|
||||
} else if (jsonVal === null) {
|
||||
return undefined;
|
||||
} else if (Array.isArray(jsonVal)) {
|
||||
@@ -42,10 +41,14 @@ export function filterByVisibility(
|
||||
}
|
||||
}
|
||||
|
||||
return arr.length === 0 ? undefined : arr;
|
||||
if (arr.length > 0 || isVisible) {
|
||||
return arr;
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const outObj: JsonObject = {};
|
||||
let hasOutput = false;
|
||||
|
||||
for (const [key, value] of Object.entries(jsonVal)) {
|
||||
if (value === undefined) {
|
||||
@@ -54,10 +57,14 @@ export function filterByVisibility(
|
||||
const out = transform(value, `${path}/${key}`);
|
||||
if (out !== undefined) {
|
||||
outObj[key] = out;
|
||||
hasOutput = true;
|
||||
}
|
||||
}
|
||||
|
||||
return Object.keys(outObj).length === 0 ? undefined : outObj;
|
||||
if (hasOutput || isVisible) {
|
||||
return outObj;
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return (transform(data, '') as JsonObject) ?? {};
|
||||
|
||||
Reference in New Issue
Block a user