diff --git a/package.json b/package.json index df44906..71b5b9d 100644 --- a/package.json +++ b/package.json @@ -2,12 +2,13 @@ "name": "stac-extensions", "version": "1.1.0", "scripts": { - "test": "npm run check-markdown && npm run check-examples", + "test": "jest && npm run check-markdown && npm run check-examples", "check-markdown": "remark . -f -r .github/remark.yaml", "check-examples": "stac-node-validator . --lint --verbose --schemaMap https://stac-extensions.github.io/processing/v1.1.0/schema.json=./json-schema/schema.json", "format-examples": "stac-node-validator . --format --schemaMap https://stac-extensions.github.io/processing/v1.1.0/schema.json=./json-schema/schema.json" }, "dependencies": { + "jest": "^27.4.4", "remark-cli": "^8.0.0", "remark-lint": "^7.0.0", "remark-lint-no-html": "^2.0.0", diff --git a/tests/collection.test.js b/tests/collection.test.js new file mode 100644 index 0000000..2ba3871 --- /dev/null +++ b/tests/collection.test.js @@ -0,0 +1,25 @@ +const { join } = require('path'); +const { promises } = require('fs'); +const { AjvOptions, rootDirectory, schemaPath } = require('./validation.js'); +const ajv = new (require('ajv'))(AjvOptions); + +const examplePath = join(rootDirectory, 'examples/collection.json'); + +let validate; +beforeAll(async () => { + const data = JSON.parse(await promises.readFile(schemaPath)); + validate = await ajv.compileAsync(data); +}); + +describe('Collection example', () => { + it('should pass validation', async () => { + // given + const example = JSON.parse(await promises.readFile(examplePath)); + + // when + let valid = validate(example); + + // then + expect(valid).toBeTruthy() + }); +}); diff --git a/tests/item.test.js b/tests/item.test.js new file mode 100644 index 0000000..e29ba9b --- /dev/null +++ b/tests/item.test.js @@ -0,0 +1,63 @@ +const { join } = require('path'); +const { promises } = require('fs'); +const { AjvOptions, rootDirectory, schemaPath } = require('./validation.js'); +const ajv = new (require('ajv'))(AjvOptions); + +const examplePath = join(rootDirectory, 'examples/item.json'); + +let validate; +beforeAll(async () => { + const data = JSON.parse(await promises.readFile(schemaPath)); + validate = await ajv.compileAsync(data); +}); + +describe('Item example', () => { + it('should pass validation', async () => { + // given + const example = JSON.parse(await promises.readFile(examplePath)); + + // when + let valid = validate(example); + + // then + expect(valid).toBeTruthy(); + }); + + it('should fail validation with invalid properties processing:software value', async () => { + // given + const example = JSON.parse(await promises.readFile(examplePath)); + example['properties']['processing:software'] = null; + + // when + let valid = validate(example); + + // then + expect(valid).toBeFalsy(); + expect( + validate.errors.some( + (error) => + error.instancePath === '/properties/processing:software' && + error.message === 'must be object', + ), + ).toBeTruthy(); + }); + + it('should fail validation with invalid asset processing:software value ', async () => { + // given + const example = JSON.parse(await promises.readFile(examplePath)); + example['assets']['manifest']['processing:software'] = null; + + // when + let valid = validate(example); + + // then + expect(valid).toBeFalsy(); + expect( + validate.errors.some( + (error) => + error.instancePath === '/assets/manifest/processing:software' && + error.message === 'must be object', + ), + ).toBeTruthy(); + }); +}); diff --git a/tests/validation.js b/tests/validation.js new file mode 100644 index 0000000..da05d6d --- /dev/null +++ b/tests/validation.js @@ -0,0 +1,31 @@ +const axios = require('axios'); +const { dirname, join } = require('path'); +const iriFormats = require('stac-node-validator/iri.js'); + +// const directory = dirname(fileURLToPath(import.meta.url)); + +const Schemas = new Map(); +const loadSchema = function (uri) { + let existing = Schemas.get(uri); + if (existing == null) { + existing = loadSchemaFromUri(uri); + Schemas.set(uri, existing); + } + return existing; +} + +/** + * function passed in to Ajv instance which allows us to load schemas from a url at run time. + */ +module.exports.loadSchemaFromUri = async function (uri) { + try { + let response = await axios.get(uri); + return response.data; + } catch (error) { + throw new Error(`-- Schema at '${uri}' not found. Please ensure all entries in 'stac_extensions' are valid.`); + } +} + +module.exports.AjvOptions = {loadSchema, formats: Object.assign(iriFormats)}; +module.exports.rootDirectory = dirname(__dirname); +module.exports.schemaPath = join(module.exports.rootDirectory, 'json-schema/schema.json');