Make readTaskScheduleDefinitionFromConfig properly handle bad inputs

Signed-off-by: Fredrik Adelöw <freben@gmail.com>
This commit is contained in:
Fredrik Adelöw
2023-08-02 15:23:46 +02:00
parent e8bebb6f5f
commit b810344311
3 changed files with 47 additions and 10 deletions
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/backend-plugin-api': patch
---
Make `readTaskScheduleDefinitionFromConfig` properly handle bad inputs
@@ -76,7 +76,7 @@ describe('readTaskScheduleDefinitionFromConfig', () => {
);
});
it('invalid frequency value', () => {
it('invalid frequency key', () => {
const config = new ConfigReader({
frequency: {
invalid: 'value',
@@ -89,6 +89,19 @@ describe('readTaskScheduleDefinitionFromConfig', () => {
);
});
it('invalid frequency value', () => {
const config = new ConfigReader({
frequency: {
minutes: 'value',
},
timeout: 'PT3M',
});
expect(() => readTaskScheduleDefinitionFromConfig(config)).toThrow(
"Unable to convert config value for key 'frequency.minutes' in 'mock-config' to a number",
);
});
it('frequency value with additional invalid prop', () => {
const config = new ConfigReader({
frequency: {
@@ -31,29 +31,48 @@ const propsOfHumanDuration = [
];
function convertToHumanDuration(config: Config, key: string): HumanDuration {
const props = config.getConfig(key).keys();
if (!props.find(prop => propsOfHumanDuration.includes(prop))) {
// Ensures that the root is an object
const root = config.getConfig(key);
const result: Record<string, number> = {};
let found = false;
for (const prop of propsOfHumanDuration) {
const value = root.getOptionalNumber(prop);
if (value !== undefined) {
result[prop] = value;
found = true;
}
}
if (!found) {
throw new Error(
`HumanDuration needs at least one of: ${propsOfHumanDuration}`,
);
}
const invalidProps = props.filter(
prop => !propsOfHumanDuration.includes(prop),
);
const invalidProps = root
.keys()
.filter(prop => !propsOfHumanDuration.includes(prop));
if (invalidProps.length > 0) {
throw new Error(
`HumanDuration does not contain properties: ${invalidProps}`,
);
}
return config.get<JsonObject>(key) as HumanDuration;
return result as HumanDuration;
}
function readDuration(config: Config, key: string): Duration | HumanDuration {
return typeof config.get(key) === 'string'
? Duration.fromISO(config.getString(key))
: convertToHumanDuration(config, key);
if (typeof config.get(key) === 'string') {
const value = config.getString(key);
const duration = Duration.fromISO(value);
if (!duration.isValid) {
throw new Error(`Invalid duration: ${value}`);
}
return duration;
}
return convertToHumanDuration(config, key);
}
function readCronOrDuration(