Skip to content

Commit

Permalink
[ACL-180] Add preselected scheme selection to preselected provider (#312
Browse files Browse the repository at this point in the history
)

Co-authored-by: Andrea Di Lisio <[email protected]>
  • Loading branch information
tl-luca-baggi and dili91 authored Sep 17, 2024
1 parent 36cf23f commit a51d5b8
Show file tree
Hide file tree
Showing 16 changed files with 437 additions and 63 deletions.
8 changes: 4 additions & 4 deletions build.gradle
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
plugins {
id 'java-library'
// to unleash the lombok magic
id "io.freefair.lombok" version "8.6"
id "io.freefair.lombok" version "8.10"
// to make our tests output more fancy
id 'com.adarshr.test-logger' version '4.0.0'
// to publish packages
Expand Down Expand Up @@ -108,14 +108,14 @@ dependencies {
implementation group: 'org.tinylog', name: 'tinylog-impl', version: tinyLogVersion

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

// Mocking libraries
testImplementation group: 'org.mockito', name: 'mockito-core', version: '5.12.0'
testImplementation group: 'org.mockito', name: 'mockito-core', version: '5.13.0'
testImplementation group: 'org.wiremock', name: 'wiremock', version: '3.9.1'

// Wait test utility
testImplementation group: 'org.awaitility', name: 'awaitility', version: '4.2.1'
testImplementation group: 'org.awaitility', name: 'awaitility', version: '4.2.2'

// Transitive dependencies constraints
constraints {
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=13.3.0
version=14.0.0

# Artifacts properties
sonatype_repository_url=https://s01.oss.sonatype.org/service/local/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import com.truelayer.java.entities.Remitter;
import com.truelayer.java.payments.entities.SchemeId;
import com.truelayer.java.payments.entities.schemeselection.preselected.SchemeSelection;
import lombok.Builder;
import lombok.EqualsAndHashCode;
import lombok.Getter;
Expand All @@ -21,5 +22,7 @@ public class PreselectedProviderSelection extends ProviderSelection {
*/
private SchemeId schemeId;

private SchemeSelection schemeSelection;

private String dataAccessToken;
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import com.truelayer.java.entities.ProviderFilter;
import com.truelayer.java.payments.entities.SchemeId;
import com.truelayer.java.payments.entities.schemeselection.SchemeSelection;
import com.truelayer.java.payments.entities.schemeselection.userselected.SchemeSelection;
import lombok.Builder;
import lombok.EqualsAndHashCode;
import lombok.Getter;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.truelayer.java.payments.entities.schemeselection;
package com.truelayer.java.payments.entities.schemeselection.preselected;

import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Builder;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.truelayer.java.payments.entities.schemeselection;
package com.truelayer.java.payments.entities.schemeselection.preselected;

import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Builder;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package com.truelayer.java.payments.entities.schemeselection.preselected;

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

@Getter
@Builder
@EqualsAndHashCode(callSuper = false)
@ToString
public class PreselectedSchemeSelection extends SchemeSelection {

private final Type type = Type.PRESELECTED;

private String schemeId;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
package com.truelayer.java.payments.entities.schemeselection.preselected;

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonSubTypes;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.annotation.JsonValue;
import com.truelayer.java.TrueLayerException;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import lombok.ToString;

@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "type", defaultImpl = InstantOnlySchemeSelection.class)
@JsonSubTypes({
@JsonSubTypes.Type(value = InstantOnlySchemeSelection.class, name = "instant_only"),
@JsonSubTypes.Type(value = InstantPreferredSchemeSelection.class, name = "instant_preferred"),
@JsonSubTypes.Type(value = PreselectedSchemeSelection.class, name = "preselected"),
})
@Getter
@ToString
@EqualsAndHashCode
public abstract class SchemeSelection {

@JsonIgnore
public abstract Type getType();

public static InstantOnlySchemeSelection.InstantOnlySchemeSelectionBuilder instantOnly() {
return InstantOnlySchemeSelection.builder();
}

public static InstantPreferredSchemeSelection.InstantPreferredSchemeSelectionBuilder instantPreferred() {
return InstantPreferredSchemeSelection.builder();
}

public static PreselectedSchemeSelection.PreselectedSchemeSelectionBuilder preselected() {
return PreselectedSchemeSelection.builder();
}

@JsonIgnore
public boolean isInstantOnly() {
return this instanceof InstantOnlySchemeSelection;
}

@JsonIgnore
public boolean isInstantPreferred() {
return this instanceof InstantPreferredSchemeSelection;
}

@JsonIgnore
public boolean isPreselected() {
return this instanceof PreselectedSchemeSelection;
}

@JsonIgnore
public InstantOnlySchemeSelection asInstantOnly() {
if (!isInstantOnly()) {
throw new TrueLayerException(buildErrorMessage());
}
return (InstantOnlySchemeSelection) this;
}

@JsonIgnore
public InstantPreferredSchemeSelection asInstantPreferred() {
if (!isInstantPreferred()) {
throw new TrueLayerException(buildErrorMessage());
}
return (InstantPreferredSchemeSelection) this;
}

@JsonIgnore
public PreselectedSchemeSelection asPreselected() {
if (!isPreselected()) {
throw new TrueLayerException(buildErrorMessage());
}
return (PreselectedSchemeSelection) this;
}

private String buildErrorMessage() {
return String.format("Scheme selection is of type %s.", this.getClass().getSimpleName());
}

@RequiredArgsConstructor
@Getter
public enum Type {
INSTANT_ONLY("instant_only"),
INSTANT_PREFERRED("instant_preferred"),
PRESELECTED("preselected");

@JsonValue
private final String type;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package com.truelayer.java.payments.entities.schemeselection.userselected;

import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Builder;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.ToString;
import lombok.experimental.Accessors;

@Getter
@Builder
@EqualsAndHashCode(callSuper = false)
@ToString
public class InstantOnlySchemeSelection extends SchemeSelection {
private final Type type = Type.INSTANT_ONLY;

@Accessors(fluent = true)
@JsonProperty // Jackson's @JsonProperty is required for serialization to work as expected
private boolean allowRemitterFee;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package com.truelayer.java.payments.entities.schemeselection.userselected;

import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Builder;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.ToString;
import lombok.experimental.Accessors;

@Getter
@Builder
@EqualsAndHashCode(callSuper = false)
@ToString
public class InstantPreferredSchemeSelection extends SchemeSelection {
private final Type type = Type.INSTANT_PREFERRED;

@Accessors(fluent = true)
@JsonProperty // Jackson's @JsonProperty is required for serialization to work as expected
private boolean allowRemitterFee;
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
package com.truelayer.java.payments.entities.schemeselection;
package com.truelayer.java.payments.entities.schemeselection.userselected;

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonSubTypes;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.annotation.JsonValue;
import lombok.*;
import com.truelayer.java.TrueLayerException;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import lombok.ToString;

@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "type", defaultImpl = InstantOnlySchemeSelection.class)
@JsonSubTypes({
Expand All @@ -15,6 +19,7 @@
@ToString
@EqualsAndHashCode
public abstract class SchemeSelection {

@JsonIgnore
public abstract Type getType();

Expand All @@ -29,6 +34,36 @@ public static InstantPreferredSchemeSelection.InstantPreferredSchemeSelectionBui
return InstantPreferredSchemeSelection.builder();
}

@JsonIgnore
public boolean isInstantOnly() {
return this instanceof InstantOnlySchemeSelection;
}

@JsonIgnore
public boolean isInstantPreferred() {
return this instanceof InstantPreferredSchemeSelection;
}

@JsonIgnore
public InstantOnlySchemeSelection asInstantOnly() {
if (!isInstantOnly()) {
throw new TrueLayerException(buildErrorMessage());
}
return (InstantOnlySchemeSelection) this;
}

@JsonIgnore
public InstantPreferredSchemeSelection asInstantPreferred() {
if (!isInstantPreferred()) {
throw new TrueLayerException(buildErrorMessage());
}
return (InstantPreferredSchemeSelection) this;
}

private String buildErrorMessage() {
return String.format("Scheme selection is of type %s.", this.getClass().getSimpleName());
}

@RequiredArgsConstructor
@Getter
public enum Type {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
import com.truelayer.java.payments.entities.providerselection.PreselectedProviderSelection;
import com.truelayer.java.payments.entities.providerselection.ProviderSelection;
import com.truelayer.java.payments.entities.providerselection.UserSelectedProviderSelection;
import com.truelayer.java.payments.entities.schemeselection.SchemeSelection;
import com.truelayer.java.payments.entities.schemeselection.userselected.SchemeSelection;
import com.truelayer.java.payments.entities.verification.AutomatedVerification;
import com.truelayer.java.payments.entities.verification.Verification;
import com.truelayer.java.versioninfo.LibraryInfoLoader;
Expand Down Expand Up @@ -103,6 +103,49 @@ public void shouldCreateAPaymentWithUserSelectionProvider(CurrencyCode currency,
assertEquals(getPaymentByIdResponse.getData().getPaymentMethod(), paymentRequest.getPaymentMethod());
}

@Test
@DisplayName("It should create and get by id a payment with preselected provider and preselected scheme_selection")
@SneakyThrows
public void shouldCreateAPaymentWithPreselectedProviderAndPreselectedSchemeSelection() {
// create payment
PreselectedProviderSelection preselectedProvider = ProviderSelection.preselected()
.providerId(PROVIDER_ID)
.schemeSelection(
com.truelayer.java.payments.entities.schemeselection.preselected.SchemeSelection.preselected()
.schemeId("faster_payments_service")
.build())
.build();
CreatePaymentRequest paymentRequest =
buildPaymentRequestWithProviderSelection(preselectedProvider, CurrencyCode.GBP);

ApiResponse<CreatePaymentResponse> createPaymentResponse =
tlClient.payments().createPayment(paymentRequest).get();

assertNotError(createPaymentResponse);
assertTrue(createPaymentResponse.getData().isAuthorizationRequired());

// get it by id
ApiResponse<PaymentDetail> getPaymentByIdResponse = tlClient.payments()
.getPayment(createPaymentResponse.getData().getId())
.get();

assertNotError(getPaymentByIdResponse);

ProviderSelection providerSelection = getPaymentByIdResponse
.getData()
.getPaymentMethod()
.asBankTransfer()
.getProviderSelection();
assertTrue(providerSelection.asPreselected().getSchemeSelection().isPreselected());
assertEquals(
providerSelection
.asPreselected()
.getSchemeSelection()
.asPreselected()
.getSchemeId(),
"faster_payments_service");
}

@Test
@DisplayName("It should create a payment to be used with Signup+")
@SneakyThrows
Expand All @@ -128,12 +171,15 @@ public void itShouldCreateAPaymentWithSignupPlusIntention() {
public void itShouldCreateAPaymentWithAutomatedVerification(Verification verification) {
CurrencyCode currency = CurrencyCode.GBP;
MerchantAccount account = getMerchantAccount(currency);
CreatePaymentRequest.CreatePaymentRequestBuilder builder = CreatePaymentRequest.builder()
CreatePaymentRequest.CreatePaymentRequestBuilder createPaymentRequestBuilder = CreatePaymentRequest.builder()
.amountInMinor(100)
.currency(currency)
.paymentMethod(PaymentMethod.bankTransfer()
.providerSelection(ProviderSelection.preselected()
.providerId(PROVIDER_ID)
.schemeSelection(com.truelayer.java.payments.entities.schemeselection.preselected
.SchemeSelection.instantPreferred()
.build())
.build())
.beneficiary(Beneficiary.merchantAccount()
.merchantAccountId(account.getId())
Expand All @@ -155,8 +201,7 @@ public void itShouldCreateAPaymentWithAutomatedVerification(Verification verific
.build());

ApiResponse<CreatePaymentResponse> createPaymentResponse = tlClient.payments()
.createPayment(buildPaymentRequestWithProviderSelection(
buildPreselectedProviderSelection(), CurrencyCode.GBP, null, null, null))
.createPayment(createPaymentRequestBuilder.build())
.get();

assertNotError(createPaymentResponse);
Expand Down
Loading

0 comments on commit a51d5b8

Please sign in to comment.