diff --git a/.github/workflows/publish.yaml b/.github/workflows/publish.yaml index 53220f9..9e1c227 100644 --- a/.github/workflows/publish.yaml +++ b/.github/workflows/publish.yaml @@ -3,7 +3,7 @@ on: release: types: [published] jobs: - deploy: + publish: runs-on: ubuntu-latest steps: - name: Inject env variables diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index dbe73cf..43b0dd6 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -1,13 +1,20 @@ name: Check Markdown and Examples on: [push, pull_request] jobs: - deploy: - runs-on: ubuntu-latest + check: + strategy: + fail-fast: false + matrix: + runner: [ + 'macos-latest', + 'ubuntu-latest', + 'windows-latest', + ] + runs-on: ${{ matrix.runner }} steps: - uses: actions/setup-node@v2 with: node-version: 'lts/*' - uses: actions/checkout@v2 - - run: | - npm install - npm test + - run: npm install + - run: npm test diff --git a/package.json b/package.json index 46d280a..e3f10d5 100644 --- a/package.json +++ b/package.json @@ -2,12 +2,14 @@ "name": "stac-extensions", "version": "1.0.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/template/v1.0.0/schema.json=./json-schema/schema.json", "format-examples": "stac-node-validator . --format --schemaMap https://stac-extensions.github.io/template/v1.0.0/schema.json=./json-schema/schema.json" }, + "type": "module", "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..780f05e --- /dev/null +++ b/tests/collection.test.js @@ -0,0 +1,42 @@ +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(); + }); + + it('should fail validation without mandatory template:new_field field', async () => { + // given + const example = JSON.parse(await promises.readFile(examplePath)); + delete example['assets']; + delete example['item_assets']; + delete example['template:new_field']; + + // when + let valid = validate(example); + + // then + expect(valid).toBeFalsy(); + expect( + validate.errors.some((error) => error.message === "must have required property 'template:new_field'"), + ).toBeTruthy(); + }); +}); diff --git a/tests/item.test.js b/tests/item.test.js new file mode 100644 index 0000000..f150f29 --- /dev/null +++ b/tests/item.test.js @@ -0,0 +1,39 @@ +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 without mandatory template:new_field property ', async () => { + // given + const example = JSON.parse(await promises.readFile(examplePath)); + delete example.properties['template:new_field']; + // when + let valid = validate(example); + + // then + expect(valid).toBeFalsy(); + expect( + validate.errors.some((error) => error.message === "must have required property 'template:new_field'"), + ).toBeTruthy(); + }); +}); diff --git a/tests/validation.js b/tests/validation.js new file mode 100644 index 0000000..bfe02cf --- /dev/null +++ b/tests/validation.js @@ -0,0 +1,29 @@ +const axios = require('axios'); +const { dirname, join } = require('path'); +const iriFormats = require('stac-node-validator/iri.js'); + +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');