From 1769a31e34537ec6913e5c5cbb145c641c3f6347 Mon Sep 17 00:00:00 2001 From: Gokulakrishna Date: Thu, 9 Aug 2018 00:48:01 +0530 Subject: [PATCH 1/3] Added unit tests --- karma.conf.js | 56 +++++ package.json | 30 +++ test/unittests/core/a.js | 1 + test/unittests/core/interceptor.test.js | 147 +++++++++++ test/unittests/core/main.test.js | 219 +++++++++++++++++ test/unittests/core/messenger.test.js | 103 ++++++++ test/unittests/core/request-sanitizer.test.js | 85 +++++++ test/unittests/internal/helpers.test.js | 228 ++++++++++++++++++ test/unittests/internal/wrappers.test.js | 45 ++++ test/unittests/main.test.js | 219 +++++++++++++++++ 10 files changed, 1133 insertions(+) create mode 100644 karma.conf.js create mode 100644 package.json create mode 100644 test/unittests/core/a.js create mode 100644 test/unittests/core/interceptor.test.js create mode 100644 test/unittests/core/main.test.js create mode 100644 test/unittests/core/messenger.test.js create mode 100644 test/unittests/core/request-sanitizer.test.js create mode 100644 test/unittests/internal/helpers.test.js create mode 100644 test/unittests/internal/wrappers.test.js create mode 100644 test/unittests/main.test.js diff --git a/karma.conf.js b/karma.conf.js new file mode 100644 index 0000000..6c4c4ca --- /dev/null +++ b/karma.conf.js @@ -0,0 +1,56 @@ +module.exports = function(config) { + config.set({ + frameworks: ["mocha", "chai", "sinon-chai", "sinon-chrome"], + + files: [ + "modules/internal/*.js", + "core/constants.js", + "core/files.js", + "core/resources.js", + "core/mappings.js", + "core/shorthands.js", + "core/main.js", + "core/messenger.js", + "core/request-sanitizer.js", + "core/state-manager.js", + "core/interceptor.js", + "core/request-analyzer.js", + + "test/unittests/**/*.test.js" + ], + reporters: ["progress", "html", "coverage", "spec"], + preprocessors: { + "modules/internal/*.js": ["coverage"], + "core/**/*.js": ["coverage"] + }, + + coverageReporter: { reporters: [{ type: "lcov" }] }, + port: 9876, + colors: true, + logLevel: config.LOG_INFO, + browsers: ["ChromeHeadless", "Chrome"], + autoWatch: false, + concurrency: Infinity, + specReporter: { + maxLogLines: 3, + suppressErrorSummary: true, + suppressFailed: false, + suppressPassed: false, + suppressSkipped: true, + showSpecTiming: true, + failFast: false + }, + + htmlReporter: { + outputDir: "karma_coverage", + templatePath: null, + focusOnFailures: true, + namedFiles: false, + pageTitle: null, + urlFriendlyName: false, + reportName: "report-summary", + preserveDescribeNesting: false, + foldAll: false + } + }); +}; diff --git a/package.json b/package.json new file mode 100644 index 0000000..91f0255 --- /dev/null +++ b/package.json @@ -0,0 +1,30 @@ +{ + "name": "Decentraleyes", + "version": "1.0.0", + "description": "A web browser extension that emulates Content Delivery Networks to improve your online privacy. It intercepts traffic, finds supported resources locally, and injects them into the environment.", + "author": "Thomas Rientjes", + "license": "MPL-2.0", + "devDependencies": { + "chai": "^4.1.2", + "codecov": "3.0.4", + "karma": "^2.0.5", + "karma-chai": "^0.1.0", + "karma-chrome-launcher": "^2.2.0", + "karma-coverage": "^1.1.2", + "karma-html-reporter": "^0.2.7", + "karma-mocha": "^1.3.0", + "karma-sinon-chai": "2.0.2", + "karma-sinon-chrome": "^0.2.0", + "karma-sinon-stub-promise": "^1.0.0", + "karma-spec-reporter": "0.0.32", + "mocha": "^5.2.0", + "sinon": "^6.1.4", + "sinon-chai": "^3.2.0", + "web-ext": "^2.8.0" + }, + "scripts": { + "testUnits": "karma start --single-run --browsers ChromeHeadless karma.conf.js", + "testUnitsWatcher": "karma start --auto-watch --browsers ChromeHeadless karma.conf.js", + "testUnitsChromeWatcher": "karma start --auto-watch --browsers Chrome karma.conf.js" + } +} diff --git a/test/unittests/core/a.js b/test/unittests/core/a.js new file mode 100644 index 0000000..9055674 --- /dev/null +++ b/test/unittests/core/a.js @@ -0,0 +1 @@ +var a = [{name: 'Host', value: 'web.archive.org'}, Object{name: 'User-Agent', value: 'Save Page Request from WaybackEverywhere Browser Extension'}, Object{name: 'Accept', value: '*/*'}, Object{name: 'Accept-Language', value: 'en-GB,en;q=0.5'}, Object{name: 'Accept-Encoding', value: 'gzip, deflate, br'}, Object{name: 'Referer', value: 'https://web.archive.org/save/http://www.gnu.org/'}, Object{name: 'Cookie', value: 'tk_or=%22%22; tk_lr=%22%22; _hp2_22%7D; _biz_dfsA=%5B%5D; _biz_uid=107f5b0ccc034617dfcf1096c1bb5372; _biz_nA=1; _biz_pendingA=%5B%22m%2Fipv%3F_biz_r%3Dhttps%253A%252F%252Fscotthelme.co.uk%252Fsecuring-dns-across-all-of-my-devices-with-pihole-dns-over-https-1-1-1-1%252F%26_biz_h%3D-884118237%26_biz_u%3D107f5b0ccc034617dfcf1096c1bb5372%26_biz_s%3D6bff7e%26_biz_l%3Dhttps%253A%252F%252Fweb.archive.org%252Fweb%252F20180611051411%252Fhttps%253A%252F%252Fblog.cloudflare.com%252Fcloudflare-argo-tunnel-with-rust-and-raspberry-pi%252F%26_biz_t%3D1532832071950%26_biz_i%3DCloudflare%2520Argo%2520Tunnel%2520with%2520Rust%252BRaspberry%2520Pi%26_biz_n%3D0%26rnd%3D803756%22%5D; AMCV_F7093025512D2B690A490D44%40AdobeOrg=1099438348%7CMCIDTS%7C17742%7CMCMID%7C79090085757024397768106107133894830525%7CMCAID%7CNONE%7CMCOPTOUT-1532840491s%7CNONE%7CvVersion%7C2.1.0; optimizelyEndUserId=oeu1532834989890r0.8011439154373176; _ga=GA1.2.1684042591.1533584166; _gid=GA1.2.1675613711.1533584166; intercom-id-pz16iron=dfebc4ad-d99d-498b-87f6-cde29abed55a; MOE_DATA=%7B%22WEB_SETTINGS%22%3A%7B%22isDomainLevelStorage%22%3Atrue%2C%22isConfigured%22%3Atrue%2C%22isPushSubBilling%22%3Atrue%2C%22platformSettings%22%3A%7B%22safari%22%3A%7B%22enabled%22%3Afalse%2C%22websitePushId%22%3Anull%7D%2C%22chrome%22%3A%7B%22enabled%22%3Atrue%2C%22domainType%22%3A%22https%22%2C%22isServiceWorkerRoot%22%3Atrue%2C%22serviceWorkerFilename%22%3A%22serviceworker.js%22%2C%22apiKey%22%3A%22AIzaSyBm2HfZqg2Gp2aVeaA901S1gJBwD-cIikI%22%2C%22subscriptionMode%22%3A%22normal%22%2C%22vapidPublicKey%22%3Anull%2C%22subdomainURL%22%3Anull%2C%22projectNumber%22%3A%22540868316921%22%7D%2C%22firefox%22%3A%7B%22enabled%22%3Atrue%2C%22domainType%22%3A%22NA%22%2C%22isServiceWorkerRoot%22%3Atrue%2C%22serviceWorkerFilename%22%3A%22serviceworker.js%22%2C%22apiKey%22%3A%22AIzaSyBm2HfZqg2Gp2aVeaA901S1gJBwD-cIikI%22%2C%22subscriptionMode%22%3A%22normal%22%2C%22vapidPublicKey%22%3Anull%2C%22projectNumber%22%3A%22540868316921%22%7D%7D%2C%22optInConfig%22%3A%7B%22type%22%3A%22SELF_HANDLED%22%2C%22reappearTime%22%3A24%2C%22softAskConfig%22%3A%7B%22desktop%22%3A%7B%22customHTML%22%3A%22%22%7D%2C%22mobile%22%3A%7B%22customHTML%22%3A%22%22%7D%7D%2C%22showOverlay%22%3Afalse%2C%22loadTime%22%3A0%7D%2C%22oldWebData%22%3A%7B%22webData%22%3A%7B%22promptAgain%22%3A24%2C%22saveSettingsInLive%22%3Afalse%2C%22domain_level_storage%22%3A%22true%22%2C%22savedSettingsFlag%22%3Atrue%2C%22optInConfigData%22%3A%7B%22load_time%22%3A1%2C%22bannerHtml%22%3A%7B%22mweb%22%3A%22%22%2C%22web%22%3A%22%22%7D%2C%22type%22%3A%22self_handled%22%2C%22saveSettingsInLive%22%3Afalse%2C%22promptAgain%22%3A24%7D%2C%22call_push_moengage%22%3Afalse%2C%22PushSubBilling%22%3A%22false%22%2C%22domain_type%22%3A%22https%22%2C%22manifestUrl%22%3A%22https%3A//webpush-manifest-files.s3.us-east-1.amazonaws.com/TheHinduHTTPS/manifest.json%3FSignature%3DEj4Hol%252B4jz%252Br3CRuRyR%252FBlu%252FTdM%253D%26Expires%3D1561715765%26AWSAccessKeyId%3DAKIAJIOYGTA3FJFQTCRQ%22%2C%22webPushPlatformData%22%3A%7B%22chrome%22%3A%7B%22savedSettingsFlagSubdomain%22%3Atrue%2C%22subdomain%22%3A%22%22%2C%22savedSettingsFlag%22%3Afalse%2C%22gcm%22%3A%22sharedProject%22%2C%22domain_type%22%3A%22https%22%2C%22subdomainUrl%22%3A%22%22%2C%22project_number%22%3A%22540868316921%22%2C%22api_key%22%3A%22AIzaSyBm2HfZqg2Gp2aVeaA901S1gJBwD-cIikI%22%2C%22default_icon%22%3A%22https%3A//image.moengage.com/thehinduhttpsmoengage/20180628095559856349OAIZF3thlogorjpgcompTheHinduHTTPS.jpg%22%7D%2C%22platform%22%3A%7B%22browser%22%3A%7B%22windows%22%3A%22chrome%22%2C%22linux%22%3A%22chrome%22%7D%7D%2C%22saveSettingsInLive%22%3Atrue%7D%2C%22banner%22%3A%7B%22banner_flag%22%3Afalse%7D%2C%22project_number%22%3A%22540868316921%22%2C%22bannerHtml%22%3A%7B%22web%22%3A%22%22%2C%22mweb%22%3A%22%22%7D%2C%22type%22%3A%22self_handled%22%2C%22default_icon%22%3A%22https%3A//image.moengage.com/thehinduhttpsmoengage/20180628095559856349OAIZF3thlogorjpgcompTheHinduHTTPS.jpg%22%7D%7D%2C%22featureAvailabilityMatrix%22%3Anull%7D%2C%22SETUP_TIME%22%3A1533658258008%2C%22INIT_DATA%22%3A%7B%22debugLevel%22%3A0%2C%22cluster%22%3Anull%2C%22environment%22%3Anull%2C%22baseDomainName%22%3A%22https%3A//web.archive.org/web/20180807160901/https%3A//websdk.moengage.com/%22%2C%22customSoftAsk%22%3A%7B%22mainClass%22%3A%22moe-main-class%22%2C%22allowClass%22%3A%22moe-allow-class%22%2C%22dismissClass%22%3A%22moe-block-class%22%7D%2C%22appId%22%3A%22BIELH8M8CONB0AXBRWP0FYQP%22%2C%22integrationType%22%3A%22NEW_SDK%22%2C%22forceSwUpdate%22%3Afalse%2C%22swPath%22%3Anull%7D%2C%22OPT_IN_SHOWN_TIME%22%3A1533658258136%2C%22SOFT_ASK_STATUS%22%3A%22shown%22%7D; init=true; switch-synchronised=1; wayback.initiatingpage=https%3A%2F%2Fweb.archive.org%2Fweb%2F20180807183018%2Fhttp%3A%2F%2Fwww.gnu.org%2F; wayback.archivalhost=https%3A%2F%2Fwww.gnu.org; wayback.collectionid=web; wayback.timestamp=20180807183018; JSESSIONID=6F3CCC7910C6879E9686FB24F5548ECC'}, Object{name: 'Connection', value: 'keep-alive'}, Object{name: 'Origin', value: 'some origin'}] \ No newline at end of file diff --git a/test/unittests/core/interceptor.test.js b/test/unittests/core/interceptor.test.js new file mode 100644 index 0000000..977b036 --- /dev/null +++ b/test/unittests/core/interceptor.test.js @@ -0,0 +1,147 @@ +/* + * Belongs to Decentraleyes. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +describe("Interceptor", function() { + var requestDetails, tabid, tab; + beforeEach(function() { + chrome.flush(); + requestDetails = { type: "", url: "", requestId: "" }; + tabid = 1; + tab = {}; + }); + + it("should return redirectURL for library when handleRequest is called", function() { + // tab.url = "https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"; + tab.url = + "https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.8/angular.js"; + var stub = sinon + .stub(requestAnalyzer, "isValidCandidate") + .returns(true); + var stub1 = sinon.stub(requestAnalyzer, "getLocalTarget").returns({ + source: "cdnjs.cloudflare.com", + version: "1.7", + path: "resources/angularjs/1.4.8/angular.min.js.dec" + }); + fileGuard = { secret: "somesecret" }; + chrome.extension.getURL + .withArgs( + "resources/angularjs/1.4.8/angular.min.js.dec" + "somesecret" + ) + .returns( + "chrome:extension://asdsdasd/resources/angularjs/1.4.8/angular.min.js.dec" + + "somesecret" + ); + var res = interceptor.handleRequest(requestDetails, tabid, tab); + stub.restore(); + stub1.restore(); + expect(res).to.be.eql({ + redirectUrl: + "chrome:extension://asdsdasd/resources/angularjs/1.4.8/angular.min.js.decsomesecret" + }); + }); + + it("should cancel unknown cdn request if setting to block unknown is enabled", function() { + // tab.url = "https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"; + tab.url = + "https://cdnjs.somebadCDN.com/ajax/libs/angular.js/1.4.8/angular.js"; + var stub = sinon + .stub(requestAnalyzer, "isValidCandidate") + .returns(true); + var stub1 = sinon + .stub(requestAnalyzer, "getLocalTarget") + .returns(false); + fileGuard = { secret: "somesecret" }; + interceptor.blockMissing = true; + + var res = interceptor.handleRequest(requestDetails, tabid, tab); + stub.restore(); + stub1.restore(); + expect(res).to.be.eql({ cancel: true }); + }); + + it("should not cancel and let through whitelisted domains or NON-GET requests by returning cancel:false", function() { + // tab.url = "https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"; + tab.url = + "https://cdnjs.somebadCDN.com/ajax/libs/angular.js/1.4.8/angular.js"; + var stub = sinon + .stub(requestAnalyzer, "isValidCandidate") + .returns(false); + // this Stub emulated isValidCandidate to return true or false. False will be sent for whitelisted and non-get calls + + fileGuard = { secret: "somesecret" }; + interceptor.blockMissing = false; + + var res = interceptor.handleRequest(requestDetails, tabid, tab); + stub.restore(); + expect(res).to.be.eql({ cancel: false }); + }); + + it("should handle tainted domains", function() { + // tab.url = "https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"; + tab.url = "http://udacity.com/ajax/libs/angular.js/1.4.8/angular.js"; + requestDetails.url = + "http://udacity.com/ajax/libs/angular.js/1.4.8/angular"; + var stub = sinon + .stub(requestAnalyzer, "isValidCandidate") + .returns(true); + // this Stub emulates isValidCandidate to return true or false. False will be sent for whitelisted and non-get calls + + fileGuard = { secret: "somesecret" }; + interceptor.blockMissing = false; + + var res = interceptor.handleRequest(requestDetails, tabid, tab); + stub.restore(); + // code turns http to https.. Need to check with Thomas on why this is done. + expect(res.redirectUrl).to.be.equal( + "https://udacity.com/ajax/libs/angular.js/1.4.8/angular" + ); + interceptor.blockMissing = false; + + tab.url = "https://udacity.com/ajax/libs/angular.js/1.4.8/angular.js"; + requestDetails.url = + "https://udacity.com/ajax/libs/angular.js/1.4.8/angular"; + stub = sinon.stub(requestAnalyzer, "isValidCandidate").returns(true); + // this Stub emulated isValidCandidate to return true or false. False will be sent for whitelisted and non-get calls + + fileGuard = { secret: "somesecret" }; + + var res = interceptor.handleRequest(requestDetails, tabid, tab); + stub.restore(); + // code turns https to http and lets proceed. Need to check with Thomas on why this is done. + expect(res).to.be.eql({ cancel: false }); + }); + + it("should handle XHR request type and null domain", function() { + tab.url = + "https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.8/angular.js"; + requestDetails.url = + "https://udacity.com/ajax/libs/angular.js/1.4.8/angular"; + + var stub = sinon + .stub(requestAnalyzer, "isValidCandidate") + .returns(true); + var stub1 = sinon.stub(requestAnalyzer, "getLocalTarget").returns({ + source: "cdnjs.cloudflare.com", + version: "1.7", + path: "resources/angularjs/1.4.8/angular.min.js.dec" + }); + requestDetails.type = "xmlhttprequest"; + var res = interceptor.handleRequest(requestDetails, tabid, tab); + }); + + it("storage changed listener function should update as needed", function() { + changes = { + xhrTestDomain: { newValue: "value", oldValue: "old" } + }; + interceptor._handleStorageChanged(changes); + changes = { + blockMissing: { newValue: "value", oldValue: "old" } + }; + interceptor._handleStorageChanged(changes); + }); +}); diff --git a/test/unittests/core/main.test.js b/test/unittests/core/main.test.js new file mode 100644 index 0000000..71760dd --- /dev/null +++ b/test/unittests/core/main.test.js @@ -0,0 +1,219 @@ +/* + * Belongs to Decentraleyes. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +describe("Main.js", function() { + describe("Options initializations", function() { + beforeEach(function() { + chrome.flush(); + var Setting = { + AMOUNT_INJECTED: "amountInjected", + BLOCK_MISSING: "blockMissing", + DISABLE_PREFETCH: "disablePrefetch", + SHOW_ICON_BADGE: "showIconBadge", + SHOW_RELEASE_NOTES: "showReleaseNotes", + STRIP_METADATA: "stripMetadata", + WHITELISTED_DOMAINS: "whitelistedDomains", + XHR_TEST_DOMAIN: "xhrTestDomain" + }; + }); + + it("should get and set values from storage", function() { + var options = { + [Setting.XHR_TEST_DOMAIN]: "https://example.org", + [Setting.SHOW_ICON_BADGE]: true, + [Setting.BLOCK_MISSING]: false, + [Setting.DISABLE_PREFETCH]: true, + [Setting.STRIP_METADATA]: true, + [Setting.WHITELISTED_DOMAINS]: {} + }; + chrome.storage.local.get.yields(options); + main._initializeOptions(); + + assert.ok(chrome.storage.local.set.calledOnce); + assert.ok(chrome.storage.local.set.calledWith(options)); + }); + + it("should disable networkPrediction when disabled via setting", function() { + var options = { + [Setting.XHR_TEST_DOMAIN]: "https://example.org", + [Setting.SHOW_ICON_BADGE]: true, + [Setting.BLOCK_MISSING]: false, + [Setting.DISABLE_PREFETCH]: true, + [Setting.STRIP_METADATA]: true, + [Setting.WHITELISTED_DOMAINS]: {} + }; + chrome.storage.local.get.yields(options); + main._initializeOptions(); + assert.ok( + chrome.privacy.network.networkPredictionEnabled.set.calledOnce + ); + assert.ok( + chrome.privacy.network.networkPredictionEnabled.set.calledWith({ + value: false + }) + ); + }); + + it("should not disable networkPrediction when enabled via setting", function() { + var options = { + [Setting.XHR_TEST_DOMAIN]: "https://example.org", + [Setting.SHOW_ICON_BADGE]: true, + [Setting.BLOCK_MISSING]: false, + [Setting.DISABLE_PREFETCH]: false, + [Setting.STRIP_METADATA]: true, + [Setting.WHITELISTED_DOMAINS]: {} + }; + chrome.storage.local.get.yields(options); + main._initializeOptions(); + assert.ok( + chrome.privacy.network.networkPredictionEnabled.set.notCalled + ); + }); + + it("when options are null, set default options", function() { + chrome.storage.local.get.yields(null); + let defaults = { + [Setting.XHR_TEST_DOMAIN]: "decentraleyes.org", + [Setting.SHOW_ICON_BADGE]: true, + [Setting.BLOCK_MISSING]: false, + [Setting.DISABLE_PREFETCH]: true, + [Setting.STRIP_METADATA]: true, + [Setting.WHITELISTED_DOMAINS]: {} + }; + main._initializeOptions(); + assert.ok( + chrome.privacy.network.networkPredictionEnabled.set.calledWith({ + value: false + }) + ); + assert.ok(chrome.storage.local.set.calledOnce); + assert.ok(chrome.storage.local.set.calledWith(defaults)); + }); + }); + + describe("Release notes", function() { + beforeEach(function() { + chrome.flush(); + chrome.runtime.OnInstalledReason = { + INSTALL: "INSTALL", + UPDATE: "UPDATE" + }; + }); + it("should not show release notes for minor release install or update", function() { + var details = { + temporary: false, + reason: "INSTALL", + previousVersion: "2.0.0" + }; + main._showReleaseNotes(details); + assert.ok(chrome.storage.local.get.notCalled); + assert.ok(chrome.tabs.create.notCalled); + + details.reason = "UPDATE"; + + main._showReleaseNotes(details); + assert.ok(chrome.storage.local.get.notCalled); + assert.ok(chrome.tabs.create.notCalled); + }); + + it("should show release notes for major release install or update", function() { + var details = { + temporary: false, + reason: "INSTALL", + previousVersion: "3.0.0" + }; + + chrome.storage.local.get.yields({ showReleaseNotes: true }); + main._showReleaseNotes(details); + assert.ok(chrome.storage.local.get.calledOnce); + assert.ok( + chrome.storage.local.get.calledWith({ + [Setting.SHOW_RELEASE_NOTES]: true + }) + ); + assert.ok( + chrome.tabs.create.calledWith({ + url: undefined, // for unit test no need to mock response for getURL + active: false + }) + ); + chrome.flush(); + + details.reason = "UPDATE"; + chrome.storage.local.get.yields({ showReleaseNotes: true }); + + main._showReleaseNotes(details); + assert.ok(chrome.storage.local.get.calledOnce); + assert.ok( + chrome.storage.local.get.calledWith({ + [Setting.SHOW_RELEASE_NOTES]: true + }) + ); + assert.ok( + chrome.tabs.create.calledWith({ + url: undefined, // for unit test no need to mock response for getURL + active: false + }) + ); + // assert.ok(chrome.tabs.create.notCalled); + }); + + it("should not show release notes for major release install or update when setting is disabled", function() { + var details = { + temporary: false, + reason: "INSTALL", + previousVersion: "3.0.0" + }; + + chrome.storage.local.get.yields({ showReleaseNotes: false }); + main._showReleaseNotes(details); + assert.ok(chrome.storage.local.get.calledOnce); + assert.ok( + chrome.storage.local.get.calledWith({ + [Setting.SHOW_RELEASE_NOTES]: true + }) + ); + assert.ok(chrome.tabs.create.notCalled); + chrome.flush(); + + details.reason = "UPDATE"; + chrome.storage.local.get.yields({ showReleaseNotes: false }); + + main._showReleaseNotes(details); + assert.ok(chrome.storage.local.get.calledOnce); + assert.ok( + chrome.storage.local.get.calledWith({ + [Setting.SHOW_RELEASE_NOTES]: true + }) + ); + assert.ok(chrome.tabs.create.notCalled); + }); + + it("should do nothing if details.reason is empty or invalid", function() { + var details = { + temporary: false, + reason: "", + previousVersion: "2.0.0" + }; + main._showReleaseNotes(details); + assert.ok(chrome.storage.local.get.notCalled); + assert.ok(chrome.tabs.create.notCalled); + }); + + it("should not show release notes if addon running in temporary mode like web-ext run", function() { + var details = { + temporary: true, + reason: "UPDATE", + previousVersion: "1.0.0" + }; + main._showReleaseNotes(details); + assert.ok(chrome.storage.local.get.notCalled); + assert.ok(chrome.tabs.create.notCalled); + }); + }); +}); diff --git a/test/unittests/core/messenger.test.js b/test/unittests/core/messenger.test.js new file mode 100644 index 0000000..5de1704 --- /dev/null +++ b/test/unittests/core/messenger.test.js @@ -0,0 +1,103 @@ +/* + * Belongs to Decentraleyes. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +describe("Messenger.js tests", function() { + var sender = {}; + var sendResponse; + var message = {}; + beforeEach(function() { + chrome.flush(); + var MessageResponse = { + ASYNCHRONOUS: true, + SYNCHRONOUS: false + }; + + //stateManager.addDomainToWhitelist = function() {}; + let a = "gnu.org"; + requestAnalyzer = { + whitelistedDomains: { + "fsf.org": true, + "gnu.org": true + } + }; + message.topic = ""; + message.value = 0; + + stateManager = {}; + stateManager.tabs = [{ injections: 4 }]; + stateManager.removeDomainFromWhitelist = function(domain) {}; + stateManager.addDomainToWhitelist = function(domain) {}; + sender = {}; + sendResponse = sinon.spy(); + }); + + it("should return injections and should not keep listener open i.e return false", function() { + message.topic = "tab:fetch-injections"; + + var response = messenger._handleMessageReceived( + message, + sender, + sendResponse + ); + + sinon.assert.calledOnce(sendResponse); + sinon.assert.calledWith(sendResponse, { value: 4 }); + expect(response).to.be.eql(false); + }); + + it("should return if domain whitelisted and not keep listener open i.e return false", function() { + message.topic = "domain:fetch-is-whitelisted"; + message.value = "gnu.org"; + + var response = messenger._handleMessageReceived( + message, + sender, + sendResponse + ); + + sinon.assert.calledOnce(sendResponse); + sinon.assert.calledWith(sendResponse, { value: true }); + expect(response).to.be.eql(false); + }); + + it("should add domain to whitelist by calling statemanager fn and keep listener open i.e return true ", function() { + message.topic = "whitelist:add-domain"; + message.value = "gnu.org"; + + var stub = sinon.stub(stateManager, "addDomainToWhitelist").returns({ + then: function() {} + }); + + var response = messenger._handleMessageReceived( + message, + sender, + sendResponse + ); + sinon.assert.calledWith(stub, "gnu.org"); + expect(response).to.be.eql(true); + }); + + it("should remove domain to whitelist by calling statemanager fn and keep listener open i.e return true", function() { + message.topic = "whitelist:remove-domain"; + message.value = "gnu.org"; + + var stub = sinon + .stub(stateManager, "removeDomainFromWhitelist") + .returns({ + then: function() {} + }); + + var response = messenger._handleMessageReceived( + message, + sender, + sendResponse + ); + sinon.assert.calledWith(stub, "gnu.org"); + expect(response).to.be.eql(true); + }); +}); diff --git a/test/unittests/core/request-sanitizer.test.js b/test/unittests/core/request-sanitizer.test.js new file mode 100644 index 0000000..709920f --- /dev/null +++ b/test/unittests/core/request-sanitizer.test.js @@ -0,0 +1,85 @@ +/* + * Belongs to Decentraleyes. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +describe("Request Sanitizer", function() { + beforeEach(function() { + chrome.flush(); + }); + it("should attach webrequest listener with Blocking response", function() { + requestSanitizer.enable(); + assert.ok(chrome.webRequest.onBeforeSendHeaders.addListener.calledOnce); + assert.ok( + chrome.webRequest.onBeforeSendHeaders.addListener.calledWith( + requestSanitizer._stripMetadata, + { + urls: stateManager.validHosts + }, + [WebRequest.BLOCKING, WebRequest.HEADERS] + ) + ); + }); + + it("should remove webrequest listener", function() { + requestSanitizer.disable(); + assert.ok( + chrome.webRequest.onBeforeSendHeaders.removeListener.calledOnce + ); + assert.ok( + chrome.webRequest.onBeforeSendHeaders.removeListener.calledWith( + requestSanitizer._stripMetadata, + { + urls: stateManager.validHosts + }, + [WebRequest.BLOCKING, WebRequest.HEADERS] + ) + ); + }); + + it("strip metadata", function() { + requestHeaders = {}; + var a = [ + { name: "Host", value: "web.archive.org" }, + { + name: "User-Agent", + value: + "Save Page Request from WaybackEverywhere Browser Extension" + }, + { name: "Accept", value: "*/*" }, + { name: "Accept-Language", value: "en-GB,en;q=0.5" }, + { name: "Accept-Encoding", value: "gzip, deflate, br" }, + { + name: "Referer", + value: "https://web.archive.org/save/http://www.gnu.org/" + }, + { + name: "Cookie", + value: + "tk_or=%22%22; tk_lr=%22%22; _hp2_22%7D; _biz_dfsA=%5B%5D; _biz_uid=107f5b0ccc034617dfcf1096c1bb5372; _biz_nA=1; _biz_pendingA=%5B%22m%2Fipv%3F_biz_r%3Dhttps%253A%252F%252Fscotthelme.co.uk%252Fsecuring-dns-across-all-of-my-devices-with-pihole-dns-over-https-1-1-1-1%252F%26_biz_h%3D-884118237%26_biz_u%3D107f5b0ccc034617dfcf1096c1bb5372%26_biz_s%3D6bff7e%26_biz_l%3Dhttps%253A%252F%252Fweb.archive.org%252Fweb%252F20180611051411%252Fhttps%253A%252F%252Fblog.cloudflare.com%252Fcloudflare-argo-tunnel-with-rust-and-raspberry-pi%252F%26_biz_t%3D1532832071950%26_biz_i%3DCloudflare%2520Argo%2520Tunnel%2520with%2520Rust%252BRaspberry%2520Pi%26_biz_n%3D0%26rnd%3D803756%22%5D; AMCV_F7093025512D2B690A490D44%40AdobeOrg=1099438348%7CMCIDTS%7C17742%7CMCMID%7C79090085757024397768106107133894830525%7CMCAID%7CNONE%7CMCOPTOUT-1532840491s%7CNONE%7CvVersion%7C2.1.0; optimizelyEndUserId=oeu1532834989890r0.8011439154373176; _ga=GA1.2.1684042591.1533584166; _gid=GA1.2.1675613711.1533584166; intercom-id-pz16iron=dfebc4ad-d99d-498b-87f6-cde29abed55a; MOE_DATA=%7B%22WEB_SETTINGS%22%3A%7B%22isDomainLevelStorage%22%3Atrue%2C%22isConfigured%22%3Atrue%2C%22isPushSubBilling%22%3Atrue%2C%22platformSettings%22%3A%7B%22safari%22%3A%7B%22enabled%22%3Afalse%2C%22websitePushId%22%3Anull%7D%2C%22chrome%22%3A%7B%22enabled%22%3Atrue%2C%22domainType%22%3A%22https%22%2C%22isServiceWorkerRoot%22%3Atrue%2C%22serviceWorkerFilename%22%3A%22serviceworker.js%22%2C%22apiKey%22%3A%22AIzaSyBm2HfZqg2Gp2aVeaA901S1gJBwD-cIikI%22%2C%22subscriptionMode%22%3A%22normal%22%2C%22vapidPublicKey%22%3Anull%2C%22subdomainURL%22%3Anull%2C%22projectNumber%22%3A%22540868316921%22%7D%2C%22firefox%22%3A%7B%22enabled%22%3Atrue%2C%22domainType%22%3A%22NA%22%2C%22isServiceWorkerRoot%22%3Atrue%2C%22serviceWorkerFilename%22%3A%22serviceworker.js%22%2C%22apiKey%22%3A%22AIzaSyBm2HfZqg2Gp2aVeaA901S1gJBwD-cIikI%22%2C%22subscriptionMode%22%3A%22normal%22%2C%22vapidPublicKey%22%3Anull%2C%22projectNumber%22%3A%22540868316921%22%7D%7D%2C%22optInConfig%22%3A%7B%22type%22%3A%22SELF_HANDLED%22%2C%22reappearTime%22%3A24%2C%22softAskConfig%22%3A%7B%22desktop%22%3A%7B%22customHTML%22%3A%22%22%7D%2C%22mobile%22%3A%7B%22customHTML%22%3A%22%22%7D%7D%2C%22showOverlay%22%3Afalse%2C%22loadTime%22%3A0%7D%2C%22oldWebData%22%3A%7B%22webData%22%3A%7B%22promptAgain%22%3A24%2C%22saveSettingsInLive%22%3Afalse%2C%22domain_level_storage%22%3A%22true%22%2C%22savedSettingsFlag%22%3Atrue%2C%22optInConfigData%22%3A%7B%22load_time%22%3A1%2C%22bannerHtml%22%3A%7B%22mweb%22%3A%22%22%2C%22web%22%3A%22%22%7D%2C%22type%22%3A%22self_handled%22%2C%22saveSettingsInLive%22%3Afalse%2C%22promptAgain%22%3A24%7D%2C%22call_push_moengage%22%3Afalse%2C%22PushSubBilling%22%3A%22false%22%2C%22domain_type%22%3A%22https%22%2C%22manifestUrl%22%3A%22https%3A//webpush-manifest-files.s3.us-east-1.amazonaws.com/TheHinduHTTPS/manifest.json%3FSignature%3DEj4Hol%252B4jz%252Br3CRuRyR%252FBlu%252FTdM%253D%26Expires%3D1561715765%26AWSAccessKeyId%3DAKIAJIOYGTA3FJFQTCRQ%22%2C%22webPushPlatformData%22%3A%7B%22chrome%22%3A%7B%22savedSettingsFlagSubdomain%22%3Atrue%2C%22subdomain%22%3A%22%22%2C%22savedSettingsFlag%22%3Afalse%2C%22gcm%22%3A%22sharedProject%22%2C%22domain_type%22%3A%22https%22%2C%22subdomainUrl%22%3A%22%22%2C%22project_number%22%3A%22540868316921%22%2C%22api_key%22%3A%22AIzaSyBm2HfZqg2Gp2aVeaA901S1gJBwD-cIikI%22%2C%22default_icon%22%3A%22https%3A//image.moengage.com/thehinduhttpsmoengage/20180628095559856349OAIZF3thlogorjpgcompTheHinduHTTPS.jpg%22%7D%2C%22platform%22%3A%7B%22browser%22%3A%7B%22windows%22%3A%22chrome%22%2C%22linux%22%3A%22chrome%22%7D%7D%2C%22saveSettingsInLive%22%3Atrue%7D%2C%22banner%22%3A%7B%22banner_flag%22%3Afalse%7D%2C%22project_number%22%3A%22540868316921%22%2C%22bannerHtml%22%3A%7B%22web%22%3A%22%22%2C%22mweb%22%3A%22%22%7D%2C%22type%22%3A%22self_handled%22%2C%22default_icon%22%3A%22https%3A//image.moengage.com/thehinduhttpsmoengage/20180628095559856349OAIZF3thlogorjpgcompTheHinduHTTPS.jpg%22%7D%7D%2C%22featureAvailabilityMatrix%22%3Anull%7D%2C%22SETUP_TIME%22%3A1533658258008%2C%22INIT_DATA%22%3A%7B%22debugLevel%22%3A0%2C%22cluster%22%3Anull%2C%22environment%22%3Anull%2C%22baseDomainName%22%3A%22https%3A//web.archive.org/web/20180807160901/https%3A//websdk.moengage.com/%22%2C%22customSoftAsk%22%3A%7B%22mainClass%22%3A%22moe-main-class%22%2C%22allowClass%22%3A%22moe-allow-class%22%2C%22dismissClass%22%3A%22moe-block-class%22%7D%2C%22appId%22%3A%22BIELH8M8CONB0AXBRWP0FYQP%22%2C%22integrationType%22%3A%22NEW_SDK%22%2C%22forceSwUpdate%22%3Afalse%2C%22swPath%22%3Anull%7D%2C%22OPT_IN_SHOWN_TIME%22%3A1533658258136%2C%22SOFT_ASK_STATUS%22%3A%22shown%22%7D; init=true; switch-synchronised=1; wayback.initiatingpage=https%3A%2F%2Fweb.archive.org%2Fweb%2F20180807183018%2Fhttp%3A%2F%2Fwww.gnu.org%2F; wayback.archivalhost=https%3A%2F%2Fwww.gnu.org; wayback.collectionid=web; wayback.timestamp=20180807183018; JSESSIONID=6F3CCC7910C6879E9686FB24F5548ECC" + }, + { name: "Connection", value: "keep-alive" }, + { name: "Origin", value: "some origin" } + ]; + requestHeaders.requestHeaders = a; + + var val = requestSanitizer._stripMetadata(requestHeaders); + var stripped = [ + { name: "Host", value: "web.archive.org" }, + { + name: "User-Agent", + value: + "Save Page Request from WaybackEverywhere Browser Extension" + }, + { name: "Accept", value: "*/*" }, + { name: "Accept-Language", value: "en-GB,en;q=0.5" }, + { name: "Accept-Encoding", value: "gzip, deflate, br" }, + + { name: "Connection", value: "keep-alive" } + ]; + expect(val).to.be.eql({ requestHeaders: stripped }); + }); +}); diff --git a/test/unittests/internal/helpers.test.js b/test/unittests/internal/helpers.test.js new file mode 100644 index 0000000..a122cab --- /dev/null +++ b/test/unittests/internal/helpers.test.js @@ -0,0 +1,228 @@ +/* + * Belongs to Decentraleyes. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +describe("Helpers", function() { + describe("domain name handlers", function() { + beforeEach(function() { + chrome.flush(); + var Address = { + ANY: "*://*/*", + ANY_PATH: "/*", + ANY_PROTOCOL: "*://", + CHROME: "chrome:", + CHROME_EXTENSION: "chrome-extension:", + DECENTRALEYES: "decentraleyes.org", + EXAMPLE: "example.org", + HTTP: "http:", + HTTPS: "https:", + RESOURCE_PATH: "/resources", + ROOT_PATH: "/", + WWW_PREFIX: "www." + }; + }); + + it("should return normalized domain", function() { + let domain = helpers.normalizeDomain("https://GnU.oRG"); + expect(domain).to.be.eql("https://gnu.org"); + domain = helpers.normalizeDomain(" https://gnu.oRG "); + expect(domain).to.be.eql("https://gnu.org"); + domain = helpers.normalizeDomain("www.gnu.org"); + expect(domain).to.be.eql("gnu.org"); + }); + + it("should extract domain from URL", function() { + let url = "https://example.org/something/some/path"; + let domain = helpers.extractDomainFromUrl(url, true); + expect(domain).to.be.eql("example.org"); + }); + + it("should handle chrome pages", function() { + let url = "chrome://newtab"; + let domain = helpers.extractDomainFromUrl(url, false); + expect(domain).to.be.eql(null); + }); + + it("should handle invalid urls to return null", function() { + let url = "invalid"; + let domain = helpers.extractDomainFromUrl(url, false); + expect(domain).to.be.eql(null); + }); + + it("should handle empty evaluated url to return null", function() { + let url = "invalid://something"; + let domain = helpers.extractDomainFromUrl(url, false); + expect(domain).to.be.eql(null); + }); + }); + + describe("Formatters", function() { + beforeEach(function() { + chrome.flush(); + }); + it("should return number as string", function() { + let number = helpers.formatNumber(2); + expect(number).to.be.a("string"); + number = helpers.formatNumber("2"); + expect(number).to.be.undefined; + }); + it("should return version formatted", function() { + let version = helpers.formatVersion("betaVersion"); + expect(version).to.be.eql("BETA"); + version = helpers.formatVersion("1.2.1"); + expect(version).to.be.eql("1.2.1"); + }); + }); + + describe("File name handler", function() { + it("should return correct file names from a path", function() { + var filename = helpers.extractFilenameFromPath( + "file://somepath/a/b/c/settings.json" + ); + expect(filename).to.be.eql("settings.json"); + }); + }); + + describe("Content insertion", function() { + it("should return reverse script direction for selected langauges", function() { + var dir = helpers.determineScriptDirection("ar"); + expect(dir).to.be.eql("rtl"); + }); + it("should return left to right script direction for other langauges", function() { + var dir = helpers.determineScriptDirection("en"); + expect(dir).to.be.eql("ltr"); + }); + }); + + describe("Language support", function() { + it("should return true is in language codeword in array", function() { + var check = helpers.languageIsFullySupported("en"); + expect(check).to.be.eql(true); + }); + it("should return false is not in language codeword in array", function() { + var check = helpers.languageIsFullySupported("ta"); + expect(check).to.be.eql(false); + }); + + // TODO it("add more here ") + }); + + describe("GenerateRandomHexString generator", function() { + it("should use crypto function", function() { + var length = 8; + var val = new Uint8Array(length); + val = crypto.getRandomValues(val); + var spy = sinon.stub(crypto, "getRandomValues").returns(val); + var returned = helpers.generateRandomHexString(); + sinon.assert.calledOnce(spy); + }); + }); + + describe("cdn and resource names", function() { + var list = [ + { name: "angular.min.js.dec", value: "AngularJS" }, + { name: "backbone-min.js.dec", value: "Backbone.js" }, + { name: "dojo.js.dec", value: "Dojo" }, + { name: "ember.min.js.dec", value: "Ember.js" }, + { name: "ext-core.js.dec", value: "Ext Core" }, + { name: "jquery.min.js.dec", value: "jQuery" }, + { name: "jquery-ui.min.js.dec", value: "jQuery UI" }, + { name: "modernizr.min.js.dec", value: "Modernizr" }, + { name: "mootools-yui-compressed.js.dec", value: "MooTools" }, + { name: "prototype.js.dec", value: "Prototype" }, + { name: "scriptaculous.js.dec", value: "Scriptaculous" }, + { name: "swfobject.js.dec", value: "SWFObject" }, + { name: "underscore-min.js.dec", value: "Underscore.js" }, + { name: "webfont.js.dec", value: "Web Font Loader" } + ]; + it("should return correct resource name", function() { + for (res in list) { + var check = helpers.determineResourceName(list[res].name); + expect(check).to.be.eql(list[res].value); + } + }); + + it("should return unknown if resouce is unknown to us", function() { + var check = helpers.determineResourceName("somenewlib.js.dec"); + expect(check).to.be.eql("Unknown"); + }); + + var list2 = [ + { + name: "ajax.googleapis.com", + value: "Google Hosted Libraries" + }, + { + name: "ajax.aspnetcdn.com", + value: "Microsoft Ajax CDN" + }, + { + name: "ajax.microsoft.com", + value: "Microsoft Ajax CDN [Deprecated]" + }, + { + name: "cdnjs.cloudflare.com", + value: "CDNJS (Cloudflare)" + }, + { + name: "code.jquery.com", + value: "jQuery CDN (MaxCDN)" + }, + { + name: "cdn.jsdelivr.net", + value: "jsDelivr (MaxCDN)" + }, + { + name: "yastatic.net", + value: "Yandex CDN" + }, + { + name: "yandex.st", + value: "Yandex CDN [Deprecated]" + }, + { + name: "apps.bdimg.com", + value: "Baidu CDN" + }, + { + name: "libs.baidu.com", + value: "Baidu CDN [Deprecated]" + }, + { + name: "lib.sinaapp.com", + value: "Sina Public Resources" + }, + { + name: "upcdn.b0.upaiyun.com", + value: "UpYun Library" + }, + { + name: "cdn.bootcss.com", + value: "BootCDN" + }, + { + name: "sdn.geekzu.org", + value: "Geekzu Public Service [Mirror]" + }, + { + name: "ajax.proxy.ustclug.org", + value: "USTC Linux User Group [Mirror]" + } + ]; + it("should return correct cdn name", function() { + for (res in list2) { + var check = helpers.determineCdnName(list2[res].name); + expect(check).to.be.eql(list2[res].value); + } + }); + + it("should return unknown if cdn unknown to us", function() { + var check = helpers.determineCdnName("some new bad cdn"); + expect(check).to.be.eql("Unknown"); + }); + }); +}); diff --git a/test/unittests/internal/wrappers.test.js b/test/unittests/internal/wrappers.test.js new file mode 100644 index 0000000..60837f7 --- /dev/null +++ b/test/unittests/internal/wrappers.test.js @@ -0,0 +1,45 @@ +/* + * Belongs to Decentraleyes. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +describe("Wrappers", function() { + describe("Wrappers for Browser Action API calls", function() { + const API = chrome.browserAction; + beforeEach(function() { + chrome.flush(); + }); + + it("should set badge background color correctly", function() { + var details = { + color: [74, 130, 108, 255] + }; + wrappers.setBadgeBackgroundColor(details); + assert.ok(API.setBadgeBackgroundColor.calledOnce); + assert.ok(API.setBadgeBackgroundColor.calledWith(details)); + }); + + it("should set Badge Text correctly", function() { + var details = { + tabId: 1, + text: "20" + }; + wrappers.setBadgeText(details); + assert.ok(API.setBadgeText.calledOnce); + assert.ok(API.setBadgeText.calledWith(details)); + }); + + it("should set badge icon correctly", function() { + var details = { + path: "path/action/icon16-disabled.png", + tabId: 3 + }; + wrappers.setIcon(details); + assert.ok(API.setIcon.calledOnce); + assert.ok(API.setIcon.calledWith(details)); + }); + }); +}); diff --git a/test/unittests/main.test.js b/test/unittests/main.test.js new file mode 100644 index 0000000..71760dd --- /dev/null +++ b/test/unittests/main.test.js @@ -0,0 +1,219 @@ +/* + * Belongs to Decentraleyes. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +describe("Main.js", function() { + describe("Options initializations", function() { + beforeEach(function() { + chrome.flush(); + var Setting = { + AMOUNT_INJECTED: "amountInjected", + BLOCK_MISSING: "blockMissing", + DISABLE_PREFETCH: "disablePrefetch", + SHOW_ICON_BADGE: "showIconBadge", + SHOW_RELEASE_NOTES: "showReleaseNotes", + STRIP_METADATA: "stripMetadata", + WHITELISTED_DOMAINS: "whitelistedDomains", + XHR_TEST_DOMAIN: "xhrTestDomain" + }; + }); + + it("should get and set values from storage", function() { + var options = { + [Setting.XHR_TEST_DOMAIN]: "https://example.org", + [Setting.SHOW_ICON_BADGE]: true, + [Setting.BLOCK_MISSING]: false, + [Setting.DISABLE_PREFETCH]: true, + [Setting.STRIP_METADATA]: true, + [Setting.WHITELISTED_DOMAINS]: {} + }; + chrome.storage.local.get.yields(options); + main._initializeOptions(); + + assert.ok(chrome.storage.local.set.calledOnce); + assert.ok(chrome.storage.local.set.calledWith(options)); + }); + + it("should disable networkPrediction when disabled via setting", function() { + var options = { + [Setting.XHR_TEST_DOMAIN]: "https://example.org", + [Setting.SHOW_ICON_BADGE]: true, + [Setting.BLOCK_MISSING]: false, + [Setting.DISABLE_PREFETCH]: true, + [Setting.STRIP_METADATA]: true, + [Setting.WHITELISTED_DOMAINS]: {} + }; + chrome.storage.local.get.yields(options); + main._initializeOptions(); + assert.ok( + chrome.privacy.network.networkPredictionEnabled.set.calledOnce + ); + assert.ok( + chrome.privacy.network.networkPredictionEnabled.set.calledWith({ + value: false + }) + ); + }); + + it("should not disable networkPrediction when enabled via setting", function() { + var options = { + [Setting.XHR_TEST_DOMAIN]: "https://example.org", + [Setting.SHOW_ICON_BADGE]: true, + [Setting.BLOCK_MISSING]: false, + [Setting.DISABLE_PREFETCH]: false, + [Setting.STRIP_METADATA]: true, + [Setting.WHITELISTED_DOMAINS]: {} + }; + chrome.storage.local.get.yields(options); + main._initializeOptions(); + assert.ok( + chrome.privacy.network.networkPredictionEnabled.set.notCalled + ); + }); + + it("when options are null, set default options", function() { + chrome.storage.local.get.yields(null); + let defaults = { + [Setting.XHR_TEST_DOMAIN]: "decentraleyes.org", + [Setting.SHOW_ICON_BADGE]: true, + [Setting.BLOCK_MISSING]: false, + [Setting.DISABLE_PREFETCH]: true, + [Setting.STRIP_METADATA]: true, + [Setting.WHITELISTED_DOMAINS]: {} + }; + main._initializeOptions(); + assert.ok( + chrome.privacy.network.networkPredictionEnabled.set.calledWith({ + value: false + }) + ); + assert.ok(chrome.storage.local.set.calledOnce); + assert.ok(chrome.storage.local.set.calledWith(defaults)); + }); + }); + + describe("Release notes", function() { + beforeEach(function() { + chrome.flush(); + chrome.runtime.OnInstalledReason = { + INSTALL: "INSTALL", + UPDATE: "UPDATE" + }; + }); + it("should not show release notes for minor release install or update", function() { + var details = { + temporary: false, + reason: "INSTALL", + previousVersion: "2.0.0" + }; + main._showReleaseNotes(details); + assert.ok(chrome.storage.local.get.notCalled); + assert.ok(chrome.tabs.create.notCalled); + + details.reason = "UPDATE"; + + main._showReleaseNotes(details); + assert.ok(chrome.storage.local.get.notCalled); + assert.ok(chrome.tabs.create.notCalled); + }); + + it("should show release notes for major release install or update", function() { + var details = { + temporary: false, + reason: "INSTALL", + previousVersion: "3.0.0" + }; + + chrome.storage.local.get.yields({ showReleaseNotes: true }); + main._showReleaseNotes(details); + assert.ok(chrome.storage.local.get.calledOnce); + assert.ok( + chrome.storage.local.get.calledWith({ + [Setting.SHOW_RELEASE_NOTES]: true + }) + ); + assert.ok( + chrome.tabs.create.calledWith({ + url: undefined, // for unit test no need to mock response for getURL + active: false + }) + ); + chrome.flush(); + + details.reason = "UPDATE"; + chrome.storage.local.get.yields({ showReleaseNotes: true }); + + main._showReleaseNotes(details); + assert.ok(chrome.storage.local.get.calledOnce); + assert.ok( + chrome.storage.local.get.calledWith({ + [Setting.SHOW_RELEASE_NOTES]: true + }) + ); + assert.ok( + chrome.tabs.create.calledWith({ + url: undefined, // for unit test no need to mock response for getURL + active: false + }) + ); + // assert.ok(chrome.tabs.create.notCalled); + }); + + it("should not show release notes for major release install or update when setting is disabled", function() { + var details = { + temporary: false, + reason: "INSTALL", + previousVersion: "3.0.0" + }; + + chrome.storage.local.get.yields({ showReleaseNotes: false }); + main._showReleaseNotes(details); + assert.ok(chrome.storage.local.get.calledOnce); + assert.ok( + chrome.storage.local.get.calledWith({ + [Setting.SHOW_RELEASE_NOTES]: true + }) + ); + assert.ok(chrome.tabs.create.notCalled); + chrome.flush(); + + details.reason = "UPDATE"; + chrome.storage.local.get.yields({ showReleaseNotes: false }); + + main._showReleaseNotes(details); + assert.ok(chrome.storage.local.get.calledOnce); + assert.ok( + chrome.storage.local.get.calledWith({ + [Setting.SHOW_RELEASE_NOTES]: true + }) + ); + assert.ok(chrome.tabs.create.notCalled); + }); + + it("should do nothing if details.reason is empty or invalid", function() { + var details = { + temporary: false, + reason: "", + previousVersion: "2.0.0" + }; + main._showReleaseNotes(details); + assert.ok(chrome.storage.local.get.notCalled); + assert.ok(chrome.tabs.create.notCalled); + }); + + it("should not show release notes if addon running in temporary mode like web-ext run", function() { + var details = { + temporary: true, + reason: "UPDATE", + previousVersion: "1.0.0" + }; + main._showReleaseNotes(details); + assert.ok(chrome.storage.local.get.notCalled); + assert.ok(chrome.tabs.create.notCalled); + }); + }); +}); -- GitLab From 527a3ed14c52ab8440f76a0d614402e512e4df01 Mon Sep 17 00:00:00 2001 From: Gokulakrishna Date: Thu, 9 Aug 2018 00:54:35 +0530 Subject: [PATCH 2/3] removed temporary file --- test/unittests/core/a.js | 1 - 1 file changed, 1 deletion(-) delete mode 100644 test/unittests/core/a.js diff --git a/test/unittests/core/a.js b/test/unittests/core/a.js deleted file mode 100644 index 9055674..0000000 --- a/test/unittests/core/a.js +++ /dev/null @@ -1 +0,0 @@ -var a = [{name: 'Host', value: 'web.archive.org'}, Object{name: 'User-Agent', value: 'Save Page Request from WaybackEverywhere Browser Extension'}, Object{name: 'Accept', value: '*/*'}, Object{name: 'Accept-Language', value: 'en-GB,en;q=0.5'}, Object{name: 'Accept-Encoding', value: 'gzip, deflate, br'}, Object{name: 'Referer', value: 'https://web.archive.org/save/http://www.gnu.org/'}, Object{name: 'Cookie', value: 'tk_or=%22%22; tk_lr=%22%22; _hp2_22%7D; _biz_dfsA=%5B%5D; _biz_uid=107f5b0ccc034617dfcf1096c1bb5372; _biz_nA=1; _biz_pendingA=%5B%22m%2Fipv%3F_biz_r%3Dhttps%253A%252F%252Fscotthelme.co.uk%252Fsecuring-dns-across-all-of-my-devices-with-pihole-dns-over-https-1-1-1-1%252F%26_biz_h%3D-884118237%26_biz_u%3D107f5b0ccc034617dfcf1096c1bb5372%26_biz_s%3D6bff7e%26_biz_l%3Dhttps%253A%252F%252Fweb.archive.org%252Fweb%252F20180611051411%252Fhttps%253A%252F%252Fblog.cloudflare.com%252Fcloudflare-argo-tunnel-with-rust-and-raspberry-pi%252F%26_biz_t%3D1532832071950%26_biz_i%3DCloudflare%2520Argo%2520Tunnel%2520with%2520Rust%252BRaspberry%2520Pi%26_biz_n%3D0%26rnd%3D803756%22%5D; AMCV_F7093025512D2B690A490D44%40AdobeOrg=1099438348%7CMCIDTS%7C17742%7CMCMID%7C79090085757024397768106107133894830525%7CMCAID%7CNONE%7CMCOPTOUT-1532840491s%7CNONE%7CvVersion%7C2.1.0; optimizelyEndUserId=oeu1532834989890r0.8011439154373176; _ga=GA1.2.1684042591.1533584166; _gid=GA1.2.1675613711.1533584166; intercom-id-pz16iron=dfebc4ad-d99d-498b-87f6-cde29abed55a; MOE_DATA=%7B%22WEB_SETTINGS%22%3A%7B%22isDomainLevelStorage%22%3Atrue%2C%22isConfigured%22%3Atrue%2C%22isPushSubBilling%22%3Atrue%2C%22platformSettings%22%3A%7B%22safari%22%3A%7B%22enabled%22%3Afalse%2C%22websitePushId%22%3Anull%7D%2C%22chrome%22%3A%7B%22enabled%22%3Atrue%2C%22domainType%22%3A%22https%22%2C%22isServiceWorkerRoot%22%3Atrue%2C%22serviceWorkerFilename%22%3A%22serviceworker.js%22%2C%22apiKey%22%3A%22AIzaSyBm2HfZqg2Gp2aVeaA901S1gJBwD-cIikI%22%2C%22subscriptionMode%22%3A%22normal%22%2C%22vapidPublicKey%22%3Anull%2C%22subdomainURL%22%3Anull%2C%22projectNumber%22%3A%22540868316921%22%7D%2C%22firefox%22%3A%7B%22enabled%22%3Atrue%2C%22domainType%22%3A%22NA%22%2C%22isServiceWorkerRoot%22%3Atrue%2C%22serviceWorkerFilename%22%3A%22serviceworker.js%22%2C%22apiKey%22%3A%22AIzaSyBm2HfZqg2Gp2aVeaA901S1gJBwD-cIikI%22%2C%22subscriptionMode%22%3A%22normal%22%2C%22vapidPublicKey%22%3Anull%2C%22projectNumber%22%3A%22540868316921%22%7D%7D%2C%22optInConfig%22%3A%7B%22type%22%3A%22SELF_HANDLED%22%2C%22reappearTime%22%3A24%2C%22softAskConfig%22%3A%7B%22desktop%22%3A%7B%22customHTML%22%3A%22%22%7D%2C%22mobile%22%3A%7B%22customHTML%22%3A%22%22%7D%7D%2C%22showOverlay%22%3Afalse%2C%22loadTime%22%3A0%7D%2C%22oldWebData%22%3A%7B%22webData%22%3A%7B%22promptAgain%22%3A24%2C%22saveSettingsInLive%22%3Afalse%2C%22domain_level_storage%22%3A%22true%22%2C%22savedSettingsFlag%22%3Atrue%2C%22optInConfigData%22%3A%7B%22load_time%22%3A1%2C%22bannerHtml%22%3A%7B%22mweb%22%3A%22%22%2C%22web%22%3A%22%22%7D%2C%22type%22%3A%22self_handled%22%2C%22saveSettingsInLive%22%3Afalse%2C%22promptAgain%22%3A24%7D%2C%22call_push_moengage%22%3Afalse%2C%22PushSubBilling%22%3A%22false%22%2C%22domain_type%22%3A%22https%22%2C%22manifestUrl%22%3A%22https%3A//webpush-manifest-files.s3.us-east-1.amazonaws.com/TheHinduHTTPS/manifest.json%3FSignature%3DEj4Hol%252B4jz%252Br3CRuRyR%252FBlu%252FTdM%253D%26Expires%3D1561715765%26AWSAccessKeyId%3DAKIAJIOYGTA3FJFQTCRQ%22%2C%22webPushPlatformData%22%3A%7B%22chrome%22%3A%7B%22savedSettingsFlagSubdomain%22%3Atrue%2C%22subdomain%22%3A%22%22%2C%22savedSettingsFlag%22%3Afalse%2C%22gcm%22%3A%22sharedProject%22%2C%22domain_type%22%3A%22https%22%2C%22subdomainUrl%22%3A%22%22%2C%22project_number%22%3A%22540868316921%22%2C%22api_key%22%3A%22AIzaSyBm2HfZqg2Gp2aVeaA901S1gJBwD-cIikI%22%2C%22default_icon%22%3A%22https%3A//image.moengage.com/thehinduhttpsmoengage/20180628095559856349OAIZF3thlogorjpgcompTheHinduHTTPS.jpg%22%7D%2C%22platform%22%3A%7B%22browser%22%3A%7B%22windows%22%3A%22chrome%22%2C%22linux%22%3A%22chrome%22%7D%7D%2C%22saveSettingsInLive%22%3Atrue%7D%2C%22banner%22%3A%7B%22banner_flag%22%3Afalse%7D%2C%22project_number%22%3A%22540868316921%22%2C%22bannerHtml%22%3A%7B%22web%22%3A%22%22%2C%22mweb%22%3A%22%22%7D%2C%22type%22%3A%22self_handled%22%2C%22default_icon%22%3A%22https%3A//image.moengage.com/thehinduhttpsmoengage/20180628095559856349OAIZF3thlogorjpgcompTheHinduHTTPS.jpg%22%7D%7D%2C%22featureAvailabilityMatrix%22%3Anull%7D%2C%22SETUP_TIME%22%3A1533658258008%2C%22INIT_DATA%22%3A%7B%22debugLevel%22%3A0%2C%22cluster%22%3Anull%2C%22environment%22%3Anull%2C%22baseDomainName%22%3A%22https%3A//web.archive.org/web/20180807160901/https%3A//websdk.moengage.com/%22%2C%22customSoftAsk%22%3A%7B%22mainClass%22%3A%22moe-main-class%22%2C%22allowClass%22%3A%22moe-allow-class%22%2C%22dismissClass%22%3A%22moe-block-class%22%7D%2C%22appId%22%3A%22BIELH8M8CONB0AXBRWP0FYQP%22%2C%22integrationType%22%3A%22NEW_SDK%22%2C%22forceSwUpdate%22%3Afalse%2C%22swPath%22%3Anull%7D%2C%22OPT_IN_SHOWN_TIME%22%3A1533658258136%2C%22SOFT_ASK_STATUS%22%3A%22shown%22%7D; init=true; switch-synchronised=1; wayback.initiatingpage=https%3A%2F%2Fweb.archive.org%2Fweb%2F20180807183018%2Fhttp%3A%2F%2Fwww.gnu.org%2F; wayback.archivalhost=https%3A%2F%2Fwww.gnu.org; wayback.collectionid=web; wayback.timestamp=20180807183018; JSESSIONID=6F3CCC7910C6879E9686FB24F5548ECC'}, Object{name: 'Connection', value: 'keep-alive'}, Object{name: 'Origin', value: 'some origin'}] \ No newline at end of file -- GitLab From 495af33554d0ee917907628fc8fad5c0798aa50b Mon Sep 17 00:00:00 2001 From: Gokulakrishna Date: Thu, 9 Aug 2018 01:21:29 +0530 Subject: [PATCH 3/3] updated request sanitizer --- test/unittests/core/request-sanitizer.test.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/test/unittests/core/request-sanitizer.test.js b/test/unittests/core/request-sanitizer.test.js index 709920f..63bd3c9 100644 --- a/test/unittests/core/request-sanitizer.test.js +++ b/test/unittests/core/request-sanitizer.test.js @@ -58,8 +58,7 @@ describe("Request Sanitizer", function() { }, { name: "Cookie", - value: - "tk_or=%22%22; tk_lr=%22%22; _hp2_22%7D; _biz_dfsA=%5B%5D; _biz_uid=107f5b0ccc034617dfcf1096c1bb5372; _biz_nA=1; _biz_pendingA=%5B%22m%2Fipv%3F_biz_r%3Dhttps%253A%252F%252Fscotthelme.co.uk%252Fsecuring-dns-across-all-of-my-devices-with-pihole-dns-over-https-1-1-1-1%252F%26_biz_h%3D-884118237%26_biz_u%3D107f5b0ccc034617dfcf1096c1bb5372%26_biz_s%3D6bff7e%26_biz_l%3Dhttps%253A%252F%252Fweb.archive.org%252Fweb%252F20180611051411%252Fhttps%253A%252F%252Fblog.cloudflare.com%252Fcloudflare-argo-tunnel-with-rust-and-raspberry-pi%252F%26_biz_t%3D1532832071950%26_biz_i%3DCloudflare%2520Argo%2520Tunnel%2520with%2520Rust%252BRaspberry%2520Pi%26_biz_n%3D0%26rnd%3D803756%22%5D; AMCV_F7093025512D2B690A490D44%40AdobeOrg=1099438348%7CMCIDTS%7C17742%7CMCMID%7C79090085757024397768106107133894830525%7CMCAID%7CNONE%7CMCOPTOUT-1532840491s%7CNONE%7CvVersion%7C2.1.0; optimizelyEndUserId=oeu1532834989890r0.8011439154373176; _ga=GA1.2.1684042591.1533584166; _gid=GA1.2.1675613711.1533584166; intercom-id-pz16iron=dfebc4ad-d99d-498b-87f6-cde29abed55a; MOE_DATA=%7B%22WEB_SETTINGS%22%3A%7B%22isDomainLevelStorage%22%3Atrue%2C%22isConfigured%22%3Atrue%2C%22isPushSubBilling%22%3Atrue%2C%22platformSettings%22%3A%7B%22safari%22%3A%7B%22enabled%22%3Afalse%2C%22websitePushId%22%3Anull%7D%2C%22chrome%22%3A%7B%22enabled%22%3Atrue%2C%22domainType%22%3A%22https%22%2C%22isServiceWorkerRoot%22%3Atrue%2C%22serviceWorkerFilename%22%3A%22serviceworker.js%22%2C%22apiKey%22%3A%22AIzaSyBm2HfZqg2Gp2aVeaA901S1gJBwD-cIikI%22%2C%22subscriptionMode%22%3A%22normal%22%2C%22vapidPublicKey%22%3Anull%2C%22subdomainURL%22%3Anull%2C%22projectNumber%22%3A%22540868316921%22%7D%2C%22firefox%22%3A%7B%22enabled%22%3Atrue%2C%22domainType%22%3A%22NA%22%2C%22isServiceWorkerRoot%22%3Atrue%2C%22serviceWorkerFilename%22%3A%22serviceworker.js%22%2C%22apiKey%22%3A%22AIzaSyBm2HfZqg2Gp2aVeaA901S1gJBwD-cIikI%22%2C%22subscriptionMode%22%3A%22normal%22%2C%22vapidPublicKey%22%3Anull%2C%22projectNumber%22%3A%22540868316921%22%7D%7D%2C%22optInConfig%22%3A%7B%22type%22%3A%22SELF_HANDLED%22%2C%22reappearTime%22%3A24%2C%22softAskConfig%22%3A%7B%22desktop%22%3A%7B%22customHTML%22%3A%22%22%7D%2C%22mobile%22%3A%7B%22customHTML%22%3A%22%22%7D%7D%2C%22showOverlay%22%3Afalse%2C%22loadTime%22%3A0%7D%2C%22oldWebData%22%3A%7B%22webData%22%3A%7B%22promptAgain%22%3A24%2C%22saveSettingsInLive%22%3Afalse%2C%22domain_level_storage%22%3A%22true%22%2C%22savedSettingsFlag%22%3Atrue%2C%22optInConfigData%22%3A%7B%22load_time%22%3A1%2C%22bannerHtml%22%3A%7B%22mweb%22%3A%22%22%2C%22web%22%3A%22%22%7D%2C%22type%22%3A%22self_handled%22%2C%22saveSettingsInLive%22%3Afalse%2C%22promptAgain%22%3A24%7D%2C%22call_push_moengage%22%3Afalse%2C%22PushSubBilling%22%3A%22false%22%2C%22domain_type%22%3A%22https%22%2C%22manifestUrl%22%3A%22https%3A//webpush-manifest-files.s3.us-east-1.amazonaws.com/TheHinduHTTPS/manifest.json%3FSignature%3DEj4Hol%252B4jz%252Br3CRuRyR%252FBlu%252FTdM%253D%26Expires%3D1561715765%26AWSAccessKeyId%3DAKIAJIOYGTA3FJFQTCRQ%22%2C%22webPushPlatformData%22%3A%7B%22chrome%22%3A%7B%22savedSettingsFlagSubdomain%22%3Atrue%2C%22subdomain%22%3A%22%22%2C%22savedSettingsFlag%22%3Afalse%2C%22gcm%22%3A%22sharedProject%22%2C%22domain_type%22%3A%22https%22%2C%22subdomainUrl%22%3A%22%22%2C%22project_number%22%3A%22540868316921%22%2C%22api_key%22%3A%22AIzaSyBm2HfZqg2Gp2aVeaA901S1gJBwD-cIikI%22%2C%22default_icon%22%3A%22https%3A//image.moengage.com/thehinduhttpsmoengage/20180628095559856349OAIZF3thlogorjpgcompTheHinduHTTPS.jpg%22%7D%2C%22platform%22%3A%7B%22browser%22%3A%7B%22windows%22%3A%22chrome%22%2C%22linux%22%3A%22chrome%22%7D%7D%2C%22saveSettingsInLive%22%3Atrue%7D%2C%22banner%22%3A%7B%22banner_flag%22%3Afalse%7D%2C%22project_number%22%3A%22540868316921%22%2C%22bannerHtml%22%3A%7B%22web%22%3A%22%22%2C%22mweb%22%3A%22%22%7D%2C%22type%22%3A%22self_handled%22%2C%22default_icon%22%3A%22https%3A//image.moengage.com/thehinduhttpsmoengage/20180628095559856349OAIZF3thlogorjpgcompTheHinduHTTPS.jpg%22%7D%7D%2C%22featureAvailabilityMatrix%22%3Anull%7D%2C%22SETUP_TIME%22%3A1533658258008%2C%22INIT_DATA%22%3A%7B%22debugLevel%22%3A0%2C%22cluster%22%3Anull%2C%22environment%22%3Anull%2C%22baseDomainName%22%3A%22https%3A//web.archive.org/web/20180807160901/https%3A//websdk.moengage.com/%22%2C%22customSoftAsk%22%3A%7B%22mainClass%22%3A%22moe-main-class%22%2C%22allowClass%22%3A%22moe-allow-class%22%2C%22dismissClass%22%3A%22moe-block-class%22%7D%2C%22appId%22%3A%22BIELH8M8CONB0AXBRWP0FYQP%22%2C%22integrationType%22%3A%22NEW_SDK%22%2C%22forceSwUpdate%22%3Afalse%2C%22swPath%22%3Anull%7D%2C%22OPT_IN_SHOWN_TIME%22%3A1533658258136%2C%22SOFT_ASK_STATUS%22%3A%22shown%22%7D; init=true; switch-synchronised=1; wayback.initiatingpage=https%3A%2F%2Fweb.archive.org%2Fweb%2F20180807183018%2Fhttp%3A%2F%2Fwww.gnu.org%2F; wayback.archivalhost=https%3A%2F%2Fwww.gnu.org; wayback.collectionid=web; wayback.timestamp=20180807183018; JSESSIONID=6F3CCC7910C6879E9686FB24F5548ECC" + value: "have some cookies" }, { name: "Connection", value: "keep-alive" }, { name: "Origin", value: "some origin" } -- GitLab