From 0a8d5c1a264d3b519295cda0b642cc3e31a1eb9f Mon Sep 17 00:00:00 2001 From: Christopher Hiller Date: Tue, 29 Aug 2023 17:03:57 -0700 Subject: [PATCH] chore: add schema validation tests I pulled in [ajv](https://npm.im/ajv) for this. I had tried to use [z-schema](https://npm.im/z-schema) but I couldn't get it working quickly (apparently you need to supply the metaschema??) so abandoned it. If there's a more lightweight, _maintained_ solution, I'm happy to try it. --- package-lock.json | 17 +++++ packages/core/package.json | 1 + .../core/test/policy/invalid-bad-path.json | 7 ++ .../test/policy/invalid-bad-pkg-name.json | 9 +++ packages/core/test/policy/invalid-empty.json | 1 + packages/core/test/policy/valid.json | 63 ++++++++++++++++ packages/core/test/policySchema.spec.js | 29 ++++++++ .../test/snapshots/policySchema.spec.js.md | 69 ++++++++++++++++++ .../test/snapshots/policySchema.spec.js.snap | Bin 0 -> 859 bytes 9 files changed, 196 insertions(+) create mode 100644 packages/core/test/policy/invalid-bad-path.json create mode 100644 packages/core/test/policy/invalid-bad-pkg-name.json create mode 100644 packages/core/test/policy/invalid-empty.json create mode 100644 packages/core/test/policy/valid.json create mode 100644 packages/core/test/policySchema.spec.js create mode 100644 packages/core/test/snapshots/policySchema.spec.js.md create mode 100644 packages/core/test/snapshots/policySchema.spec.js.snap diff --git a/package-lock.json b/package-lock.json index d19e2b78ac..2c36ab3958 100644 --- a/package-lock.json +++ b/package-lock.json @@ -19980,6 +19980,7 @@ "merge-deep": "^3.0.3" }, "devDependencies": { + "ajv": "^8.12.0", "ses": "^0.18.7", "tmp-promise": "^3.0.3" }, @@ -19987,6 +19988,22 @@ "node": ">=14.0.0 <19.0.0" } }, + "packages/core/node_modules/ajv": { + "version": "8.12.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", + "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, "packages/lavapack": { "name": "@lavamoat/lavapack", "version": "5.2.1", diff --git a/packages/core/package.json b/packages/core/package.json index 1aadd76bc2..e750c3ad7b 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -15,6 +15,7 @@ "merge-deep": "^3.0.3" }, "devDependencies": { + "ajv": "^8.12.0", "ses": "^0.18.7", "tmp-promise": "^3.0.3" }, diff --git a/packages/core/test/policy/invalid-bad-path.json b/packages/core/test/policy/invalid-bad-path.json new file mode 100644 index 0000000000..c5420e87ad --- /dev/null +++ b/packages/core/test/policy/invalid-bad-path.json @@ -0,0 +1,7 @@ +{ + "resolutions": { + "some>package": { + "some>other>package": "/etc/passwd" + } + } +} diff --git a/packages/core/test/policy/invalid-bad-pkg-name.json b/packages/core/test/policy/invalid-bad-pkg-name.json new file mode 100644 index 0000000000..8b47d86c37 --- /dev/null +++ b/packages/core/test/policy/invalid-bad-pkg-name.json @@ -0,0 +1,9 @@ +{ + "resources": { + "bad>!!packagename": { + "globals": { + "console": true + } + } + } +} diff --git a/packages/core/test/policy/invalid-empty.json b/packages/core/test/policy/invalid-empty.json new file mode 100644 index 0000000000..0967ef424b --- /dev/null +++ b/packages/core/test/policy/invalid-empty.json @@ -0,0 +1 @@ +{} diff --git a/packages/core/test/policy/valid.json b/packages/core/test/policy/valid.json new file mode 100644 index 0000000000..617d43575d --- /dev/null +++ b/packages/core/test/policy/valid.json @@ -0,0 +1,63 @@ +{ + "resources": { + "browserify>buffer": { + "globals": { + "console": true + }, + "packages": { + "browserify>buffer>base64-js": true, + "browserify>buffer>ieee754": true + } + }, + "browserify>events": { + "globals": { + "console": true + } + }, + "browserify>process": { + "globals": { + "clearTimeout": true, + "setTimeout": true + } + }, + "browserify>string_decoder": { + "packages": { + "browserify>util>safe-buffer": true + } + }, + "browserify>util>safe-buffer": { + "packages": { + "browserify>buffer": true + } + }, + "keccak": { + "packages": { + "browserify>buffer": true, + "keccak>readable-stream": true + } + }, + "keccak>readable-stream": { + "packages": { + "browserify>browser-resolve": true, + "browserify>buffer": true, + "browserify>events": true, + "browserify>inherits": true, + "browserify>process": true, + "browserify>string_decoder": true, + "keccak>readable-stream>util-deprecate": true + } + }, + "keccak>readable-stream>util-deprecate": { + "globals": { + "console.trace": true, + "console.warn": true, + "localStorage": true + } + } + }, + "resolutions": { + "some>package": { + "some>other>package": "./here" + } + } +} diff --git a/packages/core/test/policySchema.spec.js b/packages/core/test/policySchema.spec.js new file mode 100644 index 0000000000..4cd4ec78a5 --- /dev/null +++ b/packages/core/test/policySchema.spec.js @@ -0,0 +1,29 @@ +const test = require('ava') +const Ajv = require('ajv') + +const schema = require('../schema/lavamoat-policy.v0-0-1.schema.json') +const validPolicy = require('./policy/valid.json') +const invalidPolicyEmpty = require('./policy/invalid-empty.json') +const invalidBadPkgName = require('./policy/invalid-bad-pkg-name.json') +const invalidBadPath = require('./policy/invalid-bad-path.json') + +const ajv = new Ajv({ allErrors: true }) +const validate = ajv.compile(schema) +test('policy schema - known good policy', (t) => { + t.truthy(validate(validPolicy)) +}) + +test('policy schema - invalid policy - empty', (t) => { + t.falsy(validate(invalidPolicyEmpty)) + t.snapshot(validate.errors) +}) + +test('policy schema - invalid policy - bad pkg name', (t) => { + t.falsy(validate(invalidBadPkgName)) + t.snapshot(validate.errors) +}) + +test('policy schema - invalid policy - bad resolution path', (t) => { + t.falsy(validate(invalidBadPath)) + t.snapshot(validate.errors) +}) diff --git a/packages/core/test/snapshots/policySchema.spec.js.md b/packages/core/test/snapshots/policySchema.spec.js.md new file mode 100644 index 0000000000..87376ce61c --- /dev/null +++ b/packages/core/test/snapshots/policySchema.spec.js.md @@ -0,0 +1,69 @@ +# Snapshot report for `test/policySchema.spec.js` + +The actual snapshot is saved in `policySchema.spec.js.snap`. + +Generated by [AVA](https://avajs.dev). + +## policy schema - invalid policy - empty + +> Snapshot 1 + + [ + { + dataPath: '', + keyword: 'required', + message: 'should have required property \'resources\'', + params: { + missingProperty: 'resources', + }, + schemaPath: '#/anyOf/0/required', + }, + { + dataPath: '', + keyword: 'required', + message: 'should have required property \'resolutions\'', + params: { + missingProperty: 'resolutions', + }, + schemaPath: '#/anyOf/1/required', + }, + { + dataPath: '', + keyword: 'anyOf', + message: 'should match some schema in anyOf', + params: {}, + schemaPath: '#/anyOf', + }, + ] + +## policy schema - invalid policy - bad pkg name + +> Snapshot 1 + + [ + { + dataPath: '.resources', + keyword: 'additionalProperties', + message: 'should NOT have additional properties', + params: { + additionalProperty: 'bad>!!packagename', + }, + schemaPath: '#/properties/resources/additionalProperties', + }, + ] + +## policy schema - invalid policy - bad resolution path + +> Snapshot 1 + + [ + { + dataPath: '.resolutions[\'some>package\'][\'some>other>package\']', + keyword: 'pattern', + message: 'should match pattern "^(\\.{1,2})(/(?=[^/\\0])[^/\\0]+)*/?$"', + params: { + pattern: '^(\\.{1,2})(/(?=[^/\\0])[^/\\0]+)*/?$', + }, + schemaPath: '#/properties/resolutions/patternProperties/%5E(%40%5Ba-z0-9-~0%5D%5Ba-z0-9-._~0%5D*~1)%3F%5Ba-z0-9-~0%5D%5Ba-z0-9-._~0%5D*(%3E(%40%5Ba-z0-9-~0%5D%5Ba-z0-9-._~0%5D*~1)%3F%5Ba-z0-9-~0%5D%5Ba-z0-9-._~0%5D*)*%24/patternProperties/%5E(%40%5Ba-z0-9-~0%5D%5Ba-z0-9-._~0%5D*~1)%3F%5Ba-z0-9-~0%5D%5Ba-z0-9-._~0%5D*(%3E(%40%5Ba-z0-9-~0%5D%5Ba-z0-9-._~0%5D*~1)%3F%5Ba-z0-9-~0%5D%5Ba-z0-9-._~0%5D*)*%24/pattern', + }, + ] diff --git a/packages/core/test/snapshots/policySchema.spec.js.snap b/packages/core/test/snapshots/policySchema.spec.js.snap new file mode 100644 index 0000000000000000000000000000000000000000..0fb0cee4fdcecc7e2e81de11ecc957e66033f05a GIT binary patch literal 859 zcmV-h1El;xRzVJ5M5VXxe$MWYX!lrdvPHMF8l#{Cb^TO6LDe43wsAH9{}F~!y-ag0J`W4i|h|Ogm4()82AXoE~)S!?s03gOq?P=K)&yzC0e~@ z+G@k!rZ+2^O;x|2P8lOx)Y~Va_LZ_K70EW0yco%{O^e!2Rf^k`nH9T0SsdZR7(auX zd!Z4F*hFW(ALy$;c*|As(3nDu>e8l?QJS~s{DIEA9bOr3g-rx_AY0K`5YgjkdlbLA|EA?SdRPrjmG^};N;obtPceQx`|jkfgw z_T4R}Ym8~e)-r!N@4UAm(mx98Z+UlbYNZ0F)&_x1X-hJQPTPkU{@OCUgh^O)K|`xP zpH6x~5e91&@B;7=a13V7bijD(KxViv-BPCCDsGsls^*r3lzGjx_86Z4WiG%=OPA|? z*398`S}h5Pa2FpygcD;*GmX+?`H>Ne6iPtc zeSc3i`Hoc6l$&G$vv%=_54$Fw_kiz!3s3>I3*yP8TbgAh?hcrFUWoV_-L(lJ#XGIj$@mAFXNa=m7?v z@CdhwjWbvH1)5q@IiHcI&ydueOll^z1NLHbo4#H<7~jbz<*D<5ZV7p+tND`S laxVX$U%S>0bMTU9{r{VS``MG3x9>nXKLIM3O2^9z005@tmp}jj literal 0 HcmV?d00001