diff --git a/CHANGELOG.md b/CHANGELOG.md index 5fd06ee15..db686863c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,13 @@ Changelog ========= + +2.2.0 +----------------- +- Added Upload Multipart form-data (removed Jersey dependency) +- Added Business stakeholder status transitions (get, list) +- Added Bank Account status transitions (get) + + 2.1.0 ----------------- - Added Business Stakeholders status transitions diff --git a/README.md b/README.md index 6c16c1d1a..8d747054d 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ [![Coverage Status](https://coveralls.io/repos/github/hyperwallet/java-sdk/badge.svg?branch=master)](https://coveralls.io/github/hyperwallet/java-sdk?branch=master) [![Maven Central](https://img.shields.io/maven-central/v/com.hyperwallet/sdk.svg)]() -Hyperwallet REST SDK v2.1.0 +Hyperwallet REST SDK v2.2.0 =========================== A library to manage users, transfer methods and payments through the Hyperwallet V4 API @@ -22,13 +22,13 @@ Installation com.hyperwallet sdk - 2.1.0 + 2.2.0 ``` **Gradle** ``` -compile 'com.hyperwallet:sdk:2.1.0' +compile 'com.hyperwallet:sdk:2.2.0' ``` Documentation @@ -44,7 +44,7 @@ To write an app using the SDK * Register for a sandbox account and get your username, password and program token at the [Hyperwallet Program Portal](https://portal.hyperwallet.com). -* Add dependency `com.hyperwallet:sdk:2.1.0` to your `pom.xml` (or `build.gradle`). +* Add dependency `com.hyperwallet:sdk:2.2.0` to your `pom.xml` (or `build.gradle`). * Create a instance of the Hyperwallet Client (with username, password and program token) diff --git a/pom.xml b/pom.xml index aaf8c21f7..362c4a354 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ com.hyperwallet sdk - 2.1.1-SNAPSHOT + 2.2.0-SNAPSHOT jar hyperwallet-java-sdk @@ -148,16 +148,6 @@ test 20200518 - - com.sun.jersey.contribs - jersey-multipart - 1.19.4 - - - com.sun.jersey - jersey-client - 1.18 - diff --git a/src/main/java/com/hyperwallet/clientsdk/Hyperwallet.java b/src/main/java/com/hyperwallet/clientsdk/Hyperwallet.java index aa740e870..7f529b9cb 100644 --- a/src/main/java/com/hyperwallet/clientsdk/Hyperwallet.java +++ b/src/main/java/com/hyperwallet/clientsdk/Hyperwallet.java @@ -2,25 +2,20 @@ import com.fasterxml.jackson.core.type.TypeReference; import com.hyperwallet.clientsdk.model.*; -import com.hyperwallet.clientsdk.util.HyperwalletApiClient; -import com.hyperwallet.clientsdk.util.HyperwalletEncryption; -import com.hyperwallet.clientsdk.util.HyperwalletJsonUtil; -import com.sun.jersey.multipart.FormDataMultiPart; +import com.hyperwallet.clientsdk.util.*; import org.apache.commons.lang3.StringUtils; +import java.io.IOException; import java.text.DateFormat; import java.text.SimpleDateFormat; -import java.util.Date; -import java.util.HashMap; -import java.util.Locale; -import java.util.TimeZone; +import java.util.*; /** * The Hyperwallet Client */ public class Hyperwallet { - public static final String VERSION = "2.0.0"; + public static final String VERSION = "2.2.0"; private final HyperwalletApiClient apiClient; private final String programToken; private final String url; @@ -241,18 +236,31 @@ public HyperwalletList listBusinessStakeholders( * * @param userToken String * @param businessStakeholderToken Hyperwallet Stakeholder representation - * @param multiPart FormdataMultipart to get uploaded + * @param uploadData HyperwalletVerificationDocument to get uploaded * @return HyperwalletBusinessStakeholder updated Stakeholder with document status */ - public HyperwalletBusinessStakeholder uploadDocumentBusinessStakeholder(String userToken, String businessStakeholderToken, - FormDataMultiPart multiPart) { + public HyperwalletBusinessStakeholder uploadStakeholderDocuments(String userToken, String businessStakeholderToken, + List uploadData) { + Multipart multipart = new Multipart(); if (userToken == null) { throw new HyperwalletException("User token may not be present"); } if (businessStakeholderToken == null) { - throw new HyperwalletException("BusinessStakeholderToken may not be required"); + throw new HyperwalletException("BusinessStakeholderToken may not be present"); } - return apiClient.put(url + "/users/" + userToken + "/business-stakeholders/" + businessStakeholderToken, multiPart, + if (uploadData == null || uploadData.size() < 1) { + throw new HyperwalletException("Data for upload is missing"); + } + if (uploadData.get(0).getUploadFiles() == null || uploadData.get(0).getUploadFiles().size() < 1) { + throw new HyperwalletException("Upload Files are missing"); + } + try { + multipart = HyperwalletMultipartUtils.convert(uploadData); + } catch(IOException e) { + throw new HyperwalletException("Unable to convert to Multipart formdata"); + } + + return apiClient.put(url + "/users/" + userToken + "/business-stakeholders/" + businessStakeholderToken, multipart, HyperwalletBusinessStakeholder.class); } @@ -280,18 +288,76 @@ public HyperwalletStatusTransition createBusinessStakeholderStatusTransition(Str transition.setFromStatus(null); transition.setToStatus(null); - return apiClient.post(url + "/users/" + userToken + "/business-stakeholders/" + stakeholderToken + "/status-transitions", transition, HyperwalletStatusTransition.class); + return apiClient.post(url + "/users/" + userToken + "/business-stakeholders/" + stakeholderToken + "/status-transitions", transition, + HyperwalletStatusTransition.class); + } + + /** + * Get Business Stakeholder Status transition + * + * @param userToken String + * @param stakeholderToken Hyperwallet Stakeholder token + * @param statusTransitionToken Hyperwallet Status Transition token + * @return HyperwalletStatusTransition + */ + public HyperwalletStatusTransition getBusinessStakeholderStatusTransition(String userToken, String stakeholderToken, + String statusTransitionToken) { + if (userToken == null) { + throw new HyperwalletException("User token may not be present"); + } + if (stakeholderToken == null) { + throw new HyperwalletException("StakeholderToken is required"); + } + if (statusTransitionToken == null) { + throw new HyperwalletException("Status Transition token may not be present"); + } + + return apiClient + .get(url + "/users/" + userToken + "/business-stakeholders/" + stakeholderToken + "/status-transitions/" + statusTransitionToken, + HyperwalletStatusTransition.class); + } + + /** + * List Business Stakeholder Status transition + * + * @param userToken String + * @param stakeholderToken Hyperwallet Stakeholder token + * @return HyperwalletList of HyperwalletStatusTransition + */ + public HyperwalletList listBusinessStakeholderStatusTransition(String userToken, String stakeholderToken, + HyperwalletPaginationOptions options) { + if (userToken == null) { + throw new HyperwalletException("User token may not be present"); + } + if (stakeholderToken == null) { + throw new HyperwalletException("StakeholderToken is required"); + } + String url = paginate(this.url + "/users/" + userToken + "/business-stakeholders/" + stakeholderToken + "/status-transitions", options); + return apiClient.get(url, new TypeReference>() { + }); + } + + /** + * List Business Stakeholder Status transition + * + * @param userToken String + * @param stakeholderToken Hyperwallet Stakeholder token + * @return HyperwalletList of HyperwalletStatusTransition + */ + public HyperwalletList listBusinessStakeholderStatusTransition(String userToken, String stakeholderToken) { + return listBusinessStakeholderStatusTransition(userToken, stakeholderToken, null); } /** * Activate a business stakeholder * - * @param userToken User token + * @param userToken User token * @param stakeholderToken Business Stakeholder token * @return The status transition */ public HyperwalletStatusTransition activateBusinessStakeholder(String userToken, String stakeholderToken) { - return createBusinessStakeholderStatusTransition(userToken, stakeholderToken, new HyperwalletStatusTransition(HyperwalletStatusTransition.Status.ACTIVATED)); + return createBusinessStakeholderStatusTransition(userToken, stakeholderToken, + new HyperwalletStatusTransition(HyperwalletStatusTransition.Status.ACTIVATED)); } /** @@ -1847,7 +1913,30 @@ public HyperwalletStatusTransition createBankAccountStatusTransition(String user transition.setCreatedOn(null); transition.setFromStatus(null); transition.setToStatus(null); - return apiClient.post(url + "/users/" + userToken + "/bank-accounts/" + bankAccountToken + "/status-transitions", transition, HyperwalletStatusTransition.class); + return apiClient.post(url + "/users/" + userToken + "/bank-accounts/" + bankAccountToken + "/status-transitions", transition, + HyperwalletStatusTransition.class); + } + + /** + * Get Bank Account Status Transition + * + * @param userToken User token + * @param bankAccountToken Bank Account token + * @param statusTransitionToken Status transition token + * @return HyperwalletStatusTransition + */ + public HyperwalletStatusTransition getBankAccountStatusTransition(String userToken, String bankAccountToken, String statusTransitionToken) { + if (StringUtils.isEmpty(userToken)) { + throw new HyperwalletException("User token is required"); + } + if (StringUtils.isEmpty(bankAccountToken)) { + throw new HyperwalletException("Bank Account token is required"); + } + if (StringUtils.isEmpty(statusTransitionToken)) { + throw new HyperwalletException("Status Transition token may not be present"); + } + return apiClient.get(url + "/users/" + userToken + "/bank-accounts/" + bankAccountToken + "/status-transitions/" + statusTransitionToken, + HyperwalletStatusTransition.class); } /** @@ -2451,14 +2540,26 @@ public HyperwalletList listTransferMethods(String use * Upload documents * * @param userToken userToken for which documents to be uploaded - * @param multiPart multipart FormdataMultipart to get uploaded + * @param uploadData HyperwalletVerificationDocument to get uploaded * @return HyperwalletUser user object with document upload status */ - public HyperwalletUser documentUpload(String userToken, FormDataMultiPart multiPart) { + public HyperwalletUser uploadUserDocuments(String userToken, List uploadData) { + Multipart multipart = new Multipart(); if (StringUtils.isEmpty(userToken)) { throw new HyperwalletException("User token is not present"); } - return apiClient.put(url + "/users/" + userToken, multiPart, HyperwalletUser.class); + if (uploadData == null || uploadData.size() < 1) { + throw new HyperwalletException("Data for upload is missing"); + } + if (uploadData.get(0).getUploadFiles() == null || uploadData.get(0).getUploadFiles().size() < 1) { + throw new HyperwalletException("Upload Files are missing"); + } + try { + multipart = HyperwalletMultipartUtils.convert(uploadData); + } catch(IOException e) { + throw new HyperwalletException("Unable to convert to Multipart formdata"); + } + return apiClient.put(url + "/users/" + userToken, multipart, HyperwalletUser.class); } //-------------------------------------- diff --git a/src/main/java/com/hyperwallet/clientsdk/model/HyperwalletDocument.java b/src/main/java/com/hyperwallet/clientsdk/model/HyperwalletDocument.java deleted file mode 100644 index 3b0391960..000000000 --- a/src/main/java/com/hyperwallet/clientsdk/model/HyperwalletDocument.java +++ /dev/null @@ -1,120 +0,0 @@ -package com.hyperwallet.clientsdk.model; - -import com.fasterxml.jackson.annotation.JsonFilter; -import com.hyperwallet.clientsdk.util.HyperwalletJsonConfiguration; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlRootElement; - -@JsonFilter(HyperwalletJsonConfiguration.INCLUSION_FILTER) -@XmlRootElement -@XmlAccessorType(XmlAccessType.FIELD) -public class HyperwalletDocument { - - public static enum EIdentityVerificationType { - DRIVERS_LICENSE, - PASSPORT, - GOVERNMENT_ID, - UTILITY_BILL, - BIRTH_CERTIFICATE, - BANK_STATEMENT, - TAX_RETURN, - OTHER, - ACCOUNT_OPENING_LETTER, - PASS_SAVINGS_BOOK, - BANK_CARD, - CREDIT_CARD_STATEMENT, - OFFICIAL_GOVERNMENT_LETTER, - PROPERTY_TAX_ASSESSMENT, - BUSINESS_REGISTRATION, - INCORPORATION, - OPERATING_AGREEMENT, - LETTER_OF_AUTHORIZATION - } - - public static enum EDocumentCategory { - ADDRESS, - IDENTIFICATION, - BUSINESS, - AUTHORIZATION - } - - public static enum ECountryCode { - AD, AE, AF, AG, AI, AL, AM, AN, AO, AQ, AR, AS, AT, AU, AW, AX, AZ, BA, BB, BD, BE, BF, BG, BH, BI, BJ, BL, BM, BN, BO, BQ, BR, BS, BT, BV, - BW, BY, BZ, CA, CC, CD, CF, CG, CH, CI, CK, CL, CM, CN, CO, CR, CU, CV, CW, CX, CY, CZ, DE, DJ, DK, DM, DO, DZ, EC, EE, EG, EH, ER, ES, ET, - FI, FJ, FK, FM, FO, FR, FX, GA, GB, GD, GE, GF, GG, GH, GI, GL, GM, GN, GP, GQ, GR, GS, GT, GU, GW, GY, HK, HM, HN, HR, HT, HU, ID, IE, IL, - IM, IN, IO, IQ, IR, IS, IT, JE, JM, JO, JP, KE, KG, KH, KI, KM, KN, KP, KR, KW, KY, KZ, LA, LB, LC, LI, LK, LR, LS, LT, LU, LV, LY, MA, MC, - MD, ME, MF, MG, MH, MK, ML, MM, MN, MO, MP, MQ, MR, MS, MT, MU, MV, MW, MX, MY, MZ, NA, NC, NE, NF, NG, NI, NL, NO, NP, NR, NU, NZ, OM, PA, - PE, PF, PG, PH, PK, PL, PM, PN, PR, PS, PT, PW, PY, QA, RE, RO, RS, RU, RW, SA, SB, SC, SD, SE, SG, SH, SI, SJ, SK, SL, SM, SN, SO, SR, SS, - ST, SV, SX, SY, SZ, TC, TD, TF, TG, TH, TJ, TK, TL, TM, TN, TO, TR, TT, TV, TW, TZ, UA, UG, UM, US, UY, UZ, VA, VC, VE, VG, VI, VN, VU, WF, - WS, XK, YE, YT, YU, ZA, ZM, _O, ZW - } - - public enum EKycDocumentVerificationStatus { - VERIFIED, - INVALID, - NEW - } - - private EDocumentCategory category; - - private EIdentityVerificationType type; - - private ECountryCode country; - - private EKycDocumentVerificationStatus status; - - public EDocumentCategory getCategory() { - return category; - } - - public void setCategory(EDocumentCategory category) { - this.category = category; - } - - public HyperwalletDocument category(EDocumentCategory category) { - setCategory(category); - return this; - } - - public EIdentityVerificationType getType() { - return type; - } - - public void setType(EIdentityVerificationType type) { - this.type = type; - } - - public HyperwalletDocument type(EIdentityVerificationType type) { - setType(type); - return this; - } - - public ECountryCode getCountry() { - return country; - } - - public void setCountry(ECountryCode country) { - this.country = country; - } - - public HyperwalletDocument country(ECountryCode country) { - setCountry(country); - return this; - } - - public EKycDocumentVerificationStatus getStatus() { - return status; - } - - public void setStatus(EKycDocumentVerificationStatus status) { - this.status = status; - } - - public HyperwalletDocument status(EKycDocumentVerificationStatus status) { - setStatus(status); - return this; - } - -} diff --git a/src/main/java/com/hyperwallet/clientsdk/model/HyperwalletUser.java b/src/main/java/com/hyperwallet/clientsdk/model/HyperwalletUser.java index 8bf3b915f..83e8b84e7 100644 --- a/src/main/java/com/hyperwallet/clientsdk/model/HyperwalletUser.java +++ b/src/main/java/com/hyperwallet/clientsdk/model/HyperwalletUser.java @@ -75,7 +75,7 @@ public static enum GovernmentIdType {PASSPORT, NATIONAL_ID_CARD} private String language; private String programToken; private String timeZone; - private List documents; + private List documents; private List links; public String getToken() { @@ -900,16 +900,16 @@ public HyperwalletUser clearTimeZone() { return this; } - public List getDocuments() { + public List getDocuments() { return documents; } - public void setDocuments(List documents) { + public void setDocuments(List documents) { addField("documents", documents); this.documents = documents; } - public HyperwalletUser documents(List documents) { + public HyperwalletUser documents(List documents) { addField("documents", documents); this.documents = documents; return this; diff --git a/src/main/java/com/hyperwallet/clientsdk/model/HyperwalletVerificationDocument.java b/src/main/java/com/hyperwallet/clientsdk/model/HyperwalletVerificationDocument.java index caa3ee209..d3df7b79e 100644 --- a/src/main/java/com/hyperwallet/clientsdk/model/HyperwalletVerificationDocument.java +++ b/src/main/java/com/hyperwallet/clientsdk/model/HyperwalletVerificationDocument.java @@ -8,6 +8,7 @@ import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlRootElement; +import java.util.Map; @JsonFilter(HyperwalletJsonConfiguration.INCLUSION_FILTER) @XmlRootElement @@ -23,6 +24,8 @@ private String country; + public Map uploadFiles; + public String getCategory() { return category; } @@ -74,4 +77,17 @@ public HyperwalletVerificationDocument country(String country) { setCountry(country); return this; } + + public Map getUploadFiles() { + return uploadFiles; + } + + public void setUploadFiles(Map uploadFiles) { + this.uploadFiles = uploadFiles; + } + + public HyperwalletVerificationDocument uploadFiles(Map uploadFiles) { + setUploadFiles(uploadFiles); + return this; + } } diff --git a/src/main/java/com/hyperwallet/clientsdk/util/HyperwalletApiClient.java b/src/main/java/com/hyperwallet/clientsdk/util/HyperwalletApiClient.java index 2522a85ab..de3d1c9af 100644 --- a/src/main/java/com/hyperwallet/clientsdk/util/HyperwalletApiClient.java +++ b/src/main/java/com/hyperwallet/clientsdk/util/HyperwalletApiClient.java @@ -6,34 +6,25 @@ import com.hyperwallet.clientsdk.HyperwalletException; import com.hyperwallet.clientsdk.model.HyperwalletErrorList; import com.nimbusds.jose.JOSEException; -import com.sun.jersey.api.client.Client; -import com.sun.jersey.api.client.ClientResponse; -import com.sun.jersey.api.client.WebResource; -import com.sun.jersey.api.client.config.ClientConfig; -import com.sun.jersey.api.client.config.DefaultClientConfig; -import com.sun.jersey.api.client.filter.HTTPBasicAuthFilter; -import com.sun.jersey.multipart.FormDataMultiPart; -import com.sun.jersey.multipart.impl.MultiPartWriter; - -import javax.ws.rs.core.MediaType; + import javax.xml.bind.DatatypeConverter; import java.io.IOException; import java.text.ParseException; import java.util.HashMap; +import java.util.UUID; public class HyperwalletApiClient { private static final String CONTENT_TYPE_HEADER = "Content-Type"; private static final String VALID_JSON_CONTENT_TYPE = "application/json"; private static final String VALID_JSON_JOSE_CONTENT_TYPE = "application/jose+json"; - + private static final String SDK_TYPE = "java"; private final String username; private final String password; private final String version; private final HyperwalletEncryption hyperwalletEncryption; private final boolean isEncrypted; - private WebResource webResource; - private Client client; + private final String contextId; public HyperwalletApiClient(final String username, final String password, final String version) { this(username, password, version, null); @@ -46,9 +37,7 @@ public HyperwalletApiClient(final String username, final String password, final this.version = version; this.hyperwalletEncryption = hyperwalletEncryption; this.isEncrypted = hyperwalletEncryption != null; - ClientConfig cc = new DefaultClientConfig(); - cc.getClasses().add(MultiPartWriter.class); - client = Client.create(cc); + this.contextId = String.valueOf(UUID.randomUUID()); // TLS fix if (System.getProperty("java.version").startsWith("1.7.")) { @@ -76,19 +65,10 @@ public T get(final String url, final TypeReference type) { } } - private WebResource getWebResource(final String url) { - client.addFilter(new HTTPBasicAuthFilter(this.username, this.password)); - return client.resource(url); - } - - public T put(final String url, final FormDataMultiPart formDataMultiPart, final Class type) { - Response response = new Response(); + public T put(final String url, Multipart uploadData, final Class type) { + Response response = null; try { - webResource = getWebResource(url); - ClientResponse clientResponse = webResource.type(MediaType.MULTIPART_FORM_DATA_TYPE).put(ClientResponse.class, formDataMultiPart); - response.setResponseCode(clientResponse.getStatus()); - response.setBody(clientResponse.getEntity(String.class)); - response.setHeaders(clientResponse.getHeaders()); + response = getMultipartService(url, uploadData).putResource(); return processResponse(response, type); } catch (IOException | JOSEException | ParseException e) { throw new HyperwalletException(e); @@ -182,25 +162,24 @@ private void checkResponseHeader(Response response) { } private String getAuthorizationHeader() { - final String pair = this.username + ":" + this.password; - final String base64 = DatatypeConverter.printBase64Binary(pair.getBytes()); - return "Basic " + base64; + final String pair = this.username + ":" + this.password; + final String base64 = DatatypeConverter.printBase64Binary(pair.getBytes()); + return "Basic " + base64; } private Request getService(final String url, boolean isHttpGet) { String contentType = "application/" + ((isEncrypted) ? "jose+json" : "json"); - if (isHttpGet) { - return new Request(url) - .addHeader("Authorization", getAuthorizationHeader()) - .addHeader("Accept", contentType) - .addHeader("User-Agent", "Hyperwallet Java SDK v" + version); - } else { - return new Request(url) - .addHeader("Authorization", getAuthorizationHeader()) - .addHeader("Accept", contentType) - .addHeader("Content-Type", contentType) - .addHeader("User-Agent", "Hyperwallet Java SDK v" + version); + Request request = new Request(url) + .addHeader("Authorization", getAuthorizationHeader()) + .addHeader("Accept", contentType) + .addHeader("User-Agent", "Hyperwallet Java SDK v" + this.version) + .addHeader("x-sdk-version", this.version) + .addHeader("x-sdk-type", SDK_TYPE) + .addHeader("x-sdk-contextId", this.contextId); + if (!isHttpGet) { + request.addHeader("Content-Type", contentType); } + return request; } private T convert(final String responseBody, final Class type) { @@ -228,4 +207,9 @@ private String decryptResponse(String responseBody) throws ParseException, IOExc } return isEncrypted ? hyperwalletEncryption.decrypt(responseBody) : responseBody; } -} \ No newline at end of file + + private MultipartRequest getMultipartService(String requestURL, Multipart multipartData) + throws IOException { + return new MultipartRequest(requestURL, multipartData, username, password); + } +} diff --git a/src/main/java/com/hyperwallet/clientsdk/util/HyperwalletMultipartUtils.java b/src/main/java/com/hyperwallet/clientsdk/util/HyperwalletMultipartUtils.java new file mode 100644 index 000000000..39db15bd7 --- /dev/null +++ b/src/main/java/com/hyperwallet/clientsdk/util/HyperwalletMultipartUtils.java @@ -0,0 +1,71 @@ +package com.hyperwallet.clientsdk.util; + +import com.hyperwallet.clientsdk.HyperwalletException; +import com.hyperwallet.clientsdk.model.HyperwalletVerificationDocument; +import net.minidev.json.JSONObject; +import org.apache.commons.lang3.StringUtils; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class HyperwalletMultipartUtils { + + public static Multipart convert(List uploadList) throws IOException { + + JSONObject document = new JSONObject(); + Multipart multipartList = new Multipart(); + for (HyperwalletVerificationDocument uploadData : uploadList) { + + addDocumentValue(document, "type", uploadData.getType()); + addDocumentValue(document, "country", uploadData.getCountry()); + addDocumentValue(document, "category", uploadData.getCategory()); + addDocumentValue(document, "status", uploadData.getStatus()); + List documents = new ArrayList<>(); + documents.add(document); + JSONObject data = new JSONObject(); + data.put("documents", documents); + Map multiPartUploadData = new HashMap<>(); + multiPartUploadData.put("data", data.toString()); + + Multipart.MultipartData multipart = new Multipart.MultipartData("Content-Type: application/json" + MultipartRequest.CRLF, + "Content-Disposition: form-data; name=\"" + "data" + "\"" + MultipartRequest.CRLF, + multiPartUploadData); + multipartList.add(multipart); + + for (Map.Entry entry : uploadData.getUploadFiles().entrySet()) { + + Path path = Paths.get(entry.getValue()); + + String fileName = path.getFileName().toString(); + String extension = ""; + int i = fileName.lastIndexOf('.'); + if (i >= 0) { + extension = fileName.substring(i + 1); + } + Map entity = new HashMap<>(); + entity.put(entry.getKey(), entry.getValue()); + Multipart.MultipartData multipart1 = new Multipart.MultipartData("Content-Type: image/" + extension + MultipartRequest.CRLF, + "Content-Disposition: form-data; name=\"" + + entry.getKey() + "\"; filename=\"" + + fileName + "\" " + MultipartRequest.CRLF, + entity ); + multipartList.add(multipart1); + } + } + + return multipartList; + } + + private static void addDocumentValue(JSONObject document, String field, String value) { + if (!StringUtils.isEmpty(value)) { + document.put(field, value); + } + } +} diff --git a/src/main/java/com/hyperwallet/clientsdk/util/Multipart.java b/src/main/java/com/hyperwallet/clientsdk/util/Multipart.java new file mode 100644 index 000000000..abbc55afc --- /dev/null +++ b/src/main/java/com/hyperwallet/clientsdk/util/Multipart.java @@ -0,0 +1,53 @@ +package com.hyperwallet.clientsdk.util; + +import com.hyperwallet.clientsdk.model.HyperwalletVerificationDocument; +import net.minidev.json.JSONObject; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.HashMap; + +public class Multipart { + + List multipartList; + + public List getMultipartList() { + return multipartList; + } + + public void setMultipartList(List multipartList) { + this.multipartList = multipartList; + } + + public void add(MultipartData multipartData) { + if (multipartList == null) { + multipartList = new ArrayList(); + } + multipartList.add(multipartData); + } + + public static class MultipartData { + private final String contentType; //json, img + private final Map entity; //name, content + private final String contentDisposition; + + MultipartData(String contentType, String contentDisposition, Map entity){ + this.contentType = contentType; + this.contentDisposition = contentDisposition; + this.entity = entity; + } + public String getContentType() { + return contentType; + } + + public String getContentDisposition() { + return contentDisposition; + } + + public Map getEntity() { + return entity; + } + + } +} diff --git a/src/main/java/com/hyperwallet/clientsdk/util/MultipartRequest.java b/src/main/java/com/hyperwallet/clientsdk/util/MultipartRequest.java new file mode 100644 index 000000000..c95d5d1f2 --- /dev/null +++ b/src/main/java/com/hyperwallet/clientsdk/util/MultipartRequest.java @@ -0,0 +1,118 @@ +package com.hyperwallet.clientsdk.util; + +import cc.protea.util.http.Request; +import cc.protea.util.http.Response; +import com.hyperwallet.clientsdk.HyperwalletException; + +import javax.xml.bind.DatatypeConverter; +import java.io.*; +import java.net.HttpURLConnection; +import java.net.URL; +import java.nio.file.Files; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + + +public class MultipartRequest extends Request { + private final String BOUNDARY = "--0011010110123111"; + private final String SEPARATOR = "--"; + + private HttpURLConnection connection; + private Multipart multipartList = new Multipart(); + private DataOutputStream outStream; + private Map> headers = new HashMap>(); + private String requestURL; + + private final String username; + private final String password; + public static final String CRLF = "\r\n"; + + public Multipart getMultipartList() { + return multipartList; + } + + public void setMultipartList(Multipart multipartList) { + this.multipartList = multipartList; + } + + MultipartRequest(String url, Multipart multipartList, String username, String password) throws IOException { + super(url); + requestURL = url; + this.username = username; + this.password = password; + this.multipartList = multipartList; + } + + public Response putResource() throws IOException { + Response response = new Response() ; + buildHeaders(); + URL url = new URL(requestURL); + final String pair = username + ":" + password; + final String base64 = DatatypeConverter.printBase64Binary(pair.getBytes()); + connection = (HttpURLConnection) url.openConnection(); + connection.setDoOutput(true); + connection.setRequestMethod("PUT"); + connection.setRequestProperty("authorization", "Basic " + base64); + connection.setRequestProperty("accept", "application/json"); + connection.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + BOUNDARY); + outStream = new DataOutputStream(this.connection.getOutputStream()); + writeMultipartBody(); + outStream.flush(); + outStream.close(); + // checks server's status code first + int status = this.connection.getResponseCode(); + + if (status == HttpURLConnection.HTTP_CREATED) { + InputStream responseStream = new BufferedInputStream(connection.getInputStream()); + BufferedReader responseStreamReader = new BufferedReader(new InputStreamReader(responseStream)); + String line = ""; + StringBuilder stringBuilder = new StringBuilder(); + while ((line = responseStreamReader.readLine()) != null) { + stringBuilder.append(line).append("\n"); + } + responseStreamReader.close(); + response.setResponseCode(status); + response.setBody(stringBuilder.toString()); + response.setHeaders(this.connection.getHeaderFields()); + this.connection.disconnect(); + } else { + throw new HyperwalletException("Server returned non-OK status: " + status + "; Message: " + this.connection.getResponseMessage()); + } + return response; + } + + private void buildHeaders() { + if (!headers.isEmpty()) { + for (Map.Entry> entry : headers.entrySet()) { + for (String value : entry.getValue()) { + connection.addRequestProperty(entry.getKey(), value); + } + } + } + } + + private void writeMultipartBody() throws IOException { + for (Multipart.MultipartData multipartData : multipartList.getMultipartList()) { + for (Map.Entry entry : multipartData.getEntity().entrySet()) { + outStream.writeBytes(this.SEPARATOR + this.BOUNDARY + this.CRLF); + outStream.writeBytes(multipartData.getContentDisposition()); + outStream.writeBytes(multipartData.getContentType()); + outStream.writeBytes(this.CRLF); + + if (multipartData.getContentType().contains("image")) { + byte[] bytes = Files.readAllBytes(new File(entry.getValue().toString()).toPath()); + outStream.write(bytes); + outStream.writeBytes(this.CRLF); + } else { + outStream.writeBytes(entry.getValue() + this.CRLF); + } + outStream.flush(); + } + } + outStream.writeBytes(this.CRLF); + outStream.writeBytes(this.SEPARATOR + this.BOUNDARY + this.SEPARATOR + this.CRLF); + + } +} + diff --git a/src/test/java/com/hyperwallet/clientsdk/HyperwalletIT.java b/src/test/java/com/hyperwallet/clientsdk/HyperwalletIT.java index ef2abc753..45e114b15 100644 --- a/src/test/java/com/hyperwallet/clientsdk/HyperwalletIT.java +++ b/src/test/java/com/hyperwallet/clientsdk/HyperwalletIT.java @@ -18,6 +18,7 @@ import org.testng.annotations.BeforeMethod; import org.testng.annotations.Test; +import java.io.File; import java.io.IOException; import java.text.DateFormat; import java.text.SimpleDateFormat; @@ -2865,6 +2866,42 @@ public void testDeactivateBankAccount() throws Exception { assertEquals(actualHyperwalletLink.getParams(), expectedHyperwalletLink.getParams()); } + @Test + public void testGetBankAccountStatusTransition() throws Exception { + String functionality = "getBankAccountStatusTransition"; + initMockServer(functionality); + + HyperwalletStatusTransition returnValue; + try { + returnValue = client.getBankAccountStatusTransition("usr-f695ef43-9614-4e17-9269-902c234616c3", + "trm-d69300ef-5011-486b-bd2e-bfd8b20fef26", + "sts-1825afa2-61f1-4860-aa69-a65b9d14f556"); + } catch (Exception e) { + mockServer.verify(parseRequest(functionality)); + throw e; + } + List hyperwalletLinks = new ArrayList<>(); + HyperwalletLink hyperwalletLink = new HyperwalletLink(); + hyperwalletLink.setHref( + "https://api.sandbox.hyperwallet.com/rest/v4/users/usr-f695ef43-9614-4e17-9269-902c234616c3/bank-accounts/trm-d69300ef-5011-486b-bd2e" + + "-bfd8b20fef26/status-transitions/sts-1825afa2-61f1-4860-aa69-a65b9d14f556"); + Map mapParams = new HashMap<>(); + mapParams.put("rel", "self"); + hyperwalletLink.setParams(mapParams); + hyperwalletLinks.add(hyperwalletLink); + assertThat(returnValue.getToken(), is(equalTo("sts-1825afa2-61f1-4860-aa69-a65b9d14f556"))); + assertThat(returnValue.getCreatedOn(), is(equalTo(dateFormat.parse("2017-11-16T00:55:57 UTC")))); + assertThat(returnValue.getTransition(), is(equalTo(DE_ACTIVATED))); + assertThat(returnValue.getFromStatus(), is(equalTo(ACTIVATED))); + assertThat(returnValue.getToStatus(), is(equalTo(DE_ACTIVATED))); + assertThat(returnValue.getNotes(), is(equalTo("Closing this account."))); + HyperwalletLink actualHyperwalletLink = returnValue.getLinks().get(0); + HyperwalletLink expectedHyperwalletLink = hyperwalletLinks.get(0); + assertThat(actualHyperwalletLink.getHref(), is(equalTo(expectedHyperwalletLink.getHref()))); + assertEquals(actualHyperwalletLink.getParams(), expectedHyperwalletLink.getParams()); + } + + @Test public void testListBankAccountStatusTransitions() throws Exception { String functionality = "listBankAccountStatusTransitions"; @@ -3005,6 +3042,78 @@ public void testGetProgram() throws Exception { assertEquals(actualHyperwalletLink.getParams(), expectedHyperwalletLink.getParams()); } + // + // Business Stakeholders + // + + @Test + public void testGetBusinessStakeholderStatusTransition() throws Exception { + String functionality = "getBusinessStakeholderStatusTransition"; + initMockServer(functionality); + + HyperwalletStatusTransition returnValue; + try { + returnValue = client.getBusinessStakeholderStatusTransition("usr-9b0e6dfe-c26b-4ddf-9d79-96b332c1dc8a", + "stk-6829da02-7258-4b2b-bcb8-4bb97d4187d2", "sts-16d9ae38-f29f-4360-a1c0-0bceafb12c27"); + } catch (Exception e) { + mockServer.verify(parseRequest(functionality)); + throw e; + } + List hyperwalletLinks = new ArrayList<>(); + HyperwalletLink hyperwalletLink = new HyperwalletLink(); + hyperwalletLink.setHref( + "https://localhost-hyperwallet.aws.paylution.net:8181/rest/v4/users/usr-9b0e6dfe-c26b-4ddf-9d79-96b332c1dc8a/business-stakeholders" + + "/stk-6829da02-7258-4b2b-bcb8-4bb97d4187d2/status-transitions/sts-16d9ae38-f29f-4360-a1c0-0bceafb12c27"); + Map mapParams = new HashMap<>(); + mapParams.put("rel", "self"); + hyperwalletLink.setParams(mapParams); + hyperwalletLinks.add(hyperwalletLink); + assertThat(returnValue.getToken(), is(equalTo("sts-16d9ae38-f29f-4360-a1c0-0bceafb12c27"))); + assertThat(returnValue.getCreatedOn(), is(equalTo(dateFormat.parse("2020-11-13T00:41:03 UTC")))); + assertThat(returnValue.getTransition(), is(equalTo(DE_ACTIVATED))); + assertThat(returnValue.getFromStatus(), is(equalTo(ACTIVATED))); + assertThat(returnValue.getToStatus(), is(equalTo(DE_ACTIVATED))); + HyperwalletLink actualHyperwalletLink = returnValue.getLinks().get(0); + HyperwalletLink expectedHyperwalletLink = hyperwalletLinks.get(0); + assertThat(actualHyperwalletLink.getHref(), is(equalTo(expectedHyperwalletLink.getHref()))); + assertEquals(actualHyperwalletLink.getParams(), expectedHyperwalletLink.getParams()); + } + + @Test + public void testListBusinessStakeholderStatusTransition() throws Exception { + String functionality = "listBusinessStakeholderStatusTransition"; + initMockServer(functionality); + + HyperwalletList returnValue; + try { + returnValue = client.listBusinessStakeholderStatusTransition("usr-f695ef43-9614-4e17-9269-902c234616c3", + "stk-6829da02-7258-4b2b-bcb8-4bb97d4187d2"); + } catch (Exception e) { + mockServer.verify(parseRequest(functionality)); + throw e; + } + List hyperwalletLinks = new ArrayList<>(); + HyperwalletLink hyperwalletLink = new HyperwalletLink(); + hyperwalletLink.setHref( + "https://api.sandbox.hyperwallet.com/rest/v4/users/usr-f695ef43-9614-4e17-9269-902c234616c3/business-stakeholders/stk-6829da02-7258" + + "-4b2b-bcb8-4bb97d4187d2/status-transitions?limit=10"); + Map mapParams = new HashMap<>(); + mapParams.put("rel", "self"); + hyperwalletLink.setParams(mapParams); + hyperwalletLinks.add(hyperwalletLink); + assertThat(returnValue.hasNextPage(), is(equalTo(false))); + assertThat(returnValue.hasPreviousPage(), is(equalTo(false))); + assertThat(returnValue.getLimit(), is(equalTo(10))); + assertThat(returnValue.getData().get(0).getToken(), is(equalTo("sts-1825afa2-61f1-4860-aa69-a65b9d14f556"))); + assertThat(returnValue.getData().get(0).getCreatedOn(), is(equalTo(dateFormat.parse("2017-11-16T00:55:57 UTC")))); + assertThat(returnValue.getData().get(0).getTransition(), is(equalTo(DE_ACTIVATED))); + assertThat(returnValue.getData().get(0).getFromStatus(), is(equalTo(ACTIVATED))); + assertThat(returnValue.getData().get(0).getToStatus(), is(equalTo(DE_ACTIVATED))); + HyperwalletLink actualHyperwalletLink = returnValue.getLinks().get(0); + HyperwalletLink expectedHyperwalletLink = hyperwalletLinks.get(0); + assertThat(actualHyperwalletLink.getHref(), is(equalTo(expectedHyperwalletLink.getHref()))); + assertEquals(actualHyperwalletLink.getParams(), expectedHyperwalletLink.getParams()); + } // // Authentication Token diff --git a/src/test/java/com/hyperwallet/clientsdk/HyperwalletTest.java b/src/test/java/com/hyperwallet/clientsdk/HyperwalletTest.java index d94b5903c..bb88f499b 100644 --- a/src/test/java/com/hyperwallet/clientsdk/HyperwalletTest.java +++ b/src/test/java/com/hyperwallet/clientsdk/HyperwalletTest.java @@ -2,10 +2,6 @@ import com.fasterxml.jackson.core.type.TypeReference; import com.hyperwallet.clientsdk.model.*; -import com.hyperwallet.clientsdk.model.HyperwalletDocument.ECountryCode; -import com.hyperwallet.clientsdk.model.HyperwalletDocument.EDocumentCategory; -import com.hyperwallet.clientsdk.model.HyperwalletDocument.EIdentityVerificationType; -import com.hyperwallet.clientsdk.model.HyperwalletDocument.EKycDocumentVerificationStatus; import com.hyperwallet.clientsdk.model.HyperwalletStatusTransition.Status; import com.hyperwallet.clientsdk.model.HyperwalletTransfer.ForeignExchange; import com.hyperwallet.clientsdk.model.HyperwalletTransferMethod.Type; @@ -14,12 +10,13 @@ import com.hyperwallet.clientsdk.model.HyperwalletUser.LetterOfAuthorizationStatus; import com.hyperwallet.clientsdk.model.HyperwalletUser.VerificationStatus; import com.hyperwallet.clientsdk.util.HyperwalletApiClient; -import com.sun.jersey.multipart.FormDataMultiPart; +import net.minidev.json.JSONObject; import org.mockito.ArgumentCaptor; import org.mockito.Mockito; import org.testng.annotations.DataProvider; import org.testng.annotations.Test; +import java.io.File; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; @@ -29,7 +26,6 @@ import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.*; -import static org.testng.Assert.assertTrue; import static org.testng.Assert.fail; /** @@ -236,6 +232,36 @@ public void testCreateUser_withProgramTokenInUserObject() throws Exception { assertThat(apiClientUser.getLinks(), is(nullValue())); } + @Test + public void testUploadStakeholderDocuments_withError() throws Exception { + try { + Hyperwallet client = new Hyperwallet("test-username", "test-password"); + org.json.JSONObject jsonObject = new org.json.JSONObject(); + jsonObject.put("type", "DRIVERS_LICENSE"); + jsonObject.put("country", "AL"); + jsonObject.put("category", "IDENTIFICATION"); + List jsonObjectList = new ArrayList<>(); + jsonObjectList.add(jsonObject); + org.json.JSONObject jsonObject1 = new org.json.JSONObject(); + jsonObject1.put("documents", jsonObjectList); + HyperwalletVerificationDocument multipartUploadData = new HyperwalletVerificationDocument(); + multipartUploadData.setCategory("IDENTIFICATION"); + multipartUploadData.setType("DRIVERS_LICENSE"); + multipartUploadData.setCountry("US"); + HyperwalletVerificationDocument doc = new HyperwalletVerificationDocument(); + ClassLoader classLoader = getClass().getClassLoader(); + Map multipart = new HashMap(); + multipart.put("drivers_license_front", new File(classLoader.getResource("integration/test.png").toURI()).getAbsolutePath()); + String url = "https://api.sandbox.hyperwallet.com/rest/v4/users/test-user-token/business-stakeholders/test-business-token"; + doc.setUploadFiles(multipart); + List docList = new ArrayList(); + docList.add(doc); + client.uploadStakeholderDocuments("user-token", "stk-token", docList); + } catch (Exception exception) { + assertThat(exception.getMessage(), is("Server returned non-OK status: 401; Message: Unauthorized")); + } + } + @Test public void testGetUser_noUserToken() { Hyperwallet client = new Hyperwallet("test-username", "test-password"); @@ -4484,8 +4510,9 @@ public void testCreateBankAccountStatusTransition_successful() throws Exception ArgumentCaptor argument = ArgumentCaptor.forClass(HyperwalletStatusTransition.class); Mockito.verify(mockApiClient).post(Mockito - .eq("https://api.sandbox.hyperwallet.com/rest/v4/users/test-user-token/bank-accounts/test-bank-account-token/status-transitions"), - argument.capture(), Mockito.eq(transition.getClass())); + .eq("https://api.sandbox.hyperwallet.com/rest/v4/users/test-user-token/bank-accounts/test-bank-account-token/status" + + "-transitions"), + argument.capture(), Mockito.eq(transition.getClass())); HyperwalletStatusTransition apiClientTransition = argument.getValue(); assertThat(apiClientTransition, is(notNullValue())); @@ -4495,6 +4522,73 @@ public void testCreateBankAccountStatusTransition_successful() throws Exception assertThat(apiClientTransition.getCreatedOn(), is(nullValue())); } + @Test + public void testGetBankAccountStatusTransition_noUserToken() { + Hyperwallet client = new Hyperwallet("test-username", "test-password"); + try { + client.getBankAccountStatusTransition(null, null, null); + fail("Expect HyperwalletException"); + } catch (HyperwalletException e) { + assertThat(e.getErrorCode(), is(nullValue())); + assertThat(e.getResponse(), is(nullValue())); + assertThat(e.getErrorMessage(), is(equalTo("User token is required"))); + assertThat(e.getMessage(), is(equalTo("User token is required"))); + assertThat(e.getHyperwalletErrors(), is(nullValue())); + assertThat(e.getRelatedResources(), is(nullValue())); + } + } + + @Test + public void testGetBankAccountStatusTransition_noBankAccountToken() { + Hyperwallet client = new Hyperwallet("test-username", "test-password"); + try { + client.getBankAccountStatusTransition("test-user-token", null, null); + fail("Expect HyperwalletException"); + } catch (HyperwalletException e) { + assertThat(e.getErrorCode(), is(nullValue())); + assertThat(e.getResponse(), is(nullValue())); + assertThat(e.getErrorMessage(), is(equalTo("Bank Account token is required"))); + assertThat(e.getMessage(), is(equalTo("Bank Account token is required"))); + assertThat(e.getHyperwalletErrors(), is(nullValue())); + assertThat(e.getRelatedResources(), is(nullValue())); + } + } + + @Test + public void testGetBankAccountStatusTransition_noTransitionToken() { + Hyperwallet client = new Hyperwallet("test-username", "test-password"); + try { + client.getBankAccountStatusTransition("test-user-token", "test-bank-card-token", null); + fail("Expect HyperwalletException"); + } catch (HyperwalletException e) { + assertThat(e.getErrorCode(), is(nullValue())); + assertThat(e.getResponse(), is(nullValue())); + assertThat(e.getErrorMessage(), is(equalTo("Status Transition token may not be present"))); + assertThat(e.getMessage(), is(equalTo("Status Transition token may not be present"))); + assertThat(e.getHyperwalletErrors(), is(nullValue())); + assertThat(e.getRelatedResources(), is(nullValue())); + } + } + + @Test + public void testGetBankAccountStatusTransition_successful() throws Exception { + HyperwalletStatusTransition transitionResponse = new HyperwalletStatusTransition(); + + Hyperwallet client = new Hyperwallet("test-username", "test-password"); + HyperwalletApiClient mockApiClient = createAndInjectHyperwalletApiClientMock(client); + + Mockito.when(mockApiClient.get(Mockito.anyString(), Mockito.any(Class.class))).thenReturn(transitionResponse); + + HyperwalletStatusTransition resp = + client.getBankAccountStatusTransition("test-user-token", "test-bank-account-token", "test-status-transition-token"); + assertThat(resp, is(equalTo(transitionResponse))); + + Mockito.verify(mockApiClient) + .get("https://api.sandbox.hyperwallet.com/rest/v4/users/test-user-token/bank-accounts/test-bank-account-token/status-transitions" + + "/test-status-transition-token", + transitionResponse.getClass()); + } + @Test public void testListBankAccountStatusTransitions_noParameters_noUserToken() throws Exception { @@ -6860,7 +6954,7 @@ public void testListBusinessStakeholders_withUserTokenNoOptions() throws Excepti } @Test - public void testListBusinessStakeholders_withUserTokenAndOptions() throws Exception { + public void testListStakeholdersDocuments_withNoUserToken() throws Exception { String token = "test-token"; HyperwalletList response = new HyperwalletList(); @@ -6908,6 +7002,7 @@ public void testListBusinessStakeholders_withUserTokenAndSomeOptions() throws Ex } + @Test public void testCreateBusinessStakeholderStatusTransition_noTransition() { Hyperwallet client = new Hyperwallet("test-username", "test-password"); @@ -6976,34 +7071,177 @@ public void testCreateBusinessStakeholderStatusTransition_transitionTokenSpecifi } @Test - public void testCreateBusinessStakeholderStatusTransition_successful() throws Exception { - HyperwalletStatusTransition transition = new HyperwalletStatusTransition(); - transition.setFromStatus(HyperwalletStatusTransition.Status.ACTIVATED); - transition.setToStatus(HyperwalletStatusTransition.Status.DE_ACTIVATED); - transition.setCreatedOn(new Date()); - transition.setTransition(HyperwalletStatusTransition.Status.DE_ACTIVATED); + public void testUploadDocumentBusinessStakeholder_withError() throws Exception { + + Hyperwallet client = new Hyperwallet("test-username", "test-password"); + + String userToken = "user-token"; + String businessStakeholderToken = "business-token"; + HyperwalletBusinessStakeholder hyperwalletBusinessStakeholder = new HyperwalletBusinessStakeholder(); + List hyperwalletVerificationDocumentList = new ArrayList<>(); + HyperwalletVerificationDocument hyperWalletVerificationDocument = new HyperwalletVerificationDocument(); + hyperWalletVerificationDocument.category("IDENTIFICATION").type("DRIVERS_LICENSE").status("NEW").country("AL"); + Map uploadFiles = new HashMap(); + ClassLoader classLoader = getClass().getClassLoader(); + uploadFiles.put("drivers_license_front", new File(classLoader.getResource("integration/test.png").toURI()).getAbsolutePath()); + hyperWalletVerificationDocument.setUploadFiles(uploadFiles); + hyperwalletVerificationDocumentList.add(hyperWalletVerificationDocument); + hyperwalletBusinessStakeholder.setDocuments(hyperwalletVerificationDocumentList); + try { + HyperwalletBusinessStakeholder hyperwalletBusinessStakeholderResponse = + client.uploadStakeholderDocuments(userToken, businessStakeholderToken, hyperwalletVerificationDocumentList); + fail("Expect HyperwalletException"); + } catch (HyperwalletException e) { + assertThat(e.getResponse(), is(nullValue())); + assertThat(e.getErrorMessage(), is(equalTo("Server returned non-OK status: 401; Message: Unauthorized"))); + assertThat(e.getMessage(), startsWith("Server returned non-OK status: 401")); + assertThat(e.getHyperwalletErrors(), is(nullValue())); + } + } + + @Test + public void testGetBusinessStakeholderStatusTransition_noStakeholderToken() { + Hyperwallet client = new Hyperwallet("test-username", "test-password"); + try { + client.getBusinessStakeholderStatusTransition("test-user-token", null, null); + fail("Expect HyperwalletException"); + } catch (HyperwalletException e) { + assertThat(e.getErrorCode(), is(nullValue())); + assertThat(e.getResponse(), is(nullValue())); + assertThat(e.getErrorMessage(), is(equalTo("StakeholderToken is required"))); + assertThat(e.getMessage(), is(equalTo("StakeholderToken is required"))); + assertThat(e.getHyperwalletErrors(), is(nullValue())); + assertThat(e.getRelatedResources(), is(nullValue())); + } + } + @Test + public void testGetBusinessStakeholderStatusTransition_successful() throws Exception { HyperwalletStatusTransition transitionResponse = new HyperwalletStatusTransition(); Hyperwallet client = new Hyperwallet("test-username", "test-password"); HyperwalletApiClient mockApiClient = createAndInjectHyperwalletApiClientMock(client); - Mockito.when(mockApiClient.post(Mockito.anyString(), Mockito.anyObject(), Mockito.any(Class.class))).thenReturn(transitionResponse); + Mockito.when(mockApiClient.get(Mockito.anyString(), Mockito.any(Class.class))).thenReturn(transitionResponse); - HyperwalletStatusTransition resp = client.createBusinessStakeholderStatusTransition("test-user-token", "test-stk-token", transition); + HyperwalletStatusTransition resp = + client.getBusinessStakeholderStatusTransition("test-user-token", "test-stakeholder-token", "test-status-transition-token"); assertThat(resp, is(equalTo(transitionResponse))); + Mockito.verify(mockApiClient) + .get("https://api.sandbox.hyperwallet.com/rest/v4/users/test-user-token/business-stakeholders/test-stakeholder-token/status" + + "-transitions" + + "/test-status-transition-token", + transitionResponse.getClass()); + } - ArgumentCaptor argument = ArgumentCaptor.forClass(HyperwalletStatusTransition.class); - Mockito.verify(mockApiClient).post(Mockito - .eq("https://api.sandbox.hyperwallet.com/rest/v4/users/test-user-token/business-stakeholders/test-stk-token/status-transitions"), - argument.capture(), Mockito.eq(transition.getClass())); + @Test + public void testListBusinessStakeholderStatusTransition_noUserToken() { + Hyperwallet client = new Hyperwallet("test-username", "test-password"); + HyperwalletPaginationOptions options = new HyperwalletPaginationOptions(); - HyperwalletStatusTransition apiClientTransition = argument.getValue(); - assertThat(apiClientTransition, is(notNullValue())); - assertThat(apiClientTransition.getTransition(), is(equalTo(HyperwalletStatusTransition.Status.DE_ACTIVATED))); - assertThat(apiClientTransition.getFromStatus(), is(nullValue())); - assertThat(apiClientTransition.getToStatus(), is(nullValue())); - assertThat(apiClientTransition.getCreatedOn(), is(nullValue())); + try { + client.listBusinessStakeholderStatusTransition(null, null, options); + fail("Expect HyperwalletException"); + } catch (HyperwalletException e) { + assertThat(e.getErrorCode(), is(nullValue())); + assertThat(e.getResponse(), is(nullValue())); + assertThat(e.getErrorMessage(), is(equalTo("User token may not be present"))); + assertThat(e.getMessage(), is(equalTo("User token may not be present"))); + assertThat(e.getHyperwalletErrors(), is(nullValue())); + assertThat(e.getRelatedResources(), is(nullValue())); + } + } + + @Test + public void testListBusinessStakeholderStatusTransition_noStakeholderToken() { + Hyperwallet client = new Hyperwallet("test-username", "test-password"); + HyperwalletPaginationOptions options = new HyperwalletPaginationOptions(); + + try { + client.listBusinessStakeholderStatusTransition("test-user-token", null, options); + fail("Expect HyperwalletException"); + } catch (HyperwalletException e) { + assertThat(e.getErrorCode(), is(nullValue())); + assertThat(e.getResponse(), is(nullValue())); + assertThat(e.getErrorMessage(), is(equalTo("StakeholderToken is required"))); + assertThat(e.getMessage(), is(equalTo("StakeholderToken is required"))); + assertThat(e.getHyperwalletErrors(), is(nullValue())); + assertThat(e.getRelatedResources(), is(nullValue())); + } + } + + @Test + public void testListBusinessStakeholderStatusTransition_withNullOptions() { + Hyperwallet client = new Hyperwallet("test-username", "test-password"); + try { + client.listBusinessStakeholderStatusTransition("test-user-token", null, null); + fail("Expect HyperwalletException"); + } catch (HyperwalletException e) { + assertThat(e.getErrorCode(), is(nullValue())); + assertThat(e.getResponse(), is(nullValue())); + assertThat(e.getErrorMessage(), is(equalTo("StakeholderToken is required"))); + assertThat(e.getMessage(), is(equalTo("StakeholderToken is required"))); + assertThat(e.getHyperwalletErrors(), is(nullValue())); + assertThat(e.getRelatedResources(), is(nullValue())); + } + } + + + @Test + public void testListBusinessStakeholderStatusTransition_successful() throws Exception { + HyperwalletList response = new HyperwalletList(); + + Hyperwallet client = new Hyperwallet("test-username", "test-password"); + HyperwalletApiClient mockApiClient = createAndInjectHyperwalletApiClientMock(client); + + HyperwalletPaginationOptions options = new HyperwalletPaginationOptions(); + options + .sortBy("test-sort-by") + .createdAfter(convertStringToDate("2016-06-29T17:58:26Z")) + .createdBefore(convertStringToDate("2016-06-29T17:58:26Z")); + + Mockito.when(mockApiClient.get(Mockito.anyString(), Mockito.any(TypeReference.class))).thenReturn(response); + + HyperwalletList resp = + client.listBusinessStakeholderStatusTransition("test-user-token", "test-stakeholder-token", options); + assertThat(resp, is(equalTo(response))); + + Mockito.verify(mockApiClient).get(Mockito + .eq("https://api.sandbox.hyperwallet.com/rest/v4/users/test-user-token/business-stakeholders/test-stakeholder-token/status" + + "-transitions?createdAfter=2016-06-29T17:58:26Z&createdBefore=2016-06-29T17:58:26Z&sortBy=test-sort-by"), + Mockito.any(TypeReference.class)); + } + + @Test + public void testGetBusinessStakeholderStatusTransition_noUserToken() { + Hyperwallet client = new Hyperwallet("test-username", "test-password"); + try { + client.getBusinessStakeholderStatusTransition(null, null, null); + fail("Expect HyperwalletException"); + } catch (HyperwalletException e) { + assertThat(e.getErrorCode(), is(nullValue())); + assertThat(e.getResponse(), is(nullValue())); + assertThat(e.getErrorMessage(), is(equalTo("User token may not be present"))); + assertThat(e.getMessage(), is(equalTo("User token may not be present"))); + assertThat(e.getHyperwalletErrors(), is(nullValue())); + assertThat(e.getRelatedResources(), is(nullValue())); + } + } + + @Test + public void testGetBusinessStakeholderStatusTransition_noStatusTransitionToken() { + Hyperwallet client = new Hyperwallet("test-username", "test-password"); + try { + client.getBusinessStakeholderStatusTransition("test-user-token", "test-stakeholder-token", null); + fail("Expect HyperwalletException"); + } catch (HyperwalletException e) { + assertThat(e.getErrorCode(), is(nullValue())); + assertThat(e.getResponse(), is(nullValue())); + assertThat(e.getErrorMessage(), is(equalTo("Status Transition token may not be present"))); + assertThat(e.getMessage(), is(equalTo("Status Transition token may not be present"))); + assertThat(e.getHyperwalletErrors(), is(nullValue())); + assertThat(e.getRelatedResources(), is(nullValue())); + } } @Test @@ -7831,10 +8069,10 @@ public void testUpdateVenmoAccount_successful() throws Exception { } @Test - public void testDocumentUpload_noUserToken() { + public void testUploadUserDocuments_noUserToken() { Hyperwallet client = new Hyperwallet("test-username", "test-password"); try { - client.documentUpload(null, new FormDataMultiPart()); + client.uploadUserDocuments(null, null); fail("Expect HyperwalletException"); } catch (HyperwalletException e) { assertThat(e.getErrorCode(), is(nullValue())); @@ -7847,37 +8085,92 @@ public void testDocumentUpload_noUserToken() { } @Test - public void testDocumentUpload_successful() throws Exception { + public void testUploadUserDocuments_successful() throws Exception { Hyperwallet client = new Hyperwallet("test-username", "test-password"); HyperwalletUser hyperwalletUser = new HyperwalletUser(); - HyperwalletDocument hyperwalletDocument = - new HyperwalletDocument(); - hyperwalletDocument.category(EDocumentCategory.AUTHORIZATION) - .type(EIdentityVerificationType.LETTER_OF_AUTHORIZATION) - .country(ECountryCode.CA).status(EKycDocumentVerificationStatus.NEW); - List hyperwalletDocumentList = new ArrayList<>(); + HyperwalletVerificationDocument hyperwalletDocument = + new HyperwalletVerificationDocument(); + hyperwalletDocument.category("IDENTIFICATION"); + hyperwalletDocument.type("DRIVERS_LICENSE"); + hyperwalletDocument.country("US"); + + List hyperwalletDocumentList = new ArrayList<>(); hyperwalletDocumentList.add(hyperwalletDocument); hyperwalletUser.setDocuments(hyperwalletDocumentList); - HyperwalletApiClient mockApiClient = createAndInjectHyperwalletApiClientMock(client); - Mockito.when(mockApiClient.put(Mockito.anyString(), Mockito.any(FormDataMultiPart.class), Mockito.any(Class.class))) + JSONObject jsonObject = new JSONObject(); + jsonObject.put("type", "DRIVERS_LICENSE"); + jsonObject.put("country", "AL"); + jsonObject.put("category", "IDENTIFICATION"); + List jsonObjectList = new ArrayList<>(); + jsonObjectList.add(jsonObject); + JSONObject jsonObject1 = new JSONObject(); + jsonObject1.put("documents", jsonObjectList); + Map multipartUploadData =new HashMap(); + multipartUploadData.put("data",jsonObject1.toString()); + HyperwalletVerificationDocument uploadData = new HyperwalletVerificationDocument(); + Map uploadFiles = new HashMap(); + uploadFiles.put("drivers_license_front", "/integration/test.png"); + uploadData.uploadFiles(uploadFiles); + + List docList = new ArrayList(); + docList.add(uploadData); + HyperwalletApiClient mockApiClient = createAndInjectHyperwalletApiClientMock(client); + Mockito.when(mockApiClient.put(Mockito.anyString(), Mockito.any(HyperwalletUser.class), Mockito.any(Class.class))) .thenReturn(hyperwalletUser); - HyperwalletUser hyperwalletUserresponse = client.documentUpload("test-token", new FormDataMultiPart()); - assertTrue(hyperwalletUserresponse.getDocuments().get(0).getCategory().equals(EDocumentCategory.AUTHORIZATION)); - assertTrue(hyperwalletUserresponse.getDocuments().get(0).getType().equals(EIdentityVerificationType.LETTER_OF_AUTHORIZATION)); - assertTrue(hyperwalletUserresponse.getDocuments().get(0).getCountry().equals(ECountryCode.CA)); - assertTrue(hyperwalletUserresponse.getDocuments().get(0).getStatus().equals(EKycDocumentVerificationStatus.NEW)); + HyperwalletUser hyperwalletUserResponse = client.uploadUserDocuments("test-token", docList); + assertThat(hyperwalletUserResponse, isOneOf(null,hyperwalletUser)); + } + + @Test + public void testUploadUserDocument_Error() throws Exception { + HyperwalletUser hyperwalletUserresponse; + try { + + Hyperwallet client = new Hyperwallet("test-username", "test-username"); + HyperwalletUser hyperwalletUser = new HyperwalletUser(); + HyperwalletVerificationDocument hyperwalletDocument = + new HyperwalletVerificationDocument(); + hyperwalletDocument.category("IDENTIFICATION") + .type("DRIVERS_LICENSE") + .country("US"); + + Map uploadFiles = new HashMap(); + ClassLoader classLoader = getClass().getClassLoader(); + uploadFiles.put("drivers_license_front", new File(classLoader.getResource("integration/test.png").toURI()).getAbsolutePath()); + uploadFiles.put("drivers_license_back", new File(classLoader.getResource("integration/test.png").toURI()).getAbsolutePath()); + + hyperwalletDocument.setUploadFiles(uploadFiles); + List hyperwalletDocumentList = new ArrayList<>(); + hyperwalletDocumentList.add(hyperwalletDocument); + hyperwalletUser.setDocuments(hyperwalletDocumentList); + HashMap multiPartUploadData = new HashMap(); + + hyperwalletUserresponse = client.uploadUserDocuments("usr-9aff8645-4bc3-4f12-9f95-f85652806472", hyperwalletDocumentList); + fail("Expect HyperwalletException"); + } catch (HyperwalletException e) { + assertThat(e.getErrorCode(), is(nullValue())); + assertThat(e.getResponse(), is(nullValue())); + assertThat(e.getErrorMessage(), is(equalTo("Server returned non-OK status: 401; Message: Unauthorized"))); + assertThat(e.getMessage(), is(equalTo("Server returned non-OK status: 401; Message: Unauthorized"))); + assertThat(e.getHyperwalletErrors(), is(nullValue())); + assertThat(e.getRelatedResources(), is(nullValue())); + } } + @Test - public void testUploadDocumentBusinessStakeholder_noUserToken() { + public void testUploadStakeholderDocuments_noUserToken() { Hyperwallet client = new Hyperwallet("test-username", "test-password"); String businessStakeholderToken = "business-token"; try { + HyperwalletVerificationDocument multiPartUploadData = new HyperwalletVerificationDocument(); + List uploadDataList = new ArrayList(); + uploadDataList.add(multiPartUploadData); HyperwalletBusinessStakeholder hyperwalletBusinessStakeholderResponse = - client.uploadDocumentBusinessStakeholder(null, businessStakeholderToken, new FormDataMultiPart()); + client.uploadStakeholderDocuments(null, businessStakeholderToken, uploadDataList); fail("Expect HyperwalletException"); } catch (HyperwalletException e) { assertThat(e.getErrorCode(), is(nullValue())); @@ -7890,25 +8183,72 @@ public void testUploadDocumentBusinessStakeholder_noUserToken() { } @Test - public void testUploadDocumentBusinessStakeholder_noBusinessStakeholderToken() { + public void testUploadStakeholderDocuments_noBusinessStakeholderToken() { + Hyperwallet client = new Hyperwallet("test-username", "test-password"); + String userToken = "user-token"; + try { + HyperwalletVerificationDocument multiPartUploadData =new HyperwalletVerificationDocument(); + List uploadDataList = new ArrayList(); + uploadDataList.add(multiPartUploadData); + HyperwalletBusinessStakeholder hyperwalletBusinessStakeholderResponse = + client.uploadStakeholderDocuments(userToken, null, uploadDataList); + fail("Expect HyperwalletException"); + } catch (HyperwalletException e) { + assertThat(e.getErrorCode(), is(nullValue())); + assertThat(e.getResponse(), is(nullValue())); + assertThat(e.getErrorMessage(), is(equalTo("BusinessStakeholderToken may not be present"))); + assertThat(e.getMessage(), is(equalTo("BusinessStakeholderToken may not be present"))); + assertThat(e.getHyperwalletErrors(), is(nullValue())); + assertThat(e.getRelatedResources(), is(nullValue())); + } + } + + @Test + public void testUploadStakeholderDocuments_noUploadData() { + Hyperwallet client = new Hyperwallet("test-username", "test-password"); + String userToken = "user-token"; + String stkToken = "stk-token"; + try { + HyperwalletVerificationDocument multiPartUploadData =new HyperwalletVerificationDocument(); + List uploadDataList = new ArrayList(); + uploadDataList.add(multiPartUploadData); + HyperwalletBusinessStakeholder hyperwalletBusinessStakeholderResponse = + client.uploadStakeholderDocuments(userToken, stkToken, null); + fail("Expect HyperwalletException"); + } catch (HyperwalletException e) { + assertThat(e.getErrorCode(), is(nullValue())); + assertThat(e.getResponse(), is(nullValue())); + assertThat(e.getErrorMessage(), is(equalTo("Data for upload is missing"))); + assertThat(e.getMessage(), is(equalTo("Data for upload is missing"))); + assertThat(e.getHyperwalletErrors(), is(nullValue())); + assertThat(e.getRelatedResources(), is(nullValue())); + } + } + + @Test + public void testUploadStakeholderDocuments_noUploadFiles() { Hyperwallet client = new Hyperwallet("test-username", "test-password"); String userToken = "user-token"; + String stkToken = "stk-token"; try { + HyperwalletVerificationDocument multiPartUploadData = new HyperwalletVerificationDocument(); + List uploadDataList = new ArrayList(); + uploadDataList.add(multiPartUploadData); HyperwalletBusinessStakeholder hyperwalletBusinessStakeholderResponse = - client.uploadDocumentBusinessStakeholder(userToken, null, new FormDataMultiPart()); + client.uploadStakeholderDocuments(userToken, stkToken, uploadDataList); fail("Expect HyperwalletException"); } catch (HyperwalletException e) { assertThat(e.getErrorCode(), is(nullValue())); assertThat(e.getResponse(), is(nullValue())); - assertThat(e.getErrorMessage(), is(equalTo("BusinessStakeholderToken may not be required"))); - assertThat(e.getMessage(), is(equalTo("BusinessStakeholderToken may not be required"))); + assertThat(e.getErrorMessage(), is(equalTo("Upload Files are missing"))); + assertThat(e.getMessage(), is(equalTo("Upload Files are missing"))); assertThat(e.getHyperwalletErrors(), is(nullValue())); assertThat(e.getRelatedResources(), is(nullValue())); } } @Test - public void testUploadDocumentBusinessStakeholder_Successful() throws Exception { + public void testUploadStakeholderDocuments_Successful() throws Exception { Hyperwallet client = new Hyperwallet("test-username", "test-password"); String userToken = "user-token"; @@ -7917,20 +8257,18 @@ public void testUploadDocumentBusinessStakeholder_Successful() throws Exception List hyperwalletVerificationDocumentList = new ArrayList<>(); HyperwalletVerificationDocument hyperWalletVerificationDocument = new HyperwalletVerificationDocument(); hyperWalletVerificationDocument.category("IDENTIFICATION").type("DRIVERS_LICENSE").status("NEW").country("AL"); + Map uploadFiles = new HashMap(); + uploadFiles.put("drivers_license_front", "/integration/test.png"); + hyperWalletVerificationDocument.setUploadFiles(uploadFiles); hyperwalletVerificationDocumentList.add(hyperWalletVerificationDocument); hyperwalletBusinessStakeholder.setDocuments(hyperwalletVerificationDocumentList); HyperwalletApiClient mockApiClient = createAndInjectHyperwalletApiClientMock(client); - Mockito.when(mockApiClient.put(Mockito.anyString(), Mockito.any(FormDataMultiPart.class), Mockito.any(Class.class))) + Mockito.when(mockApiClient.put(Mockito.anyString(), Mockito.any(HyperwalletBusinessStakeholder.class), Mockito.any(Class.class))) .thenReturn(hyperwalletBusinessStakeholder); - - HyperwalletBusinessStakeholder hyperwalletBusinessStakeholderResponse = - client.uploadDocumentBusinessStakeholder(userToken, businessStakeholderToken, new FormDataMultiPart()); - HyperwalletVerificationDocument hyperwalletVerificationDocument = hyperwalletBusinessStakeholderResponse.getDocuments().get(0); - assertTrue(hyperwalletVerificationDocument.getCategory().equals("IDENTIFICATION")); - assertTrue(hyperwalletVerificationDocument.getType().equals("DRIVERS_LICENSE")); - assertTrue(hyperwalletVerificationDocument.getCountry().equals("AL")); - assertTrue(hyperwalletVerificationDocument.getStatus().equals("NEW")); + HashMap multipartUploadData = new HashMap(); + HyperwalletBusinessStakeholder hyperwalletBusinessStakeholderResponse = client.uploadStakeholderDocuments(userToken, businessStakeholderToken, hyperwalletVerificationDocumentList); + assertThat(hyperwalletBusinessStakeholderResponse, isOneOf(null, hyperwalletBusinessStakeholder)); } //-------------------------------------- diff --git a/src/test/java/com/hyperwallet/clientsdk/model/HyperwalletUserTest.java b/src/test/java/com/hyperwallet/clientsdk/model/HyperwalletUserTest.java index 987bda551..a697af656 100644 --- a/src/test/java/com/hyperwallet/clientsdk/model/HyperwalletUserTest.java +++ b/src/test/java/com/hyperwallet/clientsdk/model/HyperwalletUserTest.java @@ -1,9 +1,5 @@ package com.hyperwallet.clientsdk.model; -import com.hyperwallet.clientsdk.model.HyperwalletDocument.ECountryCode; -import com.hyperwallet.clientsdk.model.HyperwalletDocument.EDocumentCategory; -import com.hyperwallet.clientsdk.model.HyperwalletDocument.EIdentityVerificationType; -import com.hyperwallet.clientsdk.model.HyperwalletDocument.EKycDocumentVerificationStatus; import com.hyperwallet.clientsdk.model.HyperwalletUser.VerificationStatus; @@ -16,10 +12,10 @@ public class HyperwalletUserTest extends BaseModelTest { protected HyperwalletUser createBaseModel() { HyperwalletUser user = new HyperwalletUser(); - HyperwalletDocument hyperwalletDocument = new HyperwalletDocument(); - hyperwalletDocument.category(EDocumentCategory.AUTHORIZATION).type(EIdentityVerificationType.LETTER_OF_AUTHORIZATION) - .country(ECountryCode.CA).status(EKycDocumentVerificationStatus.NEW); - List hyperwalletDocumentList = new ArrayList<>(); + HyperwalletVerificationDocument hyperwalletDocument = new HyperwalletVerificationDocument(); + hyperwalletDocument.category("IDENTIFICATION").type("DRIVERS_LICENSE") + .country("US"); + List hyperwalletDocumentList = new ArrayList<>(); hyperwalletDocumentList.add(hyperwalletDocument); List hyperwalletUserLinks = new ArrayList<>(); HyperwalletLink link = new HyperwalletLink(); diff --git a/src/test/java/com/hyperwallet/clientsdk/util/HyperwalletApiClientTest.java b/src/test/java/com/hyperwallet/clientsdk/util/HyperwalletApiClientTest.java index e19950f58..7bbf7b47b 100644 --- a/src/test/java/com/hyperwallet/clientsdk/util/HyperwalletApiClientTest.java +++ b/src/test/java/com/hyperwallet/clientsdk/util/HyperwalletApiClientTest.java @@ -3,22 +3,13 @@ import cc.protea.util.http.Response; import com.fasterxml.jackson.annotation.JsonFilter; import com.fasterxml.jackson.core.type.TypeReference; +import com.hyperwallet.clientsdk.Hyperwallet; import com.hyperwallet.clientsdk.HyperwalletException; import com.hyperwallet.clientsdk.model.*; -import com.hyperwallet.clientsdk.model.HyperwalletDocument.ECountryCode; -import com.hyperwallet.clientsdk.model.HyperwalletDocument.EDocumentCategory; -import com.hyperwallet.clientsdk.model.HyperwalletDocument.EIdentityVerificationType; -import com.hyperwallet.clientsdk.model.HyperwalletDocument.EKycDocumentVerificationStatus; -import com.sun.jersey.api.client.Client; -import com.sun.jersey.api.client.ClientResponse; -import com.sun.jersey.api.client.WebResource; -import com.sun.jersey.core.header.FormDataContentDisposition; -import com.sun.jersey.core.header.InBoundHeaders; -import com.sun.jersey.multipart.BodyPart; -import com.sun.jersey.multipart.FormDataBodyPart; -import com.sun.jersey.multipart.FormDataMultiPart; +import org.apache.commons.lang3.SerializationUtils; import org.json.JSONException; import org.json.JSONObject; +import org.mockito.Mockito; import org.mockserver.integration.ClientAndServer; import org.mockserver.matchers.Times; import org.mockserver.model.HttpRequest; @@ -29,24 +20,21 @@ import org.testng.annotations.BeforeMethod; import org.testng.annotations.Test; -import javax.ws.rs.core.HttpHeaders; -import javax.ws.rs.core.MediaType; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlRootElement; import java.io.File; import java.lang.reflect.Field; import java.util.ArrayList; -import java.util.Collections; import java.util.HashMap; import java.util.List; +import java.util.Map; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.*; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; +import static org.hamcrest.Matchers.equalTo; import static org.mockserver.integration.ClientAndServer.startClientAndServer; -import static org.testng.Assert.*; +import static org.testng.Assert.fail; /** * @author fkrauthan @@ -539,6 +527,60 @@ public void testPut_500Response() { } } + @Test + public void testPutMultipart_noConnection() { + Multipart requestBody = new Multipart(); + List multipartList = new ArrayList(); + requestBody.setMultipartList(multipartList); + + mockServer.stop(); + if (mockServer.isRunning()) { + fail("Mockserver still running"); + } + + try { + hyperwalletApiClient.put(baseUrl + "/test?test-query=test-value", requestBody, TestBody.class); + fail("Expect HyperwalletException"); + } catch (HyperwalletException e) { + assertThat(e.getMessage(), is(containsString("java.net.ConnectException: Connection refused"))); + } + } + + @Test + public void testPutMultipart_WithError() { + try { + Multipart multipart = new Multipart(); + JSONObject jsonObject = new JSONObject(); + jsonObject.put("type", "DRIVERS_LICENSE"); + jsonObject.put("country", "US"); + jsonObject.put("category", "IDENTIFICATION"); + List documents = new ArrayList<>(); + documents.add(jsonObject); + JSONObject data = new JSONObject(); + data.put("documents", documents); + Map fields = new HashMap(); + fields.put("data", data.toString()); + Multipart.MultipartData formFields = new Multipart.MultipartData("Content-type: json", "Content-Disposition: form-data", fields); + multipart.add(formFields); + hyperwalletApiClient.put("https://api.sandbox.hyperwallet.com/rest/v4/users/test-user-token", multipart, HyperwalletUser.class); + } catch (Exception exception) { + assertThat(exception.getMessage(), startsWith("Server returned non-OK status: 401")); + } + } + + @Test + public void testPutMultipart_WithSucess() { + try { + + HyperwalletUser response = hyperwalletApiClient.put("https://api.sandbox.hyperwallet.com/rest/v4/users/test-user-token", new Multipart(), HyperwalletUser.class); + assertThat(response, is(notNullValue())); + assertThat(response.getToken(), is(equalTo("test-user-token"))); + assertThat(response.getDocuments(), is(notNullValue())); + } catch (Exception exception) { + } + } + + @Test public void testPost_noConnection() { TestBody requestBody = new TestBody(); @@ -1272,235 +1314,13 @@ public void testPost_200Response_ResponseContentTypeHeaderWithLeadingCharset() { assertThat(body.test2, is(nullValue())); } - @Test - public void testDocumentUpload() throws Exception { - FormDataMultiPart multiPart = new FormDataMultiPart(); - JSONObject jsonObject = new JSONObject(); - jsonObject.put("type", "LETTER_OF_AUTHORIZATION"); - jsonObject.put("category", "AUTHORIZATION"); - List jsonObjectList = new ArrayList<>(); - jsonObjectList.add(jsonObject); - JSONObject jsonObject1 = new JSONObject(); - jsonObject1.put("documents", jsonObjectList); - BodyPart data = - new FormDataBodyPart(FormDataContentDisposition.name("data").build(), jsonObject1.toString(), MediaType.APPLICATION_JSON_TYPE); - multiPart.bodyPart(data); - - Client mockClient = createAndInjectWebResourceClient(hyperwalletApiClient); - - WebResource webResource = mock(WebResource.class); - when(mockClient.resource(baseUrl + "/documentUpload")).thenReturn(webResource); - WebResource.Builder builder = mock(WebResource.Builder.class); - when(webResource.type(MediaType.MULTIPART_FORM_DATA_TYPE)).thenReturn(builder); - - InBoundHeaders headers = new InBoundHeaders(); - headers.put(HttpHeaders.CONTENT_TYPE, Collections.singletonList("application/json")); - - ClientResponse clientResponse = mock(ClientResponse.class); - - when(builder.put(ClientResponse.class, multiPart)).thenReturn(clientResponse); - when(clientResponse.getStatus()).thenReturn(200); - - String hyperwalletUser = "{\n" - + " \"documents\": [\n" - + " {\n" - + " \"category\": \"AUTHORIZATION\",\n" - + " \"country\": \"CA\",\n" - + " \"type\": \"LETTER_OF_AUTHORIZATION\",\n" - + " \"status\": \"NEW\"\n" - + " }\n" - + " ]\n" - + "}"; - - when(clientResponse.getEntity(String.class)).thenReturn(hyperwalletUser); - when(clientResponse.getHeaders()).thenReturn(headers); - - HyperwalletUser response = hyperwalletApiClient.put(baseUrl + "/documentUpload", multiPart, HyperwalletUser.class); - List hyperwalletDocumentList = response.getDocuments(); - assertNull(response.getToken()); - assertNull(response.getStatus()); - assertNull(response.getVerificationStatus()); - assertEquals(response.getDocuments().size(), 1); - assertEquals(response.getDocuments().get(0).getCategory(), EDocumentCategory.AUTHORIZATION); - assertEquals(response.getDocuments().get(0).getType(), EIdentityVerificationType.LETTER_OF_AUTHORIZATION); - assertEquals(response.getDocuments().get(0).getCountry(), ECountryCode.CA); - assertEquals(response.getDocuments().get(0).getStatus(), EKycDocumentVerificationStatus.NEW); - } - - - @Test - public void testDocumentUploadWithError() { - try { - ClassLoader classLoader = getClass().getClassLoader(); - String hyperwalletKeysPath = new File(classLoader.getResource("encryption/public-jwkset").toURI()).getAbsolutePath(); - String clientPrivateKeysPath = new File(classLoader.getResource("encryption/private-jwkset").toURI()).getAbsolutePath(); - - HyperwalletEncryption hyperwalletEncryption = new HyperwalletEncryption.HyperwalletEncryptionBuilder() - .clientPrivateKeySetLocation(clientPrivateKeysPath).hyperwalletKeySetLocation(hyperwalletKeysPath).build(); - String testBody = "{\"test1\":\"value1\"}"; - String encryptedBody = hyperwalletEncryption.encrypt(testBody); - - HyperwalletApiClient hyperwalletApiClientEnc = new HyperwalletApiClient( - "test-username", "test-password", "1.0", hyperwalletEncryption); - - FormDataMultiPart multiPart = new FormDataMultiPart(); - JSONObject jsonObject = new JSONObject(); - jsonObject.put("type", "LETTER_OF_AUTHORIZATION"); - jsonObject.put("category", "AUTHORIZATION"); - List jsonObjectList = new ArrayList<>(); - jsonObjectList.add(jsonObject); - - JSONObject jsonObject1 = new JSONObject(); - jsonObject1.put("documents", jsonObjectList); - BodyPart data = - new FormDataBodyPart(FormDataContentDisposition.name("data").build(), jsonObject1.toString(), MediaType.APPLICATION_JSON_TYPE); - multiPart.bodyPart(data); - - Client mockClient = createAndInjectWebResourceClient(hyperwalletApiClientEnc); - - WebResource webResource = mock(WebResource.class); - when(mockClient.resource(baseUrl + "/documentUpload")).thenReturn(webResource); - WebResource.Builder builder = mock(WebResource.Builder.class); - when(webResource.type(MediaType.MULTIPART_FORM_DATA_TYPE)).thenReturn(builder); - - InBoundHeaders headers = new InBoundHeaders(); - headers.put(HttpHeaders.CONTENT_TYPE, Collections.singletonList("application/jose+json")); - - ClientResponse clientResponse = mock(ClientResponse.class); - - when(builder.put(ClientResponse.class, multiPart)).thenReturn(clientResponse); - when(clientResponse.getStatus()).thenReturn(200); - - when(clientResponse.getEntity(String.class)).thenReturn("{result: \"Success\"}"); - when(clientResponse.getHeaders()).thenReturn(headers); - - hyperwalletApiClientEnc.put(baseUrl + "/documentUpload", multiPart, HyperwalletUser.class); - } catch (Exception exception) { - assertThat(exception.getMessage(), is("java.text.ParseException: Invalid serialized unsecured/JWS/JWE object: Missing part delimiters")); - } - } - - @Test - public void testUploadDocumentBusinessStakeholder() throws Exception { - FormDataMultiPart multiPart = new FormDataMultiPart(); - JSONObject jsonObject = new JSONObject(); - jsonObject.put("type", "LETTER_OF_AUTHORIZATION"); - jsonObject.put("category", "AUTHORIZATION"); - List jsonObjectList = new ArrayList<>(); - jsonObjectList.add(jsonObject); - JSONObject jsonObject1 = new JSONObject(); - jsonObject1.put("documents", jsonObjectList); - BodyPart data = - new FormDataBodyPart(FormDataContentDisposition.name("data").build(), jsonObject1.toString(), MediaType.APPLICATION_JSON_TYPE); - multiPart.bodyPart(data); - - Client mockClient = createAndInjectWebResourceClient(hyperwalletApiClient); - String userToken = "user-token"; - String businessStakeholderToken = "business-token"; - - WebResource webResource = mock(WebResource.class); - when(mockClient.resource(baseUrl + "/users/" + userToken + "/business-stakeholders/" + businessStakeholderToken)).thenReturn(webResource); - WebResource.Builder builder = mock(WebResource.Builder.class); - when(webResource.type(MediaType.MULTIPART_FORM_DATA_TYPE)).thenReturn(builder); - - InBoundHeaders headers = new InBoundHeaders(); - headers.put(HttpHeaders.CONTENT_TYPE, Collections.singletonList("application/json")); - - ClientResponse clientResponse = mock(ClientResponse.class); - - when(builder.put(ClientResponse.class, multiPart)).thenReturn(clientResponse); - when(clientResponse.getStatus()).thenReturn(200); - - String hyperwalletUser = "{\n" - + " \"documents\": [\n" - + " {\n" - + " \"category\": \"AUTHORIZATION\",\n" - + " \"country\": \"CA\",\n" - + " \"type\": \"LETTER_OF_AUTHORIZATION\",\n" - + " \"status\": \"NEW\"\n" - + " }\n" - + " ]\n" - + "}"; - - when(clientResponse.getEntity(String.class)).thenReturn(hyperwalletUser); - when(clientResponse.getHeaders()).thenReturn(headers); - - HyperwalletBusinessStakeholder hyperwalletBusinessStakeholderResponse = hyperwalletApiClient - .put(baseUrl + "/users/" + userToken + "/business-stakeholders/" + businessStakeholderToken, multiPart, - HyperwalletBusinessStakeholder.class); - List hyperwalletVerificationDocumentList = hyperwalletBusinessStakeholderResponse.getDocuments(); - assertNull(hyperwalletBusinessStakeholderResponse.getToken()); - assertNull(hyperwalletBusinessStakeholderResponse.getStatus()); - assertNull(hyperwalletBusinessStakeholderResponse.getVerificationStatus()); - assertEquals(hyperwalletBusinessStakeholderResponse.getDocuments().size(), 1); - assertEquals(hyperwalletBusinessStakeholderResponse.getDocuments().get(0).getCategory(), "AUTHORIZATION"); - assertEquals(hyperwalletBusinessStakeholderResponse.getDocuments().get(0).getType(), "LETTER_OF_AUTHORIZATION"); - assertEquals(hyperwalletBusinessStakeholderResponse.getDocuments().get(0).getCountry(), "CA"); - assertEquals(hyperwalletBusinessStakeholderResponse.getDocuments().get(0).getStatus(), "NEW"); - } + private HyperwalletApiClient createAndInjectHyperwalletApiClientMock(Hyperwallet client) throws Exception { + HyperwalletApiClient mock = Mockito.mock(HyperwalletApiClient.class); - @Test - public void testUploadDocumentBusinessStakeholderError() { - try { - ClassLoader classLoader = getClass().getClassLoader(); - String hyperwalletKeysPath = new File(classLoader.getResource("encryption/public-jwkset").toURI()).getAbsolutePath(); - String clientPrivateKeysPath = new File(classLoader.getResource("encryption/private-jwkset").toURI()).getAbsolutePath(); - - HyperwalletEncryption hyperwalletEncryption = new HyperwalletEncryption.HyperwalletEncryptionBuilder() - .clientPrivateKeySetLocation(clientPrivateKeysPath).hyperwalletKeySetLocation(hyperwalletKeysPath).build(); - String testBody = "{\"test1\":\"value1\"}"; - String encryptedBody = hyperwalletEncryption.encrypt(testBody); - - HyperwalletApiClient hyperwalletApiClientEnc = new HyperwalletApiClient( - "test-username", "test-password", "1.0", hyperwalletEncryption); - - FormDataMultiPart multiPart = new FormDataMultiPart(); - JSONObject jsonObject = new JSONObject(); - jsonObject.put("type", "LETTER_OF_AUTHORIZATION"); - jsonObject.put("category", "AUTHORIZATION"); - List jsonObjectList = new ArrayList<>(); - jsonObjectList.add(jsonObject); - - JSONObject jsonObject1 = new JSONObject(); - jsonObject1.put("documents", jsonObjectList); - BodyPart data = - new FormDataBodyPart(FormDataContentDisposition.name("data").build(), jsonObject1.toString(), MediaType.APPLICATION_JSON_TYPE); - multiPart.bodyPart(data); - - Client mockClient = createAndInjectWebResourceClient(hyperwalletApiClientEnc); - - String userToken = "user-token"; - String businessStakeholderToken = "business-token"; - WebResource webResource = mock(WebResource.class); - when(mockClient.resource(baseUrl + "/users/" + userToken + "/business-stakeholders/" + businessStakeholderToken)).thenReturn(webResource); - WebResource.Builder builder = mock(WebResource.Builder.class); - when(webResource.type(MediaType.MULTIPART_FORM_DATA_TYPE)).thenReturn(builder); - - InBoundHeaders headers = new InBoundHeaders(); - headers.put(HttpHeaders.CONTENT_TYPE, Collections.singletonList("application/jose+json")); - - ClientResponse clientResponse = mock(ClientResponse.class); - - when(builder.put(ClientResponse.class, multiPart)).thenReturn(clientResponse); - when(clientResponse.getStatus()).thenReturn(200); - - when(clientResponse.getEntity(String.class)).thenReturn("{result: \"Success\"}"); - when(clientResponse.getHeaders()).thenReturn(headers); - hyperwalletApiClientEnc.put(baseUrl + "/users/" + userToken + "/business-stakeholders/" + businessStakeholderToken, multiPart, - HyperwalletBusinessStakeholder.class); - } catch (Exception exception) { - assertThat(exception.getMessage(), is("java.text.ParseException: Invalid serialized unsecured/JWS/JWE object: Missing part delimiters")); - } - } - - private Client createAndInjectWebResourceClient(HyperwalletApiClient client) throws Exception { - Client mock = mock(Client.class); - - Field apiClientField = client.getClass().getDeclaredField("client"); + Field apiClientField = client.getClass().getDeclaredField("apiClient"); apiClientField.setAccessible(true); apiClientField.set(client, mock); + return mock; } - - } diff --git a/src/test/java/com/hyperwallet/clientsdk/util/MultipartTest.java b/src/test/java/com/hyperwallet/clientsdk/util/MultipartTest.java new file mode 100644 index 000000000..d9ab5be4e --- /dev/null +++ b/src/test/java/com/hyperwallet/clientsdk/util/MultipartTest.java @@ -0,0 +1,34 @@ +package com.hyperwallet.clientsdk.util; + + import org.testng.annotations.Test; + import java.util.*; + + import static org.hamcrest.MatcherAssert.assertThat; + import static org.hamcrest.Matchers.*; + + public class MultipartTest { + + @Test + public void testFields() { + Multipart multipart = new Multipart(); + Multipart.MultipartData data = new Multipart.MultipartData(null, null, null); + + assertThat(data.getContentDisposition(), is(nullValue())); + assertThat(data.getContentType(), is(nullValue())); + assertThat(data.getEntity(), is(nullValue())); + assertThat(data.getEntity(), is(nullValue())); + Map entity = new HashMap(); + entity.put("drivers_license_front", "/path/to/test/file"); + data = new Multipart.MultipartData("Content-type: json", "Content-Disposition: form-data", entity); + assertThat(data.getContentDisposition(), is(equalTo("Content-Disposition: form-data"))); + assertThat(data.getContentType(), is(equalTo("Content-type: json"))); + assertThat(data.getEntity().get("drivers_license_front"), is(equalTo("/path/to/test/file"))); + + List dataList = new ArrayList(); + dataList.add(data); + multipart.setMultipartList(dataList); + + } + } + + diff --git a/src/test/resources/integration/getBankAccountStatusTransition-request.txt b/src/test/resources/integration/getBankAccountStatusTransition-request.txt new file mode 100644 index 000000000..3b4ed6879 --- /dev/null +++ b/src/test/resources/integration/getBankAccountStatusTransition-request.txt @@ -0,0 +1,3 @@ +curl -X "GET" "https://api.sandbox.hyperwallet.com/rest/v4/users/usr-f695ef43-9614-4e17-9269-902c234616c3/bank-accounts/trm-d69300ef-5011-486b-bd2e-bfd8b20fef26/status-transitions/sts-1825afa2-61f1-4860-aa69-a65b9d14f556" \ +-u testuser@12345678:myAccPassw0rd \ +-H "Accept: application/json" diff --git a/src/test/resources/integration/getBankAccountStatusTransition-response.json b/src/test/resources/integration/getBankAccountStatusTransition-response.json new file mode 100644 index 000000000..439878045 --- /dev/null +++ b/src/test/resources/integration/getBankAccountStatusTransition-response.json @@ -0,0 +1,16 @@ +{ + "token": "sts-1825afa2-61f1-4860-aa69-a65b9d14f556", + "createdOn": "2017-11-16T00:55:57", + "transition": "DE_ACTIVATED", + "fromStatus": "ACTIVATED", + "toStatus": "DE_ACTIVATED", + "notes": "Closing this account.", + "links": [ + { + "params": { + "rel": "self" + }, + "href": "https://api.sandbox.hyperwallet.com/rest/v4/users/usr-f695ef43-9614-4e17-9269-902c234616c3/bank-accounts/trm-d69300ef-5011-486b-bd2e-bfd8b20fef26/status-transitions/sts-1825afa2-61f1-4860-aa69-a65b9d14f556" + } + ] +} diff --git a/src/test/resources/integration/getBusinessStakeholderStatusTransition-request.txt b/src/test/resources/integration/getBusinessStakeholderStatusTransition-request.txt new file mode 100644 index 000000000..9e0861106 --- /dev/null +++ b/src/test/resources/integration/getBusinessStakeholderStatusTransition-request.txt @@ -0,0 +1,3 @@ +curl -X "GET" "https://api.sandbox.hyperwallet.com/rest/v4/users/usr-9b0e6dfe-c26b-4ddf-9d79-96b332c1dc8a/business-stakeholders/stk-6829da02-7258-4b2b-bcb8-4bb97d4187d2/status-transitions/sts-16d9ae38-f29f-4360-a1c0-0bceafb12c27" \ +-u testuser@12345678:myAccPassw0rd \ +-H "Accept: application/json" diff --git a/src/test/resources/integration/getBusinessStakeholderStatusTransition-response.json b/src/test/resources/integration/getBusinessStakeholderStatusTransition-response.json new file mode 100644 index 000000000..f850c0d4b --- /dev/null +++ b/src/test/resources/integration/getBusinessStakeholderStatusTransition-response.json @@ -0,0 +1,15 @@ +{ + "token": "sts-16d9ae38-f29f-4360-a1c0-0bceafb12c27", + "createdOn": "2020-11-13T00:41:03", + "transition": "DE_ACTIVATED", + "fromStatus": "ACTIVATED", + "toStatus": "DE_ACTIVATED", + "links": [ + { + "params": { + "rel": "self" + }, + "href": "https://localhost-hyperwallet.aws.paylution.net:8181/rest/v4/users/usr-9b0e6dfe-c26b-4ddf-9d79-96b332c1dc8a/business-stakeholders/stk-6829da02-7258-4b2b-bcb8-4bb97d4187d2/status-transitions/sts-16d9ae38-f29f-4360-a1c0-0bceafb12c27" + } + ] +} diff --git a/src/test/resources/integration/listBusinessStakeholderStatusTransition-request.txt b/src/test/resources/integration/listBusinessStakeholderStatusTransition-request.txt new file mode 100644 index 000000000..500f249de --- /dev/null +++ b/src/test/resources/integration/listBusinessStakeholderStatusTransition-request.txt @@ -0,0 +1,3 @@ +curl -X "GET" "https://api.sandbox.hyperwallet.com/rest/v4/users/usr-f695ef43-9614-4e17-9269-902c234616c3/business-stakeholders/stk-6829da02-7258-4b2b-bcb8-4bb97d4187d2/status-transitions" \ +-u testuser@12345678:myAccPassw0rd \ +-H "Accept: application/json" diff --git a/src/test/resources/integration/listBusinessStakeholderStatusTransition-response.json b/src/test/resources/integration/listBusinessStakeholderStatusTransition-response.json new file mode 100644 index 000000000..b9e97102e --- /dev/null +++ b/src/test/resources/integration/listBusinessStakeholderStatusTransition-response.json @@ -0,0 +1,30 @@ +{ + "hasNextPage": "false", + "hasPreviousPage": "false", + "limit": 10, + "data": [ + { + "token": "sts-1825afa2-61f1-4860-aa69-a65b9d14f556", + "createdOn": "2017-11-16T00:55:57", + "transition": "DE_ACTIVATED", + "fromStatus": "ACTIVATED", + "toStatus": "DE_ACTIVATED", + "links": [ + { + "params": { + "rel": "self" + }, + "href": "https://api.sandbox.hyperwallet.com/rest/v4/users/usr-f695ef43-9614-4e17-9269-902c234616c3/business-stakeholders/stk-6829da02-7258-4b2b-bcb8-4bb97d4187d2/status-transitions/sts-1825afa2-61f1-4860-aa69-a65b9d14f556" + } + ] + } + ], + "links": [ + { + "params": { + "rel": "self" + }, + "href": "https://api.sandbox.hyperwallet.com/rest/v4/users/usr-f695ef43-9614-4e17-9269-902c234616c3/business-stakeholders/stk-6829da02-7258-4b2b-bcb8-4bb97d4187d2/status-transitions?limit=10" + } + ] +} diff --git a/src/test/resources/integration/test.png b/src/test/resources/integration/test.png new file mode 100644 index 000000000..e69de29bb