Skip to content
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
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,9 @@ public final class Risk {
/**
* The risk score calculated by our Fraud Detection engine. Absent if not enough data provided.
* [Optional]
* Decimal number, for example 22.5
* [ 0 .. 100 ]
*/
private Integer score;
private Double score;

}
16 changes: 15 additions & 1 deletion src/main/java/com/checkout/payments/RiskAssessment.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,24 @@

import lombok.Data;

/**
* Returns the payment's risk assessment results.
*/
@Data
public final class RiskAssessment {

/**
* Whether or not the payment was flagged by a risk check.
* [Optional]
* Default: false
*/
private Boolean flagged;

private Integer score;
/**
* The risk score calculated by our Fraud Detection engine. Absent if not enough data provided.
* [Optional]
* Decimal number, for example 22.5
* [ 0 .. 100 ]
*/
private Double score;
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
package com.checkout.handlepaymentsandpayouts.payments.postpayments.responses.requestapaymentorpayoutresponsecreated;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertInstanceOf;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertTrue;

import org.junit.jupiter.api.Test;

Expand All @@ -18,6 +21,7 @@
import com.checkout.handlepaymentsandpayouts.payments.common.source.paypalsource.PaypalSource;
import com.checkout.handlepaymentsandpayouts.payments.common.source.sepasource.SepaSource;
import com.checkout.handlepaymentsandpayouts.payments.postpayments.responses.requestapaymentorpayoutresponsecreated.processing.Processing;
import com.checkout.handlepaymentsandpayouts.payments.postpayments.responses.requestapaymentorpayoutresponsecreated.risk.Risk;

public final class RequestAPaymentOrPayoutResponseCreatedSerializationTest {

Expand Down Expand Up @@ -244,4 +248,57 @@ void shouldDeserializeProcessingSchemeTransactionLinkId() {
assertEquals("MTL-XYZ-789", processing.getSchemeTransactionLinkId());
}

// ------------------------------------------------------------------------
// Risk
// Returns the payment's risk assessment results. score is type number,
// min 0, max 100, so a fractional value must deserialize without error
// and without rounding.
// ------------------------------------------------------------------------

@Test
void shouldDeserializeRiskWithFractionalScore() {
String json = "{\"id\":\"pay_123\",\"risk\":{\"flagged\":true,\"score\":22.5}}";

RequestAPaymentOrPayoutResponseCreated response = serializer.fromJson(json, RequestAPaymentOrPayoutResponseCreated.class);

Risk risk = response.getRisk();
assertNotNull(risk);
assertTrue(risk.getFlagged());
assertEquals(22.5, risk.getScore());
}

@Test
void shouldDeserializeRiskSwaggerExample() {
String json = "{\"id\":\"pay_123\",\"risk\":{\"flagged\":true,\"score\":22}}";

RequestAPaymentOrPayoutResponseCreated response = serializer.fromJson(json, RequestAPaymentOrPayoutResponseCreated.class);

assertEquals(22.0, response.getRisk().getScore());
}

@Test
void shouldDeserializeRiskBoundaryScores() {
assertEquals(0.0, serializer.fromJson("{\"score\":0}", Risk.class).getScore());
assertEquals(100.0, serializer.fromJson("{\"score\":100}", Risk.class).getScore());
}

@Test
void shouldDeserializeRiskWithNullScore() {
Risk risk = serializer.fromJson("{\"flagged\":false}", Risk.class);

assertFalse(risk.getFlagged());
assertNull(risk.getScore());
}

@Test
void shouldRoundTripRiskAllProperties() {
Risk original = Risk.builder().flagged(true).score(22.5).build();

String json = serializer.toJson(original);
Risk deserialized = serializer.fromJson(json, Risk.class);

assertTrue(json.contains("\"score\":22.5"), json);
assertEquals(original, deserialized);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
package com.checkout.payments;

import com.checkout.GsonSerializer;
import com.checkout.payments.response.GetPaymentResponse;
import com.checkout.payments.response.PaymentResponse;
import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertTrue;

class RiskAssessmentSerializationTest {

private final GsonSerializer serializer = new GsonSerializer();

// ------------------------------------------------------------------------
// RiskAssessment
// Returns the payment's risk assessment results. Covers both properties
// (flagged, score) against the risk object of the PaymentResponse and
// PaymentDetails schemas, where score is type number, min 0, max 100.
// ------------------------------------------------------------------------

@Test
void shouldDeserializeFractionalScoreWithoutRounding() {
final RiskAssessment risk = serializer.fromJson("{\"flagged\":true,\"score\":22.5}", RiskAssessment.class);

assertTrue(risk.getFlagged());
assertEquals(22.5, risk.getScore());
}

@Test
void shouldDeserializeWholeNumberScore() {
final RiskAssessment risk = serializer.fromJson("{\"flagged\":false,\"score\":22}", RiskAssessment.class);

assertFalse(risk.getFlagged());
assertEquals(22.0, risk.getScore());
}

@Test
void shouldDeserializeBoundaryScores() {
assertEquals(0.0, serializer.fromJson("{\"score\":0}", RiskAssessment.class).getScore());
assertEquals(100.0, serializer.fromJson("{\"score\":100}", RiskAssessment.class).getScore());
}

@Test
void shouldDeserializeWithNullOptionalProperties() {
final RiskAssessment risk = serializer.fromJson("{}", RiskAssessment.class);

assertNull(risk.getFlagged());
assertNull(risk.getScore());
}

@Test
void shouldSerializeFractionalScore() {
final RiskAssessment risk = new RiskAssessment();
risk.setFlagged(true);
risk.setScore(22.5);

final String json = serializer.toJson(risk);

assertTrue(json.contains("\"flagged\":true"), json);
assertTrue(json.contains("\"score\":22.5"), json);
}

@Test
void shouldRoundTripAllProperties() {
final RiskAssessment original = new RiskAssessment();
original.setFlagged(true);
original.setScore(22.5);

final RiskAssessment deserialized = serializer.fromJson(serializer.toJson(original), RiskAssessment.class);

assertEquals(original, deserialized);
assertEquals(22.5, deserialized.getScore());
}

@Test
void shouldDeserializeSwaggerExampleInGetPaymentResponse() {
final String json = "{\"id\":\"pay_mbabizu24mvu3mela5njyhpit4\",\"risk\":{\"flagged\":true,\"score\":22}}";

final GetPaymentResponse response = serializer.fromJson(json, GetPaymentResponse.class);

assertNotNull(response.getRisk());
assertTrue(response.getRisk().getFlagged());
assertEquals(22.0, response.getRisk().getScore());
}

@Test
void shouldDeserializeFractionalScoreInGetPaymentResponse() {
final String json = "{\"id\":\"pay_123\",\"risk\":{\"flagged\":true,\"score\":22.5}}";

final GetPaymentResponse response = serializer.fromJson(json, GetPaymentResponse.class);

assertEquals(22.5, response.getRisk().getScore());
}

@Test
void shouldDeserializeFractionalScoreInPaymentResponse() {
final String json = "{\"id\":\"pay_123\",\"risk\":{\"flagged\":false,\"score\":22.7}}";

final PaymentResponse response = serializer.fromJson(json, PaymentResponse.class);

assertEquals(22.7, response.getRisk().getScore());
}
}
Loading