package com.commercetools.pspadapter.payone;

import com.commercetools.pspadapter.payone.domain.ctp.PaymentWithCartLike;
import com.commercetools.pspadapter.payone.domain.ctp.paymentmethods.MethodKeys;
import com.commercetools.pspadapter.payone.domain.ctp.paymentmethods.TransactionExecutor;
import com.commercetools.pspadapter.payone.domain.ctp.paymentmethods.PaymentMethodDispatcher;
import io.sphere.sdk.carts.Cart;
import io.sphere.sdk.payments.Transaction;
import org.junit.Test;
import util.PaymentTestHelper;

import java.util.HashMap;

import static org.assertj.core.api.Assertions.*;

public class PaymentDispatcherTest extends PaymentTestHelper {
    private class CountingPaymentMethodDispatcher extends PaymentMethodDispatcher {
        public int count = 0;

        public CountingPaymentMethodDispatcher() {
            super(new TransactionExecutor() {
                @Override
                public PaymentWithCartLike executeTransaction(PaymentWithCartLike payment, Transaction transaction) {
                    return payment;
                }
            }, new HashMap<>());
        }

        @Override
        public PaymentWithCartLike dispatchPayment(PaymentWithCartLike payment) {
            count += 1;
            return super.dispatchPayment(payment);
        }
    }

    @Test
    public void testRefusingWrongPaymentInterface() throws Exception {
        PaymentDispatcher dispatcher = new PaymentDispatcher(null);

        final Throwable noInterface = catchThrowable(() -> dispatcher.dispatchPayment(new PaymentWithCartLike(dummyPaymentNoInterface(), (Cart)null)));
        assertThat(noInterface).isInstanceOf(IllegalArgumentException.class);

        final Throwable wrongInterface = catchThrowable(() -> dispatcher.dispatchPayment(new PaymentWithCartLike(dummyPaymentWrongInterface(), (Cart)null)));
        assertThat(wrongInterface).isInstanceOf(IllegalArgumentException.class);
    }

    @Test
    public void testRefusingUnknownPaymentMethod() throws Exception {
        PaymentDispatcher dispatcher = new PaymentDispatcher(new HashMap<>());

        final Throwable noInterface = catchThrowable(() -> dispatcher.dispatchPayment(new PaymentWithCartLike(dummyPaymentUnknownMethod(), (Cart)null)));
        assertThat(noInterface).isInstanceOf(IllegalArgumentException.class);
    }

    @Test
    public void testDispatchCorrectly() throws Exception {
        final CountingPaymentMethodDispatcher creditCardDispatcher = new CountingPaymentMethodDispatcher();
        final CountingPaymentMethodDispatcher sepaDispatcher = new CountingPaymentMethodDispatcher();

        final HashMap<String, PaymentMethodDispatcher> methodDispatcherMap = new HashMap<>();
        methodDispatcherMap.put(MethodKeys.CREDIT_CARD, creditCardDispatcher);
        methodDispatcherMap.put(MethodKeys.DIRECT_DEBIT_SEPA, sepaDispatcher);

        PaymentDispatcher dispatcher = new PaymentDispatcher(methodDispatcherMap);
        dispatcher.dispatchPayment(new PaymentWithCartLike(dummyPaymentTwoTransactionsPending(), (Cart)null));
        dispatcher.dispatchPayment(new PaymentWithCartLike(dummyPaymentTwoTransactionsSuccessPending(), (Cart)null));

        assertThat(creditCardDispatcher.count).isEqualTo(2);
        assertThat(sepaDispatcher.count).isEqualTo(0);
    }
}
@@ -39,16 +39,75 @@
 ayone;%0A%0A
+import static org.assertj.core.api.Assertions.assertThat;%0A%0A
 import c
@@ -323,34 +323,38 @@
 methods.
-TransactionExecuto
+PaymentMethodDispatche
 r;%0Aimpor
@@ -417,38 +417,34 @@
 methods.
-PaymentMethodDispatche
+TransactionExecuto
 r;%0Aimpor
@@ -600,58 +600,8 @@
 p;%0A%0A
-import static org.assertj.core.api.Assertions.*;%0A%0A
 publ
@@ -1467,58 +1467,31 @@
     
-final Throwable noInterface = catchThrowable(() -%3E
+DispatchResult result =
  dis
@@ -1563,39 +1563,39 @@
 erface(), (Cart)
+ 
 null))
-)
 ;%0A        assert
@@ -1603,76 +1603,56 @@
 hat(
-noInterface).isInstanceOf(IllegalArgumentException.class
+result.getStatusCode()).isEqualTo(400
 );%0A
-%0A
         
 fina
@@ -1651,61 +1651,117 @@
     
-final Throwable wrongInterface = catchThrowable(() -%3E
+assertThat(result.getMessage()).isEqualTo(%22Unsupported Payment Interface%22);%0A%0A        DispatchResult result2 =
  dis
@@ -1836,39 +1836,39 @@
 erface(), (Cart)
+ 
 null))
-)
 ;%0A        assert
@@ -1876,67 +1876,131 @@
 hat(
-wrongInterface).isInstanceOf(IllegalArgumentException.class
+result2.getStatusCode()).isEqualTo(400);%0A        assertThat(result2.getMessage()).isEqualTo(%22Unsupported Payment Interface%22
 );%0A 
@@ -2177,58 +2177,31 @@
     
-final Throwable noInterface = catchThrowable(() -%3E
+DispatchResult result =
  dis
@@ -2287,15 +2287,15 @@
 art)
+ 
 null))
-)
 ;%0A  
@@ -2315,64 +2315,126 @@
 hat(
-noInterface).isInstanceOf(IllegalArgumentException.class
+result.getStatusCode()).isEqualTo(400);%0A        assertThat(result.getMessage()).isEqualTo(%22Unsupported Payment Method%22
 );%0A 

fix PaymentDispatcherTest with DispatchResult