diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..21c24bb --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ + +# Ignore node_module +**/node_modules/ diff --git a/.gitlab/.gitlab-ci.yml b/.gitlab/.gitlab-ci.yml new file mode 100644 index 0000000..eb4b15f --- /dev/null +++ b/.gitlab/.gitlab-ci.yml @@ -0,0 +1,172 @@ +stages: + - Manifest + - Test + - Bundle + - Distribute + - Release + +variables: + ENTRY_FOLDER: "test" # test directory for testing CI/CD, or assets directory for normal operations + RELEASE_VERSION: v0.$CI_PIPELINE_IID + PACKAGE_REGISTRY_URL: "${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/generic/${PACKAGE_NAME}/${RELEASE_VERSION}" + +# Jobs from here run on Merge Requests as prerequisite for merging. +.manifest-job: &manifest + stage: Manifest + image: node:latest + rules: + - if: $CI_PIPELINE_SOURCE == "merge_request_event" + changes: + - ${ENTRY_FOLDER}/${PACKAGE_NAME}/* + script: + - cd src/build_job + - npm install + - npm run start + - cat ../../${ENTRY_FOLDER}/${PACKAGE_NAME}/theme.json + artifacts: + paths: + - ${ENTRY_FOLDER}/${PACKAGE_NAME}/theme.json + when: on_success + expire_in: "1 hour" + +manifest-job/valid_set: + variables: + PACKAGE_NAME: "valid_set" + <<: *manifest + +.test-images-job: &test-images + stage: Test + image: python:latest + rules: + - if: $CI_PIPELINE_SOURCE == "merge_request_event" + changes: + - ${ENTRY_FOLDER}/${PACKAGE_NAME}/* + script: + - pip install -U pytest pillow iteration_utilities + - python -m pytest src/test_images_job/test_wpp.py --tb=line -rA --color=yes --code-highlight=yes -q + allow_failure: true + +test-images-job/valid_set: + variables: + PACKAGE_NAME: "valid_set" + <<: *test-images + +test-images-job/missing_tag_set: + variables: + PACKAGE_NAME: "missing_tag_set" + <<: *test-images + +.test-manifest-job: &test-manifest + stage: Test + image: node:latest + rules: + - if: $CI_PIPELINE_SOURCE == "merge_request_event" + changes: + - ${ENTRY_FOLDER}/${PACKAGE_NAME}/* + script: + - cd src/test_manifest_job + - npm install ajv ajv-errors mocha mocha-steps chai + - cd ../.. + - node src/test_manifest_job/node_modules/mocha/bin/_mocha --require mocha-steps --colors src/test_manifest_job/wpp_checker.js + +test-manifest-job/valid_set: + variables: + PACKAGE_NAME: "valid_set" + <<: *test-manifest + +test-manifest-job/missing_tag_set: + variables: + PACKAGE_NAME: "missing_tag_set" + <<: *test-manifest + +# Jobs from here run Merged_results or Push/Merge Commits to the main branch. Tag is created on release so no run with tag creation +.bundle-job: &bundle + stage: Bundle + image: javieraviles/zip:latest + rules: + - if: $CI_COMMIT_TAG + when: never # Do not run this job when a tag is created manually + - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH + changes: + - ${ENTRY_FOLDER}/${PACKAGE_NAME}/* + script: + - zip -j ${PACKAGE_NAME}.zip ${ENTRY_FOLDER}/${PACKAGE_NAME}/* + artifacts: + paths: + - ${PACKAGE_NAME}.zip + when: on_success + expire_in: "1 hour" + +bundle-job/valid_set: + variables: + PACKAGE_NAME: "valid_set" + <<: *bundle + +bundle-job/missing_tag_set: + variables: + PACKAGE_NAME: "missing_tag_set" + <<: *bundle + +.upload-job: &upload + stage: Distribute + image: curlimages/curl:latest + rules: + - if: $CI_COMMIT_TAG + when: never # Do not run this job when a tag is created manually + - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH + changes: + - ${ENTRY_FOLDER}/${PACKAGE_NAME}/* + script: + - | + curl --fail \ + --header "JOB-TOKEN: ${CI_JOB_TOKEN}" \ + --upload-file ${PACKAGE_NAME}.zip "${PACKAGE_REGISTRY_URL}/${PACKAGE_NAME}.zip?select=package_file" + +upload-job/valid_set: + needs: + - bundle-job/valid_set + variables: + PACKAGE_NAME: "valid_set" + <<: *upload + +upload-job/missing_tag_set: + needs: + - bundle-job/missing_tag_set + variables: + PACKAGE_NAME: "missing_tag_set" + <<: *upload + +.release-job: &release + stage: Release + image: registry.gitlab.com/gitlab-org/release-cli:latest + rules: + - if: $CI_COMMIT_TAG + when: never # Do not run this job when a tag is created manually + - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH + changes: + - ${ENTRY_FOLDER}/${PACKAGE_NAME}/* + script: + - echo "Releasing assets for $PACKAGE_NAME" + release: + name: "Release $PACKAGE_NAME $RELEASE_VERSION" + tag_name: "$PACKAGE_NAME.$RELEASE_VERSION" + description: "Version $RELEASE_VERSION" + ref: "$CI_COMMIT_SHA" + assets: + links: + - name: ${PACKAGE_NAME} + url: "${PACKAGE_REGISTRY_URL}/${PACKAGE_NAME}.zip" + +release-job/valid_set: + needs: + - upload-job/valid_set + variables: + PACKAGE_NAME: "valid_set" + <<: *release + +release-job/missing_tag_set: + needs: + - upload-job/missing_tag_set + variables: + PACKAGE_NAME: "missing_tag_set" + <<: *release diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..7ac5fa6 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,30 @@ +{ + // Utilisez IntelliSense pour en savoir plus sur les attributs possibles. + // Pointez pour afficher la description des attributs existants. + // Pour plus d'informations, visitez : https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "type": "node", + "request": "launch", + "name": "Tester avec Valid_set", + "skipFiles": [ + "/**" + ], + "program": "${workspaceFolder}/src/test_manifest_job/node_modules/mocha/bin/_mocha", + "args": [ + "${workspaceFolder}/src/test_manifest_job/wpp_checker.js", + "--require mocha-steps", + "--colors", + ], + "env": { + "ENTRY_FOLDER": "test", + "PACKAGE_NAME": "valid_set" + }, + "internalConsoleOptions": "openOnSessionStart", + "console": "integratedTerminal", + "cwd": "${workspaceFolder}", + "autoAttachChildProcesses": true, + } + ] +} \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..56ce11b --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,5 @@ +{ + "conventionalCommits.scopes": [ + "cicd" + ] +} \ No newline at end of file diff --git a/src/build_job/package-lock.json b/src/build_job/package-lock.json new file mode 100644 index 0000000..e268d95 --- /dev/null +++ b/src/build_job/package-lock.json @@ -0,0 +1,21 @@ +{ + "name": "build_job", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "build_job", + "version": "1.0.0", + "license": "ISC", + "dependencies": { + "node-iptc": "^1.0.5" + } + }, + "node_modules/node-iptc": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/node-iptc/-/node-iptc-1.0.5.tgz", + "integrity": "sha512-+e9aVETp/X8iFX2qBw2GnABkq/jGs7dJdxGURZysOdn4ZdOdArPW2a3xQpSq6GX2CcgEzUklDfaC/cg4sLv35g==" + } + } +} diff --git a/src/build_job/package.json b/src/build_job/package.json new file mode 100644 index 0000000..40eeb97 --- /dev/null +++ b/src/build_job/package.json @@ -0,0 +1,14 @@ +{ + "name": "build_job", + "version": "1.0.0", + "description": "Generate a theme.json file from the images' metadata of the working folder.", + "main": "themeset_builder.js", + "scripts": { + "start": "node themeset_builder.js" + }, + "author": "Simon", + "license": "ISC", + "dependencies": { + "node-iptc": "^1.0.5" + } +} \ No newline at end of file diff --git a/src/build_job/themeset_builder.js b/src/build_job/themeset_builder.js index e69de29..862f8cd 100644 --- a/src/build_job/themeset_builder.js +++ b/src/build_job/themeset_builder.js @@ -0,0 +1,74 @@ +const fs = require("fs"); +const path = require("path"); +const iptc = require("node-iptc"); + + +// find all images +const slug = process.env["PACKAGE_NAME"]; +const root = process.env["ENTRY_FOLDER"]; +let workingDirectory = path.join("../..", root, slug); + +// extract metadata from them +fs.readdir(workingDirectory, (err, files) => { + if (err) { throw err }; + + // construct a JSON file + let theme = new Object(); + theme.dayImageList = []; + theme.nightImageList = []; + theme.sunsetImageList = []; + theme.sunriseImageList = []; + + // iterate each files + files.filter(file => path.extname(file) == '.jpg').forEach(image => { + buffer = fs.readFileSync(path.join(workingDirectory, image)); + //if (err) { throw err }; + // extract metadata + let metadata = iptc(buffer); + // fill object + theme.imageFilename ||= metadata.special_instructions + "_*" + path.extname(image); + theme.imageCredits ||= metadata.copyright_notice; + theme.displayName ||= metadata.headline; + // explore categories to find if image is dayHighlight or nightHighlight + metadata.supplemental_categories?.forEach(cat => { + switch (cat) { + case "dayHighlight": + theme.dayHighlight ||= parseInt(metadata.original_transmission_reference); + break; + case "nightHighlight": + theme.nightHighlight ||= parseInt(metadata.original_transmission_reference); + break; + default: + break; + } + }); + + switch (metadata.category) { + case "day": + theme.dayImageList.push(parseInt(metadata.original_transmission_reference)); + break; + case "night": + case "nig": + theme.nightImageList.push(parseInt(metadata.original_transmission_reference)); + break; + case "sunset": + case "twilight": + case "twi": + theme.sunsetImageList.push(parseInt(metadata.original_transmission_reference)); + break; + case "sunrise": + case "dawn": + case "daw": + theme.sunriseImageList.push(parseInt(metadata.original_transmission_reference)); + break; + default: + break; + } + }); + + fs.writeFileSync(path.join(workingDirectory, 'theme.json'), JSON.stringify(theme)); +}); + + + + diff --git a/src/test_images_job/test_wpp.py b/src/test_images_job/test_wpp.py index 3bdda88..f12b1fa 100644 --- a/src/test_images_job/test_wpp.py +++ b/src/test_images_job/test_wpp.py @@ -46,8 +46,8 @@ def validate_brightness_image(working_path, theme_config, high_light, image_list @pytest.fixture def working_path(): # get the global variables containing gitlab-given project slug. - project_slug = os.environ["WPP_SLUG"] - root_folder = os.environ["WPP_ROOT"] + project_slug = os.environ["PACKAGE_NAME"] + root_folder = os.environ["ENTRY_FOLDER"] working_path = Path(root_folder, project_slug) if not working_path.is_dir(): raise FileNotFoundError(f"No project found for the given {working_path}.") @@ -76,7 +76,6 @@ def test_image_size(working_path, manifest): assert w >= h, "✖ Image orientation is portrait (must be landscape or square)" # print(f"✔ Images are big enough ({w}×{h}) and landscape.") - def test_overlapping_images(manifest): jointed_lists = manifest.get("dayImageList") jointed_lists.extend(manifest.get("nightImageList")) diff --git a/src/test_manifest_job/package-lock.json b/src/test_manifest_job/package-lock.json index 8a49224..b800ae0 100644 --- a/src/test_manifest_job/package-lock.json +++ b/src/test_manifest_job/package-lock.json @@ -1,18 +1,20 @@ { - "name": "wppchecker", + "name": "wpp-checker", "version": "1.0.0", "lockfileVersion": 2, "requires": true, "packages": { "": { - "name": "wppchecker", + "name": "wpp-checker", "version": "1.0.0", "license": "ISC", "dependencies": { - "ajv": "^8.5.0", + "ajv": "^8.12.0", "ajv-errors": "^3.0.0", - "chai": "^4.3.4", - "mocha": "^8.4.0", + "chai": "^4.3.7", + "mocha": "^8.4.0" + }, + "devDependencies": { "mocha-steps": "^1.3.0" } }, @@ -22,9 +24,9 @@ "integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==" }, "node_modules/ajv": { - "version": "8.5.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.5.0.tgz", - "integrity": "sha512-Y2l399Tt1AguU3BPRP9Fn4eN+Or+StUGWCUpbnFyXSo8NZ9S4uj+AG2pjs5apK+ZMOwYOz1+a+VKvKH7CudXgQ==", + "version": "8.12.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", + "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", "dependencies": { "fast-deep-equal": "^3.1.1", "json-schema-traverse": "^1.0.0", @@ -149,14 +151,15 @@ } }, "node_modules/chai": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.4.tgz", - "integrity": "sha512-yS5H68VYOCtN1cjfwumDSuzn/9c+yza4f3reKXlE5rUg7SFcCEy90gJvydNgOYtblyf4Zi6jIWRnXOgErta0KA==", + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.7.tgz", + "integrity": "sha512-HLnAzZ2iupm25PlN0xFreAlBA5zaBSv3og0DdeGA4Ar6h6rJ3A0rolRUKJhSF2V10GZKDgWF/VmAEsNWjCRB+A==", "dependencies": { "assertion-error": "^1.1.0", "check-error": "^1.0.2", - "deep-eql": "^3.0.1", + "deep-eql": "^4.1.2", "get-func-name": "^2.0.0", + "loupe": "^2.3.1", "pathval": "^1.1.1", "type-detect": "^4.0.5" }, @@ -322,14 +325,14 @@ } }, "node_modules/deep-eql": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", - "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.3.tgz", + "integrity": "sha512-WaEtAOpRA1MQ0eohqZjpGD8zdI0Ovsm8mmFhaDN8dvDZzyoUMcYDnf5Y6iu7HTXxf8JDS23qWa4a+hKCDyOPzw==", "dependencies": { "type-detect": "^4.0.0" }, "engines": { - "node": ">=0.12" + "node": ">=6" } }, "node_modules/diff": { @@ -605,6 +608,14 @@ "node": ">=10" } }, + "node_modules/loupe": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.6.tgz", + "integrity": "sha512-RaPMZKiMy8/JruncMU5Bt6na1eftNoo++R4Y+N2FrxkDVTrGvcyzFTsaGif4QTeKESheMGegbhw6iUAq+5A8zA==", + "dependencies": { + "get-func-name": "^2.0.0" + } + }, "node_modules/minimatch": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", @@ -662,7 +673,8 @@ "node_modules/mocha-steps": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/mocha-steps/-/mocha-steps-1.3.0.tgz", - "integrity": "sha512-KZvpMJTqzLZw3mOb+EEuYi4YZS41C9iTnb7skVFRxHjUd1OYbl64tCMSmpdIRM9LnwIrSOaRfPtNpF5msgv6Eg==" + "integrity": "sha512-KZvpMJTqzLZw3mOb+EEuYi4YZS41C9iTnb7skVFRxHjUd1OYbl64tCMSmpdIRM9LnwIrSOaRfPtNpF5msgv6Eg==", + "dev": true }, "node_modules/ms": { "version": "2.1.3", @@ -1098,9 +1110,9 @@ "integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==" }, "ajv": { - "version": "8.5.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.5.0.tgz", - "integrity": "sha512-Y2l399Tt1AguU3BPRP9Fn4eN+Or+StUGWCUpbnFyXSo8NZ9S4uj+AG2pjs5apK+ZMOwYOz1+a+VKvKH7CudXgQ==", + "version": "8.12.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", + "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", "requires": { "fast-deep-equal": "^3.1.1", "json-schema-traverse": "^1.0.0", @@ -1189,14 +1201,15 @@ "integrity": "sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==" }, "chai": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.4.tgz", - "integrity": "sha512-yS5H68VYOCtN1cjfwumDSuzn/9c+yza4f3reKXlE5rUg7SFcCEy90gJvydNgOYtblyf4Zi6jIWRnXOgErta0KA==", + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.7.tgz", + "integrity": "sha512-HLnAzZ2iupm25PlN0xFreAlBA5zaBSv3og0DdeGA4Ar6h6rJ3A0rolRUKJhSF2V10GZKDgWF/VmAEsNWjCRB+A==", "requires": { "assertion-error": "^1.1.0", "check-error": "^1.0.2", - "deep-eql": "^3.0.1", + "deep-eql": "^4.1.2", "get-func-name": "^2.0.0", + "loupe": "^2.3.1", "pathval": "^1.1.1", "type-detect": "^4.0.5" } @@ -1319,9 +1332,9 @@ "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==" }, "deep-eql": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", - "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.3.tgz", + "integrity": "sha512-WaEtAOpRA1MQ0eohqZjpGD8zdI0Ovsm8mmFhaDN8dvDZzyoUMcYDnf5Y6iu7HTXxf8JDS23qWa4a+hKCDyOPzw==", "requires": { "type-detect": "^4.0.0" } @@ -1514,6 +1527,14 @@ "chalk": "^4.0.0" } }, + "loupe": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.6.tgz", + "integrity": "sha512-RaPMZKiMy8/JruncMU5Bt6na1eftNoo++R4Y+N2FrxkDVTrGvcyzFTsaGif4QTeKESheMGegbhw6iUAq+5A8zA==", + "requires": { + "get-func-name": "^2.0.0" + } + }, "minimatch": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", @@ -1557,7 +1578,8 @@ "mocha-steps": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/mocha-steps/-/mocha-steps-1.3.0.tgz", - "integrity": "sha512-KZvpMJTqzLZw3mOb+EEuYi4YZS41C9iTnb7skVFRxHjUd1OYbl64tCMSmpdIRM9LnwIrSOaRfPtNpF5msgv6Eg==" + "integrity": "sha512-KZvpMJTqzLZw3mOb+EEuYi4YZS41C9iTnb7skVFRxHjUd1OYbl64tCMSmpdIRM9LnwIrSOaRfPtNpF5msgv6Eg==", + "dev": true }, "ms": { "version": "2.1.3", diff --git a/src/test_manifest_job/package.json b/src/test_manifest_job/package.json index b250d76..86af811 100644 --- a/src/test_manifest_job/package.json +++ b/src/test_manifest_job/package.json @@ -1,12 +1,12 @@ { - "name": "wppchecker", + "name": "wpp-checker", "version": "1.0.0", "description": "", - "main": "wppChecker.js", + "main": "wpp_checker.js", "scripts": { - "test": "mocha wppChecker.js --require mocha-step --colors" + "test": "src/test_manifest_job/node_modules/mocha/bin/_mocha --require mocha-steps --colors src/test_manifest_job/wpp_checker.js" }, - "author": "PtiSimon", + "author": "Simon", "license": "ISC", "dependencies": { "ajv": "^8.5.0", @@ -15,4 +15,4 @@ "mocha": "^8.4.0", "mocha-steps": "^1.3.0" } -} +} \ No newline at end of file diff --git a/src/test_manifest_job/wppChecker.js b/src/test_manifest_job/wppChecker.js deleted file mode 100644 index 7fc1364..0000000 --- a/src/test_manifest_job/wppChecker.js +++ /dev/null @@ -1,76 +0,0 @@ -const fs = require("fs"); -const path = require("path"); -const { env, exit } = require("process"); -const expect = require("chai").expect; -const Ajv = require("ajv").default; -const ajv = new Ajv({allErrors: true}); -require("ajv-errors")(ajv); - -//let root, slug; -//let workingDirectory = path.join(root, slug); -//console.log(`👷‍♂️ Working with ‘${slug}’ slug.`); - -const themeSchemaFile = ".gitlab/node_job/json_theme_schema.jsonc"; -let wppManifest; -let validator; -let files; - -function leftOuterJoin(leftArray, rightArray) { - return leftArray.filter(function(el) { - return this.indexOf(el) < 0; - }, rightArray); -} - -function flatReferences(wppManifest) { - allImageIds = [ - wppManifest.dayHighlight, - wppManifest.nightHighlight, - ...wppManifest.dayImageList, - ...wppManifest.nightImageList, - ...(wppManifest.sunsetImageList || []), - ...(wppManifest.sunriseImageList || []) - ]; - return allImageIds.filter(el => el !== undefined).map(el => { - return wppManifest.imageFilename.replace("*", el); - }); -} - -describe('Mandatory Checks', function() { - before(function() { - slug = env.WPP_SLUG; - expect(slug).to.be.a("string").that.is.not.empty; - root = env.WPP_ROOT; - expect(root).to.be.a("string").that.is.not.empty; - workingDirectory = path.join(root, slug); - files = fs.readdirSync(workingDirectory); - expect(files).to.be.an('array').that.is.not.empty; - validator = ajv.compile(JSON.parse(fs.readFileSync(themeSchemaFile, 'utf8'))); - }); - - step('Manifest is an existing json file', function() { - wppManifest = JSON.parse(fs.readFileSync(path.join(workingDirectory, "theme.json"), "utf8")); - }); - - step('Manifest passes the schema', function() { - const isValid = validator(wppManifest); - if(!isValid) expect.fail(`\n\t• ${validator.errors.map(el => {return el.message;}).join('\n\t• ')}`); - }); - - step('There are no missing files', function() { - let references = flatReferences(wppManifest); - references.push("theme.json"); - missings = leftOuterJoin(references, files); - expect(missings, - `The following reference${(missings.length > 1)? "s": ""} from theme.json ${(missings.length > 1)? "are": "is"} missing in the pack. Consider adding ${(missings.length > 1)? "them": " it"} to the pack or removing the reference${(missings.length > 1)? "s": ""} from the theme.json:\n\t• ${missings.join('\n\t• ')}\n` - ).to.be.lengthOf(0, ); - }); - - step('There are no orphan files', function() { - let references = flatReferences(wppManifest); - orphans = leftOuterJoin(files.filter(x => x !== "theme.json"), references); - expect(orphans, - `The following orphan file${(orphans.length > 1)? "s are": " is"} not referenced in this theme.json. Consider removing the file${(orphans.length > 1)? "s": ""} or referencing ${(orphans.length > 1)? "them": "it"} in the theme.json:\n\t• ${orphans.join('\n\t• ')}\n` - ).to.be.lengthOf(0); - }); - -}); \ No newline at end of file diff --git a/src/test_manifest_job/wpp_checker.js b/src/test_manifest_job/wpp_checker.js new file mode 100644 index 0000000..a026224 --- /dev/null +++ b/src/test_manifest_job/wpp_checker.js @@ -0,0 +1,76 @@ +const fs = require("fs"); +const path = require("path"); +const expect = require("chai").expect; +const Ajv = require("ajv").default; +const ajv = new Ajv({ allErrors: true }); +require("ajv-errors")(ajv); + +//let root, slug; +//let workingDirectory = path.join(root, slug); +//console.log(`👷‍♂️ Working with ‘${slug}’ slug.`); + +const themeSchemaFile = "src/test_manifest_job/json_theme_schema.jsonc"; +let wppManifest; +let validator; +let files; +let workingDirectory; + +function leftOuterJoin(leftArray, rightArray) { + return leftArray.filter(function (el) { + return this.indexOf(el) < 0; + }, rightArray); +} + +function flatReferences(wppManifest) { + allImageIds = [ + wppManifest.dayHighlight, + wppManifest.nightHighlight, + ...wppManifest.dayImageList, + ...wppManifest.nightImageList, + ...(wppManifest.sunsetImageList || []), + ...(wppManifest.sunriseImageList || []) + ]; + return allImageIds.filter(el => el !== undefined).map(el => { + return wppManifest.imageFilename.replace("*", el); + }); +} + +describe('Mandatory Checks', function () { + before(function () { + const slug = process.env["PACKAGE_NAME"]; + expect(slug).to.be.a("string").that.is.not.empty; + const root = process.env["ENTRY_FOLDER"]; + expect(root).to.be.a("string").that.is.not.empty; + workingDirectory = path.join(root, slug); + files = fs.readdirSync(workingDirectory); + expect(files).to.be.an('array').that.is.not.empty; + validator = ajv.compile(JSON.parse(fs.readFileSync(themeSchemaFile, 'utf8'))); + }); + + step('Manifest is an existing json file', function () { + wppManifest = JSON.parse(fs.readFileSync(path.join(workingDirectory, "theme.json"), "utf8")); + }); + + step('Manifest passes the schema', function () { + const isValid = validator(wppManifest); + if (!isValid) expect.fail(`\n\t• ${validator.errors.map(el => { return el.message; }).join('\n\t• ')}`); + }); + + step('There are no missing files', function () { + let references = flatReferences(wppManifest); + references.push("theme.json"); + let missings = leftOuterJoin(references, files); + expect(missings, + `The following reference${(missings.length > 1) ? "s" : ""} from theme.json ${(missings.length > 1) ? "are" : "is"} missing in the pack. Consider adding ${(missings.length > 1) ? "them" : " it"} to the pack or removing the reference${(missings.length > 1) ? "s" : ""} from the theme.json:\n\t• ${missings.join('\n\t• ')}\n` + ).to.be.lengthOf(0,); + }); + + step('There are no orphan files', function () { + let references = flatReferences(wppManifest); + let orphans = leftOuterJoin(files.filter(x => x !== "theme.json"), references); + expect(orphans, + `The following orphan file${(orphans.length > 1) ? "s are" : " is"} not referenced in this theme.json. Consider removing the file${(orphans.length > 1) ? "s" : ""} or referencing ${(orphans.length > 1) ? "them" : "it"} in the theme.json:\n\t• ${orphans.join('\n\t• ')}\n` + ).to.be.lengthOf(0); + }); + +}); \ No newline at end of file diff --git a/test/missing_tag_set/bl3_landscape_1.jpg b/test/missing_tag_set/bl3_landscape_1.jpg new file mode 100644 index 0000000..3e48b8b Binary files /dev/null and b/test/missing_tag_set/bl3_landscape_1.jpg differ diff --git a/test/missing_tag_set/bl3_landscape_2.jpg b/test/missing_tag_set/bl3_landscape_2.jpg new file mode 100644 index 0000000..e69683f Binary files /dev/null and b/test/missing_tag_set/bl3_landscape_2.jpg differ diff --git a/test/missing_tag_set/bl3_landscape_3.jpg b/test/missing_tag_set/bl3_landscape_3.jpg new file mode 100644 index 0000000..9fa97bb Binary files /dev/null and b/test/missing_tag_set/bl3_landscape_3.jpg differ diff --git a/test/missing_tag_set/bl3_landscape_4.jpg b/test/missing_tag_set/bl3_landscape_4.jpg new file mode 100644 index 0000000..4c3da38 Binary files /dev/null and b/test/missing_tag_set/bl3_landscape_4.jpg differ diff --git a/test/missing_tag_set/theme.json b/test/missing_tag_set/theme.json new file mode 100644 index 0000000..3add1bb --- /dev/null +++ b/test/missing_tag_set/theme.json @@ -0,0 +1,14 @@ +{ + "imageFilename": "bl3_landscape_*.jpg", + "imageCredits": "© Gearbox", + "displayName": "", + "dayImageList": [ + 2 + ], + "sunsetImageList": [ + 2 + ], + "nightImageList": [ + 3 + ] +} \ No newline at end of file diff --git a/test/valid_set/theme.json b/test/valid_set/theme.json new file mode 100644 index 0000000..4653a60 --- /dev/null +++ b/test/valid_set/theme.json @@ -0,0 +1,19 @@ +{ + "dayImageList": [ + 1 + ], + "nightImageList": [ + 3 + ], + "sunsetImageList": [ + 2 + ], + "sunriseImageList": [ + 4 + ], + "imageFilename": "bl2_eridum_badlands_*.jpg", + "imageCredits": "© Thoscellen, © 2K Games, © Gearbox Software", + "displayName": "Eridum Badlands", + "dayHighlight": 1, + "nightHighlight": 3 +} \ No newline at end of file