diff --git a/csaf_2_1/mandatoryTests.js b/csaf_2_1/mandatoryTests.js index 5a5a8a7b..d26ae836 100644 --- a/csaf_2_1/mandatoryTests.js +++ b/csaf_2_1/mandatoryTests.js @@ -18,7 +18,6 @@ export { mandatoryTest_6_1_26, 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, @@ -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_3 } from './mandatoryTests/mandatoryTest_6_1_27_3.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_3.js b/csaf_2_1/mandatoryTests/mandatoryTest_6_1_27_3.js new file mode 100644 index 00000000..0bbece52 --- /dev/null +++ b/csaf_2_1/mandatoryTests/mandatoryTest_6_1_27_3.js @@ -0,0 +1,63 @@ +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', + }, + }, + }, + vulnerabilities: {}, + }, +}) + +const validate = ajv.compile(inputSchema) +/** + * It MUST be tested that the element /vulnerabilities does not exist. + * + * The relevant values for /document/category are: + * + * csaf_informational_advisory + * csaf_withdrawn + * csaf_superseded + * @param {any} doc + */ +export function mandatoryTest_6_1_27_3(doc) { + /** @type {Array<{ message: string; instancePath: string }>} */ + const errors = [] + let isValid = true + + if (!validate(doc)) { + return { errors, isValid } + } + + const checkedDocumentCategories = new Set([ + 'csaf_informational_advisory', + 'csaf_withdrawn', + 'csaf_superseded', + ]) + + if ( + doc.vulnerabilities !== undefined && + checkedDocumentCategories.has(doc.document?.category) + ) { + isValid = false + errors.push({ + instancePath: '/vulnerabilities', + message: 'must not exist', + }) + } + return { errors, isValid } +} diff --git a/tests/csaf_2_1/mandatoryTest_6_1_27_3.js b/tests/csaf_2_1/mandatoryTest_6_1_27_3.js new file mode 100644 index 00000000..010a36fa --- /dev/null +++ b/tests/csaf_2_1/mandatoryTest_6_1_27_3.js @@ -0,0 +1,28 @@ +import assert from 'node:assert/strict' +import { mandatoryTest_6_1_27_3 } from '../../csaf_2_1/mandatoryTests/mandatoryTest_6_1_27_3.js' + +describe('mandatoryTest_6_1_27_3', function () { + it('only runs on relevant documents', function () { + assert.equal(mandatoryTest_6_1_27_3({ document: 'mydoc' }).isValid, true) + }) + + it('returns valid for documents with irrelevant category', function () { + assert.equal( + mandatoryTest_6_1_27_3({ + document: { category: 'csaf_base' }, + vulnerabilities: [{}], + }).isValid, + true + ) + }) + + it('returns invalid for documents with relevant category', function () { + assert.equal( + mandatoryTest_6_1_27_3({ + document: { category: 'csaf_superseded' }, + vulnerabilities: [{}], + }).isValid, + false + ) + }) +}) diff --git a/tests/csaf_2_1/oasis.js b/tests/csaf_2_1/oasis.js index 28758abd..6a6cd166 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.8', '6.1.26', - '6.1.27.3', '6.1.27.4', '6.1.27.6', '6.1.27.11',