killbill-aplcache

added invoicing unit tests

1/27/2012 4:50:29 PM

Details

diff --git a/invoice/src/main/java/com/ning/billing/invoice/model/DefaultInvoiceGenerator.java b/invoice/src/main/java/com/ning/billing/invoice/model/DefaultInvoiceGenerator.java
index 5223992..899b4a5 100644
--- a/invoice/src/main/java/com/ning/billing/invoice/model/DefaultInvoiceGenerator.java
+++ b/invoice/src/main/java/com/ning/billing/invoice/model/DefaultInvoiceGenerator.java
@@ -59,6 +59,10 @@ public class DefaultInvoiceGenerator implements InvoiceGenerator {
 
     private InvoiceItemList reconcileInvoiceItems(final UUID invoiceId, final InvoiceItemList currentInvoiceItems,
                                                   final InvoiceItemList existingInvoiceItems) {
+        if (existingInvoiceItems == null) {
+            return currentInvoiceItems;
+        }
+
         InvoiceItemList currentItems = new InvoiceItemList();
         for (final InvoiceItem item : currentInvoiceItems) {
             currentItems.add(new DefaultInvoiceItem(item, invoiceId));
@@ -80,7 +84,6 @@ public class DefaultInvoiceGenerator implements InvoiceGenerator {
                 }
             }
         }
-
         existingItems.removeAll(existingItemsToRemove);
 
         // remove cancelling pairs of invoice items
@@ -88,7 +91,7 @@ public class DefaultInvoiceGenerator implements InvoiceGenerator {
 
         // add existing items that aren't covered by current items as credit items
         for (final InvoiceItem existingItem : existingItems) {
-            currentItems.add(existingItem.asCredit(invoiceId));
+            currentItems.add(existingItem.asCredit(existingItem.getInvoiceId()));
         }
 
         return currentItems;
diff --git a/invoice/src/main/resources/com/ning/billing/invoice/dao/InvoiceSqlDao.sql.stg b/invoice/src/main/resources/com/ning/billing/invoice/dao/InvoiceSqlDao.sql.stg
index ce7a429..f483773 100644
--- a/invoice/src/main/resources/com/ning/billing/invoice/dao/InvoiceSqlDao.sql.stg
+++ b/invoice/src/main/resources/com/ning/billing/invoice/dao/InvoiceSqlDao.sql.stg
@@ -91,15 +91,6 @@ getUnpaidInvoicesByAccountId() ::= <<
   ORDER BY i.target_date ASC;
 >>
 
-getAccountBalance() ::= <<
-  SELECT SUM(iis.total_amount) AS amount_invoiced, SUM(ips.total_paid) AS amount_paid
-  FROM invoices i
-  LEFT JOIN invoice_payment_summary ips ON i.id = ips.invoice_id
-  LEFT JOIN invoice_item_summary iis ON i.id = iis.invoice_id
-  WHERE i.account_id = :accountId
-  GROUP BY i.account_id;
->>
-
 test() ::= <<
   SELECT 1
   FROM invoices;
diff --git a/invoice/src/test/java/com/ning/billing/invoice/dao/InvoiceDaoTestBase.java b/invoice/src/test/java/com/ning/billing/invoice/dao/InvoiceDaoTestBase.java
index 2dd88cc..4779495 100644
--- a/invoice/src/test/java/com/ning/billing/invoice/dao/InvoiceDaoTestBase.java
+++ b/invoice/src/test/java/com/ning/billing/invoice/dao/InvoiceDaoTestBase.java
@@ -21,6 +21,7 @@ import static org.testng.Assert.fail;
 
 import java.io.IOException;
 
+import com.ning.billing.invoice.tests.InvoicingTestBase;
 import org.apache.commons.io.IOUtils;
 import org.testng.annotations.AfterClass;
 import org.testng.annotations.BeforeClass;
@@ -32,7 +33,7 @@ import com.ning.billing.invoice.glue.InvoiceModuleWithEmbeddedDb;
 import com.ning.billing.util.bus.BusService;
 import com.ning.billing.util.bus.DefaultBusService;
 
-public abstract class InvoiceDaoTestBase {
+public abstract class InvoiceDaoTestBase extends InvoicingTestBase {
     protected InvoiceDao invoiceDao;
     protected InvoiceItemSqlDao invoiceItemDao;
     protected InvoicePaymentSqlDao invoicePaymentDao;
diff --git a/invoice/src/test/java/com/ning/billing/invoice/dao/InvoiceDaoTests.java b/invoice/src/test/java/com/ning/billing/invoice/dao/InvoiceDaoTests.java
index 8ce7a26..66ad993 100644
--- a/invoice/src/test/java/com/ning/billing/invoice/dao/InvoiceDaoTests.java
+++ b/invoice/src/test/java/com/ning/billing/invoice/dao/InvoiceDaoTests.java
@@ -16,13 +16,31 @@
 
 package com.ning.billing.invoice.dao;
 
+import com.ning.billing.catalog.DefaultPrice;
+import com.ning.billing.catalog.MockInternationalPrice;
+import com.ning.billing.catalog.MockPlan;
+import com.ning.billing.catalog.MockPlanPhase;
+import com.ning.billing.catalog.api.BillingPeriod;
 import com.ning.billing.catalog.api.Currency;
+import com.ning.billing.catalog.api.PhaseType;
+import com.ning.billing.catalog.api.Plan;
+import com.ning.billing.catalog.api.PlanPhase;
+import com.ning.billing.entitlement.api.billing.BillingEvent;
+import com.ning.billing.entitlement.api.billing.BillingModeType;
+import com.ning.billing.entitlement.api.billing.DefaultBillingEvent;
+import com.ning.billing.entitlement.api.user.EntitlementUserApiException;
+import com.ning.billing.entitlement.api.user.Subscription;
+import com.ning.billing.entitlement.api.user.SubscriptionTransition;
 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.invoice.model.BillingEventSet;
 import com.ning.billing.invoice.model.DefaultInvoice;
+import com.ning.billing.invoice.model.DefaultInvoiceGenerator;
 import com.ning.billing.invoice.model.DefaultInvoiceItem;
 import com.ning.billing.invoice.model.DefaultInvoicePayment;
+import com.ning.billing.invoice.model.InvoiceGenerator;
+import com.ning.billing.invoice.model.InvoiceItemList;
 import com.ning.billing.util.clock.Clock;
 import com.ning.billing.util.clock.DefaultClock;
 import org.joda.time.DateTime;
@@ -35,6 +53,7 @@ import java.util.List;
 import java.util.UUID;
 
 import static org.testng.Assert.*;
+import static org.testng.Assert.assertEquals;
 
 @Test(groups = {"invoicing", "invoicing-invoiceDao"})
 public class InvoiceDaoTests extends InvoiceDaoTestBase {
@@ -448,4 +467,189 @@ public class InvoiceDaoTests extends InvoiceDaoTestBase {
         invoices = invoiceDao.getUnpaidInvoicesByAccountId(accountId, upToDate);
         assertEquals(invoices.size(), 2);
     }
+
+    /*
+     *
+     * this test verifies that immediate changes give the correct results
+     *
+     */
+    @Test
+    public void testInvoiceGenerationForImmediateChanges() {
+        InvoiceGenerator generator = new DefaultInvoiceGenerator();
+
+        UUID accountId = UUID.randomUUID();
+        InvoiceItemList invoiceItemList = new InvoiceItemList();
+        DateTime targetDate = new DateTime(2011, 2, 16, 0, 0, 0, 0);
+
+        // generate first invoice
+        DefaultPrice price1 = new DefaultPrice(TEN, Currency.USD);
+        MockInternationalPrice recurringPrice = new MockInternationalPrice(price1);
+        MockPlanPhase phase1 = new MockPlanPhase(recurringPrice, null, BillingPeriod.MONTHLY, PhaseType.TRIAL);
+        MockPlan plan1 = new MockPlan(phase1);
+
+        Subscription subscription = new MockSubscription();
+        DateTime effectiveDate1 = new DateTime(2011, 2, 1, 0, 0, 0, 0);
+        BillingEvent event1 = new DefaultBillingEvent(subscription, effectiveDate1, plan1, phase1, null,
+                                                      recurringPrice, BillingPeriod.MONTHLY, 1, BillingModeType.IN_ADVANCE,
+                                                      "testEvent1");
+
+        BillingEventSet events = new BillingEventSet();
+        events.add(event1);
+
+        Invoice invoice1 = generator.generateInvoice(accountId, events, invoiceItemList, targetDate, Currency.USD);
+        assertEquals(invoice1.getBalance(), TEN);
+        invoiceItemList.addAll(invoice1.getInvoiceItems());
+
+        // generate second invoice
+        DefaultPrice price2 = new DefaultPrice(TWENTY, Currency.USD);
+        MockInternationalPrice recurringPrice2 = new MockInternationalPrice(price2);
+        MockPlanPhase phase2 = new MockPlanPhase(recurringPrice, null, BillingPeriod.MONTHLY, PhaseType.TRIAL);
+        MockPlan plan2 = new MockPlan(phase2);
+
+        DateTime effectiveDate2 = new DateTime(2011, 2, 15, 0, 0, 0, 0);
+        BillingEvent event2 = new DefaultBillingEvent(subscription, effectiveDate2, plan2, phase2, null,
+                                                      recurringPrice2, BillingPeriod.MONTHLY, 1, BillingModeType.IN_ADVANCE,
+                                                      "testEvent2");
+        events.add(event2);
+
+        // second invoice should be for one half (14/28 days) the difference between the rate plans
+        // this is a temporary state, since it actually contains an adjusting item that properly belong to invoice 1
+        Invoice invoice2 = generator.generateInvoice(accountId, events, invoiceItemList, targetDate, Currency.USD);
+        assertEquals(invoice2.getBalance(), FIVE);
+        invoiceItemList.addAll(invoice2.getInvoiceItems());
+
+        invoiceDao.create(invoice1);
+        invoiceDao.create(invoice2);
+
+        Invoice savedInvoice1 = invoiceDao.getById(invoice1.getId());
+        assertEquals(savedInvoice1.getTotalAmount(), ZERO);
+
+        Invoice savedInvoice2 = invoiceDao.getById(invoice2.getId());
+        assertEquals(savedInvoice2.getTotalAmount(), FIFTEEN);
+    }
+
+    @Test
+    public void testInvoiceForFreeTrial() {
+        DefaultPrice price = new DefaultPrice(BigDecimal.ZERO, Currency.USD);
+        MockInternationalPrice recurringPrice = new MockInternationalPrice(price);
+        MockPlanPhase phase = new MockPlanPhase(recurringPrice, null);
+        MockPlan plan = new MockPlan(phase);
+
+        Subscription subscription = new MockSubscription();
+        DateTime effectiveDate = buildDateTime(2011, 1, 1);
+
+        BillingEvent event = new DefaultBillingEvent(subscription, effectiveDate, plan, phase, null,
+                                                     recurringPrice, BillingPeriod.MONTHLY, 15, BillingModeType.IN_ADVANCE,
+                                                     "testEvent");
+        BillingEventSet events = new BillingEventSet();
+        events.add(event);
+
+        DateTime targetDate = buildDateTime(2011, 1, 15);
+        InvoiceGenerator generator = new DefaultInvoiceGenerator();
+        Invoice invoice = generator.generateInvoice(UUID.randomUUID(), events, null, targetDate, Currency.USD);
+        assertEquals(invoice.getNumberOfItems(), 1);
+        assertEquals(invoice.getTotalAmount().compareTo(ZERO), 0);
+    }
+
+    @Test
+    public void testInvoiceForEmptyEventSet() {
+        InvoiceGenerator generator = new DefaultInvoiceGenerator();
+        BillingEventSet events = new BillingEventSet();
+        Invoice invoice = generator.generateInvoice(UUID.randomUUID(), events, null, new DateTime(), Currency.USD);
+        assertNull(invoice);
+    }
+
+    private class MockSubscription implements Subscription {
+        private UUID subscriptionId = UUID.randomUUID();
+
+        @Override
+        public void cancel(DateTime requestedDate, boolean eot) throws EntitlementUserApiException {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public void uncancel() throws EntitlementUserApiException {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public void changePlan(String productName, BillingPeriod term, String planSet, DateTime requestedDate) throws EntitlementUserApiException {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public void pause() throws EntitlementUserApiException {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public void resume() throws EntitlementUserApiException {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public UUID getId() {
+            return subscriptionId;
+        }
+
+        @Override
+        public UUID getBundleId() {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public SubscriptionState getState() {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public DateTime getStartDate() {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public DateTime getEndDate() {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public Plan getCurrentPlan() {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public String getCurrentPriceList() {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public PlanPhase getCurrentPhase() {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public DateTime getChargedThroughDate() {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public DateTime getPaidThroughDate() {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public List<SubscriptionTransition> getActiveTransitions() {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public List<SubscriptionTransition> getAllTransitions() {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public SubscriptionTransition getPendingTransition() {
+            throw new UnsupportedOperationException();
+        }
+    }
 }
diff --git a/invoice/src/test/java/com/ning/billing/invoice/tests/DefaultInvoiceGeneratorTests.java b/invoice/src/test/java/com/ning/billing/invoice/tests/DefaultInvoiceGeneratorTests.java
index c64ae04..11c3b1d 100644
--- a/invoice/src/test/java/com/ning/billing/invoice/tests/DefaultInvoiceGeneratorTests.java
+++ b/invoice/src/test/java/com/ning/billing/invoice/tests/DefaultInvoiceGeneratorTests.java
@@ -16,24 +16,17 @@
 
 package com.ning.billing.invoice.tests;
 
-import com.ning.billing.catalog.DefaultPrice;
 import com.ning.billing.catalog.MockCatalog;
-import com.ning.billing.catalog.MockInternationalPrice;
-import com.ning.billing.catalog.MockPlan;
-import com.ning.billing.catalog.MockPlanPhase;
 import com.ning.billing.catalog.api.BillingPeriod;
 import com.ning.billing.catalog.api.Currency;
-import com.ning.billing.catalog.api.PhaseType;
 import com.ning.billing.catalog.api.Plan;
 import com.ning.billing.catalog.api.PlanPhase;
 import com.ning.billing.entitlement.api.billing.BillingEvent;
 import com.ning.billing.entitlement.api.billing.BillingModeType;
 import com.ning.billing.entitlement.api.billing.DefaultBillingEvent;
-import com.ning.billing.entitlement.api.user.EntitlementUserApiException;
 import com.ning.billing.entitlement.api.user.Subscription;
 import com.ning.billing.entitlement.api.user.SubscriptionData;
 import com.ning.billing.entitlement.api.user.SubscriptionFactory.SubscriptionBuilder;
-import com.ning.billing.entitlement.api.user.SubscriptionTransition;
 import com.ning.billing.invoice.api.Invoice;
 import com.ning.billing.invoice.api.InvoiceItem;
 import com.ning.billing.invoice.model.BillingEventSet;
@@ -45,14 +38,11 @@ import org.joda.time.DateTime;
 import org.testng.annotations.Test;
 
 import java.math.BigDecimal;
-import java.util.List;
 import java.util.UUID;
 
 import static org.testng.Assert.assertEquals;
 import static org.testng.Assert.assertNotNull;
 import static org.testng.Assert.assertNull;
-import static org.testng.Assert.assertTrue;
-import static org.testng.Assert.fail;
 
 @Test(groups = {"fast", "invoicing", "invoiceGenerator"})
 public class DefaultInvoiceGeneratorTests extends InvoicingTestBase {
@@ -437,82 +427,6 @@ public class DefaultInvoiceGeneratorTests extends InvoicingTestBase {
         testInvoiceGeneration(events, invoiceItems, buildDateTime(2011, 10, 10), 1, expectedAmount);
     }
 
-    /*
-     *
-     * this test verifies that immediate changes give the correct results
-     *
-     */
-    @Test
-    public void testInvoiceGenerationForImmediateChanges() {
-        UUID accountId = UUID.randomUUID();
-        InvoiceItemList invoiceItemList = new InvoiceItemList();
-        DateTime targetDate = new DateTime(2011, 2, 16, 0, 0, 0, 0);
-
-        // generate first invoice
-        DefaultPrice price1 = new DefaultPrice(TEN, Currency.USD);
-        MockInternationalPrice recurringPrice = new MockInternationalPrice(price1);
-        MockPlanPhase phase1 = new MockPlanPhase(recurringPrice, null, BillingPeriod.MONTHLY, PhaseType.TRIAL);
-        MockPlan plan1 = new MockPlan(phase1);
-
-        Subscription subscription = new MockSubscription();
-        DateTime effectiveDate1 = new DateTime(2011, 2, 1, 0, 0, 0, 0);
-        BillingEvent event1 = new DefaultBillingEvent(subscription, effectiveDate1, plan1, phase1, null,
-                                                      recurringPrice, BillingPeriod.MONTHLY, 15, BillingModeType.IN_ADVANCE,
-                                                      "testEvent");
-
-        BillingEventSet events = new BillingEventSet();
-        events.add(event1);
-
-        Invoice invoice1 = generator.generateInvoice(accountId, events, invoiceItemList, targetDate, Currency.USD);
-        assertEquals(invoice1.getBalance(), TEN);
-        invoiceItemList.addAll(invoice1.getInvoiceItems());
-
-        // generate second invoice
-        DefaultPrice price2 = new DefaultPrice(TWENTY, Currency.USD);
-        MockInternationalPrice recurringPrice2 = new MockInternationalPrice(price2);
-        MockPlanPhase phase2 = new MockPlanPhase(recurringPrice, null, BillingPeriod.MONTHLY, PhaseType.TRIAL);
-        MockPlan plan2 = new MockPlan(phase2);
-
-        DateTime effectiveDate2 = new DateTime(2011, 2, 15, 0, 0, 0, 0);
-        BillingEvent event2 = new DefaultBillingEvent(subscription, effectiveDate2, plan2, phase2, null,
-                                                      recurringPrice, BillingPeriod.MONTHLY, 15, BillingModeType.IN_ADVANCE,
-                                                      "testEvent");
-        events.add(event2);
-
-        Invoice invoice2 = generator.generateInvoice(accountId, events, invoiceItemList, targetDate, Currency.USD);
-        assertEquals(invoice1.getBalance(), FIFTEEN);
-        invoiceItemList.addAll(invoice2.getInvoiceItems());
-
-        fail();
-    }
-
-    @Test
-    public void testInvoiceForFreeTrial() {
-        DefaultPrice price = new DefaultPrice(BigDecimal.ZERO, Currency.USD);
-        MockInternationalPrice recurringPrice = new MockInternationalPrice(price);
-        MockPlanPhase phase = new MockPlanPhase(recurringPrice, null);
-        MockPlan plan = new MockPlan(phase);
-
-        Subscription subscription = new MockSubscription();
-        DateTime effectiveDate = new DateTime(2011, 1, 1, 0, 0, 0, 0);
-
-        BillingEvent event = new DefaultBillingEvent(subscription, effectiveDate, plan, phase, null,
-                                                     recurringPrice, BillingPeriod.MONTHLY, 15, BillingModeType.IN_ADVANCE,
-                                                     "testEvent");
-
-        fail();
-    }
-
-    @Test
-    public void testInvoiceForNoCurrentItems() {
-        fail();
-    }
-
-    @Test
-    public void testInvoiceForEmptyEventSet() {
-        fail();
-    }
-
     private DefaultBillingEvent createBillingEvent(final UUID subscriptionId, final DateTime startDate,
                                                    final Plan plan, final PlanPhase planPhase,
                                                    final BigDecimal rate, final int billCycleDay) {
@@ -545,100 +459,6 @@ public class DefaultInvoiceGeneratorTests extends InvoicingTestBase {
 
         existingInvoiceItems.addAll(invoice.getInvoiceItems());
         assertEquals(invoice.getTotalAmount(), expectedAmount);
-    }   
-    
-    private class MockSubscription implements Subscription {
-        private UUID subscriptionId = UUID.randomUUID();
-
-        @Override
-        public void cancel(DateTime requestedDate, boolean eot) throws EntitlementUserApiException {
-            throw new UnsupportedOperationException();
-        }
-
-        @Override
-        public void uncancel() throws EntitlementUserApiException {
-            throw new UnsupportedOperationException();
-        }
-
-        @Override
-        public void changePlan(String productName, BillingPeriod term, String planSet, DateTime requestedDate) throws EntitlementUserApiException {
-            throw new UnsupportedOperationException();
-        }
-
-        @Override
-        public void pause() throws EntitlementUserApiException {
-            throw new UnsupportedOperationException();
-        }
-
-        @Override
-        public void resume() throws EntitlementUserApiException {
-            throw new UnsupportedOperationException();
-        }
-
-        @Override
-        public UUID getId() {
-            return subscriptionId;
-        }
-
-        @Override
-        public UUID getBundleId() {
-            throw new UnsupportedOperationException();
-        }
-
-        @Override
-        public SubscriptionState getState() {
-            throw new UnsupportedOperationException();
-        }
-
-        @Override
-        public DateTime getStartDate() {
-            throw new UnsupportedOperationException();
-        }
-
-        @Override
-        public DateTime getEndDate() {
-            throw new UnsupportedOperationException();
-        }
-
-        @Override
-        public Plan getCurrentPlan() {
-            throw new UnsupportedOperationException();
-        }
-
-        @Override
-        public String getCurrentPriceList() {
-            throw new UnsupportedOperationException();
-        }
-
-        @Override
-        public PlanPhase getCurrentPhase() {
-            throw new UnsupportedOperationException();
-        }
-
-        @Override
-        public DateTime getChargedThroughDate() {
-            throw new UnsupportedOperationException();
-        }
-
-        @Override
-        public DateTime getPaidThroughDate() {
-            throw new UnsupportedOperationException();
-        }
-
-        @Override
-        public List<SubscriptionTransition> getActiveTransitions() {
-            throw new UnsupportedOperationException();
-        }
-
-        @Override
-        public List<SubscriptionTransition> getAllTransitions() {
-            throw new UnsupportedOperationException();
-        }
-
-        @Override
-        public SubscriptionTransition getPendingTransition() {
-            throw new UnsupportedOperationException();
-        }
     }
     // TODO: Jeff C -- how do we ensure that an annual add-on is properly aligned *at the end* with the base plan?
 }                      
\ No newline at end of file