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 { section p:first-child {
padding-top: 1em; padding-top: 1em;
}
section.container {
margin-top: 2em;
}
section {
margin-bottom: 5em;
} }

View file

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

18
package-lock.json generated
View file

@ -1637,6 +1637,24 @@
"capture-stack-trace": "1.0.0" "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": { "cross-spawn": {
"version": "5.1.0", "version": "5.1.0",
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", "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", "firefox": "web-ext -s add-on run",
"lint": "node_modules/eslint/bin/eslint.js .", "lint": "node_modules/eslint/bin/eslint.js .",
"lint:fix": "node_modules/eslint/bin/eslint.js --fix .", "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": "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": "npm test --watch" "test:watch": "cross-env npm test --watch"
}, },
"pre-push": { "pre-push": {
"run": [ "run": [
@ -37,6 +37,7 @@
}, },
"devDependencies": { "devDependencies": {
"assert": "^1.4.1", "assert": "^1.4.1",
"cross-env": "^5.1.1",
"eslint": "^4.9.0", "eslint": "^4.9.0",
"geckodriver": "^1.9.0", "geckodriver": "^1.9.0",
"gulp": "^3.9.1", "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) return this.promiseExtensionConfigPage(driver)
.then(driver.executeAsyncScript(setStandardsScript)) .then(driver.executeAsyncScript(setStandardsScript))
.then(() => module.exports.pause(1000)); .then(() => module.exports.pause(500));
}; };
module.exports.promiseGetDriver = function () { module.exports.promiseGetDriver = function () {