summaryrefslogtreecommitdiffstats
path: root/src/tests/tests/utils.js
diff options
context:
space:
mode:
Diffstat (limited to 'src/tests/tests/utils.js')
-rw-r--r--src/tests/tests/utils.js550
1 files changed, 550 insertions, 0 deletions
diff --git a/src/tests/tests/utils.js b/src/tests/tests/utils.js
new file mode 100644
index 0000000..c884374
--- /dev/null
+++ b/src/tests/tests/utils.js
@@ -0,0 +1,550 @@
+/* globals badger:false */
+
+(function() {
+
+QUnit.module("Utils");
+
+var utils = require('utils');
+var getSurrogateURI = require('surrogates').getSurrogateURI;
+
+QUnit.test("explodeSubdomains", function (assert) {
+ var fqdn = "test.what.yea.eff.org";
+ var subs = utils.explodeSubdomains(fqdn);
+ assert.equal(subs.length, 4);
+ assert.equal(subs[0], fqdn);
+ assert.equal(subs[3], "eff.org");
+});
+
+QUnit.test("xhrRequest", function (assert) {
+ // set up fake server to simulate XMLHttpRequests
+ let server = sinon.fakeServer.create({
+ respondImmediately: true
+ });
+ server.respondWith("GET", "https://www.eff.org/files/badgertest.txt",
+ [200, {}, "test passed\n"]);
+
+ let done = assert.async();
+ assert.expect(4);
+
+ utils.xhrRequest("https://www.eff.org/files/badgertest.txt", function (err1, resp) {
+ assert.strictEqual(err1, null, "there was no error");
+ assert.equal(resp, "test passed\n", "got expected response text");
+
+ utils.xhrRequest("https://www.eff.org/nonexistent-page", function(err2/*, resp*/) {
+ assert.ok(err2, "there was an error");
+ assert.equal(err2.status, 404, "error was 404");
+
+ server.restore();
+ done();
+ });
+ });
+});
+
+QUnit.test("isPrivacyBadgerEnabled basic tests", function (assert) {
+ assert.ok(badger.isPrivacyBadgerEnabled("example.com"),
+ "Domain starts out as enabled.");
+
+ badger.disablePrivacyBadgerForOrigin("example.com");
+ assert.notOk(badger.isPrivacyBadgerEnabled("example.com"),
+ "Disabling the domain works.");
+
+ badger.enablePrivacyBadgerForOrigin("example.com");
+ assert.ok(badger.isPrivacyBadgerEnabled("example.com"),
+ "Re-enabling the domain works.");
+});
+
+QUnit.test("isPrivacyBadgerEnabled wildcard tests", function (assert) {
+ badger.disablePrivacyBadgerForOrigin('*.mail.example.com');
+ assert.ok(
+ badger.isPrivacyBadgerEnabled('www.example.com'),
+ "Ignores cases without as many subdomains as the wildcard."
+ );
+ assert.ok(
+ badger.isPrivacyBadgerEnabled('web.stuff.example.com'),
+ "Ignores cases where subdomains do not match the wildcard."
+ );
+ assert.notOk(
+ badger.isPrivacyBadgerEnabled('web.mail.example.com'),
+ "Website matches wildcard pattern."
+ );
+ assert.notOk(
+ badger.isPrivacyBadgerEnabled('stuff.fakedomain.web.mail.example.com'),
+ "Wildcard catches all prefacing subdomains."
+ );
+ assert.ok(
+ badger.isPrivacyBadgerEnabled('mail.example.com'),
+ "Checks against URLs that lack a starting dot."
+ );
+
+ const PSL_TLD = "example.googlecode.com";
+ assert.equal(window.getBaseDomain(PSL_TLD), PSL_TLD,
+ PSL_TLD + " is a PSL TLD");
+ badger.disablePrivacyBadgerForOrigin('*.googlecode.com');
+ assert.notOk(badger.isPrivacyBadgerEnabled(PSL_TLD),
+ "PSL TLDs work with wildcards as expected.");
+});
+
+QUnit.test("disable/enable privacy badger for origin", function (assert) {
+ function parsed() {
+ return badger.storage.getStore('settings_map').getItem('disabledSites');
+ }
+
+ let origLength = parsed() && parsed().length || 0;
+
+ badger.disablePrivacyBadgerForOrigin('foo.com');
+ assert.ok(parsed().length == (origLength + 1), "one more disabled site");
+
+ badger.enablePrivacyBadgerForOrigin('foo.com');
+ assert.ok(parsed().length == origLength, "one less disabled site");
+});
+
+QUnit.test("surrogate script URL lookups", function (assert) {
+ const NOOP = function () {};
+ const surrogatedb = require('surrogatedb');
+ const SURROGATE_PREFIX = 'data:application/javascript;base64,';
+ const GA_JS_TESTS = [
+ {
+ url: 'http://www.google-analytics.com/ga.js',
+ msg: "Google Analytics ga.js http URL should match"
+ },
+ {
+ url: 'https://www.google-analytics.com/ga.js',
+ msg: "Google Analytics ga.js https URL should match"
+ },
+ {
+ url: 'https://www.google-analytics.com/ga.js?foo=bar',
+ msg: "Google Analytics ga.js querystring URL should match"
+ },
+ ];
+ const NYT_SCRIPT_PATH = '/assets/homepage/20160920-111441/js/foundation/lib/framework.js';
+ const NYT_URL = 'https://a1.nyt.com' + NYT_SCRIPT_PATH;
+
+ let ga_js_surrogate;
+
+ for (let i = 0; i < GA_JS_TESTS.length; i++) {
+ ga_js_surrogate = getSurrogateURI(
+ GA_JS_TESTS[i].url,
+ 'www.google-analytics.com'
+ );
+ assert.ok(ga_js_surrogate, GA_JS_TESTS[i].msg);
+ }
+
+ assert.ok(
+ ga_js_surrogate.startsWith(SURROGATE_PREFIX),
+ "The returned ga.js surrogate is a base64-encoded JavaScript data URI"
+ );
+
+ // test negative match
+ assert.notOk(
+ getSurrogateURI(NYT_URL, window.extractHostFromURL(NYT_URL)),
+ "New York Times script URL should not match any surrogates"
+ );
+
+ // test surrogate suffix token response contents
+ surrogatedb.hostnames[window.extractHostFromURL(NYT_URL)] = [
+ NYT_SCRIPT_PATH
+ ];
+ surrogatedb.surrogates[NYT_SCRIPT_PATH] = NOOP;
+ assert.equal(
+ getSurrogateURI(NYT_URL, window.extractHostFromURL(NYT_URL)),
+ SURROGATE_PREFIX + btoa(NOOP),
+ "New York Times script URL should now match the noop surrogate"
+ );
+
+ // set up test data for wildcard token tests
+ surrogatedb.hostnames['cdn.example.com'] = 'noop';
+ surrogatedb.surrogates.noop = NOOP;
+
+ // test wildcard tokens
+ for (let i = 0; i < 25; i++) {
+ let url = 'http://cdn.example.com/' + _.sample(
+ 'abcdefghijklmnopqrstuvwxyz0123456789'.split(''),
+ _.random(5, 15)
+ ).join('');
+
+ assert.equal(
+ getSurrogateURI(url, window.extractHostFromURL(url)),
+ SURROGATE_PREFIX + btoa(NOOP),
+ "A wildcard token should match all URLs for the hostname: " + url
+ );
+ }
+});
+
+QUnit.test("rateLimit", (assert) => {
+ const INTERVAL = 100,
+ NUM_TESTS = 5;
+
+ let clock = sinon.useFakeTimers(+new Date());
+
+ let callback = sinon.spy(function (password, i) {
+ // check args
+ assert.equal(password, "qwerty",
+ "rateLimit should preserve args");
+ assert.equal(i + 1, callback.callCount,
+ "rateLimit should preserve args and call order");
+
+ // check context
+ assert.ok(this.foo == "bar", "rateLimit should preserve context");
+ });
+
+ let fn = utils.rateLimit(callback, INTERVAL, {foo:"bar"});
+
+ for (let i = 0; i < NUM_TESTS; i++) {
+ fn("qwerty", i);
+ }
+
+ for (let i = 0; i < NUM_TESTS; i++) {
+ // check rate limiting
+ assert.equal(callback.callCount, i + 1,
+ "rateLimit should allow only one call per interval");
+
+ // advance the clock
+ clock.tick(INTERVAL);
+ }
+
+ clock.restore();
+});
+
+// the following cookie parsing tests are derived from
+// https://github.com/jshttp/cookie/blob/81bd3c77db6a8dcb23567de94b3beaef6c03e97a/test/parse.js
+QUnit.test("cookie parsing", function (assert) {
+
+ assert.deepEqual(utils.parseCookie('foo=bar'), { foo: 'bar' },
+ "simple cookie");
+
+ assert.deepEqual(
+ utils.parseCookie('foo=bar;bar=123'),
+ {
+ foo: 'bar',
+ bar: '123'
+ },
+ "simple cookie with two values"
+ );
+
+ assert.deepEqual(
+ utils.parseCookie('FOO = bar; baz = raz'),
+ {
+ FOO: 'bar',
+ baz: 'raz'
+ },
+ "ignore spaces"
+ );
+
+ assert.deepEqual(
+ utils.parseCookie('foo="bar=123456789&name=Magic+Mouse"'),
+ { foo: 'bar=123456789&name=Magic+Mouse' },
+ "escaped value"
+ );
+
+ assert.deepEqual(
+ utils.parseCookie('email=%20%22%2c%3b%2f'),
+ { email: ' ",;/' },
+ "encoded value"
+ );
+
+ assert.deepEqual(
+ utils.parseCookie('foo=%1;bar=bar'),
+ {
+ foo: '%1',
+ bar: 'bar'
+ },
+ "ignore escaping error and return original value"
+ );
+
+ assert.deepEqual(
+ utils.parseCookie('foo=%1;bar=bar;HttpOnly;Secure', { skipNonValues: true }),
+ {
+ foo: '%1',
+ bar: 'bar'
+ },
+ "ignore non values"
+ );
+
+ assert.deepEqual(
+ utils.parseCookie('priority=true; expires=Wed, 29 Jan 2014 17:43:25 GMT; Path=/'),
+ {
+ priority: 'true',
+ expires: 'Wed, 29 Jan 2014 17:43:25 GMT',
+ Path: '/'
+ },
+ "dates"
+ );
+
+ assert.deepEqual(
+ utils.parseCookie('foo=%1;bar=bar;foo=boo', { noOverwrite: true}),
+ {
+ foo: '%1',
+ bar: 'bar'
+ },
+ "duplicate names #1"
+ );
+
+ assert.deepEqual(
+ utils.parseCookie('foo=false;bar=bar;foo=true', { noOverwrite: true}),
+ {
+ foo: 'false',
+ bar: 'bar'
+ },
+ "duplicate names #2"
+ );
+
+ assert.deepEqual(
+ utils.parseCookie('foo=;bar=bar;foo=boo', { noOverwrite: true}),
+ {
+ foo: '',
+ bar: 'bar'
+ },
+ "duplicate names #3"
+ );
+
+ // SameSite attribute
+ let SAMESITE_COOKIE = 'abc=123; path=/; domain=.githack.com; HttpOnly; SameSite=Lax';
+ assert.deepEqual(
+ utils.parseCookie(SAMESITE_COOKIE),
+ {
+ abc: '123',
+ SameSite: 'Lax',
+ path: '/',
+ domain: '.githack.com',
+ HttpOnly: '',
+ },
+ "SameSite is parsed"
+ );
+ assert.deepEqual(
+ utils.parseCookie(SAMESITE_COOKIE, { skipAttributes: true }),
+ { abc: '123' },
+ "SameSite is ignored when ignoring attributes"
+ );
+
+});
+
+QUnit.test("cookie parsing (legacy Firefox add-on)", function (assert) {
+ // raw cookies (input)
+ let optimizelyCookie = 'optimizelyEndUserId=oeu1394241144653r0.538161732205'+
+ '5392; optimizelySegments=%7B%22237061344%22%3A%22none%22%2C%22237321400%'+
+ '22%3A%22ff%22%2C%22237335298%22%3A%22search%22%2C%22237485170%22%3A%22fa'+
+ 'lse%22%7D; optimizelyBuckets=%7B%7D';
+ let googleCookie = 'PREF=ID=d93d4e842d10e12a:U=3838eaea5cd40d37:FF=0:TM=139'+
+ '4232126:LM=1394235924:S=rKP367ac3aAdDzAS; NID=67=VwhHOGQunRmNsm9WwJyK571'+
+ 'OGqb3RtvUmH987K5DXFgKFAxFwafA_5VPF5_bsjhrCoM0BjyQdxyL2b-qs9b-fmYCQ_1Uqjt'+
+ 'qTeidAJBnc2ecjewJia6saHrcJ6yOVVgv';
+ let hackpadCookie = 'acctIds=%5B%22mIqZhIPMu7j%22%2C%221394477194%22%2C%22u'+
+ 'T/ayZECO0g/+hHtQnjrdEZivWA%3D%22%5D; expires=Wed, 01-Jan-3000 08:00:01 G'+
+ 'MT; domain=.hackpad.com; path=/; secure; httponly\nacctIds=%5B%22mIqZhIP'+
+ 'Mu7j%22%2C%221394477194%22%2C%22uT/ayZECO0g/+hHtQnjrdEZivWA%3D%22%5D; ex'+
+ 'pires=Wed, 01-Jan-3000 08:00:00 GMT; domain=.hackpad.com; path=/; secure'+
+ '; httponly\n1ASIE=T; expires=Wed, 01-Jan-3000 08:00:00 GMT; domain=hackp'+
+ 'ad.com; path=/\nPUAS3=3186efa7f8bca99c; expires=Wed, 01-Jan-3000 08:00:0'+
+ '0 GMT; path=/; secure; httponly';
+ let emptyCookie = '';
+ let testCookie = ' notacookiestring; abc=123 ';
+
+ // parsed cookies (expected output)
+ let COOKIES = {};
+ COOKIES[optimizelyCookie] = {
+ optimizelyEndUserId: 'oeu1394241144653r0.5381617322055392',
+ optimizelySegments: '%7B%22237061344%22%3A%22none%22%2C%22237321400%2' +
+ '2%3A%22ff%22%2C%22237335298%22%3A%22search%22%2C%22237485170%22%3A%2' +
+ '2false%22%7D',
+ optimizelyBuckets: '%7B%7D'
+ };
+ COOKIES[emptyCookie] = {};
+ COOKIES[testCookie] = {abc: '123'};
+ COOKIES[googleCookie] = {
+ PREF: 'ID=d93d4e842d10e12a:U=3838eaea5cd40d37:FF=0:TM=1394232126:LM=1'+
+ '394235924:S=rKP367ac3aAdDzAS',
+ NID: '67=VwhHOGQunRmNsm9WwJyK571OGqb3RtvUmH987K5DXFgKFAxFwafA_5VPF5_b'+
+ 'sjhrCoM0BjyQdxyL2b-qs9b-fmYCQ_1UqjtqTeidAJBnc2ecjewJia6saHrcJ6yOVVgv'
+ };
+ COOKIES[hackpadCookie] = {
+ acctIds: '%5B%22mIqZhIPMu7j%22%2C%221394477194%22%2C%22uT/ayZECO0g/+h'+
+ 'HtQnjrdEZivWA%3D%22%5D',
+ PUAS3: '3186efa7f8bca99c',
+ '1ASIE': 'T'
+ };
+
+ // compare actual to expected
+ let test_number = 0;
+ for (let cookieString in COOKIES) {
+ if (COOKIES.hasOwnProperty(cookieString)) {
+ test_number++;
+
+ let expected = COOKIES[cookieString];
+
+ let actual = utils.parseCookie(
+ cookieString, {
+ noDecode: true,
+ skipAttributes: true,
+ skipNonValues: true
+ }
+ );
+
+ assert.deepEqual(actual, expected, "cookie test #" + test_number);
+ }
+ }
+});
+
+// the following cookie parsing tests are derived from
+// https://github.com/yui/yui3/blob/25264e3629b1c07fb779d203c4a25c0879ec862c/src/cookie/tests/cookie-tests.js
+QUnit.test("cookie parsing (YUI3)", function (assert) {
+
+ let cookieString = "a=b";
+ let cookies = utils.parseCookie(cookieString);
+ assert.ok(cookies.hasOwnProperty("a"), "Cookie 'a' is present.");
+ assert.equal(cookies.a, "b", "Cookie 'a' should have value 'b'.");
+
+ cookieString = "12345=b";
+ cookies = utils.parseCookie(cookieString);
+ assert.ok(cookies.hasOwnProperty("12345"), "Cookie '12345' is present.");
+ assert.equal(cookies["12345"], "b", "Cookie '12345' should have value 'b'.");
+
+ cookieString = "a=b; c=d; e=f; g=h";
+ cookies = utils.parseCookie(cookieString);
+ assert.ok(cookies.hasOwnProperty("a"), "Cookie 'a' is present.");
+ assert.ok(cookies.hasOwnProperty("c"), "Cookie 'c' is present.");
+ assert.ok(cookies.hasOwnProperty("e"), "Cookie 'e' is present.");
+ assert.ok(cookies.hasOwnProperty("g"), "Cookie 'g' is present.");
+ assert.equal(cookies.a, "b", "Cookie 'a' should have value 'b'.");
+ assert.equal(cookies.c, "d", "Cookie 'c' should have value 'd'.");
+ assert.equal(cookies.e, "f", "Cookie 'e' should have value 'f'.");
+ assert.equal(cookies.g, "h", "Cookie 'g' should have value 'h'.");
+
+ cookieString = "name=Nicholas%20Zakas; title=front%20end%20engineer";
+ cookies = utils.parseCookie(cookieString);
+ assert.ok(cookies.hasOwnProperty("name"), "Cookie 'name' is present.");
+ assert.ok(cookies.hasOwnProperty("title"), "Cookie 'title' is present.");
+ assert.equal(cookies.name, "Nicholas Zakas", "Cookie 'name' should have value 'Nicholas Zakas'.");
+ assert.equal(cookies.title, "front end engineer", "Cookie 'title' should have value 'front end engineer'.");
+
+ cookieString = "B=2nk0a3t3lj7cr&b=3&s=13; LYC=l_v=2&l_lv=10&l_l=94ddoa70d&l_s=qz54t4qwrsqquyv51w0z4xxwtx31x1t0&l_lid=146p1u6&l_r=4q&l_lc=0_0_0_0_0&l_mpr=50_0_0&l_um=0_0_1_0_0;YMRAD=1215072198*0_0_7318647_1_0_40123839_1; l%5FPD3=840";
+ cookies = utils.parseCookie(cookieString);
+ assert.ok(cookies.hasOwnProperty("B"), "Cookie 'B' is present.");
+ assert.ok(cookies.hasOwnProperty("LYC"), "Cookie 'LYC' is present.");
+ assert.ok(cookies.hasOwnProperty("l_PD3"), "Cookie 'l_PD3' is present.");
+
+ let cookieName = "something[1]";
+ let cookieValue = "123";
+ cookieString = encodeURIComponent(cookieName) + "=" + encodeURIComponent(cookieValue);
+ cookies = utils.parseCookie(cookieString);
+ assert.ok(cookies.hasOwnProperty(cookieName), "Cookie '" + cookieName + "' is present.");
+ assert.equal(cookies[cookieName], cookieValue, "Cookie value for '" + cookieName + "' is " + cookieValue + ".");
+
+ cookieString = "SESSION=27bedbdf3d35252d0db07f34d81dcca6; STATS=OK; SCREEN=1280x1024; undefined; ys-bottom-preview=o%3Aheight%3Dn%253A389";
+ cookies = utils.parseCookie(cookieString);
+ assert.ok(cookies.hasOwnProperty("SCREEN"), "Cookie 'SCREEN' is present.");
+ assert.ok(cookies.hasOwnProperty("STATS"), "Cookie 'STATS' is present.");
+ assert.ok(cookies.hasOwnProperty("SESSION"), "Cookie 'SESSION' is present.");
+ assert.ok(cookies.hasOwnProperty("ys-bottom-preview"), "Cookie 'ys-bottom-preview' is present.");
+ assert.ok(cookies.hasOwnProperty("undefined"), "Cookie 'undefined' is present.");
+
+ // Tests that cookie parsing deals with cookies that contain an invalid
+ // encoding. It shouldn't error, but should treat the cookie as if it
+ // doesn't exist (return null).
+ cookieString = "DetailInfoList=CPN03022194=@|@=CPN03#|#%B4%EB%C3%B5%C7%D8%BC%F6%BF%E5%C0%E5#|#1016026000#|#%BD%C5%C8%E6%B5%BF#|##|#";
+ cookies = utils.parseCookie(cookieString, { skipInvalid: true });
+ assert.equal(cookies.DetailInfoList, null, "Cookie 'DetailInfoList' should not have a value.");
+
+ // Tests that a Boolean cookie, one without an equals sign of value,
+ // is represented as an empty string.
+ cookieString = "info";
+ cookies = utils.parseCookie(cookieString);
+ assert.equal(cookies.info, "", "Cookie 'info' should be an empty string.");
+
+ cookieString = "name=Nicholas%20Zakas; hash=a=b&c=d&e=f&g=h; title=front%20end%20engineer";
+ cookies = utils.parseCookie(cookieString);
+ assert.ok(cookies.hasOwnProperty("name"), "Cookie 'name' is present.");
+ assert.ok(cookies.hasOwnProperty("hash"), "Cookie 'hash' is present.");
+ assert.ok(cookies.hasOwnProperty("title"), "Cookie 'title' is present.");
+ assert.equal(cookies.name, "Nicholas Zakas", "Cookie 'name' should have value 'Nicholas Zakas'.");
+ assert.equal(cookies.hash, "a=b&c=d&e=f&g=h", "Cookie 'hash' should have value 'a=b&c=d&e=f&g=h'.");
+ assert.equal(cookies.title, "front end engineer", "Cookie 'title' should have value 'front end engineer'.");
+
+});
+
+QUnit.test("getHostFromDomainInput", assert => {
+ assert.equal(
+ utils.getHostFromDomainInput("www.spiegel.de"),
+ "www.spiegel.de",
+ "Valid domains are accepted"
+ );
+
+ assert.equal(
+ utils.getHostFromDomainInput("http://www.spiegel.de/"),
+ "www.spiegel.de",
+ "URLs get transformed into domains"
+ );
+
+ assert.equal(
+ utils.getHostFromDomainInput("http://www.spiegel.de"),
+ "www.spiegel.de",
+ "Trailing slashes are not required"
+ );
+
+ assert.equal(
+ utils.getHostFromDomainInput("@"),
+ false,
+ "Valid URIs with empty hosts are rejected."
+ );
+});
+
+// used in pixel tracking heuristic, given a string the estimateMaxEntropy function
+// will return the estimated entropy value from it, based on logic parsing the string's length,
+// and classes of character complication included in the string
+QUnit.test("estimateMaxEntropy", assert => {
+ assert.equal(
+ utils.estimateMaxEntropy("google.com/analytics.google/analytics.google/google.com/analytics.google/analytics.google/google.com/analytics.google/analytics.google/google.com/analytics.google/analytics.google/google.com/analytics.google/analytics.google/google.com/analytics.google/anal"),
+ 257,
+ "returns length of string if it's above 256 (MAX_LS_LEN_FOR_ENTROPY_EST)"
+ );
+
+ assert.equal(
+ utils.estimateMaxEntropy("googlecomanalytics"),
+ utils.estimateMaxEntropy("GOOGLECOMANALYTICS"),
+ "if the same string is all lower case or all upper case, the returned estimated entropy value is the same"
+ );
+
+ assert.notEqual(
+ utils.estimateMaxEntropy('analytics.GOOGLE1234_'),
+ utils.estimateMaxEntropy('ANALYTICS.google1234'),
+ "two nearly identical strings of mixed character classes and different cases will return different values"
+ );
+
+ assert.notEqual(
+ utils.estimateMaxEntropy('google.com/analytics'),
+ utils.estimateMaxEntropy('0191/_-goo~le9x+xzxo'),
+ "strings of the same length but from different character classes will estimate different entropy values"
+ );
+
+ assert.equal(
+ utils.estimateMaxEntropy("google.com/0191/_-google/analytics.fizz?buzz=foobar"),
+ 320.55551316197466,
+ "entropy for complex string of varying character classes is correctly estimated"
+ );
+
+ assert.equal(
+ utils.estimateMaxEntropy("03899029.01_293"),
+ 49.82892142331044,
+ "entropy for string from the common classes of characters is correctly estimated"
+ );
+
+ assert.equal(
+ utils.estimateMaxEntropy("fizzBUZZ012345"),
+ 84,
+ "entropy for string from the case-insensitive class of characters is correctly estimated"
+ );
+
+ assert.equal(
+ utils.estimateMaxEntropy("fizz/buzz+fizzy~buzzy%"),
+ 142.82076811925285,
+ "entropy for string from the case-sensitive class of characters is correctly estimated"
+ );
+
+ assert.equal(
+ utils.estimateMaxEntropy("1280x720") < 32,
+ true,
+ "resolution strings with 'x' char from SEPS class are correctly estimated as low entropy"
+ );
+
+});
+
+})();