killbill-uncached
Changes
beatrix/src/test/java/com/ning/billing/beatrix/integration/payment/MockPaymentInfoReceiver.java 53(+53 -0)
beatrix/src/test/java/com/ning/billing/beatrix/integration/payment/PaymentTestModule.java 75(+75 -0)
beatrix/src/test/java/com/ning/billing/beatrix/integration/payment/TestNotifyInvoicePaymentApi.java 118(+118 -0)
beatrix/src/test/java/com/ning/billing/beatrix/integration/payment/TestPaymentInvoiceIntegration.java 166(+166 -0)
Details
diff --git a/beatrix/src/test/java/com/ning/billing/beatrix/integration/payment/MockPaymentInfoReceiver.java b/beatrix/src/test/java/com/ning/billing/beatrix/integration/payment/MockPaymentInfoReceiver.java
new file mode 100644
index 0000000..ab7ed20
--- /dev/null
+++ b/beatrix/src/test/java/com/ning/billing/beatrix/integration/payment/MockPaymentInfoReceiver.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2010-2011 Ning, Inc.
+ *
+ * Ning 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 com.ning.billing.beatrix.integration.payment;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import com.google.common.eventbus.Subscribe;
+import com.ning.billing.payment.api.PaymentErrorEvent;
+import com.ning.billing.payment.api.PaymentInfoEvent;
+
+public class MockPaymentInfoReceiver {
+ private final List<PaymentInfoEvent> processedPayments = Collections.synchronizedList(new ArrayList<PaymentInfoEvent>());
+ private final List<PaymentErrorEvent> errors = Collections.synchronizedList(new ArrayList<PaymentErrorEvent>());
+
+ @Subscribe
+ public void processedPayment(PaymentInfoEvent paymentInfo) {
+ processedPayments.add(paymentInfo);
+ }
+
+ @Subscribe
+ public void processedPaymentError(PaymentErrorEvent paymentError) {
+ errors.add(paymentError);
+ }
+
+ public List<PaymentInfoEvent> getProcessedPayments() {
+ return new ArrayList<PaymentInfoEvent>(processedPayments);
+ }
+
+ public List<PaymentErrorEvent> getErrors() {
+ return new ArrayList<PaymentErrorEvent>(errors);
+ }
+
+ public void clear() {
+ processedPayments.clear();
+ errors.clear();
+ }
+}
\ No newline at end of file
diff --git a/beatrix/src/test/java/com/ning/billing/beatrix/integration/payment/PaymentTestModule.java b/beatrix/src/test/java/com/ning/billing/beatrix/integration/payment/PaymentTestModule.java
new file mode 100644
index 0000000..538f3dd
--- /dev/null
+++ b/beatrix/src/test/java/com/ning/billing/beatrix/integration/payment/PaymentTestModule.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2010-2011 Ning, Inc.
+ *
+ * Ning 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 com.ning.billing.beatrix.integration.payment;
+
+import org.apache.commons.collections.MapUtils;
+
+import com.google.common.collect.ImmutableMap;
+import com.google.inject.Provider;
+import com.ning.billing.account.dao.AccountDao;
+import com.ning.billing.account.dao.MockAccountDao;
+import com.ning.billing.config.PaymentConfig;
+import com.ning.billing.invoice.dao.InvoiceDao;
+import com.ning.billing.invoice.dao.MockInvoiceDao;
+import com.ning.billing.junction.api.BillingApi;
+import com.ning.billing.mock.BrainDeadProxyFactory;
+import com.ning.billing.payment.dao.MockPaymentDao;
+import com.ning.billing.payment.dao.PaymentDao;
+import com.ning.billing.payment.provider.MockPaymentProviderPluginModule;
+import com.ning.billing.payment.setup.PaymentModule;
+import com.ning.billing.util.bus.Bus;
+import com.ning.billing.util.bus.InMemoryBus;
+import com.ning.billing.util.notificationq.MockNotificationQueueService;
+import com.ning.billing.util.notificationq.NotificationQueueService;
+
+public class PaymentTestModule extends PaymentModule {
+ public static class MockProvider implements Provider<BillingApi> {
+ @Override
+ public BillingApi get() {
+ return BrainDeadProxyFactory.createBrainDeadProxyFor(BillingApi.class);
+ }
+
+ }
+
+
+ public PaymentTestModule() {
+ super(MapUtils.toProperties(ImmutableMap.of("killbill.payment.provider.default", "my-mock",
+ "killbill.payment.engine.events.off", "false")));
+ }
+
+ @Override
+ protected void installPaymentDao() {
+ bind(PaymentDao.class).to(MockPaymentDao.class).asEagerSingleton();
+ }
+
+ @Override
+ protected void installPaymentProviderPlugins(PaymentConfig config) {
+ install(new MockPaymentProviderPluginModule("my-mock"));
+ }
+
+ @Override
+ protected void configure() {
+ super.configure();
+ bind(Bus.class).to(InMemoryBus.class).asEagerSingleton();
+ bind(MockAccountDao.class).asEagerSingleton();
+ bind(AccountDao.class).to(MockAccountDao.class);
+ bind(MockInvoiceDao.class).asEagerSingleton();
+ bind(InvoiceDao.class).to(MockInvoiceDao.class);
+ bind(NotificationQueueService.class).to(MockNotificationQueueService.class).asEagerSingleton();
+
+ }
+}
diff --git a/beatrix/src/test/java/com/ning/billing/beatrix/integration/payment/TestHelper.java b/beatrix/src/test/java/com/ning/billing/beatrix/integration/payment/TestHelper.java
new file mode 100644
index 0000000..24c8042
--- /dev/null
+++ b/beatrix/src/test/java/com/ning/billing/beatrix/integration/payment/TestHelper.java
@@ -0,0 +1,127 @@
+/*
+ * Copyright 2010-2011 Ning, Inc.
+ *
+ * Ning 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 com.ning.billing.beatrix.integration.payment;
+
+import java.math.BigDecimal;
+import java.util.UUID;
+
+import org.apache.commons.lang.RandomStringUtils;
+import org.joda.time.DateTime;
+import org.joda.time.DateTimeZone;
+
+import com.google.inject.Inject;
+import com.ning.billing.account.api.Account;
+import com.ning.billing.account.api.AccountUserApi;
+import com.ning.billing.account.api.user.AccountBuilder;
+import com.ning.billing.catalog.api.Currency;
+import com.ning.billing.invoice.api.Invoice;
+import com.ning.billing.invoice.api.InvoiceItem;
+import com.ning.billing.invoice.api.test.InvoiceTestApi;
+import com.ning.billing.invoice.model.DefaultInvoice;
+import com.ning.billing.invoice.model.RecurringInvoiceItem;
+import com.ning.billing.mock.BrainDeadProxyFactory.ZombieControl;
+import com.ning.billing.util.callcontext.CallContext;
+import com.ning.billing.util.callcontext.CallContextFactory;
+import com.ning.billing.util.callcontext.CallOrigin;
+import com.ning.billing.util.callcontext.UserType;
+import com.ning.billing.util.entity.EntityPersistenceException;
+
+public class TestHelper {
+ protected final AccountUserApi accountUserApi;
+ protected final InvoiceTestApi invoiceTestApi;
+ private final CallContext context;
+
+ @Inject
+ public TestHelper(CallContextFactory factory, AccountUserApi accountUserApi, InvoiceTestApi invoiceTestApi) {
+ this.accountUserApi = accountUserApi;
+ this.invoiceTestApi = invoiceTestApi;
+ context = factory.createCallContext("Princess Buttercup", CallOrigin.TEST, UserType.TEST);
+ }
+
+ // These helper methods can be overridden in a plugin implementation
+ public Account createTestCreditCardAccount() throws EntityPersistenceException {
+ final String name = "First" + RandomStringUtils.randomAlphanumeric(5) + " " + "Last" + RandomStringUtils.randomAlphanumeric(5);
+ final String externalKey = RandomStringUtils.randomAlphanumeric(10);
+ final Account account = new AccountBuilder(UUID.randomUUID()).name(name)
+ .firstNameLength(name.length())
+ .externalKey(externalKey)
+ .phone("123-456-7890")
+ .email("ccuser" + RandomStringUtils.randomAlphanumeric(8) + "@example.com")
+ .currency(Currency.USD)
+ .billingCycleDay(1)
+ .build();
+ ((ZombieControl)accountUserApi).addResult("getAccountById", account);
+ ((ZombieControl)accountUserApi).addResult("getAccountByKey", account);
+ return account;
+ }
+
+ public Account createTestPayPalAccount() throws EntityPersistenceException {
+ final String name = "First" + RandomStringUtils.randomAlphanumeric(5) + " " + "Last" + RandomStringUtils.randomAlphanumeric(5);
+ final String externalKey = RandomStringUtils.randomAlphanumeric(10);
+ final Account account = new AccountBuilder(UUID.randomUUID()).name(name)
+ .firstNameLength(name.length())
+ .externalKey(externalKey)
+ .phone("123-456-7890")
+ .email("ppuser@example.com")
+ .currency(Currency.USD)
+ .billingCycleDay(1)
+ .build();
+ ((ZombieControl)accountUserApi).addResult("getAccountById", account);
+ ((ZombieControl)accountUserApi).addResult("getAccountByKey", account);
+ return account;
+ }
+
+ public Invoice createTestInvoice(Account account,
+ DateTime targetDate,
+ Currency currency,
+ InvoiceItem... items) {
+ Invoice invoice = new DefaultInvoice(account.getId(), new DateTime(), targetDate, currency);
+
+ for (InvoiceItem item : items) {
+ if (item instanceof RecurringInvoiceItem) {
+ RecurringInvoiceItem recurringInvoiceItem = (RecurringInvoiceItem) item;
+ invoice.addInvoiceItem(new RecurringInvoiceItem(invoice.getId(),
+ account.getId(),
+ recurringInvoiceItem.getBundleId(),
+ recurringInvoiceItem.getSubscriptionId(),
+ recurringInvoiceItem.getPlanName(),
+ recurringInvoiceItem.getPhaseName(),
+ recurringInvoiceItem.getStartDate(),
+ recurringInvoiceItem.getEndDate(),
+ recurringInvoiceItem.getAmount(),
+ recurringInvoiceItem.getRate(),
+ recurringInvoiceItem.getCurrency()));
+ }
+ }
+
+ invoiceTestApi.create(invoice, context);
+ return invoice;
+ }
+
+ public Invoice createTestInvoice(Account account) {
+ final DateTime now = new DateTime(DateTimeZone.UTC);
+ final UUID subscriptionId = UUID.randomUUID();
+ final UUID bundleId = UUID.randomUUID();
+ final BigDecimal amount = new BigDecimal("10.00");
+
+ final InvoiceItem item = new RecurringInvoiceItem(null, account.getId(), bundleId, subscriptionId, "test plan", "test phase", now, now.plusMonths(1),
+ amount, new BigDecimal("1.0"), Currency.USD);
+
+
+ return createTestInvoice(account, now, Currency.USD, item);
+ }
+}
diff --git a/beatrix/src/test/java/com/ning/billing/beatrix/integration/payment/TestNotifyInvoicePaymentApi.java b/beatrix/src/test/java/com/ning/billing/beatrix/integration/payment/TestNotifyInvoicePaymentApi.java
new file mode 100644
index 0000000..d7febde
--- /dev/null
+++ b/beatrix/src/test/java/com/ning/billing/beatrix/integration/payment/TestNotifyInvoicePaymentApi.java
@@ -0,0 +1,118 @@
+/*
+ * Copyright 2010-2011 Ning, Inc.
+ *
+ * Ning 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 com.ning.billing.beatrix.integration.payment;
+
+import static org.testng.Assert.assertNotNull;
+
+import java.util.UUID;
+
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Guice;
+import org.testng.annotations.Test;
+
+import com.google.inject.Inject;
+import com.ning.billing.account.api.Account;
+import com.ning.billing.account.api.AccountApiException;
+import com.ning.billing.account.api.AccountUserApi;
+import com.ning.billing.account.glue.AccountModuleWithMocks;
+import com.ning.billing.invoice.api.Invoice;
+import com.ning.billing.invoice.api.InvoicePayment;
+import com.ning.billing.invoice.api.InvoicePaymentApi;
+import com.ning.billing.invoice.glue.InvoiceModuleWithMocks;
+import com.ning.billing.mock.BrainDeadProxyFactory;
+import com.ning.billing.mock.BrainDeadProxyFactory.ZombieControl;
+import com.ning.billing.mock.glue.MockJunctionModule;
+import com.ning.billing.payment.RequestProcessor;
+import com.ning.billing.payment.api.PaymentAttempt;
+import com.ning.billing.payment.setup.PaymentTestModuleWithMocks;
+import com.ning.billing.util.bus.Bus;
+import com.ning.billing.util.bus.Bus.EventBusException;
+import com.ning.billing.util.callcontext.CallContext;
+import com.ning.billing.util.callcontext.TestCallContext;
+import com.ning.billing.util.entity.EntityPersistenceException;
+
+@Test
+@Guice(modules = { PaymentTestModule.class, AccountModuleWithMocks.class, InvoiceModuleWithMocks.class, MockJunctionModule.class})
+public class TestNotifyInvoicePaymentApi {
+ @Inject
+ private Bus eventBus;
+ @Inject
+ private RequestProcessor invoiceProcessor;
+ @Inject
+ private InvoicePaymentApi invoicePaymentApi;
+ @Inject
+ private TestHelper testHelper;
+ @Inject
+ private AccountUserApi accountApi;
+
+ private CallContext context = new TestCallContext("Payment Api Tests");
+
+ @BeforeClass(alwaysRun = true)
+ public void setUpClass() {
+ ((ZombieControl)accountApi).addResult("getAccountById", BrainDeadProxyFactory.ZOMBIE_VOID);
+ }
+
+ @BeforeMethod(alwaysRun = true)
+ public void setUp() throws EventBusException {
+ eventBus.start();
+ eventBus.register(invoiceProcessor);
+ }
+
+ @AfterMethod(alwaysRun = true)
+ public void tearDown() throws EventBusException {
+ eventBus.unregister(invoiceProcessor);
+ eventBus.stop();
+ }
+
+ @Test
+ public void testNotifyPaymentSuccess() throws AccountApiException, EntityPersistenceException {
+ final Account account = testHelper.createTestCreditCardAccount();
+ final Invoice invoice = testHelper.createTestInvoice(account);
+
+ PaymentAttempt paymentAttempt = new PaymentAttempt(UUID.randomUUID(), invoice);
+
+ invoicePaymentApi.notifyOfPaymentAttempt(invoice.getId(),
+ invoice.getBalance(),
+ invoice.getCurrency(),
+ paymentAttempt.getPaymentAttemptId(),
+ paymentAttempt.getPaymentAttemptDate(),
+ context);
+
+ InvoicePayment invoicePayment = invoicePaymentApi.getInvoicePayment(paymentAttempt.getPaymentAttemptId());
+
+ assertNotNull(invoicePayment);
+ }
+
+ @Test
+ public void testNotifyPaymentFailure() throws AccountApiException, EntityPersistenceException {
+ final Account account = testHelper.createTestCreditCardAccount();
+ final Invoice invoice = testHelper.createTestInvoice(account);
+
+ PaymentAttempt paymentAttempt = new PaymentAttempt(UUID.randomUUID(), invoice);
+ invoicePaymentApi.notifyOfPaymentAttempt(invoice.getId(),
+ paymentAttempt.getPaymentAttemptId(),
+ paymentAttempt.getPaymentAttemptDate(),
+ context);
+
+ InvoicePayment invoicePayment = invoicePaymentApi.getInvoicePayment(paymentAttempt.getPaymentAttemptId());
+
+ assertNotNull(invoicePayment);
+ }
+
+}
diff --git a/beatrix/src/test/java/com/ning/billing/beatrix/integration/payment/TestPaymentInvoiceIntegration.java b/beatrix/src/test/java/com/ning/billing/beatrix/integration/payment/TestPaymentInvoiceIntegration.java
new file mode 100644
index 0000000..32a7157
--- /dev/null
+++ b/beatrix/src/test/java/com/ning/billing/beatrix/integration/payment/TestPaymentInvoiceIntegration.java
@@ -0,0 +1,166 @@
+/*
+ * Copyright 2010-2011 Ning, Inc.
+ *
+ * Ning 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 com.ning.billing.beatrix.integration.payment;
+
+import static com.jayway.awaitility.Awaitility.await;
+import static java.util.concurrent.TimeUnit.MINUTES;
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertTrue;
+
+import java.io.IOException;
+import java.math.BigDecimal;
+import java.util.List;
+import java.util.concurrent.Callable;
+
+import org.apache.commons.io.IOUtils;
+import org.joda.time.DateTime;
+import org.skife.jdbi.v2.IDBI;
+import org.testng.Assert;
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import com.google.inject.AbstractModule;
+import com.google.inject.Guice;
+import com.google.inject.Inject;
+import com.google.inject.Injector;
+import com.ning.billing.account.api.Account;
+import com.ning.billing.dbi.MysqlTestingHelper;
+import com.ning.billing.invoice.api.Invoice;
+import com.ning.billing.invoice.api.InvoicePaymentApi;
+import com.ning.billing.invoice.glue.InvoiceModuleWithMocks;
+import com.ning.billing.mock.glue.MockJunctionModule;
+import com.ning.billing.payment.RequestProcessor;
+import com.ning.billing.payment.api.PaymentApi;
+import com.ning.billing.payment.api.PaymentAttempt;
+import com.ning.billing.payment.api.PaymentErrorEvent;
+import com.ning.billing.payment.api.PaymentInfoEvent;
+import com.ning.billing.payment.setup.PaymentTestModuleWithEmbeddedDb;
+import com.ning.billing.util.bus.Bus;
+import com.ning.billing.util.bus.Bus.EventBusException;
+import com.ning.billing.util.clock.MockClockModule;
+import com.ning.billing.util.glue.CallContextModule;
+
+public class TestPaymentInvoiceIntegration {
+ // create payment for received invoice and save it -- positive and negative
+ // check that notification for payment attempt is created
+ // check that invoice-payment is saved
+ @Inject
+ private Bus eventBus;
+ @Inject
+ private RequestProcessor invoiceProcessor;
+ @Inject
+ private InvoicePaymentApi invoicePaymentApi;
+ @Inject
+ private PaymentApi paymentApi;
+ @Inject
+ private TestHelper testHelper;
+
+ private MockPaymentInfoReceiver paymentInfoReceiver;
+
+ private IDBI dbi;
+ private MysqlTestingHelper helper;
+
+ @BeforeClass(alwaysRun = true)
+ public void startMysql() throws IOException {
+ final String accountddl = IOUtils.toString(MysqlTestingHelper.class.getResourceAsStream("/com/ning/billing/account/ddl.sql"));
+ final String utilddl = IOUtils.toString(MysqlTestingHelper.class.getResourceAsStream("/com/ning/billing/util/ddl.sql"));
+ final String invoiceddl = IOUtils.toString(MysqlTestingHelper.class.getResourceAsStream("/com/ning/billing/invoice/ddl.sql"));
+ final String paymentddl = IOUtils.toString(MysqlTestingHelper.class.getResourceAsStream("/com/ning/billing/payment/ddl.sql"));
+
+ helper = new MysqlTestingHelper();
+ helper.startMysql();
+ helper.initDb(accountddl + "\n" + invoiceddl + "\n" + utilddl + "\n" + paymentddl);
+ dbi = helper.getDBI();
+ }
+
+ @AfterClass(alwaysRun = true)
+ public void stopMysql() {
+ if (helper != null) helper.stopMysql();
+ }
+
+ @BeforeMethod(alwaysRun = true)
+ public void setUp() throws EventBusException {
+ Injector injector = Guice.createInjector(new PaymentTestModuleWithEmbeddedDb(),
+ new InvoiceModuleWithMocks(),
+ new CallContextModule(),
+ new MockClockModule(),
+ new MockJunctionModule(),
+ new AbstractModule()
+
+ {
+ @Override
+ protected void configure() {
+ bind(IDBI.class).toInstance(dbi);
+ }
+ });
+ injector.injectMembers(this);
+
+ paymentInfoReceiver = new MockPaymentInfoReceiver();
+
+ eventBus.start();
+ eventBus.register(invoiceProcessor);
+ eventBus.register(paymentInfoReceiver);
+ }
+
+ @AfterMethod(alwaysRun = true)
+ public void tearDown() throws EventBusException {
+ if (eventBus != null) {
+ eventBus.unregister(invoiceProcessor);
+ eventBus.unregister(paymentInfoReceiver);
+ eventBus.stop();
+ }
+ }
+
+ @Test
+ public void testInvoiceIntegration() throws Exception {
+ final Account account = testHelper.createTestCreditCardAccount();
+ final Invoice invoice = testHelper.createTestInvoice(account);
+
+ await().atMost(1, MINUTES).until(new Callable<Boolean>() {
+ @Override
+ public Boolean call() throws Exception {
+ List<PaymentInfoEvent> processedPayments = paymentInfoReceiver.getProcessedPayments();
+ List<PaymentErrorEvent> errors = paymentInfoReceiver.getErrors();
+
+ return processedPayments.size() == 1 || errors.size() == 1;
+ }
+ });
+
+ assertFalse(paymentInfoReceiver.getProcessedPayments().isEmpty());
+ assertTrue(paymentInfoReceiver.getErrors().isEmpty());
+
+ List<PaymentInfoEvent> payments = paymentInfoReceiver.getProcessedPayments();
+ PaymentAttempt paymentAttempt = paymentApi.getPaymentAttemptForPaymentId(payments.get(0).getPaymentId());
+ Assert.assertNotNull(paymentAttempt);
+
+ Invoice invoiceForPayment = invoicePaymentApi.getInvoiceForPaymentAttemptId(paymentAttempt.getPaymentAttemptId());
+
+ Assert.assertNotNull(invoiceForPayment);
+ Assert.assertEquals(invoiceForPayment.getId(), invoice.getId());
+ Assert.assertEquals(invoiceForPayment.getAccountId(), account.getId());
+
+ DateTime invoicePaymentAttempt = invoiceForPayment.getLastPaymentAttempt();
+ DateTime correctedDate = invoicePaymentAttempt.minus(invoicePaymentAttempt.millisOfSecond().get());
+ Assert.assertTrue(correctedDate.isEqual(paymentAttempt.getPaymentAttemptDate()));
+
+ Assert.assertEquals(invoiceForPayment.getBalance().floatValue(), new BigDecimal("0").floatValue());
+ Assert.assertEquals(invoiceForPayment.getAmountPaid().floatValue(), invoice.getAmountPaid().floatValue());
+ }
+}
diff --git a/beatrix/src/test/java/com/ning/billing/beatrix/integration/payment/TestPaymentProvider.java b/beatrix/src/test/java/com/ning/billing/beatrix/integration/payment/TestPaymentProvider.java
new file mode 100644
index 0000000..a28f7df
--- /dev/null
+++ b/beatrix/src/test/java/com/ning/billing/beatrix/integration/payment/TestPaymentProvider.java
@@ -0,0 +1,96 @@
+/*
+ * Copyright 2010-2011 Ning, Inc.
+ *
+ * Ning 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 com.ning.billing.beatrix.integration.payment;
+
+import static com.jayway.awaitility.Awaitility.await;
+import static java.util.concurrent.TimeUnit.MINUTES;
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertTrue;
+
+import java.util.List;
+import java.util.concurrent.Callable;
+
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Guice;
+import org.testng.annotations.Test;
+
+import com.google.inject.Inject;
+import com.ning.billing.account.api.Account;
+import com.ning.billing.account.glue.AccountModuleWithMocks;
+import com.ning.billing.invoice.api.Invoice;
+import com.ning.billing.invoice.glue.InvoiceModuleWithMocks;
+import com.ning.billing.mock.glue.MockJunctionModule;
+import com.ning.billing.payment.RequestProcessor;
+import com.ning.billing.payment.api.PaymentErrorEvent;
+import com.ning.billing.payment.api.PaymentInfoEvent;
+import com.ning.billing.payment.setup.PaymentTestModuleWithMocks;
+import com.ning.billing.util.bus.Bus;
+import com.ning.billing.util.bus.Bus.EventBusException;
+
+@Guice(modules = { PaymentTestModule.class, AccountModuleWithMocks.class, InvoiceModuleWithMocks.class, MockJunctionModule.class })
+public class TestPaymentProvider {
+ @Inject
+ private Bus eventBus;
+ @Inject
+ private RequestProcessor invoiceProcessor;
+ @Inject
+ private TestHelper testHelper;
+
+ private MockPaymentInfoReceiver paymentInfoReceiver;
+
+ @BeforeMethod(alwaysRun = true)
+ public void setUp() throws EventBusException {
+ paymentInfoReceiver = new MockPaymentInfoReceiver();
+
+ eventBus.start();
+ eventBus.register(invoiceProcessor);
+ eventBus.register(paymentInfoReceiver);
+
+ assertTrue(true);
+ }
+
+ @AfterMethod(alwaysRun = true)
+ public void tearDown() throws EventBusException {
+ eventBus.unregister(invoiceProcessor);
+ eventBus.unregister(paymentInfoReceiver);
+ eventBus.stop();
+
+ assertTrue(true);
+ }
+
+ @Test
+ public void testSimpleInvoice() throws Exception {
+ final Account account = testHelper.createTestCreditCardAccount();
+
+ Invoice invoice = testHelper.createTestInvoice(account);
+
+ await().atMost(1, MINUTES).until(new Callable<Boolean>() {
+ @Override
+ public Boolean call() throws Exception {
+ List<PaymentInfoEvent> processedPayments = paymentInfoReceiver.getProcessedPayments();
+ List<PaymentErrorEvent> errors = paymentInfoReceiver.getErrors();
+
+ return processedPayments.size() == 1 || errors.size() == 1;
+ }
+ });
+
+ assertFalse(paymentInfoReceiver.getProcessedPayments().isEmpty());
+ // can't check errors; the mock is flaky and results in $0 payment attempt
+ assertTrue(invoice.getPayments().size() > 0);
+ }
+}
diff --git a/payment/src/test/java/com/ning/billing/payment/MockInvoice.java b/payment/src/test/java/com/ning/billing/payment/MockInvoice.java
new file mode 100644
index 0000000..6da3323
--- /dev/null
+++ b/payment/src/test/java/com/ning/billing/payment/MockInvoice.java
@@ -0,0 +1,236 @@
+/*
+ * Copyright 2010-2011 Ning, Inc.
+ *
+ * Ning 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 com.ning.billing.payment;
+
+import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.UUID;
+
+import javax.annotation.Nullable;
+
+import org.joda.time.DateTime;
+
+import com.ning.billing.catalog.api.Currency;
+import com.ning.billing.invoice.api.Invoice;
+import com.ning.billing.invoice.api.InvoiceItem;
+import com.ning.billing.invoice.api.InvoicePayment;
+import com.ning.billing.util.callcontext.CallContext;
+import com.ning.billing.util.customfield.CustomField;
+import com.ning.billing.util.entity.ExtendedEntityBase;
+
+public class MockInvoice extends ExtendedEntityBase implements Invoice {
+ private final List<InvoiceItem> invoiceItems = new ArrayList<InvoiceItem>();
+ private final List<InvoicePayment> payments = new ArrayList<InvoicePayment>();
+ private final UUID accountId;
+ private final Integer invoiceNumber;
+ private final DateTime invoiceDate;
+ private final DateTime targetDate;
+ private final Currency currency;
+ private final boolean migrationInvoice;
+
+ // used to create a new invoice
+ public MockInvoice(UUID accountId, DateTime invoiceDate, DateTime targetDate, Currency currency) {
+ this(UUID.randomUUID(), accountId, null, invoiceDate, targetDate, currency, false, null, null);
+ }
+
+ // used to hydrate invoice from persistence layer
+ public MockInvoice(UUID invoiceId, UUID accountId, @Nullable Integer invoiceNumber, DateTime invoiceDate,
+ DateTime targetDate, Currency currency, boolean isMigrationInvoice, @Nullable String createdBy, @Nullable DateTime createdDate) {
+ super(invoiceId, createdBy, createdDate);
+ this.accountId = accountId;
+ this.invoiceNumber = invoiceNumber;
+ this.invoiceDate = invoiceDate;
+ this.targetDate = targetDate;
+ this.currency = currency;
+ this.migrationInvoice = isMigrationInvoice;
+ }
+
+ @Override
+ public boolean addInvoiceItem(final InvoiceItem item) {
+ return invoiceItems.add(item);
+ }
+
+ @Override
+ public boolean addInvoiceItems(final List<InvoiceItem> items) {
+ return this.invoiceItems.addAll(items);
+ }
+
+ @Override
+ public List<InvoiceItem> getInvoiceItems() {
+ return invoiceItems;
+ }
+
+ @Override
+ public <T extends InvoiceItem> List<InvoiceItem> getInvoiceItems(Class<T> clazz) {
+ List<InvoiceItem> results = new ArrayList<InvoiceItem>();
+ for (InvoiceItem item : invoiceItems) {
+ if ( clazz.isInstance(item) ) {
+ results.add(item);
+ }
+ }
+ return results;
+ }
+
+ @Override
+ public int getNumberOfItems() {
+ return invoiceItems.size();
+ }
+
+ @Override
+ public boolean addPayment(final InvoicePayment payment) {
+ return payments.add(payment);
+ }
+
+ @Override
+ public boolean addPayments(final List<InvoicePayment> payments) {
+ return this.payments.addAll(payments);
+ }
+
+ @Override
+ public List<InvoicePayment> getPayments() {
+ return payments;
+ }
+
+ @Override
+ public int getNumberOfPayments() {
+ return payments.size();
+ }
+
+ @Override
+ public UUID getId() {
+ return id;
+ }
+
+ @Override
+ public UUID getAccountId() {
+ return accountId;
+ }
+
+ /**
+ * null until retrieved from the database
+ * @return the invoice number
+ */
+ @Override
+ public Integer getInvoiceNumber() {
+ return invoiceNumber;
+ }
+
+ @Override
+ public DateTime getInvoiceDate() {
+ return invoiceDate;
+ }
+
+ @Override
+ public DateTime getTargetDate() {
+ return targetDate;
+ }
+
+ @Override
+ public Currency getCurrency() {
+ return currency;
+ }
+
+ @Override
+ public boolean isMigrationInvoice() {
+ return migrationInvoice;
+ }
+
+ @Override
+ public DateTime getLastPaymentAttempt() {
+ DateTime lastPaymentAttempt = null;
+
+ for (final InvoicePayment paymentAttempt : payments) {
+ DateTime paymentAttemptDate = paymentAttempt.getPaymentAttemptDate();
+ if (lastPaymentAttempt == null) {
+ lastPaymentAttempt = paymentAttemptDate;
+ }
+
+ if (lastPaymentAttempt.isBefore(paymentAttemptDate)) {
+ lastPaymentAttempt = paymentAttemptDate;
+ }
+ }
+
+ return lastPaymentAttempt;
+ }
+
+ @Override
+ public BigDecimal getAmountPaid() {
+ BigDecimal amountPaid = BigDecimal.ZERO;
+ for (final InvoicePayment payment : payments) {
+ if (payment.getAmount() != null) {
+ amountPaid = amountPaid.add(payment.getAmount());
+ }
+ }
+ return amountPaid;
+ }
+
+ @Override
+ public BigDecimal getTotalAmount() {
+ BigDecimal result = BigDecimal.ZERO;
+
+ for(InvoiceItem i : invoiceItems) {
+ result = result.add(i.getAmount());
+ }
+ return result;
+ }
+
+ @Override
+ public BigDecimal getBalance() {
+ return getTotalAmount().subtract(getAmountPaid());
+ }
+
+ @Override
+ public boolean isDueForPayment(final DateTime targetDate, final int numberOfDays) {
+ if (getTotalAmount().compareTo(BigDecimal.ZERO) == 0) {
+ return false;
+ }
+
+ DateTime lastPaymentAttempt = getLastPaymentAttempt();
+ if (lastPaymentAttempt == null) {
+ return true;
+ }
+
+ return !lastPaymentAttempt.plusDays(numberOfDays).isAfter(targetDate);
+ }
+
+ @Override
+ public String toString() {
+ return "DefaultInvoice [items=" + invoiceItems + ", payments=" + payments + ", id=" + id + ", accountId=" + accountId + ", invoiceDate=" + invoiceDate + ", targetDate=" + targetDate + ", currency=" + currency + ", amountPaid=" + getAmountPaid() + ", lastPaymentAttempt=" + getLastPaymentAttempt() + "]";
+ }
+
+ @Override
+ public String getObjectName() {
+ return Invoice.ObjectType;
+ }
+
+ @Override
+ public void saveFieldValue(String fieldName, String fieldValue, CallContext context) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void saveFields(List<CustomField> fields, CallContext context) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void clearPersistedFields(CallContext context) {
+ throw new UnsupportedOperationException();
+ }
+}
+
diff --git a/payment/src/test/java/com/ning/billing/payment/MockInvoiceCreationEvent.java b/payment/src/test/java/com/ning/billing/payment/MockInvoiceCreationEvent.java
new file mode 100644
index 0000000..9a700cd
--- /dev/null
+++ b/payment/src/test/java/com/ning/billing/payment/MockInvoiceCreationEvent.java
@@ -0,0 +1,157 @@
+/*
+ * Copyright 2010-2011 Ning, Inc.
+ *
+ * Ning 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 com.ning.billing.payment;
+
+import java.math.BigDecimal;
+import java.util.UUID;
+
+import org.codehaus.jackson.annotate.JsonCreator;
+import org.codehaus.jackson.annotate.JsonIgnore;
+import org.codehaus.jackson.annotate.JsonProperty;
+import org.joda.time.DateTime;
+
+import com.ning.billing.catalog.api.Currency;
+import com.ning.billing.invoice.api.InvoiceCreationEvent;
+import com.ning.billing.util.bus.BusEvent.BusEventType;
+
+public class MockInvoiceCreationEvent implements InvoiceCreationEvent {
+
+ private final UUID invoiceId;
+ private final UUID accountId;
+ private final BigDecimal amountOwed;
+ private final Currency currency;
+ private final DateTime invoiceCreationDate;
+ private final UUID userToken;
+
+ @JsonCreator
+ public MockInvoiceCreationEvent(@JsonProperty("invoiceId") UUID invoiceId,
+ @JsonProperty("accountId") UUID accountId,
+ @JsonProperty("amountOwed") BigDecimal amountOwed,
+ @JsonProperty("currency") Currency currency,
+ @JsonProperty("invoiceCreationDate") DateTime invoiceCreationDate,
+ @JsonProperty("userToken") UUID userToken) {
+ this.invoiceId = invoiceId;
+ this.accountId = accountId;
+ this.amountOwed = amountOwed;
+ this.currency = currency;
+ this.invoiceCreationDate = invoiceCreationDate;
+ this.userToken = userToken;
+ }
+
+ @JsonIgnore
+ @Override
+ public BusEventType getBusEventType() {
+ return BusEventType.INVOICE_CREATION;
+ }
+
+ @Override
+ public UUID getUserToken() {
+ return userToken;
+ }
+
+ @Override
+ public UUID getInvoiceId() {
+ return invoiceId;
+ }
+
+ @Override
+ public UUID getAccountId() {
+ return accountId;
+ }
+
+ @Override
+ public BigDecimal getAmountOwed() {
+ return amountOwed;
+ }
+
+ @Override
+ public Currency getCurrency() {
+ return currency;
+ }
+
+ @Override
+ public DateTime getInvoiceCreationDate() {
+ return invoiceCreationDate;
+ }
+
+ @Override
+ public String toString() {
+ return "DefaultInvoiceCreationNotification [invoiceId=" + invoiceId + ", accountId=" + accountId + ", amountOwed=" + amountOwed + ", currency=" + currency + ", invoiceCreationDate=" + invoiceCreationDate + "]";
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result
+ + ((accountId == null) ? 0 : accountId.hashCode());
+ result = prime * result
+ + ((amountOwed == null) ? 0 : amountOwed.hashCode());
+ result = prime * result
+ + ((currency == null) ? 0 : currency.hashCode());
+ result = prime
+ * result
+ + ((invoiceCreationDate == null) ? 0 : invoiceCreationDate
+ .hashCode());
+ result = prime * result
+ + ((invoiceId == null) ? 0 : invoiceId.hashCode());
+ result = prime * result
+ + ((userToken == null) ? 0 : userToken.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ MockInvoiceCreationEvent other = (MockInvoiceCreationEvent) obj;
+ if (accountId == null) {
+ if (other.accountId != null)
+ return false;
+ } else if (!accountId.equals(other.accountId))
+ return false;
+ if (amountOwed == null) {
+ if (other.amountOwed != null)
+ return false;
+ } else if (!amountOwed.equals(other.amountOwed))
+ return false;
+ if (currency != other.currency)
+ return false;
+ if (invoiceCreationDate == null) {
+ if (other.invoiceCreationDate != null)
+ return false;
+ } else if (invoiceCreationDate.compareTo(other.invoiceCreationDate) != 0)
+ return false;
+ if (invoiceId == null) {
+ if (other.invoiceId != null)
+ return false;
+ } else if (!invoiceId.equals(other.invoiceId))
+ return false;
+ if (userToken == null) {
+ if (other.userToken != null)
+ return false;
+ } else if (!userToken.equals(other.userToken))
+ return false;
+ return true;
+ }
+
+
+}
diff --git a/payment/src/test/java/com/ning/billing/payment/MockRecurringInvoiceItem.java b/payment/src/test/java/com/ning/billing/payment/MockRecurringInvoiceItem.java
new file mode 100644
index 0000000..40a927f
--- /dev/null
+++ b/payment/src/test/java/com/ning/billing/payment/MockRecurringInvoiceItem.java
@@ -0,0 +1,271 @@
+/*
+ * Copyright 2010-2011 Ning, Inc.
+ *
+ * Ning 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 com.ning.billing.payment;
+
+import com.ning.billing.catalog.api.Currency;
+import com.ning.billing.invoice.api.InvoiceItem;
+import com.ning.billing.util.entity.EntityBase;
+
+import org.apache.commons.lang.NotImplementedException;
+import org.joda.time.DateTime;
+
+import java.math.BigDecimal;
+import java.util.UUID;
+
+import javax.annotation.Nullable;
+
+public class MockRecurringInvoiceItem extends EntityBase implements InvoiceItem {
+ private final BigDecimal rate;
+ private final UUID reversedItemId;
+ protected final UUID invoiceId;
+ protected final UUID accountId;
+ protected final UUID subscriptionId;
+ protected final UUID bundleId;
+ protected final String planName;
+ protected final String phaseName;
+ protected final DateTime startDate;
+ protected final DateTime endDate;
+ protected final BigDecimal amount;
+ protected final Currency currency;
+
+
+ public MockRecurringInvoiceItem(UUID invoiceId, UUID accountId, UUID bundleId, UUID subscriptionId, String planName, String phaseName,
+ DateTime startDate, DateTime endDate,
+ BigDecimal amount, BigDecimal rate,
+ Currency currency) {
+ this(invoiceId, accountId, bundleId, subscriptionId, planName, phaseName, startDate, endDate, amount, currency, rate, null);
+
+ }
+
+ public MockRecurringInvoiceItem(UUID invoiceId, UUID accountId, UUID bundleId, UUID subscriptionId, String planName, String phaseName,
+ DateTime startDate, DateTime endDate,
+ BigDecimal amount, BigDecimal rate,
+ Currency currency, UUID reversedItemId) {
+ this(invoiceId, accountId, bundleId, subscriptionId, planName, phaseName, startDate, endDate,
+ amount, currency, rate, reversedItemId);
+ }
+
+ public MockRecurringInvoiceItem(UUID id, UUID invoiceId, UUID accountId, UUID bundleId, UUID subscriptionId, String planName, String phaseName,
+ DateTime startDate, DateTime endDate,
+ BigDecimal amount, BigDecimal rate,
+ Currency currency,
+ String createdBy, DateTime createdDate) {
+ this(id, invoiceId, accountId, bundleId, subscriptionId, planName, phaseName, startDate, endDate, amount, currency, createdBy, createdDate, rate, null);
+
+ }
+
+ public MockRecurringInvoiceItem(UUID id, UUID invoiceId, UUID accountId, UUID bundleId, UUID subscriptionId, String planName, String phaseName,
+ DateTime startDate, DateTime endDate,
+ BigDecimal amount, BigDecimal rate,
+ Currency currency, UUID reversedItemId,
+ String createdBy, DateTime createdDate) {
+ this(id, invoiceId, accountId, bundleId, subscriptionId, planName, phaseName, startDate, endDate, amount, currency, createdBy, createdDate, rate, reversedItemId);
+ }
+ public MockRecurringInvoiceItem(UUID invoiceId, UUID accountId, UUID bundleId, UUID subscriptionId, String planName, String phaseName,
+ DateTime startDate, DateTime endDate, BigDecimal amount, Currency currency, BigDecimal rate, UUID reversedItemId){
+ this(UUID.randomUUID(), invoiceId, accountId, bundleId, subscriptionId, planName, phaseName,
+ startDate, endDate, amount, currency, null, null, rate, reversedItemId);
+ }
+
+
+ public MockRecurringInvoiceItem(UUID id, UUID invoiceId, UUID accountId, @Nullable UUID bundleId, @Nullable UUID subscriptionId, String planName, String phaseName,
+ DateTime startDate, DateTime endDate, BigDecimal amount, Currency currency,
+ @Nullable String createdBy, @Nullable DateTime createdDate, BigDecimal rate, UUID reversedItemId) {
+ super(id, createdBy, createdDate);
+ this.invoiceId = invoiceId;
+ this.accountId = accountId;
+ this.subscriptionId = subscriptionId;
+ this.bundleId = bundleId;
+ this.planName = planName;
+ this.phaseName = phaseName;
+ this.startDate = startDate;
+ this.endDate = endDate;
+ this.amount = amount;
+ this.currency = currency;
+ this.rate = rate;
+ this.reversedItemId = reversedItemId;
+
+ }
+
+ public DateTime getCreatedDate() {
+ return createdDate;
+ }
+
+ @Override
+ public UUID getId() {
+ return id;
+ }
+
+ @Override
+ public UUID getInvoiceId() {
+ return invoiceId;
+ }
+
+ @Override
+ public UUID getBundleId() {
+ return bundleId;
+ }
+
+ public UUID getAccountId() {
+ return accountId;
+ }
+
+ @Override
+ public UUID getSubscriptionId() {
+ return subscriptionId;
+ }
+
+ @Override
+ public String getPlanName() {
+ return planName;
+ }
+
+ @Override
+ public String getPhaseName() {
+ return phaseName;
+ }
+
+ @Override
+ public BigDecimal getAmount() {
+ return amount;
+ }
+
+ @Override
+ public DateTime getStartDate() {
+ return startDate;
+ }
+
+ @Override
+ public DateTime getEndDate() {
+ return endDate;
+ }
+
+ @Override
+ public Currency getCurrency() {
+ return currency;
+ }
+ @Override
+ public InvoiceItem asReversingItem() {
+ throw new NotImplementedException();
+ }
+
+ @Override
+ public String getDescription() {
+ return String.format("%s from %s to %s", phaseName, startDate.toString(), endDate.toString());
+ }
+
+ public UUID getReversedItemId() {
+ return reversedItemId;
+ }
+
+ public boolean reversesItem() {
+ return (reversedItemId != null);
+ }
+
+ public BigDecimal getRate() {
+ return rate;
+ }
+
+ @Override
+ public int compareTo(InvoiceItem item) {
+ if (item == null) {
+ return -1;
+ }
+ if (!(item instanceof MockRecurringInvoiceItem)) {
+ return -1;
+ }
+
+ MockRecurringInvoiceItem that = (MockRecurringInvoiceItem) item;
+ int compareAccounts = getAccountId().compareTo(that.getAccountId());
+ if (compareAccounts == 0 && bundleId != null) {
+ int compareBundles = getBundleId().compareTo(that.getBundleId());
+ if (compareBundles == 0 && subscriptionId != null) {
+
+ int compareSubscriptions = getSubscriptionId().compareTo(that.getSubscriptionId());
+ if (compareSubscriptions == 0) {
+ int compareStartDates = getStartDate().compareTo(that.getStartDate());
+ if (compareStartDates == 0) {
+ return getEndDate().compareTo(that.getEndDate());
+ } else {
+ return compareStartDates;
+ }
+ } else {
+ return compareSubscriptions;
+ }
+ } else {
+ return compareBundles;
+ }
+ } else {
+ return compareAccounts;
+ }
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ MockRecurringInvoiceItem that = (MockRecurringInvoiceItem) o;
+
+ if (accountId.compareTo(that.accountId) != 0) return false;
+ if (amount.compareTo(that.amount) != 0) return false;
+ if (currency != that.currency) return false;
+ if (startDate.compareTo(that.startDate) != 0) return false;
+ if (endDate.compareTo(that.endDate) != 0) return false;
+ if (!phaseName.equals(that.phaseName)) return false;
+ if (!planName.equals(that.planName)) return false;
+ if (rate.compareTo(that.rate) != 0) return false;
+ if (reversedItemId != null ? !reversedItemId.equals(that.reversedItemId) : that.reversedItemId != null)
+ return false;
+ if (subscriptionId != null ? !subscriptionId.equals(that.subscriptionId) : that.subscriptionId != null)
+ return false;
+ if (bundleId != null ? !bundleId.equals(that.bundleId) : that.bundleId != null)
+ return false;
+
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ int result = accountId.hashCode();
+ result = 31 * result + (subscriptionId != null ? subscriptionId.hashCode() : 0);
+ result = 31 * result + (bundleId != null ? bundleId.hashCode() : 0);
+ result = 31 * result + planName.hashCode();
+ result = 31 * result + phaseName.hashCode();
+ result = 31 * result + startDate.hashCode();
+ result = 31 * result + endDate.hashCode();
+ result = 31 * result + amount.hashCode();
+ result = 31 * result + rate.hashCode();
+ result = 31 * result + currency.hashCode();
+ result = 31 * result + (reversedItemId != null ? reversedItemId.hashCode() : 0);
+ return result;
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder();
+
+ sb.append(phaseName).append(", ");
+ sb.append(startDate.toString()).append(", ");
+ sb.append(endDate.toString()).append(", ");
+ sb.append(amount.toString()).append(", ");
+ sb.append("subscriptionId = ").append(subscriptionId == null ? null : subscriptionId.toString()).append(", ");
+ sb.append("bundleId = ").append(bundleId == null ? null : bundleId.toString()).append(", ");
+
+ return sb.toString();
+ }
+}
diff --git a/util/src/test/java/com/ning/billing/mock/glue/MockNotificationQueueModule.java b/util/src/test/java/com/ning/billing/mock/glue/MockNotificationQueueModule.java
new file mode 100644
index 0000000..899be2b
--- /dev/null
+++ b/util/src/test/java/com/ning/billing/mock/glue/MockNotificationQueueModule.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2010-2011 Ning, Inc.
+ *
+ * Ning 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 com.ning.billing.mock.glue;
+
+import com.google.inject.AbstractModule;
+import com.ning.billing.util.notificationq.MockNotificationQueueService;
+import com.ning.billing.util.notificationq.NotificationQueueService;
+
+public class MockNotificationQueueModule extends AbstractModule {
+
+ @Override
+ protected void configure() {
+ bind(NotificationQueueService.class).to(MockNotificationQueueService.class).asEagerSingleton();
+ }
+
+}
diff --git a/util/src/test/java/com/ning/billing/mock/glue/TestDbiModule.java b/util/src/test/java/com/ning/billing/mock/glue/TestDbiModule.java
new file mode 100644
index 0000000..c42717d
--- /dev/null
+++ b/util/src/test/java/com/ning/billing/mock/glue/TestDbiModule.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2010-2011 Ning, Inc.
+ *
+ * Ning 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 com.ning.billing.mock.glue;
+
+import org.skife.config.ConfigurationObjectFactory;
+import org.skife.jdbi.v2.IDBI;
+
+import com.google.inject.AbstractModule;
+import com.ning.billing.dbi.DBIProvider;
+import com.ning.billing.dbi.DbiConfig;
+import com.ning.billing.dbi.MysqlTestingHelper;
+
+public class TestDbiModule extends AbstractModule {
+
+ protected void configure() {
+
+ final MysqlTestingHelper helper = new MysqlTestingHelper();
+ bind(MysqlTestingHelper.class).toInstance(helper);
+ if (helper.isUsingLocalInstance()) {
+ bind(IDBI.class).toProvider(DBIProvider.class).asEagerSingleton();
+ final DbiConfig config = new ConfigurationObjectFactory(System.getProperties()).build(DbiConfig.class);
+ bind(DbiConfig.class).toInstance(config);
+ } else {
+ final IDBI dbi = helper.getDBI();
+ bind(IDBI.class).toInstance(dbi);
+ }
+
+ }
+}
diff --git a/util/src/test/java/com/ning/billing/mock/MockAccountBuilder.java b/util/src/test/java/com/ning/billing/mock/MockAccountBuilder.java
new file mode 100644
index 0000000..ec2b431
--- /dev/null
+++ b/util/src/test/java/com/ning/billing/mock/MockAccountBuilder.java
@@ -0,0 +1,462 @@
+/*
+ * Copyright 2010-2011 Ning, Inc.
+ *
+ * Ning 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 com.ning.billing.mock;
+
+import java.util.List;
+import java.util.UUID;
+
+import org.apache.commons.lang.NotImplementedException;
+import org.joda.time.DateTime;
+import org.joda.time.DateTimeZone;
+
+import com.ning.billing.account.api.Account;
+import com.ning.billing.account.api.MutableAccountData;
+import com.ning.billing.catalog.api.Currency;
+import com.ning.billing.junction.api.BlockingState;
+import com.ning.billing.util.callcontext.CallContext;
+import com.ning.billing.util.customfield.CustomField;
+import com.ning.billing.util.tag.ControlTagType;
+import com.ning.billing.util.tag.Tag;
+import com.ning.billing.util.tag.TagDefinition;
+
+public class MockAccountBuilder {
+ private final UUID id;
+ private String externalKey;
+ private String email;
+ private String name;
+ private int firstNameLength;
+ private Currency currency;
+ private int billingCycleDay;
+ private String paymentProviderName;
+ private DateTimeZone timeZone;
+ private String locale;
+ private String address1;
+ private String address2;
+ private String companyName;
+ private String city;
+ private String stateOrProvince;
+ private String country;
+ private String postalCode;
+ private String phone;
+ private boolean migrated;
+ private boolean isNotifiedForInvoices;
+ private String createdBy;
+ private DateTime createdDate;
+ private String updatedBy;
+ private DateTime updatedDate;
+
+ public MockAccountBuilder() {
+ this(UUID.randomUUID());
+ }
+
+ public MockAccountBuilder(final UUID id) {
+ this.id = id;
+ }
+
+ public MockAccountBuilder externalKey(final String externalKey) {
+ this.externalKey = externalKey;
+ return this;
+ }
+
+ public MockAccountBuilder email(final String email) {
+ this.email = email;
+ return this;
+ }
+
+ public MockAccountBuilder name(final String name) {
+ this.name = name;
+ return this;
+ }
+
+ public MockAccountBuilder firstNameLength(final int firstNameLength) {
+ this.firstNameLength = firstNameLength;
+ return this;
+ }
+
+ public MockAccountBuilder billingCycleDay(final int billingCycleDay) {
+ this.billingCycleDay = billingCycleDay;
+ return this;
+ }
+
+ public MockAccountBuilder currency(final Currency currency) {
+ this.currency = currency;
+ return this;
+ }
+
+ public MockAccountBuilder paymentProviderName(final String paymentProviderName) {
+ this.paymentProviderName = paymentProviderName;
+ return this;
+ }
+
+ public MockAccountBuilder timeZone(final DateTimeZone timeZone) {
+ this.timeZone = timeZone;
+ return this;
+ }
+
+ public MockAccountBuilder locale(final String locale) {
+ this.locale = locale;
+ return this;
+ }
+
+ public MockAccountBuilder address1(final String address1) {
+ this.address1 = address1;
+ return this;
+ }
+
+ public MockAccountBuilder address2(final String address2) {
+ this.address2 = address2;
+ return this;
+ }
+
+ public MockAccountBuilder companyName(final String companyName) {
+ this.companyName = companyName;
+ return this;
+ }
+
+ public MockAccountBuilder city(final String city) {
+ this.city = city;
+ return this;
+ }
+
+ public MockAccountBuilder stateOrProvince(final String stateOrProvince) {
+ this.stateOrProvince = stateOrProvince;
+ return this;
+ }
+
+ public MockAccountBuilder postalCode(final String postalCode) {
+ this.postalCode = postalCode;
+ return this;
+ }
+
+ public MockAccountBuilder country(final String country) {
+ this.country = country;
+ return this;
+ }
+
+ public MockAccountBuilder phone(final String phone) {
+ this.phone = phone;
+ return this;
+ }
+
+ public MockAccountBuilder migrated(final boolean migrated) {
+ this.migrated = migrated;
+ return this;
+ }
+
+ public MockAccountBuilder isNotifiedForInvoices(final boolean isNotifiedForInvoices) {
+ this.isNotifiedForInvoices = isNotifiedForInvoices;
+ return this;
+ }
+
+ public MockAccountBuilder createdBy(final String createdBy) {
+ this.createdBy = createdBy;
+ return this;
+ }
+
+ public MockAccountBuilder createdDate(final DateTime createdDate) {
+ this.createdDate = createdDate;
+ return this;
+ }
+
+ public MockAccountBuilder updatedBy(final String updatedBy) {
+ this.updatedBy = updatedBy;
+ return this;
+ }
+
+ public MockAccountBuilder updatedDate(final DateTime updatedDate) {
+ this.updatedDate = updatedDate;
+ return this;
+ }
+
+ public Account build() {
+ return new Account(){
+
+ @Override
+ public String getExternalKey() {
+ return externalKey;
+ }
+
+ @Override
+ public String getName() {
+
+ return name;
+ }
+
+ @Override
+ public int getFirstNameLength() {
+
+ return firstNameLength;
+ }
+
+ @Override
+ public String getEmail() {
+
+ return email;
+ }
+
+ @Override
+ public int getBillCycleDay() {
+
+ return billingCycleDay;
+ }
+
+ @Override
+ public Currency getCurrency() {
+
+ return currency;
+ }
+
+ @Override
+ public String getPaymentProviderName() {
+
+ return paymentProviderName;
+ }
+
+ @Override
+ public DateTimeZone getTimeZone() {
+
+ return timeZone;
+ }
+
+ @Override
+ public String getLocale() {
+
+ return locale;
+ }
+
+ @Override
+ public String getAddress1() {
+
+ return address1;
+ }
+
+ @Override
+ public String getAddress2() {
+
+ return address2;
+ }
+
+ @Override
+ public String getCompanyName() {
+
+ return companyName;
+ }
+
+ @Override
+ public String getCity() {
+
+ return city;
+ }
+
+ @Override
+ public String getStateOrProvince() {
+
+ return stateOrProvince;
+ }
+
+ @Override
+ public String getPostalCode() {
+
+ return postalCode;
+ }
+
+ @Override
+ public String getCountry() {
+
+ return country;
+ }
+
+ @Override
+ public String getPhone() {
+
+ return phone;
+ }
+
+ @Override
+ public boolean isMigrated() {
+
+ return migrated;
+ }
+
+ @Override
+ public boolean isNotifiedForInvoices() {
+
+ return isNotifiedForInvoices;
+ }
+
+ @Override
+ public String getFieldValue(String fieldName) {
+
+ return null;
+ }
+
+ @Override
+ public void setFieldValue(String fieldName, String fieldValue) {
+
+
+ }
+
+ @Override
+ public void saveFieldValue(String fieldName, String fieldValue, CallContext context) {
+
+
+ }
+
+ @Override
+ public List<CustomField> getFieldList() {
+
+ return null;
+ }
+
+ @Override
+ public void setFields(List<CustomField> fields) {
+
+
+ }
+
+ @Override
+ public void saveFields(List<CustomField> fields, CallContext context) {
+
+
+ }
+
+ @Override
+ public void clearFields() {
+
+
+ }
+
+ @Override
+ public void clearPersistedFields(CallContext context) {
+
+
+ }
+
+ @Override
+ public String getObjectName() {
+
+ return null;
+ }
+
+ @Override
+ public String getUpdatedBy() {
+
+ return updatedBy;
+ }
+
+ @Override
+ public DateTime getUpdatedDate() {
+
+ return updatedDate;
+ }
+
+ @Override
+ public UUID getId() {
+
+ return id;
+ }
+
+ @Override
+ public String getCreatedBy() {
+
+ return createdBy;
+ }
+
+ @Override
+ public DateTime getCreatedDate() {
+
+ return createdDate;
+ }
+
+ @Override
+ public List<Tag> getTagList() {
+
+ return null;
+ }
+
+ @Override
+ public boolean hasTag(TagDefinition tagDefinition) {
+
+ return false;
+ }
+
+ @Override
+ public boolean hasTag(ControlTagType controlTagType) {
+
+ return false;
+ }
+
+ @Override
+ public void addTag(TagDefinition definition) {
+
+
+ }
+
+ @Override
+ public void addTags(List<Tag> tags) {
+
+
+ }
+
+ @Override
+ public void addTagsFromDefinitions(List<TagDefinition> tagDefinitions) {
+
+
+ }
+
+ @Override
+ public void clearTags() {
+
+
+ }
+
+ @Override
+ public void removeTag(TagDefinition definition) {
+
+
+ }
+
+ @Override
+ public boolean generateInvoice() {
+
+ return true;
+ }
+
+ @Override
+ public boolean processPayment() {
+
+ return true;
+ }
+
+ @Override
+ public BlockingState getBlockingState() {
+
+ return null;
+ }
+
+ @Override
+ public MutableAccountData toMutableAccountData() {
+
+ throw new NotImplementedException();
+ }
+
+
+ };
+
+
+ }
+}