Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Optimise test framework (bunq/sdk_java#78) #85

Merged
merged 14 commits into from
May 28, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -73,3 +73,4 @@ context-save-restore-test.conf
config.properties
bunq-test.conf
.idea/codeStyles/
.idea
4 changes: 2 additions & 2 deletions src/main/java/com/bunq/sdk/context/ApiContext.java
Original file line number Diff line number Diff line change
Expand Up @@ -223,8 +223,8 @@ public void ensureSessionActive() {
}

public boolean isSessionActive() {
return sessionContext != null ||
getTimeToSessionExpiryInSeconds() > TIME_TO_SESSION_EXPIRY_MINIMUM_SECONDS;
return sessionContext != null &&
getTimeToSessionExpiryInSeconds() < TIME_TO_SESSION_EXPIRY_MINIMUM_SECONDS;
}

private long getTimeToSessionExpiryInSeconds() {
Expand Down
4 changes: 2 additions & 2 deletions src/main/java/com/bunq/sdk/context/ApiEnvironmentType.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,11 @@ public enum ApiEnvironmentType {
/**
* @return Base URI of the environment.
*/
String getBaseUri() {
public String getBaseUri() {
return this.baseUri;
}

String getApiVersion() {
public String getApiVersion() {
return this.apiVersion;
}

Expand Down
2 changes: 1 addition & 1 deletion src/main/java/com/bunq/sdk/context/SessionContext.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
/**
* Context of your current bunq Public API session.
*/
class SessionContext implements java.io.Serializable {
public class SessionContext implements java.io.Serializable {

/**
* Error constants.
Expand Down
16 changes: 8 additions & 8 deletions src/main/java/com/bunq/sdk/http/ApiClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -67,10 +67,10 @@ public class ApiClient {
public static final String HEADER_CONTENT_TYPE = "Content-Type";
public static final String HEADER_USER_AGENT = "User-Agent";
public static final String HEADER_CACHE_CONTROL = "Cache-Control";
private static final String HEADER_LANGUAGE = "X-Bunq-Language";
private static final String HEADER_REGION = "X-Bunq-Region";
private static final String HEADER_REQUEST_ID = "X-Bunq-Client-Request-Id";
private static final String HEADER_GEOLOCATION = "X-Bunq-Geolocation";
public static final String HEADER_LANGUAGE = "X-Bunq-Language";
public static final String HEADER_REGION = "X-Bunq-Region";
public static final String HEADER_REQUEST_ID = "X-Bunq-Client-Request-Id";
public static final String HEADER_GEOLOCATION = "X-Bunq-Geolocation";
private static final String HEADER_SIGNATURE = "X-Bunq-Client-Signature";
private static final String HEADER_AUTHENTICATION = "X-Bunq-Client-Authentication";
private static final String HEADER_RESPONSE_ID_LOWER_CASE = "x-bunq-client-response-id";
Expand All @@ -85,15 +85,15 @@ public class ApiClient {
/**
* Header value to disable the cache control.
*/
private static final String CACHE_CONTROL_NONE = "no-cache";
public static final String CACHE_CONTROL_NONE = "no-cache";

/**
* Prefix for bunq's own headers.
*/
private static final String USER_AGENT_BUNQ = "bunq-sdk-java/0.13.0";
private static final String LANGUAGE_EN_US = "en_US";
private static final String REGION_NL_NL = "nl_NL";
private static final String GEOLOCATION_ZERO = "0 0 0 0 000";
public static final String LANGUAGE_EN_US = "en_US";

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

public under private?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hmm., i normally group constants in groups, not on visibility. Error constants on top, ten the first used group in the class. So there could indeed be a mixture of visibility in a specific group.

public static final String REGION_NL_NL = "nl_NL";
public static final String GEOLOCATION_ZERO = "0 0 0 0 000";
private static final String SCHEME_HTTPS = "https";

/**
Expand Down
176 changes: 160 additions & 16 deletions src/test/java/com/bunq/sdk/BunqSdkTestBase.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,51 +4,195 @@
import com.bunq.sdk.context.ApiEnvironmentType;
import com.bunq.sdk.context.BunqContext;
import com.bunq.sdk.exception.BunqException;
import com.bunq.sdk.http.ApiClient;
import com.bunq.sdk.http.BunqResponse;
import com.bunq.sdk.model.generated.endpoint.CashRegister;
import com.bunq.sdk.model.generated.endpoint.MonetaryAccountBank;
import com.bunq.sdk.model.generated.endpoint.RequestInquiry;
import com.bunq.sdk.model.generated.endpoint.SandboxUser;
import com.bunq.sdk.model.generated.object.Amount;
import com.bunq.sdk.model.generated.object.Pointer;
import com.google.gson.Gson;
import com.google.gson.JsonObject;
import com.google.gson.stream.JsonReader;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import org.junit.BeforeClass;

import java.util.Arrays;
import java.util.List;
import java.io.File;
import java.io.IOException;
import java.io.StringReader;
import java.util.UUID;

/**
* Base class for the Bunq SDK tests.
*/
public class BunqSdkTestBase {

/**
* Description of the test device for Java SDK.
* Error constants.
*/
private static final String ERROR_COULD_NOT_GENERATE_NEW_API_KEY = "Encountered error while retrieving new sandbox ApiKey.\nError message %s";

private static final String DEVICE_DESCRIPTION = "Java test device";
private static final int HTTP_STATUS_OK = 200;
private static final String FIELD_RESPONSE = "Response";
private static final String FIELD_API_KEY = "ApiKey";
private static final int INDEX_FIRST = 0;

protected static final String TEST_CONFIG_PATH = "bunq-test.conf";

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

protected under private?

protected static final String CONTENT_TYPE = "image/png";
protected static final String ATTACHMENT_DESCRIPTION = "TEST PNG JAVA";
protected static final String ATTACHMENT_PATH_IN = "assets/[email protected]";
protected static final String SCHEME_HTTPS = "https://";
protected static final String URL_PATH_SEPARATOR = "/";
protected static final String URL_PATH_SANDBOX_USER = "/sandbox-user";
protected static final String CURRENCY_EUR = "EUR";
protected static final String ACCOUNT_DESCRIPTION = "test account java";
protected static final String SPENDING_MONEY_AMOUNT = "500";
protected static final String POINTER_TYPE_EMAIL = "EMAIL";
protected static final String SUGAR_DADDY_EMAIL = "[email protected]";
protected static final String SUGAR_DADDY_REQUESTS_DESCRIPTION = "sdk java test, thanks daddy <3";
protected static final String EMAIL_BRAVO = "[email protected]";
protected static final String CASH_REGISTER_DESCRIPTION = "java cash register test";


/**
* Individual properties.
*/
private static String apiKey = Config.getApiKey();
private static String[] permittedIps = Config.getPermittedIps();
private static String apiConfigPath = Config.getApiConfigPath();
protected static MonetaryAccountBank secondMonetaryAccountBank;
protected static CashRegister cashRegister;

@BeforeClass
public static void setUp() {
public static void setUpBeforeClass() {
BunqContext.loadApiContext(getApiContext());
setSecondMonetaryAccountBank();
requestSpendingMoney();

try {
Thread.sleep(500);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why this sleep?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To ensure the spending money request has been accepted before refreshing. The refresh part will be added with #79

BunqContext.getUserContext().refreshContext();
} catch (InterruptedException exception) {
throw new BunqException(exception.getMessage());
}
}

/**
* Based on the result of isSessionActive will create a new ApiContext or restore an old conf
* file
*/
protected static ApiContext getApiContext() {
ApiContext apiContext;
if (doesTestConfFileExist()) {
ApiContext apiContext = ApiContext.restore(TEST_CONFIG_PATH);
apiContext.ensureSessionActive();
apiContext.save(TEST_CONFIG_PATH);

return apiContext;
} else {
SandboxUser sandboxUser = generateNewSandboxUser();
ApiContext apiContext = ApiContext.create(
ApiEnvironmentType.SANDBOX,
sandboxUser.getApiKey(),
DEVICE_DESCRIPTION
);
apiContext.save(TEST_CONFIG_PATH);

return apiContext;
}
}

private static boolean doesTestConfFileExist() {
File confFile = new File(TEST_CONFIG_PATH);

return confFile.exists() && !confFile.isDirectory();
}

private static SandboxUser generateNewSandboxUser() {
OkHttpClient client = new OkHttpClient();

Request request = new Request.Builder()
.url(
SCHEME_HTTPS +
ApiEnvironmentType.SANDBOX.getBaseUri() +
URL_PATH_SEPARATOR +
ApiEnvironmentType.SANDBOX.getApiVersion() +
URL_PATH_SANDBOX_USER
)
.post(RequestBody.create(null, new byte[INDEX_FIRST]))
.addHeader(ApiClient.HEADER_REQUEST_ID, UUID.randomUUID().toString())
.addHeader(ApiClient.HEADER_CACHE_CONTROL, ApiClient.CACHE_CONTROL_NONE)
.addHeader(ApiClient.HEADER_GEOLOCATION, ApiClient.GEOLOCATION_ZERO)
.addHeader(ApiClient.HEADER_LANGUAGE, ApiClient.LANGUAGE_EN_US)
.addHeader(ApiClient.HEADER_REGION, ApiClient.REGION_NL_NL)
.build();

try {
apiContext = ApiContext.restore(apiConfigPath);
apiContext.ensureSessionActive();
} catch (BunqException exception) {
List<String> ips = Arrays.asList(permittedIps);
apiContext = ApiContext.create(ApiEnvironmentType.SANDBOX, apiKey, DEVICE_DESCRIPTION, ips);
Response response = client.newCall(request).execute();
if (response.code() == HTTP_STATUS_OK) {
String responseString = response.body().string();
JsonObject jsonObject = new Gson().fromJson(responseString, JsonObject.class);
JsonObject apiKEy =jsonObject.getAsJsonArray(FIELD_RESPONSE)
.get(INDEX_FIRST)
.getAsJsonObject()
.get(FIELD_API_KEY)
.getAsJsonObject();

return SandboxUser.fromJsonReader(new JsonReader(new StringReader(apiKEy.toString())));
} else {
throw new BunqException(String.format(ERROR_COULD_NOT_GENERATE_NEW_API_KEY, response.body().string()));
}
} catch (IOException e) {
throw new BunqException(e.getMessage());
}
}

private static void setSecondMonetaryAccountBank() {
BunqResponse<Integer> response = MonetaryAccountBank.create(CURRENCY_EUR, ACCOUNT_DESCRIPTION);

secondMonetaryAccountBank = MonetaryAccountBank.get(response.getValue()).getValue();
}

/**
* To ensure that our test user has enough money on the account, we sent a request to [email protected]
* to top-up the account.
*/
private static void requestSpendingMoney() {
if (shouldMoneyBeRequested(BunqContext.getUserContext().getPrimaryMonetaryAccountBank())) {
RequestInquiry.create(
new Amount(SPENDING_MONEY_AMOUNT, CURRENCY_EUR),
new Pointer(POINTER_TYPE_EMAIL, SUGAR_DADDY_EMAIL),
SUGAR_DADDY_REQUESTS_DESCRIPTION,
false
);
}

if (shouldMoneyBeRequested(secondMonetaryAccountBank)) {
RequestInquiry.create(
new Amount(SPENDING_MONEY_AMOUNT, CURRENCY_EUR),
new Pointer(POINTER_TYPE_EMAIL, SUGAR_DADDY_EMAIL),
SUGAR_DADDY_REQUESTS_DESCRIPTION,
false,
secondMonetaryAccountBank.getId()
);
}
}

apiContext.save(apiConfigPath);
protected static Pointer getPointerBravo() {
return new Pointer(POINTER_TYPE_EMAIL, EMAIL_BRAVO);
}

protected static CashRegister getCashRegister() {
if (cashRegister == null) {
BunqResponse<Integer> response = CashRegister.create(CASH_REGISTER_DESCRIPTION);
cashRegister = CashRegister.get(response.getValue()).getValue();
}

return apiContext;
return cashRegister;
}

}
private static boolean shouldMoneyBeRequested(MonetaryAccountBank monetaryAccountBank) {
return Float.parseFloat(monetaryAccountBank.getBalance().getValue()) < 10;
}
}
10 changes: 2 additions & 8 deletions src/test/java/com/bunq/sdk/http/PaginationScenarioTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,6 @@
*/
public class PaginationScenarioTest extends BunqSdkTestBase {

/**
* Config values.
*/
private static final Integer monetaryAccountId = Config.getMonetaryAccountId();
private static final Pointer counterPartyAliasOther = Config.getCounterPartyAliasOther();

/**
* Constants for scenario testing.
*/
Expand Down Expand Up @@ -65,11 +59,11 @@ private static List<Payment> GetPaymentsRequired() {
}

private static BunqResponse<List<Payment>> ListPayments(Map<String, String> urlParams) {
return Payment.list(monetaryAccountId, urlParams);
return Payment.list(null, urlParams);
}

private static void CreatePayment() {
Payment.create(new Amount(PAYMENT_AMOUNT_EUR, PAYMENT_CURRENCY), counterPartyAliasOther, PAYMENT_DESCRIPTION);
Payment.create(new Amount(PAYMENT_AMOUNT_EUR, PAYMENT_CURRENCY), getPointerBravo(), PAYMENT_DESCRIPTION);
}

@Test
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
package com.bunq.sdk.model.generated.endpoint;

import com.bunq.sdk.BunqSdkTestBase;
import com.bunq.sdk.Config;
import com.bunq.sdk.context.ApiContext;
import com.bunq.sdk.exception.BunqException;
import com.bunq.sdk.http.ApiClient;
import org.apache.commons.io.FileUtils;
import org.junit.Test;
Expand All @@ -24,30 +23,24 @@ public class AttachmentPublicTest extends BunqSdkTestBase {
/**
* Config values.
*/
private static final String contentType = Config.getContentType();
private static final String attachmentDescription = Config.getAttachmentDescription();
private static final String pathAttachmentIn = Config.getPathAttachmentIn();

private static final ApiContext apiContext = getApiContext();

private static byte[] getAttachmentPublicContentBytes(String uuid, ApiContext apiContext) {
private static byte[] getAttachmentPublicContentBytes(String uuid) {
return AttachmentPublicContent.list(uuid).getValue();
}

private static byte[] getRequestBytes(String path) {
private static byte[] getRequestBytes() {
try {
return FileUtils.readFileToByteArray(new File(path));
return FileUtils.readFileToByteArray(new File(BunqSdkTestBase.ATTACHMENT_PATH_IN));
} catch (IOException exception) {
return null;
throw new BunqException(exception.getMessage());
}
}

private static String uploadFileAndGetUuid() {
HashMap<String, String> customHeaders = new HashMap<>();
customHeaders.put(ApiClient.HEADER_CONTENT_TYPE, contentType);
customHeaders.put(ApiClient.HEADER_ATTACHMENT_DESCRIPTION, attachmentDescription);
customHeaders.put(ApiClient.HEADER_CONTENT_TYPE, CONTENT_TYPE);
customHeaders.put(ApiClient.HEADER_ATTACHMENT_DESCRIPTION, ATTACHMENT_DESCRIPTION);

byte[] RequestBytes = getRequestBytes(pathAttachmentIn);
byte[] RequestBytes = getRequestBytes();

return AttachmentPublic.create(customHeaders, RequestBytes).getValue();
}
Expand All @@ -56,13 +49,13 @@ private static String uploadFileAndGetUuid() {
* Tests if the file we upload is the file we are getting back with the received uuid
*/
@Test
public void fileUploadAndRetrievalTest() throws Exception {
public void fileUploadAndRetrievalTest() {
String uuidBefore = uploadFileAndGetUuid();
AttachmentPublic uuidFromAttachmentPublic = AttachmentPublic.get(uuidBefore)
.getValue();

byte[] requestBytes = getRequestBytes(pathAttachmentIn);
byte[] responseBytes = getAttachmentPublicContentBytes(uuidBefore, apiContext);
byte[] requestBytes = getRequestBytes();
byte[] responseBytes = getAttachmentPublicContentBytes(uuidBefore);

assertArrayEquals(requestBytes, responseBytes);
assertEquals(uuidBefore, uuidFromAttachmentPublic.getUuid());
Expand Down
Loading