add import / export functionality, along with tests, fixes #8

This commit is contained in:
Peter Snyder 2017-10-28 15:29:44 -05:00
parent 49b9833f86
commit 77a34bd4b9
6 changed files with 198 additions and 65 deletions

View file

@ -12,4 +12,12 @@ body {
section p:first-child {
padding-top: 1em;
}
section.container {
margin-top: 2em;
}
section {
margin-bottom: 5em;
}

View file

@ -6,9 +6,11 @@
const generateExportString = function (domainsToExport, allDomainData) {
const dataToExport = domainsToExport.map(function (domain) {
const domainsToBlock = allDomainData[domain];
domainsToBlock.sort();
return {
"pattern": domain,
"standards": allDomainData[domain]
"standards": domainsToBlock
};
});
@ -18,73 +20,81 @@
Vue.component("import-export", {
props: ["domainNames", "selectedStandards"],
template: `
<h2>Export Settings</h2>
<div class="form-group">
<label class="control-label">Select domain rules to export:</label>
<select multiple class="form-control" v-model="domainsToExport">
<option v-for="domain in domainNames" :value="domain">
{{ domain }}
</option>
</select>
<span class="help-block">
Select one or more domain rules to export.
</span>
</div>
<div class="form-group">
<label class="control-label">
The below is a copy of the selected standards to export elsewhere:
</label>
<textarea
class="form-control"
rows="3"
readonly
v-model="exportedData"
placeholder="Exported data will appear here."></textarea>
</div>
<h2>Import Settings</h2>
<div :class="['form-group', {'has-error': importError }]">
<label class="control-label">
Paste the exported data you'd like to import in the textarea below:
</label>
<textarea
class="form-control"
rows="3"
v-model="importTextAreaData"
placeholder="Paste the data you would like to import below."></textarea>
</div>
<div :class="['form-group', {'has-error': importError }]">
<div class="checkbox">
<label>
<input type="checkbox" v-model="shouldOverwrite">
Overwrite existing settings?
<section class="export-section">
<h2>Export Settings</h2>
<div class="form-group">
<label class="control-label">
Select domain rules to export:
</label>
<select multiple class="form-control" v-model="domainsToExport">
<option v-for="domain in domainNames" :value="domain">
{{ domain }}
</option>
</select>
<span class="help-block">
If this option is selected, than existing options will be
overwritten. If it is unchecked, then the blocked standards
for existing domains will not be affected.
Select one or more domain rules to export.
</span>
</div>
</div>
<div class="form-group">
<button class="btn btn-primary"
v-bind:disabled="!isValidToImport()"
@click="onImportClicked">Import Settings</button>
</div>
<div class="form-group">
<label class="control-label">
The below is a copy of the selected standards to export elsewhere:
</label>
<textarea
class="form-control"
rows="3"
readonly
v-model="exportedData"
placeholder="Exported data will appear here."></textarea>
</div>
</section>
<div class="form-group>
<label class="control-label">Import log:</label>
<textarea
readonly
:class="['form-control', importError ? 'alert-danger' : '']"
rows="3"
v-model="importLog"
placeholder="The results of each import will be presented here."></textarea>
</div>
<section class="import-section">
<h2>Import Settings</h2>
<div :class="['form-group', {'has-error': importError }]">
<label class="control-label">
Paste the exported data you'd like to import in the textarea below:
</label>
<textarea
class="form-control"
rows="3"
v-model="importTextAreaData"
placeholder="Paste the data you would like to import below."></textarea>
</div>
<div :class="['form-group', {'has-error': importError }]">
<div class="checkbox">
<label>
<input type="checkbox" v-model="shouldOverwrite">
Overwrite existing settings?
</label>
<span class="help-block">
If this option is selected, than existing options will be
overwritten. If it is unchecked, then the blocked standards
for existing domains will not be affected.
</span>
</div>
</div>
<div class="form-group">
<button class="btn btn-primary"
v-bind:disabled="!isValidToImport()"
@click="onImportClicked">Import Settings</button>
</div>
<div class="form-group">
<label class="control-label">
Import log:
</label>
<textarea
readonly
:class="['form-control', importError ? 'alert-danger' : '']"
rows="3"
v-model="importLog"
placeholder="The results of each import will be presented here."></textarea>
</div>
</section?
`,
data: function () {
return {

18
package-lock.json generated
View file

@ -1637,6 +1637,24 @@
"capture-stack-trace": "1.0.0"
}
},
"cross-env": {
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/cross-env/-/cross-env-5.1.1.tgz",
"integrity": "sha512-Wtvr+z0Z06KO1JxjfRRsPC+df7biIOiuV4iZ73cThjFGkH+ULBZq1MkBdywEcJC4cTDbO6c8IjgRjfswx3YTBA==",
"dev": true,
"requires": {
"cross-spawn": "5.1.0",
"is-windows": "1.0.1"
},
"dependencies": {
"is-windows": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.1.tgz",
"integrity": "sha1-MQ23D3QtJZoWo2kgK1GvhCMzENk=",
"dev": true
}
}
},
"cross-spawn": {
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz",

View file

@ -26,8 +26,8 @@
"firefox": "web-ext -s add-on run",
"lint": "node_modules/eslint/bin/eslint.js .",
"lint:fix": "node_modules/eslint/bin/eslint.js --fix .",
"test": "npm run clean; npm run bundle && ln -s `ls dist/` dist/webapi_manager.zip && node_modules/mocha/bin/mocha test/functional/*.js",
"test:watch": "npm test --watch"
"test": "npm run clean; npm run bundle && ln -s `ls dist/` dist/webapi_manager.zip && cross-env node_modules/mocha/bin/mocha test/functional/*.js",
"test:watch": "cross-env npm test --watch"
},
"pre-push": {
"run": [
@ -37,6 +37,7 @@
},
"devDependencies": {
"assert": "^1.4.1",
"cross-env": "^5.1.1",
"eslint": "^4.9.0",
"geckodriver": "^1.9.0",
"gulp": "^3.9.1",

View file

@ -0,0 +1,96 @@
"use strict";
const assert = require("assert");
const utils = require("./lib/utils");
const webdriver = require("selenium-webdriver");
const by = webdriver.By;
const until = webdriver.until;
const emptyRuleSet = "[{\"pattern\":\"(default)\",\"standards\":[]}]";
const blockingSVGandBeacon = "[{\"pattern\":\"(default)\",\"standards\":[\"Beacon\",\"Scalable Vector Graphics (SVG) 1.1 (Second Edition)\"]}]";
const promiseOpenImportExportTab = function (driver) {
return utils.promiseExtensionConfigPage(driver)
.then(() => driver.wait(until.elementLocated(by.css("a[href='#import-export']"))), 500)
.then(element => element.click());
};
describe("Import / Export", function () {
this.timeout = () => 5000;
describe("Exporting", function () {
it("Exporting empty blocking rule", function (done) {
let driverReference;
utils.promiseGetDriver()
.then(function (driver) {
driverReference = driver;
return promiseOpenImportExportTab(driverReference);
})
.then(() => driverReference.findElement(by.css(".export-section select option:nth-child(1)")).click())
.then(() => driverReference.findElement(by.css(".export-section textarea")).getAttribute("value"))
.then(function (exportValue) {
assert.equal(exportValue.trim(), emptyRuleSet, "Exported ruleset does not match expected value.");
done();
})
.catch(done);
});
it("Exporting SVG and Beacon blocking rules", function (done) {
let driverReference;
utils.promiseGetDriver()
.then(function (driver) {
driverReference = driver;
return utils.promiseSetBlockingRules(driverReference, utils.constants.svgBlockRule.concat(["Beacon"]));
})
.then(() => promiseOpenImportExportTab(driverReference))
.then(() => driverReference.findElement(by.css(".export-section select option:nth-child(1)")).click())
.then(() => driverReference.findElement(by.css(".export-section textarea")).getAttribute("value"))
.then(function (exportValue) {
assert.equal(exportValue.trim(), blockingSVGandBeacon, "Exported ruleset does not match expected value.");
done();
})
.catch(done);
});
});
describe("Importing", function () {
it("Importing SVG and Beacon blocking rules", function (done) {
let driverReference;
let checkedCheckboxes;
utils.promiseGetDriver()
.then(function (driver) {
driverReference = driver;
return promiseOpenImportExportTab(driverReference);
})
.then(() => driverReference.findElement(by.css(".import-section textarea")).sendKeys(blockingSVGandBeacon))
.then(() => driverReference.findElement(by.css(".import-section input[type='checkbox']")).click())
.then(() => driverReference.findElement(by.css(".import-section button")).click())
.then(() => utils.pause(500))
.then(() => driverReference.findElements(by.css("#domain-rules input[type='checkbox']:checked")))
.then(function (checkboxElms) {
checkedCheckboxes = checkboxElms;
assert.equal(checkboxElms.length, 2, "There should be two standards blocked.");
return checkedCheckboxes[0].getAttribute("value");
})
.then(function (firstCheckboxValue) {
assert.equal(firstCheckboxValue, "Beacon", "The first blocked standard should be 'Beacon'.");
return checkedCheckboxes[1].getAttribute("value");
})
.then(function (secondCheckboxValue) {
assert.equal(secondCheckboxValue, utils.constants.svgBlockRule[0], "The second blocked standard should be the SVG standard.");
done();
})
.catch(done);
});
});
});

View file

@ -75,7 +75,7 @@ module.exports.promiseSetBlockingRules = function (driver, standardsToBlock) {
return this.promiseExtensionConfigPage(driver)
.then(driver.executeAsyncScript(setStandardsScript))
.then(() => module.exports.pause(1000));
.then(() => module.exports.pause(500));
};
module.exports.promiseGetDriver = function () {