diff --git a/csaf_2_1/mandatoryTests.js b/csaf_2_1/mandatoryTests.js index 5a5a8a7b..f6ce9042 100644 --- a/csaf_2_1/mandatoryTests.js +++ b/csaf_2_1/mandatoryTests.js @@ -19,7 +19,6 @@ export { mandatoryTest_6_1_27_1, mandatoryTest_6_1_27_2, mandatoryTest_6_1_27_3, - mandatoryTest_6_1_27_4, mandatoryTest_6_1_27_6, mandatoryTest_6_1_27_7, mandatoryTest_6_1_27_8, @@ -42,6 +41,7 @@ export { mandatoryTest_6_1_9 } from './mandatoryTests/mandatoryTest_6_1_9.js' export { mandatoryTest_6_1_10 } from './mandatoryTests/mandatoryTest_6_1_10.js' export { mandatoryTest_6_1_11 } from './mandatoryTests/mandatoryTest_6_1_11.js' export { mandatoryTest_6_1_13 } from './mandatoryTests/mandatoryTest_6_1_13.js' +export { mandatoryTest_6_1_27_4 } from './mandatoryTests/mandatoryTest_6_1_27_4.js' export { mandatoryTest_6_1_27_5 } from './mandatoryTests/mandatoryTest_6_1_27_5.js' export { mandatoryTest_6_1_27_12 } from './mandatoryTests/mandatoryTest_6_1_27_12.js' export { mandatoryTest_6_1_27_14 } from './mandatoryTests/mandatoryTest_6_1_27_14.js' diff --git a/csaf_2_1/mandatoryTests/mandatoryTest_6_1_27_4.js b/csaf_2_1/mandatoryTests/mandatoryTest_6_1_27_4.js new file mode 100644 index 00000000..07ede3e3 --- /dev/null +++ b/csaf_2_1/mandatoryTests/mandatoryTest_6_1_27_4.js @@ -0,0 +1,61 @@ +import { Ajv } from 'ajv/dist/jtd.js' + +const ajv = new Ajv() + +/* + This is the jtd schema that needs to match the input document so that the + test is activated. If this schema doesn't match it normally means that the input + document does not validate against the csaf json schema or optional fields that + the test checks are not present. + */ +const inputSchema = /** @type {const} */ ({ + additionalProperties: true, + properties: { + document: { + additionalProperties: true, + properties: { + category: { + type: 'string', + }, + }, + }, + product_tree: {}, + }, +}) + +const validate = ajv.compile(inputSchema) + +/** + * It MUST be tested that the element /product_tree exists. + * + * The relevant values for /document/category are: + * + * @param {any} doc + */ +export function mandatoryTest_6_1_27_4(doc) { + /** @type {Array<{ message: string; instancePath: string }>} */ + const errors = [] + let isValid = true + + if (!validate(doc)) { + return { errors, isValid } + } + + const checkedDocumentCategories = new Set([ + 'csaf_security_advisory', + 'csaf_vex', + 'csaf_deprecated_security_advisory', + ]) + + if ( + doc.product_tree === undefined && + checkedDocumentCategories.has(doc.document?.category) + ) { + isValid = false + errors.push({ + instancePath: '/product_tree', + message: 'needs a product_tree', + }) + } + return { errors, isValid } +} diff --git a/tests/csaf_2_1/mandatoryTest_6_1_27_4.js b/tests/csaf_2_1/mandatoryTest_6_1_27_4.js new file mode 100644 index 00000000..ec6a8398 --- /dev/null +++ b/tests/csaf_2_1/mandatoryTest_6_1_27_4.js @@ -0,0 +1,28 @@ +import assert from 'node:assert/strict' +import { mandatoryTest_6_1_27_4 } from '../../csaf_2_1/mandatoryTests/mandatoryTest_6_1_27_4.js' + +describe('mandatoryTest_6_1_27_4', function () { + it('only runs on relevant documents', function () { + assert.equal(mandatoryTest_6_1_27_4({ document: 'mydoc' }).isValid, true) + }) + + it('returns invalid for documents without product_tree with relevant category', function () { + assert.equal( + mandatoryTest_6_1_27_4({ + document: { category: 'csaf_deprecated_security_advisory' }, + vulnerabilities: [{}], + }).isValid, + false + ) + }) + + it('returns valid for documents with product_tree with relevant category', function () { + assert.equal( + mandatoryTest_6_1_27_4({ + document: { category: 'csaf_deprecated_security_advisory' }, + product_tree: [{}], + }).isValid, + true + ) + }) +}) diff --git a/tests/csaf_2_1/oasis.js b/tests/csaf_2_1/oasis.js index d13519a2..7a8f03f0 100644 --- a/tests/csaf_2_1/oasis.js +++ b/tests/csaf_2_1/oasis.js @@ -12,7 +12,6 @@ import * as mandatory from '../../csaf_2_1/mandatoryTests.js' const excluded = [ '6.1.26', '6.1.27.3', - '6.1.27.4', '6.1.27.6', '6.1.27.11', '6.1.27.13',