From d7e13b046bd5a7b89f3cf50ccb43556ad42127d0 Mon Sep 17 00:00:00 2001 From: Sefa Ilkimen Date: Fri, 20 Oct 2017 17:22:51 +0200 Subject: [PATCH] - feature #24: extended behaviour of "setHeader" method - added test suite for www interface of plugin (js files) --- .gitignore | 1 + .travis.yml | 3 +- package.json | 5 +- scripts/build-test-app.sh | 2 +- scripts/{test.sh => test-app.sh} | 2 +- .../helpers/apps.js | 0 .../helpers/caps.js | 0 .../helpers/logging.js | 0 .../helpers/server.js | 0 .../helpers/setup.js | 0 test/{mocha-specs => app-mocha-specs}/test.js | 2 +- test/app-template/www/index.html | 2 +- ...definitions.js => app-test-definitions.js} | 2 +- test/js-mocha-specs.js | 94 +++++++++++++++++++ www/advanced-http.js | 68 ++++++++------ www/angular-integration.js | 4 +- 16 files changed, 149 insertions(+), 36 deletions(-) rename scripts/{test.sh => test-app.sh} (63%) rename test/{mocha-specs => app-mocha-specs}/helpers/apps.js (100%) rename test/{mocha-specs => app-mocha-specs}/helpers/caps.js (100%) rename test/{mocha-specs => app-mocha-specs}/helpers/logging.js (100%) rename test/{mocha-specs => app-mocha-specs}/helpers/server.js (100%) rename test/{mocha-specs => app-mocha-specs}/helpers/setup.js (100%) rename test/{mocha-specs => app-mocha-specs}/test.js (97%) rename test/{test-definitions.js => app-test-definitions.js} (98%) create mode 100644 test/js-mocha-specs.js diff --git a/.gitignore b/.gitignore index 9ca4c2b..0c2a6ef 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ node_modules/** tags .zedstate +npm-debug.log /temp diff --git a/.travis.yml b/.travis.yml index 38b4b1f..35ba419 100644 --- a/.travis.yml +++ b/.travis.yml @@ -32,7 +32,8 @@ install: script: - travis_wait scripts/build-test-app.sh - scripts/upload-artifact.sh -- scripts/test.sh --ios --emulator +- npm run testjs +- scripts/test-app.sh --ios --emulator after_success: diff --git a/package.json b/package.json index a23a6c3..3de5d1f 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,9 @@ "version": "1.6.2", "description": "Cordova / Phonegap plugin for communicating with HTTP servers using SSL pinning", "scripts": { - "test": "./scripts/build-test-app.sh && ./scripts/test.sh --ios --emulator", + "testapp": "./scripts/build-test-app.sh && ./scripts/test-app.sh --ios --emulator", + "testjs": "mocha ./test/js-mocha-specs.js", + "test": "npm run testjs && npm run testapp", "release": "npm run test && ./scripts/release.sh" }, "cordova": { @@ -55,6 +57,7 @@ "colors": "1.1.2", "cordova": "7.0.1", "mocha": "4.0.0", + "mock-require": "2.0.2", "mz": "2.7.0", "umd-tough-cookie": "2.3.2", "wd": "1.4.1", diff --git a/scripts/build-test-app.sh b/scripts/build-test-app.sh index ef062fa..441df5c 100755 --- a/scripts/build-test-app.sh +++ b/scripts/build-test-app.sh @@ -9,7 +9,7 @@ CDV=$ROOT/node_modules/.bin/cordova rm -rf $ROOT/temp mkdir $ROOT/temp cp -r $ROOT/test/app-template/ $ROOT/temp/ -cp $ROOT/test/test-definitions.js $ROOT/temp/www/js/ +cp $ROOT/test/app-test-definitions.js $ROOT/temp/www/js/ cd $ROOT/temp $CDV prepare $CDV plugins add $ROOT diff --git a/scripts/test.sh b/scripts/test-app.sh similarity index 63% rename from scripts/test.sh rename to scripts/test-app.sh index 15404ba..5957d2c 100755 --- a/scripts/test.sh +++ b/scripts/test-app.sh @@ -4,5 +4,5 @@ set -e ROOT="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"/.. pushd $ROOT -./node_modules/.bin/mocha ./test/mocha-specs/test.js "$@" +./node_modules/.bin/mocha ./test/app-mocha-specs/test.js "$@" popd diff --git a/test/mocha-specs/helpers/apps.js b/test/app-mocha-specs/helpers/apps.js similarity index 100% rename from test/mocha-specs/helpers/apps.js rename to test/app-mocha-specs/helpers/apps.js diff --git a/test/mocha-specs/helpers/caps.js b/test/app-mocha-specs/helpers/caps.js similarity index 100% rename from test/mocha-specs/helpers/caps.js rename to test/app-mocha-specs/helpers/caps.js diff --git a/test/mocha-specs/helpers/logging.js b/test/app-mocha-specs/helpers/logging.js similarity index 100% rename from test/mocha-specs/helpers/logging.js rename to test/app-mocha-specs/helpers/logging.js diff --git a/test/mocha-specs/helpers/server.js b/test/app-mocha-specs/helpers/server.js similarity index 100% rename from test/mocha-specs/helpers/server.js rename to test/app-mocha-specs/helpers/server.js diff --git a/test/mocha-specs/helpers/setup.js b/test/app-mocha-specs/helpers/setup.js similarity index 100% rename from test/mocha-specs/helpers/setup.js rename to test/app-mocha-specs/helpers/setup.js diff --git a/test/mocha-specs/test.js b/test/app-mocha-specs/test.js similarity index 97% rename from test/mocha-specs/test.js rename to test/app-mocha-specs/test.js index 6ae2ce2..09049dc 100644 --- a/test/mocha-specs/test.js +++ b/test/app-mocha-specs/test.js @@ -4,7 +4,7 @@ const wd = require('wd'); const apps = require('./helpers/apps'); const caps = Object.assign({}, require('./helpers/caps')); const serverConfig = require('./helpers/server'); -const testDefinitions = require('../test-definitions'); +const testDefinitions = require('../app-test-definitions'); const pkgjson = require('../../package.json'); describe('Advanced HTTP', function() { diff --git a/test/app-template/www/index.html b/test/app-template/www/index.html index ff105fe..fa9273a 100644 --- a/test/app-template/www/index.html +++ b/test/app-template/www/index.html @@ -14,7 +14,7 @@ - + diff --git a/test/test-definitions.js b/test/app-test-definitions.js similarity index 98% rename from test/test-definitions.js rename to test/app-test-definitions.js index f52259e..7cb8f2f 100644 --- a/test/test-definitions.js +++ b/test/app-test-definitions.js @@ -62,6 +62,6 @@ const tests = [ } ]; -if (module && module.exports) { +if (typeof module !== 'undefined' && module.exports) { module.exports = { tests: tests, hooks: hooks }; } diff --git a/test/js-mocha-specs.js b/test/js-mocha-specs.js new file mode 100644 index 0000000..47efd98 --- /dev/null +++ b/test/js-mocha-specs.js @@ -0,0 +1,94 @@ +const chai = require('chai'); +const mock = require('mock-require'); +const path = require('path'); + +const should = chai.should(); +const PLUGIN_ID = path.resolve(__dirname, '..', 'www', 'advanced-http'); + +describe('Advanced HTTP www interface', function() { + let http = {}; + const noop = () => { /* intentionally doing nothing */ }; + const loadHttp = () => { + http = mock.reRequire('../www/advanced-http'); + }; + + this.timeout(900000); + + beforeEach(() => { + mock('cordova/exec', noop); + mock(`${PLUGIN_ID}.angular-integration`, { registerService: noop }); + mock(`${PLUGIN_ID}.cookie-handler`, {}); + loadHttp(); + }); + + it('sets global headers correctly with two args (old interface)', () => { + http.setHeader('myKey', 'myValue'); + http.headers['*'].myKey.should.equal('myValue'); + }); + + it('sets global headers correctly with three args (new interface)', () => { + http.setHeader('*', 'myKey', 'myValue'); + http.headers['*'].myKey.should.equal('myValue'); + }); + + it('sets host headers correctly', () => { + http.setHeader('www.google.de', 'myKey', 'myValue'); + http.headers['www.google.de'].myKey.should.equal('myValue'); + }); + + it('resolves global headers correctly', () => { + mock(`${PLUGIN_ID}.cookie-handler`, { + getCookieString: () => 'fakeCookieString' + }); + + mock('cordova/exec', (onSuccess, onFail, namespace, method, params) => { + const headers = params[2]; + headers.should.eql({ + Cookie: 'fakeCookieString', + myKey: 'myValue' + }); + }); + + loadHttp(); + + http.setHeader('*', 'myKey', 'myValue'); + http.get('url', {}, {}, noop, noop); + }); + + it('resolves host headers correctly', () => { + mock(`${PLUGIN_ID}.cookie-handler`, { + getCookieString: () => 'fakeCookieString' + }); + + mock('cordova/exec', (onSuccess, onFail, namespace, method, params) => { + const headers = params[2]; + headers.should.eql({ + Cookie: 'fakeCookieString', + myKey: 'myValue' + }); + }); + + loadHttp(); + + http.setHeader('www.google.de', 'myKey', 'myValue'); + http.get('https://www.google.de/?gws_rd=ssl', {}, {}, noop, noop); + }); + + it('resolves request headers correctly', () => { + mock(`${PLUGIN_ID}.cookie-handler`, { + getCookieString: () => 'fakeCookieString' + }); + + mock('cordova/exec', (onSuccess, onFail, namespace, method, params) => { + const headers = params[2]; + headers.should.eql({ + Cookie: 'fakeCookieString', + myKey: 'myValue' + }); + }); + + loadHttp(); + + http.get('https://www.google.de/?gws_rd=ssl', {}, { myKey: 'myValue' }, noop, noop); + }); +}); diff --git a/www/advanced-http.js b/www/advanced-http.js index 342470b..cecb2bf 100644 --- a/www/advanced-http.js +++ b/www/advanced-http.js @@ -114,6 +114,24 @@ function getCookieHeader(url) { return { Cookie: cookieHandler.getCookieString(url) }; } +function getMatchingHostHeaders(url, headersList) { + var matches = url.match(/^https?\:\/\/([^\/?#]+)(?:[\/?#]|$)/i); + var domain = matches && matches[1]; + + return headersList[domain] || null; +} + +function getMergedHeaders(url, requestHeaders, predefinedHeaders) { + var globalHeaders = predefinedHeaders['*'] || {}; + var hostHeaders = getMatchingHostHeaders(url, predefinedHeaders) || {}; + var mergedHeaders = mergeHeaders(globalHeaders, hostHeaders); + + mergedHeaders = mergeHeaders(mergedHeaders, requestHeaders); + mergedHeaders = mergeHeaders(mergedHeaders, getCookieHeader(url)); + + return mergedHeaders; +} + function handleMissingCallbacks(successFn, failFn) { if (Object.prototype.toString.call(successFn) !== '[object Function]') { throw new Error('advanced-http: missing mandatory "onSuccess" callback function'); @@ -133,10 +151,22 @@ var http = { return {'Authorization': 'Basic ' + b64EncodeUnicode(username + ':' + password)}; }, useBasicAuth: function (username, password) { - this.headers.Authorization = 'Basic ' + b64EncodeUnicode(username + ':' + password); + this.headers['*'].Authorization = 'Basic ' + b64EncodeUnicode(username + ':' + password); }, - setHeader: function (header, value) { - this.headers[header] = value; + setHeader: function () { + // this one is for being backward compatible + var host = '*'; + var header = arguments[0]; + var value = arguments[1]; + + if (arguments.length === 3) { + host = arguments[0]; + header = arguments[1]; + value = arguments[2]; + } + + this.headers[host] = this.headers[host] || {}; + this.headers[host][header] = value; }, setDataSerializer: function (serializer) { this.dataSerializer = checkSerializer(serializer); @@ -166,9 +196,7 @@ var http = { handleMissingCallbacks(success, failure); data = data || {}; - headers = headers || {}; - headers = mergeHeaders(this.headers, headers); - headers = mergeHeaders(getCookieHeader(url), headers); + headers = getMergedHeaders(url, headers, this.headers); var onSuccess = injectCookieHandler(url, success); var onFail = injectCookieHandler(url, failure); @@ -179,9 +207,7 @@ var http = { handleMissingCallbacks(success, failure); params = params || {}; - headers = headers || {}; - headers = mergeHeaders(this.headers, headers); - headers = mergeHeaders(getCookieHeader(url), headers); + headers = getMergedHeaders(url, headers, this.headers); var onSuccess = injectCookieHandler(url, success); var onFail = injectCookieHandler(url, failure); @@ -192,9 +218,7 @@ var http = { handleMissingCallbacks(success, failure); data = data || {}; - headers = headers || {}; - headers = mergeHeaders(this.headers, headers); - headers = mergeHeaders(getCookieHeader(url), headers); + headers = getMergedHeaders(url, headers, this.headers); var onSuccess = injectCookieHandler(url, success); var onFail = injectCookieHandler(url, failure); @@ -206,9 +230,7 @@ var http = { handleMissingCallbacks(success, failure); data = data || {}; - headers = headers || {}; - headers = mergeHeaders(this.headers, headers); - headers = mergeHeaders(getCookieHeader(url), headers); + headers = getMergedHeaders(url, headers, this.headers); var onSuccess = injectCookieHandler(url, success); var onFail = injectCookieHandler(url, failure); @@ -220,9 +242,7 @@ var http = { handleMissingCallbacks(success, failure); params = params || {}; - headers = headers || {}; - headers = mergeHeaders(this.headers, headers); - headers = mergeHeaders(getCookieHeader(url), headers); + headers = getMergedHeaders(url, headers, this.headers); var onSuccess = injectCookieHandler(url, success); var onFail = injectCookieHandler(url, failure); @@ -233,9 +253,7 @@ var http = { handleMissingCallbacks(success, failure); params = params || {}; - headers = headers || {}; - headers = mergeHeaders(this.headers, headers); - headers = mergeHeaders(getCookieHeader(url), headers); + headers = getMergedHeaders(url, headers, this.headers); var onSuccess = injectCookieHandler(url, success); var onFail = injectCookieHandler(url, failure); @@ -246,9 +264,7 @@ var http = { handleMissingCallbacks(success, failure); params = params || {}; - headers = headers || {}; - headers = mergeHeaders(this.headers, headers); - headers = mergeHeaders(getCookieHeader(url), headers); + headers = getMergedHeaders(url, headers, this.headers); var onSuccess = injectCookieHandler(url, success); var onFail = injectCookieHandler(url, failure); @@ -259,9 +275,7 @@ var http = { handleMissingCallbacks(success, failure); params = params || {}; - headers = headers || {}; - headers = mergeHeaders(this.headers, headers); - headers = mergeHeaders(getCookieHeader(url), headers); + headers = getMergedHeaders(url, headers, this.headers); var onSuccess = injectCookieHandler(url, injectFileEntryHandler(success)); var onFail = injectCookieHandler(url, failure); diff --git a/www/angular-integration.js b/www/angular-integration.js index 5199ee2..39820f5 100644 --- a/www/angular-integration.js +++ b/www/angular-integration.js @@ -38,8 +38,8 @@ function registerService(http) { useBasicAuth: function (username, password) { return http.useBasicAuth(username, password); }, - setHeader: function (header, value) { - return http.setHeader(header, value); + setHeader: function (host, header, value) { + return http.setHeader(host, header, value); }, setDataSerializer: function (serializer) { return http.setDataSerializer(serializer);