Skip to content

Commit

Permalink
Merge pull request #52 from johannesmarx/fix/problem-json-inheritance2
Browse files Browse the repository at this point in the history
fix: handle allOf correctly for inheritance cases of problem JSON
  • Loading branch information
kullmanp authored Mar 6, 2024
2 parents ff2a8c7 + d4419f7 commit df62022
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 1 deletion.
27 changes: 26 additions & 1 deletion functions/is-problem-json-schema.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,33 @@ const assertProblemSchema = (schema) => {
}
};

/*
* Merge list of schema definitions of type = 'object'.
* Return object will have a super set of attributes 'properties' and 'required'.
*/
const mergeObjectDefinitions = (allOfTypes) => {
if (allOfTypes.filter((item) => item.type !== 'object').length !== 0) {
throw "All schema definitions must be of type 'object'";
}

return allOfTypes.reduce((acc, item) => {
return {
type: 'object',
properties: { ...(acc.properties || {}), ...(item.properties || {}) },
required: [...(acc.required || []), ...(item.required || [])],
};
}, {});
};

const check = (schema) => {
const combinedSchemas = [...(schema.anyOf || []), ...(schema.oneOf || []), ...(schema.allOf || [])];
const combinedSchemas = [...(schema.anyOf || []), ...(schema.oneOf || [])];
if (schema.allOf) {
const mergedAllOf = mergeObjectDefinitions(schema.allOf);
if (mergedAllOf) {
combinedSchemas.push(mergedAllOf);
}
}

if (combinedSchemas.length > 0) {
combinedSchemas.forEach(check);
} else {
Expand Down
32 changes: 32 additions & 0 deletions tests/176-MUST-support-problem-JSON.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,4 +44,36 @@ describe('MUST support problem JSON [176]', () => {
}),
]);
});

test('Verify custom problem extending valid problem object does not cause error', async () => {
const openApi = await loadOpenApiSpec('base-openapi.yml');

// define custom problem extending problem json
openApi.components.schemas['CustomValidationProblem'] = {
allOf: [
{ $ref: '#/components/schemas/Problem' },
{
type: 'object',
required: ['title', 'status', 'detail', 'validation_error'],
properties: {
validation_error: { type: 'string' },
},
},
],
};

openApi.paths['/example'].get.responses['400'] = {
description: 'bad request',
content: {
'application/problem+json': {
schema: {
$ref: '#/components/schemas/CustomValidationProblem',
},
},
},
};

const result = await lint(openApi);
expect(result).toEqual([]);
});
});

0 comments on commit df62022

Please sign in to comment.