killbill-memoizeit

payment: make transactionStatus Nullable in AdminPaymentApi#fixPaymentTransactionState This

6/24/2016 10:54:06 PM

Details

diff --git a/payment/src/main/java/org/killbill/billing/payment/api/DefaultAdminPaymentApi.java b/payment/src/main/java/org/killbill/billing/payment/api/DefaultAdminPaymentApi.java
index 6b02b9b..2e654e5 100644
--- a/payment/src/main/java/org/killbill/billing/payment/api/DefaultAdminPaymentApi.java
+++ b/payment/src/main/java/org/killbill/billing/payment/api/DefaultAdminPaymentApi.java
@@ -21,17 +21,20 @@ import javax.annotation.Nullable;
 import javax.inject.Inject;
 
 import org.killbill.billing.callcontext.InternalCallContext;
+import org.killbill.billing.payment.core.PaymentTransactionInfoPluginConverter;
 import org.killbill.billing.payment.dao.PaymentDao;
 import org.killbill.billing.util.callcontext.CallContext;
 import org.killbill.billing.util.callcontext.InternalCallContextFactory;
+import org.killbill.billing.util.config.PaymentConfig;
 
-public class DefaultAdminPaymentApi implements AdminPaymentApi {
+public class DefaultAdminPaymentApi extends DefaultApiBase implements AdminPaymentApi {
 
     private final PaymentDao paymentDao;
     private final InternalCallContextFactory internalCallContextFactory;
 
     @Inject
-    public DefaultAdminPaymentApi(final PaymentDao paymentDao, final InternalCallContextFactory internalCallContextFactory) {
+    public DefaultAdminPaymentApi(final PaymentConfig paymentConfig, final PaymentDao paymentDao, final InternalCallContextFactory internalCallContextFactory) {
+        super(paymentConfig);
         this.paymentDao = paymentDao;
         this.internalCallContextFactory = internalCallContextFactory;
     }
@@ -39,12 +42,21 @@ public class DefaultAdminPaymentApi implements AdminPaymentApi {
     @Override
     public void fixPaymentTransactionState(final Payment payment,
                                            final PaymentTransaction paymentTransaction,
-                                           final TransactionStatus transactionStatus,
+                                           @Nullable final TransactionStatus transactionStatusMaybeNull,
                                            @Nullable final String lastSuccessPaymentState,
                                            final String currentPaymentStateName,
                                            final Iterable<PluginProperty> properties,
                                            final CallContext callContext) throws PaymentApiException {
         final InternalCallContext internalCallContext = internalCallContextFactory.createInternalCallContext(payment.getAccountId(), callContext);
+
+        final TransactionStatus transactionStatus;
+        if (transactionStatusMaybeNull == null) {
+            checkNotNullParameter(paymentTransaction.getPaymentInfoPlugin(), "PaymentTransactionInfoPlugin");
+            transactionStatus = PaymentTransactionInfoPluginConverter.toTransactionStatus(paymentTransaction.getPaymentInfoPlugin());
+        } else {
+            transactionStatus = transactionStatusMaybeNull;
+        }
+
         paymentDao.updatePaymentAndTransactionOnCompletion(payment.getAccountId(),
                                                            null,
                                                            payment.getId(),
diff --git a/payment/src/test/java/org/killbill/billing/payment/api/TestDefaultAdminPaymentApi.java b/payment/src/test/java/org/killbill/billing/payment/api/TestDefaultAdminPaymentApi.java
new file mode 100644
index 0000000..03f6d8a
--- /dev/null
+++ b/payment/src/test/java/org/killbill/billing/payment/api/TestDefaultAdminPaymentApi.java
@@ -0,0 +1,209 @@
+/*
+ * Copyright 2016 Groupon, Inc
+ * Copyright 2016 The Billing Project, LLC
+ *
+ * The Billing Project licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at:
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.killbill.billing.payment.api;
+
+import java.math.BigDecimal;
+import java.util.UUID;
+
+import org.killbill.billing.ErrorCode;
+import org.killbill.billing.account.api.Account;
+import org.killbill.billing.catalog.api.Currency;
+import org.killbill.billing.control.plugin.api.PaymentControlPluginApi;
+import org.killbill.billing.osgi.api.OSGIServiceDescriptor;
+import org.killbill.billing.payment.PaymentTestSuiteWithEmbeddedDB;
+import org.killbill.billing.payment.dao.PaymentModelDao;
+import org.killbill.billing.payment.dao.PaymentTransactionModelDao;
+import org.killbill.billing.payment.plugin.api.PaymentPluginStatus;
+import org.killbill.billing.payment.plugin.api.PaymentTransactionInfoPlugin;
+import org.killbill.billing.payment.provider.DefaultNoOpPaymentInfoPlugin;
+import org.killbill.billing.payment.provider.MockPaymentControlProviderPlugin;
+import org.killbill.billing.payment.provider.MockPaymentProviderPlugin;
+import org.mockito.Mockito;
+import org.testng.Assert;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import com.google.common.collect.ImmutableList;
+
+public class TestDefaultAdminPaymentApi extends PaymentTestSuiteWithEmbeddedDB {
+
+    private MockPaymentProviderPlugin mockPaymentProviderPlugin;
+    private Account account;
+
+    @BeforeClass(groups = "slow")
+    protected void beforeClass() throws Exception {
+        super.beforeClass();
+        mockPaymentProviderPlugin = (MockPaymentProviderPlugin) registry.getServiceForName(MockPaymentProviderPlugin.PLUGIN_NAME);
+    }
+
+    @BeforeMethod(groups = "slow")
+    public void beforeMethod() throws Exception {
+        super.beforeMethod();
+
+        mockPaymentProviderPlugin.clear();
+        account = testHelper.createTestAccount("bobo@gmail.com", true);
+
+        final PaymentControlPluginApi mockPaymentControlProviderPlugin = new MockPaymentControlProviderPlugin();
+        controlPluginRegistry.registerService(new OSGIServiceDescriptor() {
+                                                  @Override
+                                                  public String getPluginSymbolicName() {
+                                                      return null;
+                                                  }
+
+                                                  @Override
+                                                  public String getPluginName() {
+                                                      return MockPaymentControlProviderPlugin.PLUGIN_NAME;
+                                                  }
+
+                                                  @Override
+                                                  public String getRegistrationName() {
+                                                      return MockPaymentControlProviderPlugin.PLUGIN_NAME;
+                                                  }
+                                              },
+                                              mockPaymentControlProviderPlugin);
+    }
+
+    @Test(groups = "slow")
+    public void testFixPaymentTransactionState() throws PaymentApiException {
+        final Payment payment = paymentApi.createAuthorization(account,
+                                                               account.getPaymentMethodId(),
+                                                               null,
+                                                               BigDecimal.TEN,
+                                                               Currency.EUR,
+                                                               UUID.randomUUID().toString(),
+                                                               UUID.randomUUID().toString(),
+                                                               ImmutableList.<PluginProperty>of(),
+                                                               callContext);
+
+        final PaymentModelDao paymentModelDao = paymentDao.getPayment(payment.getId(), internalCallContext);
+        final PaymentTransactionModelDao paymentTransactionModelDao = paymentDao.getPaymentTransaction(payment.getTransactions().get(0).getId(), internalCallContext);
+        Assert.assertEquals(paymentModelDao.getStateName(), "AUTH_SUCCESS");
+        Assert.assertEquals(paymentModelDao.getLastSuccessStateName(), "AUTH_SUCCESS");
+        Assert.assertEquals(paymentTransactionModelDao.getTransactionStatus(), TransactionStatus.SUCCESS);
+        Assert.assertEquals(paymentTransactionModelDao.getProcessedAmount().compareTo(BigDecimal.TEN), 0);
+        Assert.assertEquals(paymentTransactionModelDao.getProcessedCurrency(), Currency.EUR);
+        Assert.assertEquals(paymentTransactionModelDao.getGatewayErrorCode(), "");
+        Assert.assertEquals(paymentTransactionModelDao.getGatewayErrorMsg(), "");
+
+        adminPaymentApi.fixPaymentTransactionState(payment, payment.getTransactions().get(0), TransactionStatus.PAYMENT_FAILURE, null, "AUTH_ERRORED", ImmutableList.<PluginProperty>of(), callContext);
+
+        final PaymentModelDao refreshedPaymentModelDao = paymentDao.getPayment(payment.getId(), internalCallContext);
+        final PaymentTransactionModelDao refreshedPaymentTransactionModelDao = paymentDao.getPaymentTransaction(payment.getTransactions().get(0).getId(), internalCallContext);
+        Assert.assertEquals(refreshedPaymentModelDao.getStateName(), "AUTH_ERRORED");
+        // TODO Shouldn't we allow the user to override this too?
+        Assert.assertEquals(refreshedPaymentModelDao.getLastSuccessStateName(), "AUTH_SUCCESS");
+        Assert.assertEquals(refreshedPaymentTransactionModelDao.getTransactionStatus(), TransactionStatus.PAYMENT_FAILURE);
+        Assert.assertEquals(refreshedPaymentTransactionModelDao.getProcessedAmount().compareTo(BigDecimal.TEN), 0);
+        Assert.assertEquals(refreshedPaymentTransactionModelDao.getProcessedCurrency(), Currency.EUR);
+        Assert.assertEquals(refreshedPaymentTransactionModelDao.getGatewayErrorCode(), "");
+        Assert.assertEquals(refreshedPaymentTransactionModelDao.getGatewayErrorMsg(), "");
+    }
+
+    @Test(groups = "slow", description = "https://github.com/killbill/killbill/issues/551")
+    public void testFixPaymentTransactionStateNoPaymentTransactionInfoPlugin() throws PaymentApiException {
+        final Payment payment = paymentApi.createAuthorization(account,
+                                                               account.getPaymentMethodId(),
+                                                               null,
+                                                               BigDecimal.TEN,
+                                                               Currency.EUR,
+                                                               UUID.randomUUID().toString(),
+                                                               UUID.randomUUID().toString(),
+                                                               ImmutableList.<PluginProperty>of(),
+                                                               callContext);
+
+        final PaymentModelDao paymentModelDao = paymentDao.getPayment(payment.getId(), internalCallContext);
+        final PaymentTransactionModelDao paymentTransactionModelDao = paymentDao.getPaymentTransaction(payment.getTransactions().get(0).getId(), internalCallContext);
+        Assert.assertEquals(paymentModelDao.getStateName(), "AUTH_SUCCESS");
+        Assert.assertEquals(paymentModelDao.getLastSuccessStateName(), "AUTH_SUCCESS");
+        Assert.assertEquals(paymentTransactionModelDao.getTransactionStatus(), TransactionStatus.SUCCESS);
+        Assert.assertEquals(paymentTransactionModelDao.getProcessedAmount().compareTo(BigDecimal.TEN), 0);
+        Assert.assertEquals(paymentTransactionModelDao.getProcessedCurrency(), Currency.EUR);
+        Assert.assertEquals(paymentTransactionModelDao.getGatewayErrorCode(), "");
+        Assert.assertEquals(paymentTransactionModelDao.getGatewayErrorMsg(), "");
+
+        try {
+            // Since no transaction status is passed, PaymentTransactionInfoPlugin should be set
+            adminPaymentApi.fixPaymentTransactionState(payment, Mockito.mock(DefaultPaymentTransaction.class), null, null, "AUTH_ERRORED", ImmutableList.<PluginProperty>of(), callContext);
+        } catch (final PaymentApiException e) {
+            Assert.assertEquals(e.getCode(), ErrorCode.PAYMENT_INVALID_PARAMETER.getCode());
+        }
+    }
+
+    @Test(groups = "slow", description = "https://github.com/killbill/killbill/issues/551")
+    public void testFixPaymentTransactionStateFromPaymentTransactionInfoPlugin() throws PaymentApiException {
+        final Payment payment = paymentApi.createAuthorization(account,
+                                                               account.getPaymentMethodId(),
+                                                               null,
+                                                               BigDecimal.TEN,
+                                                               Currency.EUR,
+                                                               UUID.randomUUID().toString(),
+                                                               UUID.randomUUID().toString(),
+                                                               ImmutableList.<PluginProperty>of(),
+                                                               callContext);
+
+        final PaymentModelDao paymentModelDao = paymentDao.getPayment(payment.getId(), internalCallContext);
+        final PaymentTransactionModelDao paymentTransactionModelDao = paymentDao.getPaymentTransaction(payment.getTransactions().get(0).getId(), internalCallContext);
+        Assert.assertEquals(paymentModelDao.getStateName(), "AUTH_SUCCESS");
+        Assert.assertEquals(paymentModelDao.getLastSuccessStateName(), "AUTH_SUCCESS");
+        Assert.assertEquals(paymentTransactionModelDao.getTransactionStatus(), TransactionStatus.SUCCESS);
+        Assert.assertEquals(paymentTransactionModelDao.getProcessedAmount().compareTo(BigDecimal.TEN), 0);
+        Assert.assertEquals(paymentTransactionModelDao.getProcessedCurrency(), Currency.EUR);
+        Assert.assertEquals(paymentTransactionModelDao.getGatewayErrorCode(), "");
+        Assert.assertEquals(paymentTransactionModelDao.getGatewayErrorMsg(), "");
+
+        final PaymentTransactionInfoPlugin infoPlugin = new DefaultNoOpPaymentInfoPlugin(paymentTransactionModelDao.getPaymentId(),
+                                                                                         paymentTransactionModelDao.getId(),
+                                                                                         paymentTransactionModelDao.getTransactionType(),
+                                                                                         paymentTransactionModelDao.getAmount(),
+                                                                                         paymentTransactionModelDao.getCurrency(),
+                                                                                         paymentTransactionModelDao.getEffectiveDate(),
+                                                                                         paymentTransactionModelDao.getCreatedDate(),
+                                                                                         PaymentPluginStatus.ERROR,
+                                                                                         "error-code",
+                                                                                         "error-msg");
+        final PaymentTransaction newPaymentTransaction = new DefaultPaymentTransaction(paymentTransactionModelDao.getId(),
+                                                                                       paymentTransactionModelDao.getAttemptId(),
+                                                                                       paymentTransactionModelDao.getTransactionExternalKey(),
+                                                                                       paymentTransactionModelDao.getCreatedDate(),
+                                                                                       paymentTransactionModelDao.getUpdatedDate(),
+                                                                                       paymentTransactionModelDao.getPaymentId(),
+                                                                                       paymentTransactionModelDao.getTransactionType(),
+                                                                                       paymentTransactionModelDao.getEffectiveDate(),
+                                                                                       TransactionStatus.PAYMENT_FAILURE,
+                                                                                       paymentTransactionModelDao.getAmount(),
+                                                                                       paymentTransactionModelDao.getCurrency(),
+                                                                                       paymentTransactionModelDao.getProcessedAmount(),
+                                                                                       paymentTransactionModelDao.getProcessedCurrency(),
+                                                                                       infoPlugin.getGatewayErrorCode(),
+                                                                                       infoPlugin.getGatewayError(),
+                                                                                       infoPlugin);
+        adminPaymentApi.fixPaymentTransactionState(payment, newPaymentTransaction, null, null, "AUTH_ERRORED", ImmutableList.<PluginProperty>of(), callContext);
+
+        final PaymentModelDao refreshedPaymentModelDao = paymentDao.getPayment(payment.getId(), internalCallContext);
+        final PaymentTransactionModelDao refreshedPaymentTransactionModelDao = paymentDao.getPaymentTransaction(payment.getTransactions().get(0).getId(), internalCallContext);
+        Assert.assertEquals(refreshedPaymentModelDao.getStateName(), "AUTH_ERRORED");
+        // TODO Shouldn't we allow the user to override this too?
+        Assert.assertEquals(refreshedPaymentModelDao.getLastSuccessStateName(), "AUTH_SUCCESS");
+        Assert.assertEquals(refreshedPaymentTransactionModelDao.getTransactionStatus(), TransactionStatus.PAYMENT_FAILURE);
+        Assert.assertEquals(refreshedPaymentTransactionModelDao.getProcessedAmount().compareTo(BigDecimal.TEN), 0);
+        Assert.assertEquals(refreshedPaymentTransactionModelDao.getProcessedCurrency(), Currency.EUR);
+        Assert.assertEquals(refreshedPaymentTransactionModelDao.getGatewayErrorCode(), "error-code");
+        Assert.assertEquals(refreshedPaymentTransactionModelDao.getGatewayErrorMsg(), "error-msg");
+    }
+}
diff --git a/payment/src/test/java/org/killbill/billing/payment/PaymentTestSuiteWithEmbeddedDB.java b/payment/src/test/java/org/killbill/billing/payment/PaymentTestSuiteWithEmbeddedDB.java
index 786dae5..0d21398 100644
--- a/payment/src/test/java/org/killbill/billing/payment/PaymentTestSuiteWithEmbeddedDB.java
+++ b/payment/src/test/java/org/killbill/billing/payment/PaymentTestSuiteWithEmbeddedDB.java
@@ -1,7 +1,7 @@
 /*
  * Copyright 2010-2013 Ning, Inc.
- * Copyright 2014 Groupon, Inc
- * Copyright 2014 The Billing Project, LLC
+ * Copyright 2014-2016 Groupon, Inc
+ * Copyright 2014-2016 The Billing Project, LLC
  *
  * The Billing Project licenses this file to you under the Apache License, version 2.0
  * (the "License"); you may not use this file except in compliance with the
@@ -23,6 +23,7 @@ import org.killbill.billing.account.api.AccountInternalApi;
 import org.killbill.billing.control.plugin.api.PaymentControlPluginApi;
 import org.killbill.billing.invoice.api.InvoiceInternalApi;
 import org.killbill.billing.osgi.api.OSGIServiceRegistration;
+import org.killbill.billing.payment.api.AdminPaymentApi;
 import org.killbill.billing.payment.api.PaymentApi;
 import org.killbill.billing.payment.api.PaymentGatewayApi;
 import org.killbill.billing.payment.core.PaymentExecutors;
@@ -66,6 +67,8 @@ public abstract class PaymentTestSuiteWithEmbeddedDB extends GuicyKillbillTestSu
     @Inject
     protected PaymentApi paymentApi;
     @Inject
+    protected AdminPaymentApi adminPaymentApi;
+    @Inject
     protected PaymentGatewayApi paymentGatewayApi;
     @Inject
     protected AccountInternalApi accountApi;