Skip to content

Commit

Permalink
feat(ACL-251): Adds method to generate SU+ Authentication URI for FI …
Browse files Browse the repository at this point in the history
…payments (#332)
  • Loading branch information
dili91 authored Dec 20, 2024
1 parent 653cd57 commit 1058d1a
Show file tree
Hide file tree
Showing 12 changed files with 131 additions and 20 deletions.
1 change: 1 addition & 0 deletions .github/pull_request_template.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ Please select multiple options if required.

# Checklist:

- [ ] I have updated the `gradle.properties` file with the new version
- [ ] My code follows the style guidelines of this project
- [ ] I have performed a self-review of my own code
- [ ] I have commented my code where necessary
Expand Down
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ dependencies {
implementation group: 'org.tinylog', name: 'tinylog-impl', version: tinyLogVersion

// JUnit test framework.
testImplementation group: 'org.junit.jupiter', name: 'junit-jupiter', version: '5.11.3'
testImplementation group: 'org.junit.jupiter', name: 'junit-jupiter', version: '5.11.4'

// Mocking libraries
testImplementation group: 'org.mockito', name: 'mockito-core', version: '5.14.2'
Expand Down
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Main properties
group=com.truelayer
archivesBaseName=truelayer-java
version=16.2.0
version=16.3.0

# Artifacts properties
sonatype_repository_url=https://s01.oss.sonatype.org/service/local/
Expand Down
10 changes: 7 additions & 3 deletions src/main/java/com/truelayer/java/signupplus/ISignupPlusApi.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@

import com.truelayer.java.entities.RequestScopes;
import com.truelayer.java.http.entities.ApiResponse;
import com.truelayer.java.signupplus.entities.GenerateAuthUriRequest;
import com.truelayer.java.signupplus.entities.GenerateAuthUriResponse;
import com.truelayer.java.signupplus.entities.UserData;
import java.util.concurrent.CompletableFuture;
import retrofit2.http.GET;
import retrofit2.http.Query;
import retrofit2.http.Tag;
import retrofit2.http.*;

public interface ISignupPlusApi {

Expand All @@ -20,4 +20,8 @@ public interface ISignupPlusApi {
@GET("/signup-plus/payments")
CompletableFuture<ApiResponse<UserData>> getUserDataByPayment(
@Tag RequestScopes scopes, @Query("payment_id") String paymentId);

@POST("/signup-plus/authuri")
CompletableFuture<ApiResponse<GenerateAuthUriResponse>> generateAuthUri(
@Tag RequestScopes scopes, @Body GenerateAuthUriRequest request);
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
package com.truelayer.java.signupplus;

import com.truelayer.java.http.entities.ApiResponse;
import com.truelayer.java.signupplus.entities.GenerateAuthUriRequest;
import com.truelayer.java.signupplus.entities.GenerateAuthUriResponse;
import com.truelayer.java.signupplus.entities.UserData;
import java.util.concurrent.CompletableFuture;

public interface ISignupPlusHandler {

CompletableFuture<ApiResponse<UserData>> getUserDataByPayment(String paymentId);

CompletableFuture<ApiResponse<GenerateAuthUriResponse>> generateAuthUri(GenerateAuthUriRequest request);
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
import com.truelayer.java.IAuthenticatedHandler;
import com.truelayer.java.entities.RequestScopes;
import com.truelayer.java.http.entities.ApiResponse;
import com.truelayer.java.signupplus.entities.GenerateAuthUriRequest;
import com.truelayer.java.signupplus.entities.GenerateAuthUriResponse;
import com.truelayer.java.signupplus.entities.UserData;
import java.util.concurrent.CompletableFuture;
import lombok.Builder;
Expand All @@ -26,4 +28,9 @@ public RequestScopes getRequestScopes() {
public CompletableFuture<ApiResponse<UserData>> getUserDataByPayment(String paymentId) {
return signupPlusApi.getUserDataByPayment(getRequestScopes(), paymentId);
}

@Override
public CompletableFuture<ApiResponse<GenerateAuthUriResponse>> generateAuthUri(GenerateAuthUriRequest request) {
return signupPlusApi.generateAuthUri(getRequestScopes(), request);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.truelayer.java.signupplus.entities;

import lombok.Builder;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.ToString;

@Builder
@Getter
@ToString
@EqualsAndHashCode
public class GenerateAuthUriRequest {
private String paymentId;

private String state;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.truelayer.java.signupplus.entities;

import java.net.URI;
import lombok.ToString;
import lombok.Value;

@ToString
@Value
public class GenerateAuthUriResponse {
URI authUri;
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@

import com.truelayer.java.TestUtils;
import com.truelayer.java.entities.*;
import com.truelayer.java.entities.accountidentifier.AccountIdentifier;
import com.truelayer.java.entities.accountidentifier.IbanAccountIdentifier;
import com.truelayer.java.entities.accountidentifier.SortCodeAccountNumberAccountIdentifier;
import com.truelayer.java.http.entities.ApiResponse;
import com.truelayer.java.merchantaccounts.entities.MerchantAccount;
Expand All @@ -14,6 +16,8 @@
import com.truelayer.java.payments.entities.paymentmethod.PaymentMethod;
import com.truelayer.java.payments.entities.providerselection.ProviderSelection;
import com.truelayer.java.payments.entities.schemeselection.preselected.SchemeSelection;
import com.truelayer.java.signupplus.entities.GenerateAuthUriRequest;
import com.truelayer.java.signupplus.entities.GenerateAuthUriResponse;
import com.truelayer.java.signupplus.entities.UserData;
import java.net.URI;
import java.time.LocalDate;
Expand Down Expand Up @@ -45,10 +49,34 @@ public void itShouldAuthorizeAUkPaymentAndThenQueryTheAssociatedIdentityData() {
assertNotError(userDataResponse);
}

@Test
@DisplayName("It should create a payment and generate an auth URI via Signup+ in FI")
@SneakyThrows
public void itShouldAuthorizeAFinPaymentAndThenGenerateAnAuthUri() {
// Create and authorize a payment
String paymentId = createAndAuthorizePayment("mock-payments-fi-redirect", CurrencyCode.EUR, RETURN_URI);
waitForPaymentStatusUpdate(tlClient, paymentId, Status.EXECUTED);

ApiResponse<GenerateAuthUriResponse> generateAuthUriResponse = tlClient.signupPlus()
.generateAuthUri(
GenerateAuthUriRequest.builder().paymentId(paymentId).build())
.get();
assertNotError(generateAuthUriResponse);
}

@SneakyThrows
private String createAndAuthorizePayment(String providerId, CurrencyCode currencyCode, URI returnUri) {
MerchantAccount account = getMerchantAccount(currencyCode);

AccountIdentifier accountIdentifier = SortCodeAccountNumberAccountIdentifier.builder()
.accountNumber("31510604")
.sortCode("100000")
.build();
if (currencyCode == CurrencyCode.EUR) {
accountIdentifier =
IbanAccountIdentifier.iban().iban("FI4950009420028730").build();
}

CreatePaymentRequest paymentRequest = CreatePaymentRequest.builder()
.amountInMinor(ThreadLocalRandom.current().nextInt(50, 500))
.currency(currencyCode)
Expand All @@ -58,11 +86,8 @@ private String createAndAuthorizePayment(String providerId, CurrencyCode currenc
.schemeSelection(
SchemeSelection.instantPreferred().build())
.remitter(Remitter.builder()
.accountHolderName("Andrea Di Lisio")
.accountIdentifier(SortCodeAccountNumberAccountIdentifier.builder()
.accountNumber("12345678")
.sortCode("123456")
.build())
.accountHolderName("John Doe")
.accountIdentifier(accountIdentifier)
.build())
.build())
.beneficiary(Beneficiary.merchantAccount()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@
import static com.github.tomakehurst.wiremock.client.WireMock.urlPathEqualTo;
import static com.truelayer.java.Constants.Scopes.SIGNUP_PLUS;
import static com.truelayer.java.TestUtils.assertNotError;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertTrue;

import com.truelayer.java.TestUtils.RequestStub;
import com.truelayer.java.http.entities.ApiResponse;
import com.truelayer.java.signupplus.entities.Address;
import com.truelayer.java.signupplus.entities.Sex;
import com.truelayer.java.signupplus.entities.UserData;
import com.truelayer.java.signupplus.entities.*;
import java.util.Collections;
import lombok.SneakyThrows;
import org.junit.jupiter.api.Assertions;
Expand Down Expand Up @@ -51,9 +51,8 @@ public void shouldGetUserDataByPaymentUk() {
Assertions.assertEquals("Holmes", response.getData().getLastName().orElseThrow());
Assertions.assertEquals(
"1854-01-06", response.getData().getDateOfBirth().orElseThrow());
Assertions.assertTrue(response.getData().getSex().isEmpty());
Assertions.assertTrue(
response.getData().getNationalIdentificationNumber().isEmpty());
assertTrue(response.getData().getSex().isEmpty());
assertTrue(response.getData().getNationalIdentificationNumber().isEmpty());
Address address = response.getData().getAddress().orElseThrow();
Assertions.assertEquals("221B Baker St", address.getAddressLine1().orElseThrow());
Assertions.assertEquals("Flat 2", address.getAddressLine2().orElseThrow());
Expand Down Expand Up @@ -89,7 +88,7 @@ public void shouldGetUserDataByPaymentFinland() {
verifyGeneratedToken(Collections.singletonList(SIGNUP_PLUS));
assertNotError(response);

Assertions.assertTrue(response.getData().getTitle().isEmpty());
assertTrue(response.getData().getTitle().isEmpty());
Assertions.assertEquals("Väinö", response.getData().getFirstName().orElseThrow());
Assertions.assertEquals("Tunnistus", response.getData().getLastName().orElseThrow());
Assertions.assertEquals(
Expand All @@ -100,10 +99,40 @@ public void shouldGetUserDataByPaymentFinland() {
response.getData().getNationalIdentificationNumber().orElseThrow());
Address address = response.getData().getAddress().orElseThrow();
Assertions.assertEquals("Sepänkatu 11 A 5", address.getAddressLine1().orElseThrow());
Assertions.assertTrue(address.getAddressLine2().isEmpty());
assertTrue(address.getAddressLine2().isEmpty());
Assertions.assertEquals("KUOPIO", address.getCity().orElseThrow());
Assertions.assertTrue(address.getState().isEmpty());
assertTrue(address.getState().isEmpty());
Assertions.assertEquals("70100", address.getZip().orElseThrow());
Assertions.assertEquals("FI", address.getCountry().orElseThrow());
}

@Test
@DisplayName("It should generate an auth URI for a payment in Finland")
@SneakyThrows
public void shouldGenerateAuthUriByPaymentFinland() {
String jsonResponseFile = "signup_plus/200.generate_auth_uri.json";
RequestStub.New()
.method("post")
.path(urlPathEqualTo("/connect/token"))
.status(200)
.bodyFile("auth/200.access_token.json")
.build();
RequestStub.New()
.method("post")
.path(urlPathEqualTo("/signup-plus/authuri"))
.withAuthorization()
.status(200)
.bodyFile(jsonResponseFile)
.build();

ApiResponse<GenerateAuthUriResponse> response = tlClient.signupPlus()
.generateAuthUri(
GenerateAuthUriRequest.builder().paymentId(A_PAYMENT_ID).build())
.get();

verifyGeneratedToken(Collections.singletonList(SIGNUP_PLUS));
assertNotError(response);
assertNotNull(response.getData().getAuthUri());
assertTrue(response.getData().getAuthUri().toString().contains("truelayer.com"));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

import com.truelayer.java.Constants;
import com.truelayer.java.entities.RequestScopes;
import com.truelayer.java.signupplus.entities.GenerateAuthUriRequest;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
Expand Down Expand Up @@ -32,9 +33,19 @@ public void setup() {

@Test
@DisplayName("It should call the get user data by payment endpoint")
public void shouldCallCreatePayoutEndpoint() {
public void shouldCallGetUserDataByPaymentEndpoint() {
sut.getUserDataByPayment(A_PAYMENT_ID);

verify(signupPlusApiMock, times(1)).getUserDataByPayment(SCOPES, A_PAYMENT_ID);
}

@Test
@DisplayName("It should call the generate auth URI endpoint")
public void shouldCallGenerateAuthUriEndpoint() {
var generateAuthUriRequest =
GenerateAuthUriRequest.builder().paymentId(A_PAYMENT_ID).build();
sut.generateAuthUri(generateAuthUriRequest);

verify(signupPlusApiMock, times(1)).generateAuthUri(SCOPES, generateAuthUriRequest);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"auth_uri": "https://truelayer.com/redirect?id=863619242079485953&uuid=b912cc0d-149b-40a2-8a24-79a9d1f0913e"
}

0 comments on commit 1058d1a

Please sign in to comment.