Skip to content

Commit a247e4f

Browse files
committed
feat: Updated validation checks to ensure that only one of an element exists if allowMultiple: false
1 parent 59fdf3a commit a247e4f

File tree

2 files changed

+70
-1
lines changed

2 files changed

+70
-1
lines changed

src/plugin/plugin.test.ts

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -448,4 +448,47 @@ describe('Plugin tests', () => {
448448

449449
console.log(match)
450450
})
451+
452+
it('Validates that a config correctly allows multiple of a config when allowMultiple is true', async () => {
453+
const resource = spy(new class extends TestResource {
454+
getSettings(): ResourceSettings<TestConfig> {
455+
return {
456+
id: 'ssh-config',
457+
allowMultiple: true
458+
}
459+
}
460+
})
461+
462+
const testPlugin = Plugin.create('testPlugin', [resource as any]);
463+
464+
const validate1 = await testPlugin.validate({
465+
configs: [{ core: { type: 'ssh-config' }, parameters: { propA: 'a' } }, {
466+
core: { type: 'ssh-config' },
467+
parameters: { propB: 'b' }
468+
}]
469+
})
470+
471+
expect(validate1.resourceValidations.every((r) => r.isValid)).to.be.true;
472+
})
473+
474+
it('Validates that a config correctly dis-allows multiple of a config when allowMultiple is false', async () => {
475+
const resource = spy(new class extends TestResource {
476+
getSettings(): ResourceSettings<TestConfig> {
477+
return {
478+
id: 'ssh-config',
479+
}
480+
}
481+
})
482+
483+
const testPlugin = Plugin.create('testPlugin', [resource as any]);
484+
485+
const validate1 = await testPlugin.validate({
486+
configs: [{ core: { type: 'ssh-config' }, parameters: { propA: 'a' } }, {
487+
core: { type: 'ssh-config' },
488+
parameters: { propB: 'b' }
489+
}]
490+
})
491+
492+
expect(validate1.resourceValidations.every((r) => r.isValid)).to.be.false;
493+
})
451494
});

src/plugin/plugin.ts

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ export class Plugin {
145145
}
146146

147147
async validate(data: ValidateRequestData): Promise<ValidateResponseData> {
148-
const validationResults = [];
148+
const validationResults: ValidateResponseData['resourceValidations'] = [];
149149
for (const config of data.configs) {
150150
const { core, parameters } = config;
151151

@@ -160,6 +160,32 @@ export class Plugin {
160160
validationResults.push(validation);
161161
}
162162

163+
// Validate that if allow multiple is false, then only 1 of each resource exists
164+
const countMap = data.configs.reduce((map, resource) => {
165+
if (!map.has(resource.core.type)) {
166+
map.set(resource.core.type, 0);
167+
}
168+
169+
const count = map.get(resource.core.type)!;
170+
map.set(resource.core.type, count + 1)
171+
172+
return map;
173+
}, new Map<string, number>())
174+
175+
const invalidMultipleConfigs = [...countMap.entries()].filter(([k, v]) => {
176+
const controller = this.resourceControllers.get(k)!;
177+
return !controller.parsedSettings.allowMultiple && v > 1;
178+
});
179+
180+
if (invalidMultipleConfigs.length > 0) {
181+
validationResults.push(...invalidMultipleConfigs.map(([k, v]) => ({
182+
resourceType: k,
183+
schemaValidationErrors: [],
184+
customValidationErrorMessage: `Multiple of resource type: ${k} found in configs. Only allowed 1.`,
185+
isValid: false,
186+
})));
187+
}
188+
163189
await this.crossValidateResources(data.configs);
164190
return {
165191
resourceValidations: validationResults

0 commit comments

Comments
 (0)