killbill-memoizeit

entitlement: fix bug in ProxyBlockingStateDao We were adding

11/16/2013 2:09:22 AM

Details

diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/dao/ProxyBlockingStateDao.java b/entitlement/src/main/java/com/ning/billing/entitlement/dao/ProxyBlockingStateDao.java
index e0f3b60..9150555 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/dao/ProxyBlockingStateDao.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/dao/ProxyBlockingStateDao.java
@@ -226,10 +226,15 @@ public class ProxyBlockingStateDao implements BlockingStateDao {
 
             final Collection<BlockingState> blockingStatesNotOnDisk = eventsStream.computeAddonsBlockingStatesForFutureSubscriptionBaseEvents();
 
-            // Inject the extra blocking states into the stream
+            // Inject the extra blocking states into the stream if needed
             for (final BlockingState blockingState : blockingStatesNotOnDisk) {
-                final BlockingStateModelDao blockingStateModelDao = new BlockingStateModelDao(blockingState, now, now);
-                blockingStatesOnDiskCopy.add(BlockingStateModelDao.toBlockingState(blockingStateModelDao));
+                // In case we're coming from getBlockingHistoryForService / getBlockingAll, make sure we don't add
+                // blocking states for other add-ons on that base subscription
+                if (blockingStateType == null ||
+                    (BlockingStateType.SUBSCRIPTION.equals(blockingStateType) && blockingState.getBlockedId().equals(blockableId))) {
+                    final BlockingStateModelDao blockingStateModelDao = new BlockingStateModelDao(blockingState, now, now);
+                    blockingStatesOnDiskCopy.add(BlockingStateModelDao.toBlockingState(blockingStateModelDao));
+                }
             }
         }
 
diff --git a/entitlement/src/test/java/com/ning/billing/entitlement/engine/core/TestEntitlementUtils.java b/entitlement/src/test/java/com/ning/billing/entitlement/engine/core/TestEntitlementUtils.java
index bb5f2d9..5398bce 100644
--- a/entitlement/src/test/java/com/ning/billing/entitlement/engine/core/TestEntitlementUtils.java
+++ b/entitlement/src/test/java/com/ning/billing/entitlement/engine/core/TestEntitlementUtils.java
@@ -69,7 +69,7 @@ public class TestEntitlementUtils extends EntitlementTestSuiteWithEmbeddedDB {
         baseEntitlement = (DefaultEntitlement) entitlementApi.createBaseEntitlement(account.getId(), baseSpec, account.getExternalKey(), initialDate, callContext);
 
         // Add ADD_ON
-        final PlanPhaseSpecifier addOnSpec = new PlanPhaseSpecifier("Telescopic-Scope", ProductCategory.BASE, BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, null);
+        final PlanPhaseSpecifier addOnSpec = new PlanPhaseSpecifier("Telescopic-Scope", ProductCategory.ADD_ON, BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, null);
         addOnEntitlement = (DefaultEntitlement) entitlementApi.addEntitlement(baseEntitlement.getBundleId(), addOnSpec, initialDate, callContext);
 
         // Verify the initial state
@@ -227,6 +227,26 @@ public class TestEntitlementUtils extends EntitlementTestSuiteWithEmbeddedDB {
         checkBlockingStatesDAO(changedBaseEntitlement, cancelledAddOnEntitlement, baseEffectiveCancellationOrChangeDate, false);
     }
 
+    @Test(groups = "slow", description = "Verify we don't mix add-ons for EOT changes")
+    public void testChangePlanEOTWith2AddOns() throws Exception {
+        // Add a second ADD_ON (Laser-Scope is available, not included)
+        testListener.pushExpectedEvents(NextEvent.CREATE);
+        final PlanPhaseSpecifier secondAddOnSpec = new PlanPhaseSpecifier("Laser-Scope", ProductCategory.ADD_ON, BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, null);
+        final DefaultEntitlement secondAddOnEntitlement = (DefaultEntitlement) entitlementApi.addEntitlement(baseEntitlement.getBundleId(), secondAddOnSpec, clock.getUTCToday(), callContext);
+        assertListenerStatus();
+
+        // Change plan EOT to Assault-Rifle (Telescopic-Scope is included)
+        final DefaultEntitlement changedBaseEntitlement = (DefaultEntitlement) baseEntitlement.changePlanWithDate("Assault-Rifle", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, new LocalDate(2013, 10, 7), callContext);
+        // No blocking event (EOT)
+        assertListenerStatus();
+
+        // Verify the blocking states DAO adds events not on disk for the first add-on...
+        checkBlockingStatesDAO(changedBaseEntitlement, addOnEntitlement, baseEffectiveCancellationOrChangeDate, false);
+        // ...but not for the second one
+        final List<BlockingState> blockingStatesForSecondAddOn = blockingStateDao.getBlockingAll(secondAddOnEntitlement.getId(), BlockingStateType.SUBSCRIPTION, internalCallContext);
+        Assert.assertEquals(blockingStatesForSecondAddOn.size(), 0);
+    }
+
     @Test(groups = "slow", description = "Verify add-ons blocking states are added for IMM change plans")
     public void testChangePlanIMM() throws Exception {
         // Approximate check, as the blocking state check (checkBlockingStatesDAO) could be a bit off