Add user interaction for hook list (#49)

This commit is contained in:
struga 2024-02-29 14:56:52 +07:00 committed by GitHub
parent 360468eaef
commit a2dd68f8db
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
17 changed files with 462 additions and 6 deletions

View File

@ -81,7 +81,7 @@
<dependency>
<groupId>dev.vality</groupId>
<artifactId>damsel</artifactId>
<version>1.611-958e5f0</version>
<version>1.619-da17a84</version>
</dependency>
<dependency>
<groupId>dev.vality</groupId>
@ -127,7 +127,7 @@
<dependency>
<groupId>dev.vality</groupId>
<artifactId>swag-webhook-events</artifactId>
<version>1.112-a02ceb6-client</version>
<version>1.122-9daaca8-client</version>
</dependency>
<dependency>
<groupId>dev.vality</groupId>

View File

@ -0,0 +1,56 @@
package dev.vality.hooker.converter;
import dev.vality.damsel.payment_processing.InvoiceChange;
import dev.vality.damsel.user_interaction.*;
import dev.vality.hooker.model.interaction.PaymentTerminalReceipt;
import dev.vality.hooker.model.interaction.UserInteraction;
import dev.vality.hooker.model.interaction.*;
import lombok.RequiredArgsConstructor;
import org.jetbrains.annotations.Nullable;
import org.springframework.core.convert.converter.Converter;
import org.springframework.stereotype.Component;
@Component
@RequiredArgsConstructor
public class InvoiceChangeToUserInteractionConverter implements Converter<InvoiceChange, UserInteraction> {
@Override
public UserInteraction convert(InvoiceChange source) {
var interaction = source.getInvoicePaymentChange().getPayload().getInvoicePaymentSessionChange().getPayload()
.getSessionInteractionChanged().getInteraction();
return createUserInteraction(interaction);
}
@Nullable
private static UserInteraction createUserInteraction(
dev.vality.damsel.user_interaction.UserInteraction interaction) {
UserInteraction userInteraction = null;
if (interaction.isSetApiExtensionRequest()) {
userInteraction = new ApiExtension(interaction.getApiExtensionRequest().getApiType());
} else if (interaction.isSetCryptoCurrencyTransferRequest()) {
CryptoCurrencyTransferRequest cryptoCurrencyTransferRequest =
interaction.getCryptoCurrencyTransferRequest();
CryptoCash cryptoCash = cryptoCurrencyTransferRequest.getCryptoCash();
userInteraction = new CryptoCurrencyTransfer(cryptoCurrencyTransferRequest.getCryptoAddress(),
cryptoCash.getCryptoAmount(),
cryptoCash.getCryptoSymbolicCode());
} else if (interaction.isSetPaymentTerminalReciept()) {
dev.vality.damsel.user_interaction.PaymentTerminalReceipt paymentTerminalReciept =
interaction.getPaymentTerminalReciept();
userInteraction = new PaymentTerminalReceipt(paymentTerminalReciept.getShortPaymentId(),
paymentTerminalReciept.getDue());
} else if (interaction.isSetQrCodeDisplayRequest()) {
QrCode qrCode = interaction.getQrCodeDisplayRequest().getQrCode();
userInteraction = new QrCodeDisplay(qrCode.getPayload());
} else if (interaction.isSetRedirect()) {
if (interaction.getRedirect().isSetPostRequest()) {
BrowserPostRequest postRequest = interaction.getRedirect().getPostRequest();
userInteraction = new BrowserHttpInteraction("post", postRequest.getUri(), postRequest.getForm());
} else {
BrowserGetRequest getRequest = interaction.getRedirect().getGetRequest();
userInteraction = new BrowserHttpInteraction("get", getRequest.getUri(), null);
}
}
return userInteraction;
}
}

View File

@ -0,0 +1,98 @@
package dev.vality.hooker.converter;
import dev.vality.hooker.model.InvoicingMessage;
import dev.vality.hooker.model.interaction.PaymentTerminalReceipt;
import dev.vality.hooker.model.interaction.*;
import dev.vality.hooker.utils.TimeUtils;
import dev.vality.swag_webhook_events.model.*;
import lombok.RequiredArgsConstructor;
import org.jetbrains.annotations.NotNull;
import org.springframework.core.convert.converter.Converter;
import org.springframework.stereotype.Component;
@Component
@RequiredArgsConstructor
public class UserInteractionConverter implements Converter<InvoicingMessage, UserInteractionDetails> {
@Override
public UserInteractionDetails convert(InvoicingMessage invoicingMessage) {
UserInteractionDetails userInteractionDetails = new UserInteractionDetails();
UserInteraction interaction = invoicingMessage.getUserInteraction();
if (interaction instanceof BrowserHttpInteraction browserHttpInteraction) {
return createBrowserHttpRequest(browserHttpInteraction);
} else if (interaction instanceof ApiExtension apiExtension) {
return createApiExtensionRequest(apiExtension);
} else if (interaction instanceof CryptoCurrencyTransfer cryptoCurrencyTransfer) {
return createCryptoCurrencyTransferRequest(cryptoCurrencyTransfer);
} else if (interaction instanceof PaymentTerminalReceipt paymentTerminalReceipt) {
return createPaymentTerminalReceipt(paymentTerminalReceipt);
} else if (interaction instanceof QrCodeDisplay qrCodeDisplay) {
return createQrCodeDisplayRequest(qrCodeDisplay);
}
return userInteractionDetails;
}
@NotNull
private static QrCodeDisplayRequest createQrCodeDisplayRequest(QrCodeDisplay qrCodeDisplay) {
QrCodeDisplayRequest qrCodeDisplayRequest = new QrCodeDisplayRequest();
QrCodeDisplayInfo qrCodeDisplayInfo = new QrCodeDisplayInfo();
qrCodeDisplayInfo.setQrCode(new String(qrCodeDisplay.getQrCode()));
qrCodeDisplayRequest.setQrCodeDisplayInfo(qrCodeDisplayInfo);
qrCodeDisplayRequest.setUserInteractionType(
UserInteractionDetails.UserInteractionTypeEnum.QRCODEDISPLAYREQUEST);
return qrCodeDisplayRequest;
}
@NotNull
private static dev.vality.swag_webhook_events.model.PaymentTerminalReceipt createPaymentTerminalReceipt(
PaymentTerminalReceipt paymentTerminalReceipt) {
var paymentTerminalReceiptRequest = new dev.vality.swag_webhook_events.model.PaymentTerminalReceipt();
PaymentTerminalReceiptInfo paymentTerminalReceiptInfo = new PaymentTerminalReceiptInfo();
paymentTerminalReceiptInfo.setShortPaymentId(paymentTerminalReceipt.getShortPaymentId());
paymentTerminalReceiptInfo.setDue(TimeUtils.toOffsetDateTime(paymentTerminalReceipt.getDue()));
paymentTerminalReceiptRequest.setPaymentTerminalReceiptInfo(paymentTerminalReceiptInfo);
paymentTerminalReceiptRequest.setUserInteractionType(
UserInteractionDetails.UserInteractionTypeEnum.PAYMENTTERMINALRECEIPT);
return paymentTerminalReceiptRequest;
}
@NotNull
private static CryptoCurrencyTransferRequest createCryptoCurrencyTransferRequest(
CryptoCurrencyTransfer cryptoCurrencyTransfer) {
CryptoCurrencyTransferInfo cryptoCurrencyTransferInfo = new CryptoCurrencyTransferInfo();
cryptoCurrencyTransferInfo.setCryptoAddress(cryptoCurrencyTransfer.getCryptoAddress());
cryptoCurrencyTransferInfo.setCryptoCurrency(cryptoCurrencyTransfer.getCryptoSymbolicCode());
Rational cryptoAmount = new Rational();
cryptoAmount.setDenominator(cryptoCurrencyTransfer.getCryptoAmount().getP());
cryptoAmount.setDivider(cryptoCurrencyTransfer.getCryptoAmount().getQ());
cryptoCurrencyTransferInfo.setCryptoAmount(cryptoAmount);
CryptoCurrencyTransferRequest cryptoCurrencyTransferRequest = new CryptoCurrencyTransferRequest();
cryptoCurrencyTransferRequest.setCryptoCurrencyTransferInfo(cryptoCurrencyTransferInfo);
cryptoCurrencyTransferRequest.setUserInteractionType(
UserInteractionDetails.UserInteractionTypeEnum.CRYPTOCURRENCYTRANSFERREQUEST);
return cryptoCurrencyTransferRequest;
}
@NotNull
private static ApiExtensionRequest createApiExtensionRequest(ApiExtension apiExtension) {
ApiExtensionRequest apiExtensionRequest = new ApiExtensionRequest();
ApiExtensionInfo apiExtensionInfo = new ApiExtensionInfo();
apiExtensionInfo.setApiType(apiExtension.getApiType());
apiExtensionRequest.setApiExtensionInfo(apiExtensionInfo);
apiExtensionRequest.setUserInteractionType(UserInteractionDetails.UserInteractionTypeEnum.APIEXTENSIONREQUEST);
return apiExtensionRequest;
}
@NotNull
private static BrowserHTTPRequest createBrowserHttpRequest(BrowserHttpInteraction browserHttpInteraction) {
BrowserHTTPInfo browserHttpInfo = new BrowserHTTPInfo();
browserHttpInfo.setUrl(browserHttpInteraction.getUrl());
browserHttpInfo.setRequestType(
BrowserHTTPInfo.RequestTypeEnum.fromValue(browserHttpInteraction.getRequestType()));
browserHttpInfo.setForm(browserHttpInteraction.getForm());
BrowserHTTPRequest browserHttpRequest = new BrowserHTTPRequest();
browserHttpRequest.setBrowserHTTPInfo(browserHttpInfo);
browserHttpRequest.setUserInteractionType(UserInteractionDetails.UserInteractionTypeEnum.BROWSERHTTPREQUEST);
return browserHttpRequest;
}
}

View File

@ -0,0 +1,68 @@
package dev.vality.hooker.handler.invoicing;
import dev.vality.damsel.payment_processing.InvoiceChange;
import dev.vality.geck.filter.Filter;
import dev.vality.geck.filter.PathConditionFilter;
import dev.vality.geck.filter.condition.IsNullCondition;
import dev.vality.geck.filter.rule.PathConditionRule;
import dev.vality.hooker.converter.InvoiceChangeToUserInteractionConverter;
import dev.vality.hooker.dao.InvoicingMessageDao;
import dev.vality.hooker.model.EventType;
import dev.vality.hooker.model.InvoicingMessage;
import dev.vality.hooker.model.InvoicingMessageEnum;
import dev.vality.hooker.model.InvoicingMessageKey;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class InvoicePaymentUserInteractionChangeCompletedMapper extends NeedReadInvoiceEventMapper {
@Autowired
private InvoiceChangeToUserInteractionConverter userInteractionConverter;
private EventType eventType = EventType.INVOICE_PAYMENT_USER_INTERACTION_CHANGE_COMPLETED;
private Filter filter =
new PathConditionFilter(new PathConditionRule(eventType.getThriftPath(), new IsNullCondition().not()));
public InvoicePaymentUserInteractionChangeCompletedMapper(InvoicingMessageDao messageDao) {
super(messageDao);
}
@Override
public Filter getFilter() {
return filter;
}
@Override
protected InvoicingMessageKey getMessageKey(String invoiceId, InvoiceChange ic) {
return InvoicingMessageKey.builder()
.invoiceId(invoiceId)
.paymentId(ic.getInvoicePaymentChange().getId())
.type(InvoicingMessageEnum.PAYMENT)
.build();
}
@Override
protected InvoicingMessageEnum getMessageType() {
return InvoicingMessageEnum.PAYMENT;
}
@Override
protected EventType getEventType() {
return eventType;
}
@Override
protected void modifyMessage(InvoiceChange ic, InvoicingMessage message) {
message.setUserInteraction(userInteractionConverter.convert(ic));
}
@Override
public boolean accept(InvoiceChange change) {
return getFilter().match(change)
&& !change.getInvoicePaymentChange().getPayload().getInvoicePaymentSessionChange().getPayload()
.getSessionInteractionChanged()
.getStatus().isSetCompleted();
}
}

View File

@ -0,0 +1,63 @@
package dev.vality.hooker.handler.invoicing;
import dev.vality.damsel.payment_processing.InvoiceChange;
import dev.vality.geck.filter.Filter;
import dev.vality.geck.filter.PathConditionFilter;
import dev.vality.geck.filter.condition.IsNullCondition;
import dev.vality.geck.filter.rule.PathConditionRule;
import dev.vality.hooker.dao.InvoicingMessageDao;
import dev.vality.hooker.model.*;
import org.springframework.stereotype.Component;
@Component
public class InvoicePaymentUserInteractionChangeRequestedMapper extends NeedReadInvoiceEventMapper {
private EventType eventType = EventType.INVOICE_PAYMENT_USER_INTERACTION_CHANGE_REQUESTED;
private Filter filter =
new PathConditionFilter(new PathConditionRule(eventType.getThriftPath(), new IsNullCondition().not()));
public InvoicePaymentUserInteractionChangeRequestedMapper(InvoicingMessageDao messageDao) {
super(messageDao);
}
@Override
public Filter getFilter() {
return filter;
}
@Override
protected InvoicingMessageKey getMessageKey(String invoiceId, InvoiceChange ic) {
return InvoicingMessageKey.builder()
.invoiceId(invoiceId)
.paymentId(ic.getInvoicePaymentChange().getId())
.type(InvoicingMessageEnum.PAYMENT)
.build();
}
@Override
protected InvoicingMessageEnum getMessageType() {
return InvoicingMessageEnum.PAYMENT;
}
@Override
protected EventType getEventType() {
return eventType;
}
@Override
protected void modifyMessage(InvoiceChange ic, InvoicingMessage message) {
message.setPaymentStatus(PaymentStatusEnum.lookup(ic.getInvoicePaymentChange().getPayload()
.getInvoicePaymentStatusChanged().getStatus().getSetField().getFieldName()));
}
@Override
public boolean accept(InvoiceChange change) {
return getFilter().match(change)
&& !change.getInvoicePaymentChange().getPayload().getInvoicePaymentSessionChange()
.getPayload()
.getSessionInteractionChanged()
.getStatus()
.isSetRequested();
}
}

View File

@ -18,6 +18,9 @@ public enum EventType {
INVOICE_PAYMENT_CASH_FLOW_CHANGED("invoice_payment_change.payload.invoice_payment_cash_flow_changed"),
INVOICE_PAYMENT_CASH_CHANGED("invoice_payment_change.payload.invoice_payment_cash_changed"),
INVOICE_PAYMENT_USER_INTERACTION_CHANGE_REQUESTED("invoice_payment_change.payload.user_interaction.status.requested"),
INVOICE_PAYMENT_USER_INTERACTION_CHANGE_COMPLETED("invoice_payment_change.payload.user_interaction.status.completed"),
CUSTOMER_CREATED("customer_created"),
CUSTOMER_DELETED("customer_deleted"),
CUSTOMER_READY("customer_status_changed.status.ready"),

View File

@ -1,5 +1,6 @@
package dev.vality.hooker.model;
import dev.vality.hooker.model.interaction.UserInteraction;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;
@ -16,6 +17,7 @@ public class InvoicingMessage extends Message {
private PaymentStatusEnum paymentStatus;
private String refundId;
private RefundStatusEnum refundStatus;
private UserInteraction userInteraction;
public boolean isInvoice() {
return type == InvoicingMessageEnum.INVOICE;

View File

@ -0,0 +1,12 @@
package dev.vality.hooker.model.interaction;
import lombok.AllArgsConstructor;
import lombok.Data;
@Data
@AllArgsConstructor
public class ApiExtension implements UserInteraction {
private String apiType;
}

View File

@ -0,0 +1,16 @@
package dev.vality.hooker.model.interaction;
import lombok.AllArgsConstructor;
import lombok.Data;
import java.util.Map;
@Data
@AllArgsConstructor
public class BrowserHttpInteraction implements UserInteraction {
private String requestType;
private String url;
private Map<String, String> form;
}

View File

@ -0,0 +1,15 @@
package dev.vality.hooker.model.interaction;
import dev.vality.damsel.base.Rational;
import lombok.AllArgsConstructor;
import lombok.Data;
@Data
@AllArgsConstructor
public class CryptoCurrencyTransfer implements UserInteraction {
private String cryptoAddress;
public Rational cryptoAmount;
public String cryptoSymbolicCode;
}

View File

@ -0,0 +1,13 @@
package dev.vality.hooker.model.interaction;
import lombok.AllArgsConstructor;
import lombok.Data;
@Data
@AllArgsConstructor
public class PaymentTerminalReceipt implements UserInteraction {
private String shortPaymentId;
private String due;
}

View File

@ -0,0 +1,12 @@
package dev.vality.hooker.model.interaction;
import lombok.AllArgsConstructor;
import lombok.Data;
@Data
@AllArgsConstructor
public class QrCodeDisplay implements UserInteraction {
private byte[] qrCode;
}

View File

@ -0,0 +1,4 @@
package dev.vality.hooker.model.interaction;
public interface UserInteraction {
}

View File

@ -7,6 +7,7 @@ import dev.vality.damsel.payment_processing.InvoicingSrv;
import dev.vality.hooker.converter.InvoiceConverter;
import dev.vality.hooker.converter.PaymentConverter;
import dev.vality.hooker.converter.RefundConverter;
import dev.vality.hooker.converter.UserInteractionConverter;
import dev.vality.hooker.exception.NotFoundException;
import dev.vality.hooker.exception.RemoteHostException;
import dev.vality.hooker.model.ExpandedPayment;
@ -26,6 +27,7 @@ public class InvoicingEventService
private final InvoiceConverter invoiceConverter;
private final PaymentConverter paymentConverter;
private final RefundConverter refundConverter;
private final UserInteractionConverter userInteractionConverter;
@Override
public Event getEventByMessage(InvoicingMessage message) {
@ -73,6 +75,10 @@ public class InvoicingEventService
.eventType(Event.EventTypeEnum.REFUNDCREATED);
case INVOICE_PAYMENT_REFUND_STATUS_CHANGED -> resolveRefundStatusChanged(m, invoiceInfo);
case INVOICE_PAYMENT_CASH_CHANGED -> resolvePaymentCashChange(m, invoiceInfo);
case INVOICE_PAYMENT_USER_INTERACTION_CHANGE_REQUESTED -> resolvePaymentUserInteraction(m)
.eventType(Event.EventTypeEnum.PAYMENTINTERACTIONREQUESTED);
case INVOICE_PAYMENT_USER_INTERACTION_CHANGE_COMPLETED -> resolvePaymentUserInteraction(m)
.eventType(Event.EventTypeEnum.PAYMENTINTERACTIONCOMPLETED);
default -> throw new UnsupportedOperationException("Unknown event type " + m.getEventType());
};
}
@ -207,7 +213,7 @@ public class InvoicingEventService
}
private Event resolvePaymentCashChange(InvoicingMessage message,
dev.vality.damsel.payment_processing.Invoice invoiceInfo) {
dev.vality.damsel.payment_processing.Invoice invoiceInfo) {
Invoice swagInvoice = getSwagInvoice(invoiceInfo);
ExpandedPayment swagPayment = getSwagPayment(message, invoiceInfo);
return new PaymentCashChanged()
@ -215,4 +221,9 @@ public class InvoicingEventService
.payment(swagPayment)
.eventType(Event.EventTypeEnum.PAYMENTCASHCHANGED);
}
private Event resolvePaymentUserInteraction(InvoicingMessage message) {
return new PaymentInteractionRequested()
.userInteractionDetails(userInteractionConverter.convert(message));
}
}

View File

@ -1,5 +1,6 @@
package dev.vality.hooker.utils;
import dev.vality.damsel.user_interaction.UserInteraction;
import dev.vality.damsel.webhooker.*;
import dev.vality.hooker.dao.WebhookAdditionalFilter;
import dev.vality.hooker.model.EventType;
@ -204,6 +205,14 @@ public class EventFilterUtils {
.getFieldName());
}
}
} else if (payment.isSetUserInteraction()) {
if (payment.getUserInteraction().getStatus().isSetRequested()) {
webhookAdditionalFilter.setEventType(
EventType.INVOICE_PAYMENT_USER_INTERACTION_CHANGE_REQUESTED);
} else if (payment.getUserInteraction().getStatus().isSetCompleted()) {
webhookAdditionalFilter.setEventType(
EventType.INVOICE_PAYMENT_USER_INTERACTION_CHANGE_COMPLETED);
}
}
}
}

