diff --git a/csaf_2_1/mandatoryTests.js b/csaf_2_1/mandatoryTests.js index 95c5c092..fab00600 100644 --- a/csaf_2_1/mandatoryTests.js +++ b/csaf_2_1/mandatoryTests.js @@ -38,6 +38,7 @@ export { mandatoryTest_6_1_1 } from './mandatoryTests/mandatoryTest_6_1_1.js' export { mandatoryTest_6_1_8 } from './mandatoryTests/mandatoryTest_6_1_8.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_15 } from './mandatoryTests/mandatoryTest_6_1_27_15.js' export { mandatoryTest_6_1_34 } from './mandatoryTests/mandatoryTest_6_1_34.js' export { mandatoryTest_6_1_35 } from './mandatoryTests/mandatoryTest_6_1_35.js' export { mandatoryTest_6_1_9 } from './mandatoryTests/mandatoryTest_6_1_9.js' diff --git a/csaf_2_1/mandatoryTests/mandatoryTest_6_1_27_15.js b/csaf_2_1/mandatoryTests/mandatoryTest_6_1_27_15.js new file mode 100644 index 00000000..3118de3d --- /dev/null +++ b/csaf_2_1/mandatoryTests/mandatoryTest_6_1_27_15.js @@ -0,0 +1,65 @@ +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', + }, + }, + }, + }, + optionalProperties: { + product_tree: { + additionalProperties: true, + properties: {}, + }, + }, +}) + +const validate = ajv.compile(inputSchema) + +/** + * This implements the mandatory test 6.1.27.15 of the CSAF 2.1 standard. + * + * @param {unknown} doc + */ +export function mandatoryTest_6_1_27_15(doc) { + /* + The `ctx` variable holds the state that is accumulated during the test ran and is + finally returned by the function. + */ + const ctx = { + errors: + /** @type {Array<{ instancePath: string; message: string }>} */ ([]), + isValid: true, + } + + if ( + !validate(doc) || + !['csaf_withdrawn', 'csaf_superseded'].includes(doc.document.category) + ) + return ctx + + if (doc.product_tree) { + ctx.isValid = false + ctx.errors.push({ + instancePath: `/product_tree`, + message: + 'the product_tree is not allowed in the specified document category', + }) + } + + return ctx +} diff --git a/tests/csaf_2_1/mandatoryTest_6_1_27_15.js b/tests/csaf_2_1/mandatoryTest_6_1_27_15.js new file mode 100644 index 00000000..d9a50013 --- /dev/null +++ b/tests/csaf_2_1/mandatoryTest_6_1_27_15.js @@ -0,0 +1,26 @@ +import assert from 'node:assert/strict' +import { mandatoryTest_6_1_27_15 } from '../../csaf_2_1/mandatoryTests/mandatoryTest_6_1_27_15.js' + +describe('mandatoryTest_6_1_27_15', function () { + it('only runs on documents matching the input schema', function () { + assert.equal( + mandatoryTest_6_1_27_15({ + document: 'invalid json', + product_tree: [], + }).isValid, + true + ) + }) + + it('only runs on csaf_withdrawn and csaf_superseded documents', function () { + assert.equal( + mandatoryTest_6_1_27_15({ + document: { + category: 'unknown category', + }, + product_tree: [], + }).isValid, + true + ) + }) +}) diff --git a/tests/csaf_2_1/oasis.js b/tests/csaf_2_1/oasis.js index 6fb44c13..721128bc 100644 --- a/tests/csaf_2_1/oasis.js +++ b/tests/csaf_2_1/oasis.js @@ -23,7 +23,6 @@ const excluded = [ '6.1.27.12', '6.1.27.13', '6.1.27.14', - '6.1.27.15', '6.1.27.16', '6.1.27.17', '6.1.27.18',