Files
notifications-admin/tests/javascripts/support/helpers/globals.js
2019-10-03 07:56:57 +01:00

90 lines
1.9 KiB
JavaScript

// helpers for mocking objects attached to the global space as properties, ie. window.location
class LocationMock {
constructor (URL) {
this._location = window.location;
// setting href sets all sub-properties
this.href = URL;
// JSDOM sets window.location as non-configurable
// the only way to mock it, currently, is to replace it completely
delete window.location;
window.location = this;
}
get href () {
return `${this.protocol}://${this.host}${this.pathname}${this.search}${this.hash}`
}
set href (value) {
const partNames = ['protocol', 'hostname', 'port', 'pathname', 'search', 'hash'];
const protocol = '(https:|http:)';
const hostname = '[^\\/]+';
const port = '(:\\d)';
const pathname = '([^?]+)';
const search = '([^#])';
const hash = '(#[\\x00-\\x7F])'; // match any ASCII character
const re = new RegExp(`^${protocol}{0,1}(?:\\/\\/){0,1}(${hostname}${port}{0,1}){0,1}${pathname}{0,1}${search}{0,1}${hash}{0,1}$`);
const match = value.match(re)
if (match === null) { throw Error(`${value} is not a valid URL`); }
match.forEach((part, idx) => {
let partName;
// 0 index is whole match, we want the groups
if (idx > 0) {
partName = partNames[idx - 1];
if (part !== undefined) {
this[partName] = part;
} else if (!(partName in this)) { // only get value from window.location if property not set
this[partName] = this._location[partName];
}
}
});
}
get host () {
return `${this.hostname}:${this.port}`;
}
set host (value) {
const parts = value.split(':');
this.hostname = parts[0];
this.protocol = parts[1];
}
// origin is read-only
get origin () {
return `${this.protol}://${this.hostname}`;
}
reset () {
window.location = this._location;
}
}
exports.LocationMock = LocationMock;