Compare commits

...
11 Commits
Author SHA1 Message Date
Sefa Ilkimen 937296b371 release v1.8.1 2017-11-08 11:17:53 +01:00
Sefa Ilkimen a48a91dd14 add OS identifier for saucelabs tests 2017-11-08 11:15:32 +01:00
Sefa Ilkimen e8a72a53cc split CI build into two jobs 2017-11-08 10:29:59 +01:00
Sefa Ilkimen efbdc21221 fix: ANDROID_HOME path for CI build 2017-11-07 18:30:42 +01:00
Sefa Ilkimen 06d7d859e7 update change log 2017-11-07 14:53:37 +01:00
Sefa Ilkimen 239b82c08e enable saucelabs testing for android platform 2017-11-07 14:52:11 +01:00
Sefa Ilkimen e987652d97 fix #40: generic error codes are different on Android and iOS 2017-11-07 13:31:38 +01:00
Sefa Ilkimen 068b25b6f9 - fix #27: "uploadFile" method doesn't return data object on iOS
- update version number
2017-11-03 15:51:19 +01:00
Sefa Ilkimen 8c55572eb8 implement test for "downloadFile" method 2017-11-02 17:01:35 +01:00
Sefa Ilkimen 48afeefbc3 - update version number
- update change log
2017-11-02 15:45:37 +01:00
Sefa Ilkimen 292d726b20 - feature #33: response object contains response url
- annotate tests with issue numbers
- refactor android source code
2017-11-02 14:59:53 +01:00
20 changed files with 269 additions and 290 deletions
+2
View File
@@ -3,3 +3,5 @@ tags
.zedstate
npm-debug.log
/temp
/android-sdk-macosx.zip
/android-sdk-macosx/**
+11 -14
View File
@@ -4,6 +4,10 @@ language: objective-c
os: osx
osx_image: xcode9.1
env:
- TARGET_PLATFORM=android
- TARGET_PLATFORM=ios
cache:
directories:
- node_modules
@@ -19,23 +23,16 @@ before_install:
install:
- npm install
- brew install gradle
- wget http://dl.google.com/android/android-sdk_r24.4-macosx.zip
- tar -xvf android-sdk_r24.4-macosx.zip
- echo y | ./android-sdk-macosx/tools/android update sdk --no-ui --all --filter platform-tools
- echo y | ./android-sdk-macosx/tools/android update sdk --no-ui --all --filter build-tools-25.0.0
- echo y | ./android-sdk-macosx/tools/android update sdk --no-ui --all --filter android-25
- echo y | ./android-sdk-macosx/tools/android update sdk --no-ui --all --filter extra-android-support
- echo y | ./android-sdk-macosx/tools/android update sdk --no-ui --all --filter extra-android-m2repository
- echo y | ./android-sdk-macosx/tools/android update sdk --no-ui --all --filter extra-google-m2repository
- export ANDROID_HOME=./android-sdk-macosx
- export PATH=${PATH}:$ANDROID_HOME/tools:$ANDROID_HOME/platform-tools:$ANDROID_HOME/build-tools/23.0.2
- if [ $TARGET_PLATFORM = "android" ]; then brew install gradle; fi
- if [ $TARGET_PLATFORM = "android" ]; then scripts/setup-android-sdk.sh; fi
- if [ $TARGET_PLATFORM = "android" ]; then export ANDROID_HOME=$(pwd)/android-sdk-macosx; fi
- if [ $TARGET_PLATFORM = "android" ]; then export PATH=${PATH}:$ANDROID_HOME/tools:$ANDROID_HOME/platform-tools:$ANDROID_HOME/build-tools/23.0.2; fi
script:
- travis_wait scripts/build-test-app.sh
- scripts/upload-artifact.sh
- npm run testjs
- scripts/test-app.sh --ios --emulator
- travis_wait scripts/build-test-app.sh --$TARGET_PLATFORM --emulator
- scripts/upload-artifact.sh --$TARGET_PLATFORM
- scripts/test-app.sh --$TARGET_PLATFORM --emulator
after_success:
+9
View File
@@ -1,5 +1,14 @@
# Changelog
## v1.8.1
- Fixed #27: "uploadFile" method doesn't return data object on iOS (thanks Faisalali23 and laiyinjie)
- Fixed #40: generic error codes are different on Android and iOS
## v1.8.0
- Feature #33: response object contains response url
## v1.7.1
- Fixed #36: setting basic authentication not working correctly (thanks jkfb)
+4 -2
View File
@@ -1,9 +1,11 @@
{
"name": "cordova-plugin-advanced-http",
"version": "1.7.1",
"version": "1.8.1",
"description": "Cordova / Phonegap plugin for communicating with HTTP servers using SSL pinning",
"scripts": {
"testapp": "./scripts/build-test-app.sh && ./scripts/test-app.sh --ios --emulator",
"testandroid": "./scripts/build-test-app.sh --android --emulator && ./scripts/test-app.sh --android --emulator",
"testios": "./scripts/build-test-app.sh --ios --emulator && ./scripts/test-app.sh --ios --emulator",
"testapp": "npm run testandroid && npm run testios",
"testjs": "mocha ./test/js-mocha-specs.js",
"test": "npm run testjs && npm run testapp",
"release": "npm run test && ./scripts/release.sh"
+1 -1
View File
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<plugin xmlns="http://www.phonegap.com/ns/plugins/1.0" xmlns:android="http://schemas.android.com/apk/res/android" id="cordova-plugin-advanced-http" version="1.7.1">
<plugin xmlns="http://www.phonegap.com/ns/plugins/1.0" xmlns:android="http://schemas.android.com/apk/res/android" id="cordova-plugin-advanced-http" version="1.8.1">
<name>Advanced HTTP plugin</name>
<description>
Cordova / Phonegap plugin for communicating with HTTP servers using SSL pinning
+12
View File
@@ -0,0 +1,12 @@
#!/usr/bin/env bash
set -e
curl http://dl.google.com/android/android-sdk_r24.4-macosx.zip -o android-sdk-macosx.zip
tar -xvf android-sdk-macosx.zip
echo y | ./android-sdk-macosx/tools/android update sdk --no-ui --all --filter platform-tools
echo y | ./android-sdk-macosx/tools/android update sdk --no-ui --all --filter build-tools-25.0.0
echo y | ./android-sdk-macosx/tools/android update sdk --no-ui --all --filter android-25
echo y | ./android-sdk-macosx/tools/android update sdk --no-ui --all --filter extra-android-support
echo y | ./android-sdk-macosx/tools/android update sdk --no-ui --all --filter extra-android-m2repository
echo y | ./android-sdk-macosx/tools/android update sdk --no-ui --all --filter extra-google-m2repository
+18 -9
View File
@@ -1,16 +1,25 @@
#!/usr/bin/env bash
set -e
PLATFORM=$([[ "${@#--android}" = "$@" ]] && echo "ios" || echo "android")
ROOT="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"/..
TEMP=$ROOT/temp
rm -rf $TEMP/HttpDemo.app.zip
pushd $TEMP/platforms/ios/build/emulator
zip -r $TEMP/HttpDemo.app.zip ./HttpDemo.app
popd
if [ $PLATFORM = "android" ]; then
curl -u $SAUCE_USERNAME:$SAUCE_ACCESS_KEY \
-X POST \
-H "Content-Type: application/octet-stream" \
https://saucelabs.com/rest/v1/storage/$SAUCE_USERNAME/HttpDemo.apk?overwrite=true \
--data-binary @$TEMP/platforms/android/build/outputs/apk/android-debug.apk
else
rm -rf $TEMP/HttpDemo.app.zip
pushd $TEMP/platforms/ios/build/emulator
zip -r $TEMP/HttpDemo.app.zip ./HttpDemo.app
popd
curl -u $SAUCE_USERNAME:$SAUCE_ACCESS_KEY \
-X POST \
-H "Content-Type: application/octet-stream" \
https://saucelabs.com/rest/v1/storage/$SAUCE_USERNAME/HttpDemo.app.zip?overwrite=true \
--data-binary @$TEMP/HttpDemo.app.zip
curl -u $SAUCE_USERNAME:$SAUCE_ACCESS_KEY \
-X POST \
-H "Content-Type: application/octet-stream" \
https://saucelabs.com/rest/v1/storage/$SAUCE_USERNAME/HttpDemo.app.zip?overwrite=true \
--data-binary @$TEMP/HttpDemo.app.zip
fi
@@ -8,6 +8,11 @@ import org.apache.cordova.CallbackContext;
import org.json.JSONException;
import org.json.JSONObject;
import java.net.SocketTimeoutException;
import java.net.UnknownHostException;
import javax.net.ssl.SSLHandshakeException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -17,6 +22,7 @@ import java.util.Iterator;
import android.text.TextUtils;
import com.github.kevinsawicki.http.HttpRequest;
import com.github.kevinsawicki.http.HttpRequest.HttpRequestException;
abstract class CordovaHttp {
protected static final String TAG = "CordovaHTTP";
@@ -120,6 +126,7 @@ abstract class CordovaHttp {
if (sslPinning.get()) {
request.pinToCerts();
}
return request;
}
@@ -127,9 +134,21 @@ abstract class CordovaHttp {
if (disableRedirect.get()) {
request.followRedirects(false);
}
return request;
}
protected HttpRequest setupDataSerializer(HttpRequest request) throws JSONException, Exception {
if (new String("json").equals(this.getSerializerName())) {
request.contentType(request.CONTENT_TYPE_JSON, request.CHARSET_UTF8);
request.send(this.getParamsObject().toString());
} else {
request.form(this.getParamsMap());
}
return request;
}
protected void respondWithError(int status, String msg) {
try {
JSONObject response = new JSONObject();
@@ -142,7 +161,7 @@ abstract class CordovaHttp {
}
protected void respondWithError(String msg) {
this.respondWithError(500, msg);
this.respondWithError(-1, msg);
}
protected void addResponseHeaders(HttpRequest request, JSONObject response) throws JSONException {
@@ -182,4 +201,47 @@ abstract class CordovaHttp {
}
return map;
}
protected void prepareRequest(HttpRequest request) throws HttpRequestException, JSONException {
this.setupRedirect(request);
this.setupSecurity(request);
request.readTimeout(this.getRequestTimeout());
request.acceptCharset(CHARSET);
request.headers(this.getHeadersMap());
request.uncompress(true);
}
protected void returnResponseObject(HttpRequest request) throws HttpRequestException {
try {
JSONObject response = new JSONObject();
int code = request.code();
String body = request.body(CHARSET);
response.put("status", code);
response.put("url", request.url().toString());
this.addResponseHeaders(request, response);
if (code >= 200 && code < 300) {
response.put("data", body);
this.getCallbackContext().success(response);
} else {
response.put("error", body);
this.getCallbackContext().error(response);
}
} catch(JSONException e) {
this.respondWithError("There was an error generating the response");
}
}
protected void handleHttpRequestException(HttpRequestException e) {
if (e.getCause() instanceof UnknownHostException) {
this.respondWithError(0, "The host could not be resolved");
} else if (e.getCause() instanceof SocketTimeoutException) {
this.respondWithError(1, "The request timed out");
} else if (e.getCause() instanceof SSLHandshakeException) {
this.respondWithError("SSL handshake failed");
} else {
this.respondWithError("There was an error with the request: " + e.getMessage());
}
}
}
@@ -57,7 +57,7 @@ class CordovaHttpDelete extends CordovaHttp implements Runnable {
} else if (e.getCause() instanceof SSLHandshakeException) {
this.respondWithError("SSL handshake failed");
} else {
this.respondWithError("There was an error with the request");
this.respondWithError("There was an error with the request: " + e.getMessage());
}
} catch (Exception e) {
this.respondWithError(-1, e.getMessage());
@@ -33,17 +33,15 @@ class CordovaHttpDownload extends CordovaHttp implements Runnable {
try {
HttpRequest request = HttpRequest.get(this.getUrlString(), this.getParamsMap(), true);
request.readTimeout(this.getRequestTimeout());
this.setupRedirect(request);
this.setupSecurity(request);
request.acceptCharset(CHARSET);
request.headers(this.getHeadersMap());
request.uncompress(true);
int code = request.code();
this.prepareRequest(request);
JSONObject response = new JSONObject();
this.addResponseHeaders(request, response);
int code = request.code();
response.put("status", code);
response.put("url", request.url().toString());
this.addResponseHeaders(request, response);
if (code >= 200 && code < 300) {
URI uri = new URI(filePath);
File file = new File(uri);
@@ -60,17 +58,9 @@ class CordovaHttpDownload extends CordovaHttp implements Runnable {
} catch (JSONException e) {
this.respondWithError("There was an error generating the response");
} catch (HttpRequestException e) {
if (e.getCause() instanceof UnknownHostException) {
this.respondWithError(0, "The host could not be resolved");
} else if (e.getCause() instanceof SocketTimeoutException) {
this.respondWithError(1, "The request timed out");
} else if (e.getCause() instanceof SSLHandshakeException) {
this.respondWithError("SSL handshake failed");
} else {
this.respondWithError("There was an error with the request");
}
this.handleHttpRequestException(e);
} catch (Exception e) {
this.respondWithError(-1, e.getMessage());
this.respondWithError(e.getMessage());
}
}
}
@@ -26,41 +26,12 @@ class CordovaHttpGet extends CordovaHttp implements Runnable {
try {
HttpRequest request = HttpRequest.get(this.getUrlString(), this.getParamsMap(), false);
request.readTimeout(this.getRequestTimeout());
this.setupRedirect(request);
this.setupSecurity(request);
request.acceptCharset(CHARSET);
request.headers(this.getHeadersMap());
request.uncompress(true);
int code = request.code();
String body = request.body(CHARSET);
JSONObject response = new JSONObject();
this.addResponseHeaders(request, response);
response.put("status", code);
if (code >= 200 && code < 300) {
response.put("data", body);
this.getCallbackContext().success(response);
} else {
response.put("error", body);
this.getCallbackContext().error(response);
}
} catch (JSONException e) {
this.respondWithError("There was an error generating the response");
this.prepareRequest(request);
this.returnResponseObject(request);
} catch (HttpRequestException e) {
if (e.getCause() instanceof UnknownHostException) {
this.respondWithError(0, "The host could not be resolved");
} else if (e.getCause() instanceof SocketTimeoutException) {
this.respondWithError(1, "The request timed out");
} else if (e.getCause() instanceof SSLHandshakeException) {
this.respondWithError("SSL handshake failed");
} else {
this.respondWithError("There was an error with the request");
}
this.handleHttpRequestException(e);
} catch (Exception e) {
this.respondWithError(-1, e.getMessage());
this.respondWithError(e.getMessage());
}
}
}
@@ -25,41 +25,12 @@ class CordovaHttpHead extends CordovaHttp implements Runnable {
try {
HttpRequest request = HttpRequest.head(this.getUrlString(), this.getParamsMap(), true);
request.readTimeout(this.getRequestTimeout());
this.setupRedirect(request);
this.setupSecurity(request);
request.acceptCharset(CHARSET);
request.headers(this.getHeadersMap());
request.uncompress(true);
int code = request.code();
JSONObject response = new JSONObject();
this.addResponseHeaders(request, response);
response.put("status", code);
if (code >= 200 && code < 300) {
// no 'body' to return for HEAD request
this.getCallbackContext().success(response);
} else {
String body = request.body(CHARSET);
response.put("error", body);
this.getCallbackContext().error(response);
}
} catch (JSONException e) {
this.respondWithError("There was an error generating the response");
this.prepareRequest(request);
this.returnResponseObject(request);
} catch (HttpRequestException e) {
if (e.getCause() instanceof UnknownHostException) {
this.respondWithError(0, "The host could not be resolved");
} else if (e.getCause() instanceof SocketTimeoutException) {
this.respondWithError(1, "The request timed out");
} else if (e.getCause() instanceof SSLHandshakeException) {
this.respondWithError("SSL handshake failed");
} else {
this.respondWithError("There was an error with the request");
}
this.handleHttpRequestException(e);
} catch (Exception e) {
this.respondWithError(-1, e.getMessage());
this.respondWithError(e.getMessage());
}
}
}
@@ -25,48 +25,13 @@ class CordovaHttpPatch extends CordovaHttp implements Runnable {
try {
HttpRequest request = HttpRequest.patch(this.getUrlString());
request.readTimeout(this.getRequestTimeout());
this.setupRedirect(request);
this.setupSecurity(request);
request.acceptCharset(CHARSET);
request.headers(this.getHeadersMap());
request.uncompress(true);
if (new String("json").equals(this.getSerializerName())) {
request.contentType(request.CONTENT_TYPE_JSON, request.CHARSET_UTF8);
request.send(this.getParamsObject().toString());
} else {
request.form(this.getParamsMap());
}
int code = request.code();
String body = request.body(CHARSET);
JSONObject response = new JSONObject();
this.addResponseHeaders(request, response);
response.put("status", code);
if (code >= 200 && code < 300) {
response.put("data", body);
this.getCallbackContext().success(response);
} else {
response.put("error", body);
this.getCallbackContext().error(response);
}
} catch (JSONException e) {
this.respondWithError("There was an error generating the response");
this.prepareRequest(request);
this.setupDataSerializer(request);
this.returnResponseObject(request);
} catch (HttpRequestException e) {
if (e.getCause() instanceof UnknownHostException) {
this.respondWithError(0, "The host could not be resolved");
} else if (e.getCause() instanceof SocketTimeoutException) {
this.respondWithError(1, "The request timed out");
} else if (e.getCause() instanceof SSLHandshakeException) {
this.respondWithError("SSL handshake failed");
} else {
this.respondWithError("There was an error with the request");
}
this.handleHttpRequestException(e);
} catch (Exception e) {
this.respondWithError(-1, e.getMessage());
this.respondWithError(e.getMessage());
}
}
}
@@ -25,48 +25,13 @@ class CordovaHttpPost extends CordovaHttp implements Runnable {
try {
HttpRequest request = HttpRequest.post(this.getUrlString());
request.readTimeout(this.getRequestTimeout());
this.setupRedirect(request);
this.setupSecurity(request);
request.acceptCharset(CHARSET);
request.headers(this.getHeadersMap());
request.uncompress(true);
if (new String("json").equals(this.getSerializerName())) {
request.contentType(request.CONTENT_TYPE_JSON, request.CHARSET_UTF8);
request.send(this.getParamsObject().toString());
} else {
request.form(this.getParamsMap());
}
int code = request.code();
String body = request.body(CHARSET);
JSONObject response = new JSONObject();
this.addResponseHeaders(request, response);
response.put("status", code);
if (code >= 200 && code < 300) {
response.put("data", body);
this.getCallbackContext().success(response);
} else {
response.put("error", body);
this.getCallbackContext().error(response);
}
} catch (JSONException e) {
this.respondWithError("There was an error generating the response");
this.prepareRequest(request);
this.setupDataSerializer(request);
this.returnResponseObject(request);
} catch (HttpRequestException e) {
if (e.getCause() instanceof UnknownHostException) {
this.respondWithError(0, "The host could not be resolved");
} else if (e.getCause() instanceof SocketTimeoutException) {
this.respondWithError(1, "The request timed out");
} else if (e.getCause() instanceof SSLHandshakeException) {
this.respondWithError("SSL handshake failed");
} else {
this.respondWithError("There was an error with the request");
}
this.handleHttpRequestException(e);
} catch (Exception e) {
this.respondWithError(-1, e.getMessage());
this.respondWithError(e.getMessage());
}
}
}
@@ -25,48 +25,13 @@ class CordovaHttpPut extends CordovaHttp implements Runnable {
try {
HttpRequest request = HttpRequest.put(this.getUrlString());
request.readTimeout(this.getRequestTimeout());
this.setupRedirect(request);
this.setupSecurity(request);
request.acceptCharset(CHARSET);
request.headers(this.getHeadersMap());
request.uncompress(true);
if (new String("json").equals(this.getSerializerName())) {
request.contentType(request.CONTENT_TYPE_JSON, request.CHARSET_UTF8);
request.send(this.getParamsObject().toString());
} else {
request.form(this.getParamsMap());
}
int code = request.code();
String body = request.body(CHARSET);
JSONObject response = new JSONObject();
this.addResponseHeaders(request, response);
response.put("status", code);
if (code >= 200 && code < 300) {
response.put("data", body);
this.getCallbackContext().success(response);
} else {
response.put("error", body);
this.getCallbackContext().error(response);
}
} catch (JSONException e) {
this.respondWithError("There was an error generating the response");
this.prepareRequest(request);
this.setupDataSerializer(request);
this.returnResponseObject(request);
} catch (HttpRequestException e) {
if (e.getCause() instanceof UnknownHostException) {
this.respondWithError(0, "The host could not be resolved");
} else if (e.getCause() instanceof SocketTimeoutException) {
this.respondWithError(1, "The request timed out");
} else if (e.getCause() instanceof SSLHandshakeException) {
this.respondWithError("SSL handshake failed");
} else {
this.respondWithError("There was an error with the request");
}
this.handleHttpRequestException(e);
} catch (Exception e) {
this.respondWithError(-1, e.getMessage());
this.respondWithError(e.getMessage());
}
}
}
@@ -41,12 +41,7 @@ class CordovaHttpUpload extends CordovaHttp implements Runnable {
try {
HttpRequest request = HttpRequest.post(this.getUrlString());
request.readTimeout(this.getRequestTimeout());
this.setupRedirect(request);
this.setupSecurity(request);
request.acceptCharset(CHARSET);
request.headers(this.getHeadersMap());
request.uncompress(true);
this.prepareRequest(request);
URI uri = new URI(filePath);
@@ -78,37 +73,15 @@ class CordovaHttpUpload extends CordovaHttp implements Runnable {
}
}
int code = request.code();
String body = request.body(CHARSET);
JSONObject response = new JSONObject();
this.addResponseHeaders(request, response);
response.put("status", code);
if (code >= 200 && code < 300) {
response.put("data", body);
this.getCallbackContext().success(response);
} else {
response.put("error", body);
this.getCallbackContext().error(response);
}
this.returnResponseObject(request);
} catch (URISyntaxException e) {
this.respondWithError("There was an error loading the file");
} catch (JSONException e) {
this.respondWithError("There was an error generating the response");
} catch (HttpRequestException e) {
if (e.getCause() instanceof UnknownHostException) {
this.respondWithError(0, "The host could not be resolved");
} else if (e.getCause() instanceof SocketTimeoutException) {
this.respondWithError(1, "The request timed out");
} else if (e.getCause() instanceof SSLHandshakeException) {
this.respondWithError("SSL handshake failed");
} else {
this.respondWithError("There was an error with the request");
}
this.handleHttpRequestException(e);
} catch (Exception e) {
this.respondWithError(-1, e.getMessage());
this.respondWithError(e.getMessage());
}
}
}
+3 -1
View File
@@ -51,6 +51,7 @@
- (void)handleSuccess:(NSMutableDictionary*)dictionary withResponse:(NSHTTPURLResponse*)response andData:(id)data {
if (response != nil) {
[dictionary setValue:response.URL.absoluteString forKey:@"url"];
[dictionary setObject:[NSNumber numberWithInt:response.statusCode] forKey:@"status"];
[dictionary setObject:[self copyHeaderFields:response.allHeaderFields] forKey:@"headers"];
}
@@ -62,6 +63,7 @@
- (void)handleError:(NSMutableDictionary*)dictionary withResponse:(NSHTTPURLResponse*)response error:(NSError*)error {
if (response != nil) {
[dictionary setValue:response.URL.absoluteString forKey:@"url"];
[dictionary setObject:[NSNumber numberWithInt:response.statusCode] forKey:@"status"];
[dictionary setObject:[self copyHeaderFields:response.allHeaderFields] forKey:@"headers"];
[dictionary setObject:[[NSString alloc] initWithData:(NSData *)error.userInfo[AFNetworkingOperationFailingURLResponseDataErrorKey] encoding:NSUTF8StringEncoding] forKey:@"error"];
@@ -364,7 +366,7 @@
}
} progress:nil success:^(NSURLSessionTask *task, id responseObject) {
NSMutableDictionary *dictionary = [NSMutableDictionary dictionary];
[self handleSuccess:dictionary withResponse:(NSHTTPURLResponse*)task.response andData:nil];
[self handleSuccess:dictionary withResponse:(NSHTTPURLResponse*)task.response andData:responseObject];
CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:dictionary];
[weakSelf.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
+9 -6
View File
@@ -8,18 +8,21 @@ const testDefinitions = require('../app-test-definitions');
const pkgjson = require('../../package.json');
describe('Advanced HTTP', function() {
const isDevice = process.argv.includes('--device');
const isAndroid = process.argv.includes('--android');
const targetInfo = { isDevice, isAndroid };
let driver = null;
let allPassed = true;
this.timeout(900000);
const getCaps = appName => {
const isDevice = process.argv.includes('--device');
const isAndroid = process.argv.includes('--android');
const desiredCaps = caps[(isAndroid ? 'android' : 'ios') + (isDevice ? 'Device' : 'Emulator')];
const desiredApp = apps[(isAndroid ? 'android' : 'ios') + appName];
const desiredOs = isAndroid ? 'android' : 'ios';
const desiredCaps = caps[desiredOs + (isDevice ? 'Device' : 'Emulator')];
const desiredApp = apps[desiredOs + appName];
desiredCaps.name = pkgjson.name;
desiredCaps.name = pkgjson.name + ` (${desiredOs})`;
desiredCaps.app = desiredApp;
return desiredCaps;
@@ -57,7 +60,7 @@ describe('Advanced HTTP', function() {
const validateResult = testDefinition => driver
.safeExecute('app.lastResult')
.then(result => testDefinition.validationFunc(driver, result));
.then(result => testDefinition.validationFunc(driver, result, targetInfo));
const clickNext = () => driver
.elementById('nextBtn')
+95 -14
View File
@@ -6,7 +6,30 @@ const hooks = {
const helpers = {
acceptAllCerts: function(done) { cordova.plugin.http.acceptAllCerts(true, done, done); },
setJsonSerializer: function(done) { done(cordova.plugin.http.setDataSerializer('json')); }
setJsonSerializer: function(done) { done(cordova.plugin.http.setDataSerializer('json')); },
getWithXhr: function(done, url) {
var xhr = new XMLHttpRequest();
xhr.addEventListener('load', function() {
done(this.responseText);
});
xhr.open('GET', url);
xhr.send();
},
writeToFile: function (done, fileName, content) {
window.resolveLocalFileSystemURL(cordova.file.cacheDirectory, function (directoryEntry) {
directoryEntry.getFile(fileName, { create: true, exclusive: false }, function (fileEntry) {
fileEntry.createWriter(function (fileWriter) {
var blob = new Blob([ content ], { type: 'text/plain' });
fileWriter.onwriteend = done;
fileWriter.onerror = done;
fileWriter.write(blob);
}, done);
}, done);
}, done);
}
};
const tests = [
@@ -14,41 +37,41 @@ const tests = [
description: 'should reject self signed cert (GET)',
expected: 'rejected: {"status":-1,"error":"cancelled"}',
func: function(resolve, reject) { cordova.plugin.http.get('https://self-signed.badssl.com/', {}, {}, resolve, reject); },
validationFunc: function(driver, result) {
validationFunc: function(driver, result, targetInfo) {
result.type.should.be.equal('rejected');
result.data.should.be.eql({ status: -1, error:'cancelled' });
result.data.should.be.eql({ status: -1, error: targetInfo.isAndroid ? 'SSL handshake failed' : 'cancelled' });
}
},{
description: 'should reject self signed cert (PUT)',
expected: 'rejected: {"status":-1,"error":"cancelled"}',
func: function(resolve, reject) { cordova.plugin.http.put('https://self-signed.badssl.com/', { test: 'testString' }, {}, resolve, reject); },
validationFunc: function(driver, result) {
validationFunc: function(driver, result, targetInfo) {
result.type.should.be.equal('rejected');
result.data.should.be.eql({ status: -1, error:'cancelled' });
result.data.should.be.eql({ status: -1, error: targetInfo.isAndroid ? 'SSL handshake failed' : 'cancelled' });
}
},{
description: 'should reject self signed cert (POST)',
expected: 'rejected: {"status":-1,"error":"cancelled"}',
func: function(resolve, reject) { cordova.plugin.http.post('https://self-signed.badssl.com/', { test: 'testString' }, {}, resolve, reject); },
validationFunc: function(driver, result) {
validationFunc: function(driver, result, targetInfo) {
result.type.should.be.equal('rejected');
result.data.should.be.eql({ status: -1, error:'cancelled' });
result.data.should.be.eql({ status: -1, error: targetInfo.isAndroid ? 'SSL handshake failed' : 'cancelled' });
}
},{
description: 'should reject self signed cert (PATCH)',
expected: 'rejected: {"status":-1,"error":"cancelled"}',
func: function(resolve, reject) { cordova.plugin.http.patch('https://self-signed.badssl.com/', { test: 'testString' }, {}, resolve, reject); },
validationFunc: function(driver, result) {
validationFunc: function(driver, result, targetInfo) {
result.type.should.be.equal('rejected');
result.data.should.be.eql({ status: -1, error:'cancelled' });
result.data.should.be.eql({ status: -1, error: targetInfo.isAndroid ? 'SSL handshake failed' : 'cancelled' });
}
},{
description: 'should reject self signed cert (DELETE)',
expected: 'rejected: {"status":-1,"error":"cancelled"}',
func: function(resolve, reject) { cordova.plugin.http.delete('https://self-signed.badssl.com/', {}, {}, resolve, reject); },
validationFunc: function(driver, result) {
validationFunc: function(driver, result, targetInfo) {
result.type.should.be.equal('rejected');
result.data.should.be.eql({ status: -1, error:'cancelled' });
result.data.should.be.eql({ status: -1, error: targetInfo.isAndroid ? 'SSL handshake failed' : 'cancelled' });
}
},{
description: 'should accept bad cert (GET)',
@@ -132,7 +155,7 @@ const tests = [
JSON.parse(result.data.data).json.should.eql({ test: 'testString' });
}
},{
description: 'should send JSON array correctly (POST)',
description: 'should send JSON array correctly (POST) #26',
expected: 'resolved: {"status": 200, data: "[ 1, 2, 3 ]\" ...',
before: helpers.setJsonSerializer,
func: function(resolve, reject) { cordova.plugin.http.post('http://httpbin.org/anything', [ 1, 2, 3 ], {}, resolve, reject); },
@@ -141,7 +164,7 @@ const tests = [
JSON.parse(result.data.data).json.should.eql([ 1, 2, 3 ]);
}
},{
description: 'should send JSON array correctly (PUT)',
description: 'should send JSON array correctly (PUT) #26',
expected: 'resolved: {"status": 200, data: "[ 1, 2, 3 ]\" ...',
before: helpers.setJsonSerializer,
func: function(resolve, reject) { cordova.plugin.http.put('http://httpbin.org/anything', [ 1, 2, 3 ], {}, resolve, reject); },
@@ -150,14 +173,72 @@ const tests = [
JSON.parse(result.data.data).json.should.eql([ 1, 2, 3 ]);
}
},{
description: 'should send JSON array correctly (PATCH)',
description: 'should send JSON array correctly (PATCH) #26',
expected: 'resolved: {"status": 200, data: "[ 1, 2, 3 ]\" ...',
before: helpers.setJsonSerializer,
func: function(resolve, reject) { cordova.plugin.http.patch('http://httpbin.org/anything', [ 1, 2, 3 ], {}, resolve, reject); },
validationFunc: function(driver, result) {
result.type.should.be.equal('resolved');
result.data.data.should.be.a('string');
JSON.parse(result.data.data).json.should.eql([ 1, 2, 3 ]);
}
},{
description: 'should resolve correct URL after redirect (GET) #33',
expected: 'resolved: {"status": 200, url: "http://httpbin.org/anything", ...',
func: function(resolve, reject) { cordova.plugin.http.get('http://httpbin.org/redirect-to?url=http://httpbin.org/anything', {}, {}, resolve, reject); },
validationFunc: function(driver, result) {
result.type.should.be.equal('resolved');
result.data.url.should.be.equal('http://httpbin.org/anything');
}
},{
description: 'should download a file from given URL to given path in local filesystem',
expected: 'resolved: {"content": "<?xml version=\'1.0\' encoding=\'us-ascii\'?>\\n\\n<!-- A SAMPLE set of slides -->" ...',
func: function(resolve, reject) {
var sourceUrl = 'http://httpbin.org/xml';
var targetPath = cordova.file.cacheDirectory + 'test.xml';
cordova.plugin.http.downloadFile(sourceUrl, {}, {}, targetPath, function(entry) {
helpers.getWithXhr(function(content) {
resolve({
sourceUrl: sourceUrl,
targetPath: targetPath,
fullPath: entry.fullPath,
name: entry.name,
content: content
});
}, targetPath);
}, reject);
},
validationFunc: function(driver, result) {
result.type.should.be.equal('resolved');
result.data.name.should.be.equal('test.xml');
result.data.content.should.be.equal("<?xml version='1.0' encoding='us-ascii'?>\n\n<!-- A SAMPLE set of slides -->\n\n<slideshow \n title=\"Sample Slide Show\"\n date=\"Date of publication\"\n author=\"Yours Truly\"\n >\n\n <!-- TITLE SLIDE -->\n <slide type=\"all\">\n <title>Wake up to WonderWidgets!</title>\n </slide>\n\n <!-- OVERVIEW -->\n <slide type=\"all\">\n <title>Overview</title>\n <item>Why <em>WonderWidgets</em> are great</item>\n <item/>\n <item>Who <em>buys</em> WonderWidgets</item>\n </slide>\n\n</slideshow>");
}
},{
description: 'should upload a file from given path in local filesystem to given URL #27',
expected: 'resolved: {"status": 200, "data": "files": {"test-file.txt": "I am a dummy file. I am used ...',
func: function(resolve, reject) {
var fileName = 'test-file.txt';
var fileContent = 'I am a dummy file. I am used for testing purposes!';
var sourcePath = cordova.file.cacheDirectory + fileName;
var targetUrl = 'http://httpbin.org/post';
helpers.writeToFile(function() {
cordova.plugin.http.uploadFile(targetUrl, {}, {}, sourcePath, fileName, resolve, reject);
}, fileName, fileContent);
},
validationFunc: function(driver, result) {
var fileName = 'test-file.txt';
var fileContent = 'I am a dummy file. I am used for testing purposes!';
result.type.should.be.equal('resolved');
result.data.data.should.be.a('string');
JSON
.parse(result.data.data)
.files[fileName]
.should.be.equal(fileContent);
}
}
];
+6 -6
View File
@@ -29,17 +29,17 @@ describe('Advanced HTTP www interface', function() {
http.headers['*'].myKey.should.equal('myValue');
});
it('sets global headers correctly with three args (new interface)', () => {
it('sets global headers correctly with three args (new interface) #24', () => {
http.setHeader('*', 'myKey', 'myValue');
http.headers['*'].myKey.should.equal('myValue');
});
it('sets host headers correctly', () => {
it('sets host headers correctly #24', () => {
http.setHeader('www.google.de', 'myKey', 'myValue');
http.headers['www.google.de'].myKey.should.equal('myValue');
});
it('resolves global headers correctly', () => {
it('resolves global headers correctly #24', () => {
mock(`${PLUGIN_ID}.cookie-handler`, {
getCookieString: () => 'fakeCookieString'
});
@@ -58,7 +58,7 @@ describe('Advanced HTTP www interface', function() {
http.get('url', {}, {}, noop, noop);
});
it('resolves host headers correctly (set without port number)', () => {
it('resolves host headers correctly (set without port number) #37', () => {
mock(`${PLUGIN_ID}.cookie-handler`, {
getCookieString: () => 'fakeCookieString'
});
@@ -77,7 +77,7 @@ describe('Advanced HTTP www interface', function() {
http.get('https://www.google.de/?gws_rd=ssl', {}, {}, noop, noop);
});
it('resolves host headers correctly (set with port number)', () => {
it('resolves host headers correctly (set with port number) #37', () => {
mock(`${PLUGIN_ID}.cookie-handler`, {
getCookieString: () => 'fakeCookieString'
});
@@ -114,7 +114,7 @@ describe('Advanced HTTP www interface', function() {
http.get('https://www.google.de/?gws_rd=ssl', {}, { myKey: 'myValue' }, noop, noop);
});
it('sets basic authentication header correctly', () => {
it('sets basic authentication header correctly #36', () => {
http.useBasicAuth('name', 'pass');
http.headers['*'].Authorization.should.equal('Basic bmFtZTpwYXNz');
});