From 60976cf67b4d2fb4b14b35afae7e968453a780f0 Mon Sep 17 00:00:00 2001 From: Jeremy Wentworth Date: Wed, 20 Dec 2017 16:25:06 -0500 Subject: [PATCH] add jasmine test --- .travis.yml | 6 +- package.json | 3 +- spec/basics.spec.js | 35 +++++++++++ spec/support/jasmine.json | 11 ++++ test.js | 129 -------------------------------------- 5 files changed, 53 insertions(+), 131 deletions(-) create mode 100644 spec/basics.spec.js create mode 100644 spec/support/jasmine.json delete mode 100644 test.js diff --git a/.travis.yml b/.travis.yml index 28c24c79..c11d00f5 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,3 +1,7 @@ language: node_js node_js: - "6.2.0" \ No newline at end of file + "6.2.0" + +before_install: +- git config remote.origin.fetch "+refs/heads/*:refs/remotes/origin/*" +- git fetch \ No newline at end of file diff --git a/package.json b/package.json index d57bb914..b6ee41b0 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,7 @@ "version": "1.0.0", "description": "*Manifest repository for VCV Rack plugins*", "scripts": { - "test": "node test.js" + "test": "jasmine" }, "repository": { "type": "git", @@ -14,6 +14,7 @@ }, "homepage": "https://github.com/VCVRack/community#readme", "devDependencies": { + "jasmine": "^2.8.0", "node-virustotal": "^2.4.2", "request": "^2.83.0" } diff --git a/spec/basics.spec.js b/spec/basics.spec.js new file mode 100644 index 00000000..4e926e80 --- /dev/null +++ b/spec/basics.spec.js @@ -0,0 +1,35 @@ +//Jasmine Test - https://jasmine.github.io/2.8/introduction.html +const fs = require("fs"); + +describe("json", function() { + + it("simply valid parsable json", function(done) { + fs.readdir('plugins', function(err, files) { + if (err){ + fail("unable to read plugins dir"); + } + + for (let index in files) { + const filePath = `plugins/${files[index]}`; + if(!filePath.toLowerCase().endsWith('.json')){ + fail("manifests should have .json extension"); + } + + fs.readFile(filePath, 'utf8', (err, fileContent) => { + if (err){ + fail("unable to read manifest file"); + } + + let manifestObj; + try { + manifestObj = JSON.parse(fileContent+"FAIL"); + done(); + } catch(err){ + fail(`Invalid JSON: ${filePath}\n${err}`); + } + }); + } + }); + }); + +}); diff --git a/spec/support/jasmine.json b/spec/support/jasmine.json new file mode 100644 index 00000000..3ea31669 --- /dev/null +++ b/spec/support/jasmine.json @@ -0,0 +1,11 @@ +{ + "spec_dir": "spec", + "spec_files": [ + "**/*[sS]pec.js" + ], + "helpers": [ + "helpers/**/*.js" + ], + "stopSpecOnExpectationFailure": false, + "random": false +} diff --git a/test.js b/test.js deleted file mode 100644 index b9911afe..00000000 --- a/test.js +++ /dev/null @@ -1,129 +0,0 @@ -/* - -check valid JSON -check valid SHA256 -upload to VirusTotal and assert less than 3 or so engines return suspicious for each ZIP - -ZIP must not contain a __MACOSX directory at root level. -ZIP must not be a tarbomb. Yes, I know the first is a subset of this one, but it's better to have more feedback. -We might even want to assert that the single folder at root level is named as the slug of the plugin. I'm for this. - -schema validation - -slug required -if we could have a "soft" warning for slugs matching /[a-zA-Z0-9_\-]/+, that'd be great, although I'd rather their slugs break this than change. -version required -version must begin with "0.5." (this will be changed with each version bump.) - -*/ - - - -const fs = require("fs"); -const request = require("request"); -const { exec } = require('child_process'); -const vt = require("node-virustotal");//https://github.com/natewatson999/node-virustotal -const con = vt.MakePublicConnection(); -const archArr = ['win', 'lin', 'mac']; -const verbose = false; - -//VT_API_KEY is set in travisci (or set when run locally) -con.setKey(process.env.VT_API_KEY); -if(verbose){console.log('key', con.getKey());} - -//15 seconds between calls is required by virus total (4 per minute) -//https://www.virustotal.com/en/documentation/public-api/v2/ -con.setDelay(15000); -if(verbose){console.log('delay', con.getDelay());} - -//We always just check all JSON because it's easy. -//However, we only want to check zip files of manifests that have changed. - - - -//TODO FIX - travis doesn't have master -// https://github.com/travis-ci/travis-ci/issues/6069 -// todo check diff to see if "download" or "sha256" changed -exec('git diff -w --stat --name-only origin/master -- plugins/', (error, stdout, stderr) => { - if (error) { - console.error(`exec error: ${error}`); - return; - } - const changedManifestFiles = stdout.trim().split('\n'); - testAllManifests(changedManifestFiles); -}); - -function testAllManifests(changedManifestFiles){ - if(verbose){console.log("changedManifestFiles", changedManifestFiles);} - fs.readdir('plugins', function(err, files) { - if (err){ throw err; } - - for (let index in files) { - const filePath = `plugins/${files[index]}`; - if(!filePath.toLowerCase().endsWith('.json')){ - throw new Error("manifests should have .json extension"); - } - fs.readFile(filePath, 'utf8', (err, data) => { - if (err){ throw err; } - if(verbose){console.log("testing: ", filePath);} - - const shouldTestZip = changedManifestFiles.includes(filePath); - testOneManifest(filePath, data, shouldTestZip); - }); - } - }); -} - -function testOneManifest(filePath, fileContent, shouldTestZip = false) { - let manifestObj; - try { - manifestObj = JSON.parse(fileContent); - } catch(err){ - console.error(`Invalid JSON: ${filePath}`); - throw err; - } - - if (manifestObj.downloads) { - let zipUrlsChecked = []; - let lastSha256; - - archArr.map(arch => { - const archObj = manifestObj.downloads[arch]; - if (archObj && archObj.download) { - if(zipUrlsChecked.includes(archObj.download)){ - if(lastSha256 !== archObj.sha256){ - throw new Error('SHA256 should be the same if the download URL is the same.'); - } - } else { - zipUrlsChecked.push(archObj.download); - lastSha256 = archObj.sha256; - - if(shouldTestZip){ - testOneArch(archObj); - } else { - if(verbose){console.log("not testing zip because the manifest hasn't changed: ", filePath);} - } - } - } - }); - } -} - -function testOneArch(archObj) { - const urlParts = archObj.download.split('/'); - const zipName = urlParts[urlParts.length - 1].split('\?')[0]; - if(verbose){console.log(`Downloading ${archObj.download}`);} - request(archObj.download).pipe(fs.createWriteStream(zipName)).on('finish', ()=>{ - con.FileEvaluation(zipName, "application/zip", fs.readFileSync(zipName), function(data) { - console.log(data); - if(archObj.sha256 !== data.sha256){ - throw new Error(`Invalid sha256 value. manifest:${archObj.sha256} virustotal:${data.sha256}`); - } - if(data.positives > 2){ - throw new Error(`Too many positives from virustotal.`); - } - }, function(err) { - if (err){ throw err; } - }); - }); -}