View File

@ -9,7 +9,7 @@ public class InvoicingMessageTest {
@Test
public void testCopy() {
InvoicingMessage invoicingMessage = random(InvoicingMessage.class);
InvoicingMessage invoicingMessage = random(InvoicingMessage.class, "userInteraction");
InvoicingMessage copy = invoicingMessage.copy();
invoicingMessage.setRefundId("asd");
assertNotEquals("asd", copy.getRefundId());

View File

@ -2,6 +2,7 @@ package dev.vality.hooker.service;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import dev.vality.damsel.base.Rational;
import dev.vality.damsel.domain.InvoicePaid;
import dev.vality.damsel.domain.InvoicePaymentPending;
import dev.vality.damsel.domain.InvoicePaymentStatus;
@ -9,11 +10,14 @@ import dev.vality.damsel.domain.InvoiceStatus;
import dev.vality.damsel.payment_processing.InvoicingSrv;
import dev.vality.hooker.config.PostgresqlSpringBootITest;
import dev.vality.hooker.model.*;
import dev.vality.hooker.model.interaction.*;
import dev.vality.hooker.utils.BuildUtils;
import dev.vality.swag_webhook_events.model.Event;
import dev.vality.swag_webhook_events.model.RefundSucceeded;
import org.jetbrains.annotations.NotNull;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.RepeatedTest;
import org.junit.jupiter.api.Test;
import org.mockito.Mockito;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.mock.mockito.MockBean;
@ -45,7 +49,7 @@ public class InvoicingEventServiceTest {
@RepeatedTest(7)
public void testRefundSucceeded() {
InvoicingMessage message = random(InvoicingMessage.class);
InvoicingMessage message = random(InvoicingMessage.class, "userInteraction");
message.setPaymentId("1");
message.setRefundId("1");
message.setType(InvoicingMessageEnum.REFUND);
@ -64,7 +68,7 @@ public class InvoicingEventServiceTest {
@RepeatedTest(7)
public void testJson() throws JsonProcessingException {
InvoicingMessage message = random(InvoicingMessage.class);
InvoicingMessage message = random(InvoicingMessage.class, "userInteraction");
message.setPaymentId("1");
message.setType(InvoicingMessageEnum.PAYMENT);
message.setEventTime("2016-03-22T06:12:27Z");
@ -77,4 +81,74 @@ public class InvoicingEventServiceTest {
assertTrue(json.contains("\"externalId\":\"payment-external-id\""));
assertTrue(json.contains("\"externalId\":\"invoice-external-id\""));
}
@Test
public void testUserInteractions() throws JsonProcessingException {
InvoicingMessage message = createDefaultInvoicingMessage();
message.setEventType(EventType.INVOICE_PAYMENT_USER_INTERACTION_CHANGE_REQUESTED);
message.setUserInteraction(new BrowserHttpInteraction("get", "http://test", null));
Event event = service.getEventByMessage(message);
String json = objectMapper.writeValueAsString(event);
assertTrue(json.contains("\"eventType\":\"PaymentInteractionRequested\""));
assertTrue(json.contains("\"requestType\":\"get\""));
assertTrue(json.contains("\"userInteractionType\":\"BrowserHTTPRequest\""));
}
@Test
public void testUserInteractionsCompleted() throws JsonProcessingException {
InvoicingMessage message = createDefaultInvoicingMessage();
message.setEventType(EventType.INVOICE_PAYMENT_USER_INTERACTION_CHANGE_COMPLETED);
message.setUserInteraction(new QrCodeDisplay("wefvqewvrq32fveqrw".getBytes()));
Event event = service.getEventByMessage(message);
String json = objectMapper.writeValueAsString(event);
assertTrue(json.contains("\"eventType\":\"PaymentInteractionCompleted\""));
assertTrue(json.contains("\"userInteractionType\":\"QrCodeDisplayRequest\""));
}
@Test
public void testUserInteractionsCompletedApiExtension() throws JsonProcessingException {
InvoicingMessage message = createDefaultInvoicingMessage();
message.setEventType(EventType.INVOICE_PAYMENT_USER_INTERACTION_CHANGE_COMPLETED);
message.setUserInteraction(new ApiExtension("p2p"));
Event event = service.getEventByMessage(message);
String json = objectMapper.writeValueAsString(event);
assertTrue(json.contains("\"eventType\":\"PaymentInteractionCompleted\""));
assertTrue(json.contains("\"userInteractionType\":\"ApiExtensionRequest\""));
}
@Test
public void testUserInteractionsCompletedPaymentTerminal() throws JsonProcessingException {
InvoicingMessage message = createDefaultInvoicingMessage();
message.setEventType(EventType.INVOICE_PAYMENT_USER_INTERACTION_CHANGE_COMPLETED);
message.setUserInteraction(new PaymentTerminalReceipt("p2p", "2016-03-22T06:12:27Z"));
Event event = service.getEventByMessage(message);
String json = objectMapper.writeValueAsString(event);
assertTrue(json.contains("\"eventType\":\"PaymentInteractionCompleted\""));
assertTrue(json.contains("\"userInteractionType\":\"PaymentTerminalReceipt\""));
}
@Test
public void testUserInteractionsCompletedCrypto() throws JsonProcessingException {
InvoicingMessage message = createDefaultInvoicingMessage();
message.setEventType(EventType.INVOICE_PAYMENT_USER_INTERACTION_CHANGE_COMPLETED);
message.setUserInteraction(new CryptoCurrencyTransfer("address", new Rational(1L, 10L), "bitcoin"));
Event event = service.getEventByMessage(message);
String json = objectMapper.writeValueAsString(event);
assertTrue(json.contains("\"eventType\":\"PaymentInteractionCompleted\""));
assertTrue(json.contains("\"userInteractionType\":\"CryptoCurrencyTransferRequest\""));
assertTrue(json.contains("\"cryptoAddress\":\"address\""));
assertTrue(json.contains("\"cryptoCurrency\":\"bitcoin\""));
assertTrue(json.contains("\"denominator\":1"));
}
@NotNull
private static InvoicingMessage createDefaultInvoicingMessage() {
InvoicingMessage message = new InvoicingMessage();
message.setId(123L);
message.setPaymentId("271771960");
message.setSequenceId(123L);
message.setType(InvoicingMessageEnum.PAYMENT);
message.setEventTime("2016-03-22T06:12:27Z");
return message;
}
}