Skip to content

Commit

Permalink
HPP link builder implemented with tests
Browse files Browse the repository at this point in the history
  • Loading branch information
tl-andrea-dilisio committed Jan 5, 2022
1 parent 822ad7d commit 1f02664
Show file tree
Hide file tree
Showing 9 changed files with 177 additions and 3 deletions.
3 changes: 3 additions & 0 deletions lib/src/main/java/truelayer/java/ITrueLayerClient.java
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
package truelayer.java;

import truelayer.java.auth.IAuthenticationHandler;
import truelayer.java.hpp.IHostedPaymentPageLinkBuilder;
import truelayer.java.payments.IPaymentHandler;

public interface ITrueLayerClient {
IAuthenticationHandler auth();

IPaymentHandler payments();

IHostedPaymentPageLinkBuilder hpp();
}
23 changes: 22 additions & 1 deletion lib/src/main/java/truelayer/java/TrueLayerClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
import truelayer.java.auth.AuthenticationHandler;
import truelayer.java.auth.IAuthenticationApi;
import truelayer.java.auth.IAuthenticationHandler;
import truelayer.java.hpp.HostedPaymentPageLinkBuilder;
import truelayer.java.hpp.IHostedPaymentPageLinkBuilder;
import truelayer.java.http.HttpClientFactory;
import truelayer.java.payments.IPaymentHandler;
import truelayer.java.payments.IPaymentsApi;
Expand All @@ -27,6 +29,7 @@ public class TrueLayerClient implements ITrueLayerClient {

private IAuthenticationHandler authenticationHandler;
private IPaymentHandler paymentHandler;
private IHostedPaymentPageLinkBuilder hppBuilder;

public TrueLayerClient(ClientCredentialsOptions clientCredentialsOptions,
Optional<SigningOptions> signingOptions, boolean useSandbox) {
Expand Down Expand Up @@ -81,7 +84,17 @@ public IPaymentHandler payments() {
.signingOptions(signingOptions)
.build();
}
return paymentHandler;
return this.paymentHandler;
}

@Override
public IHostedPaymentPageLinkBuilder hpp() {
if (ObjectUtils.isEmpty(this.hppBuilder)) {
this.hppBuilder = HostedPaymentPageLinkBuilder.builder()
.endpoint(getHppEndpointUrl())
.build();
}
return this.hppBuilder;
}

public boolean useSandbox(){
Expand All @@ -98,6 +111,11 @@ private String getPaymentsEndpointUrl(){
return this.configuration.getString(endpointKey);
}

private String getHppEndpointUrl(){
var endpointKey = useSandbox ? HPP_ENDPOINT_URL_SANDBOX: HPP_ENDPOINT_URL_LIVE;
return this.configuration.getString(endpointKey);
}

private String[] getPaymentsScopes() {
return this.configuration.getStringArray(PAYMENTS_SCOPES);
}
Expand All @@ -109,6 +127,9 @@ public static class ConfigurationKeys {
public static final String PAYMENTS_ENDPOINT_URL_LIVE = "tl.payments.endpoint.live";
public static final String PAYMENTS_ENDPOINT_URL_SANDBOX = "tl.payments.endpoint.sandbox";
public static final String PAYMENTS_SCOPES = "tl.payments.scopes";

public static final String HPP_ENDPOINT_URL_LIVE = "tl.hpp.endpoint.live";
public static final String HPP_ENDPOINT_URL_SANDBOX = "tl.hpp.endpoint.sandbox";
}

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package truelayer.java.hpp;

import lombok.Builder;
import lombok.Getter;
import truelayer.java.TrueLayerException;

import java.net.URI;

import static org.apache.commons.lang3.ObjectUtils.isEmpty;

@Builder
@Getter
public class HostedPaymentPageLinkBuilder implements IHostedPaymentPageLinkBuilder {
private String endpoint;

@Override
public URI getHostedPaymentPageLink(String paymentId, String resourceToken, URI returnUrl) {
if(isEmpty(paymentId)){
throw new TrueLayerException("payment_id must be set");
}

if(isEmpty(resourceToken)){
throw new TrueLayerException("resource_token must be set");
}

if(isEmpty(returnUrl) || isEmpty(returnUrl.toString())){
throw new TrueLayerException("return_url must be set");
}

var link = String.format("%s/payments#payment_id=%s&resource_token=%s&return_url=%s",
endpoint,
paymentId,
resourceToken,
returnUrl);
return URI.create(link);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package truelayer.java.hpp;

import java.net.URI;

public interface IHostedPaymentPageLinkBuilder {
URI getHostedPaymentPageLink(String paymentId, String resourceToken, URI returnUrl);
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
import truelayer.java.payments.entities.CreatePaymentRequest;
import truelayer.java.payments.entities.Payment;

import java.net.URI;

public interface IPaymentHandler {

ApiResponse<Payment> createPayment(CreatePaymentRequest request);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import truelayer.java.signing.Signer;

import java.io.IOException;
import java.net.URI;
import java.util.Arrays;
import java.util.UUID;

Expand All @@ -23,6 +24,7 @@ public class PaymentHandler implements IPaymentHandler {
private IAuthenticationHandler authenticationHandler;
private IPaymentsApi paymentsApi;
private String[] paymentsScopes;
private URI hostedPaymentPageEndpoint;

private SigningOptions signingOptions;

Expand Down Expand Up @@ -57,7 +59,6 @@ public ApiResponse<Payment> getPayment(String paymentId) {
}
}


private String signRequest(String idempotencyKey, String jsonRequest, String path) {
byte[] privateKey = signingOptions.getPrivateKey();

Expand Down
5 changes: 4 additions & 1 deletion lib/src/main/resources/application.properties
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,7 @@ tl.auth.endpoint.sandbox=https://auth.truelayer-sandbox.com

tl.payments.endpoint.live=https://test-pay-api.truelayer.com
tl.payments.endpoint.sandbox=https://test-pay-api.truelayer-sandbox.com
tl.payments.scopes=payments
tl.payments.scopes=payments

tl.hpp.endpoint.live=https://checkout.truelayer.com
tl.hpp.endpoint.sandbox=https://checkout.truelayer-sandbox.com
26 changes: 26 additions & 0 deletions lib/src/test/java/truelayer/java/TrueLayerClientTests.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import truelayer.java.auth.AuthenticationHandler;
import truelayer.java.hpp.HostedPaymentPageLinkBuilder;
import truelayer.java.payments.PaymentHandler;

import static org.junit.jupiter.api.Assertions.*;
Expand Down Expand Up @@ -70,6 +71,31 @@ public void itShouldYieldTheSamePaymentHandler() {
assertTrue(paymentHandler1 == paymentHandler2);
}

@Test
@DisplayName("It should yield an HPP link builder")
public void itShouldBuildAnHppLinkBuilder() {
var trueLayerClient = TrueLayerClient.builder()
.build();

var hppLinkBuilder = (HostedPaymentPageLinkBuilder) trueLayerClient.hpp();

assertNotNull(hppLinkBuilder);
assertNotNull(hppLinkBuilder.getEndpoint());
}

@Test
@DisplayName("It should yield the same instance of the HPP link builder if hpp() is called multiple times")
@SneakyThrows
public void itShouldYieldTheSameHppLinkBuilder() {
var trueLayerClient = TrueLayerClient.builder()
.build();

var hpp1 = trueLayerClient.hpp();
var hpp2 = trueLayerClient.hpp();

assertTrue(hpp1 == hpp2);
}

@Test
@DisplayName("It should throw an exception if credentials options are missing")
@SneakyThrows
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
package truelayer.java.hpp;

import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import truelayer.java.TrueLayerException;

import java.net.URI;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;

class HostedPaymentPageLinkBuilderTests {

public static final String AN_ENDPOINT = "https://an-endpoint.com";
public static final String A_RETURN_URL = "https://a-redirect-url.com";
public static final String A_RESOURCE_TOKEN = "a-resource-token";
public static final String A_PAYMENT_ID = "a-payment-id";

@Test
@DisplayName("it should yield an HPP link with the given details")
public void itShouldYieldAnHppLink() {
var sut = buildHppBuilder();

var link = sut.getHostedPaymentPageLink(A_PAYMENT_ID, A_RESOURCE_TOKEN, URI.create(A_RETURN_URL));

assertEquals(
new StringBuilder(AN_ENDPOINT)
.append("/payments#payment_id=")
.append(A_PAYMENT_ID)
.append("&resource_token=")
.append(A_RESOURCE_TOKEN)
.append("&return_url=")
.append(A_RETURN_URL)
.toString(),
link.toString()
);
}

@Test
@DisplayName("it should thrown an exception if redirect_url is empty")
public void itShouldThrowExceptionForEmptyRedirectUrl() {
var sut = buildHppBuilder();

var thrown = assertThrows(TrueLayerException.class, () -> sut.getHostedPaymentPageLink(A_PAYMENT_ID, A_RESOURCE_TOKEN, URI.create("")));

assertEquals("return_url must be set", thrown.getMessage());
}

@Test
@DisplayName("it should thrown an exception if payment_id is empty")
public void itShouldThrowExceptionForEmptyPaymentId() {
var sut = buildHppBuilder();

var thrown = assertThrows(TrueLayerException.class, () -> sut.getHostedPaymentPageLink("", A_RESOURCE_TOKEN, URI.create(A_RETURN_URL)));

assertEquals("payment_id must be set", thrown.getMessage());
}

@Test
@DisplayName("it should thrown an exception if resource_token is empty")
public void itShouldThrowExceptionForEmptyResourceToken() {
var sut = buildHppBuilder();

var thrown = assertThrows(TrueLayerException.class, () -> sut.getHostedPaymentPageLink(A_PAYMENT_ID, "", URI.create(A_RETURN_URL)));

assertEquals("resource_token must be set", thrown.getMessage());
}

private HostedPaymentPageLinkBuilder buildHppBuilder() {
return HostedPaymentPageLinkBuilder.builder()
.endpoint(AN_ENDPOINT)
.build();
}
}

0 comments on commit 1f02664

Please sign in to comment.