/* * Copyright 2010-2013 Ning, Inc. * 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 * 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.entitlement.api; import java.util.ArrayList; import java.util.List; import java.util.UUID; import org.joda.time.DateTime; import org.joda.time.LocalDate; import org.killbill.billing.ErrorCode; import org.killbill.billing.account.api.Account; import org.killbill.billing.account.api.AccountApiException; import org.killbill.billing.api.TestApiListener.NextEvent; import org.killbill.billing.catalog.api.BillingActionPolicy; import org.killbill.billing.catalog.api.BillingPeriod; import org.killbill.billing.catalog.api.PlanPhasePriceOverride; import org.killbill.billing.catalog.api.PlanPhaseSpecifier; import org.killbill.billing.catalog.api.PriceListSet; import org.killbill.billing.catalog.api.ProductCategory; import org.killbill.billing.entitlement.EntitlementTestSuiteWithEmbeddedDB; import org.killbill.billing.entitlement.api.Entitlement.EntitlementSourceType; import org.killbill.billing.entitlement.api.Entitlement.EntitlementState; import org.killbill.billing.payment.api.PluginProperty; import org.killbill.billing.subscription.api.user.SubscriptionBaseApiException; import org.testng.Assert; import org.testng.annotations.Test; import com.google.common.collect.ImmutableList; 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; public class TestDefaultEntitlementApi extends EntitlementTestSuiteWithEmbeddedDB { @Test(groups = "slow") public void testCheckStaleStates() throws AccountApiException, EntitlementApiException { final LocalDate initialDate = new LocalDate(2013, 8, 7); clock.setDay(initialDate); final Account account = createAccount(getAccountData(7)); final PlanPhaseSpecifier spec = new PlanPhaseSpecifier("Shotgun", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, null); // Keep the same object for the whole test, to make sure we refresh its state before r/w calls testListener.pushExpectedEvents(NextEvent.CREATE, NextEvent.BLOCK); final Entitlement entitlement = entitlementApi.createBaseEntitlement(account.getId(), spec, account.getExternalKey(), null, null, null, false, ImmutableList.<PluginProperty>of(), callContext); assertListenerStatus(); // Add ADD_ON // Keep the same object for the whole test, to make sure we refresh its state before r/w calls final PlanPhaseSpecifier addOnSpec = new PlanPhaseSpecifier("Telescopic-Scope", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, null); testListener.pushExpectedEvents(NextEvent.CREATE, NextEvent.BLOCK); final Entitlement addOnEntitlement = entitlementApi.addEntitlement(entitlement.getBundleId(), addOnSpec, null, initialDate, initialDate, false, ImmutableList.<PluginProperty>of(), callContext); assertListenerStatus(); try { entitlement.uncancelEntitlement(ImmutableList.<PluginProperty>of(), callContext); Assert.fail("Entitlement hasn't been cancelled yet"); } catch (final EntitlementApiException e) { Assert.assertEquals(e.getCode(), ErrorCode.ENT_UNCANCEL_BAD_STATE.getCode()); } clock.addDays(3); // Cancelling the base entitlement will cancel the add-on testListener.pushExpectedEvents(NextEvent.CANCEL, NextEvent.BLOCK, NextEvent.CANCEL, NextEvent.BLOCK); entitlement.cancelEntitlementWithDateOverrideBillingPolicy(clock.getUTCToday(), BillingActionPolicy.IMMEDIATE, ImmutableList.<PluginProperty>of(), callContext); assertListenerStatus(); try { entitlement.cancelEntitlementWithDateOverrideBillingPolicy(clock.getUTCToday(), BillingActionPolicy.IMMEDIATE, ImmutableList.<PluginProperty>of(), callContext); Assert.fail("Entitlement is already cancelled"); } catch (final EntitlementApiException e) { Assert.assertEquals(e.getCode(), ErrorCode.SUB_CANCEL_BAD_STATE.getCode()); } try { addOnEntitlement.cancelEntitlementWithDateOverrideBillingPolicy(clock.getUTCToday(), BillingActionPolicy.IMMEDIATE, ImmutableList.<PluginProperty>of(), callContext); Assert.fail("Add-On Entitlement is already cancelled"); } catch (final EntitlementApiException e) { Assert.assertEquals(e.getCode(), ErrorCode.SUB_CANCEL_BAD_STATE.getCode()); } try { entitlement.uncancelEntitlement(ImmutableList.<PluginProperty>of(), callContext); Assert.fail("Entitlement is already cancelled"); } catch (final EntitlementApiException e) { Assert.assertEquals(e.getCode(), ErrorCode.SUB_UNCANCEL_BAD_STATE.getCode()); } try { addOnEntitlement.uncancelEntitlement(ImmutableList.<PluginProperty>of(), callContext); Assert.fail("Add-On Entitlement is already cancelled"); } catch (final EntitlementApiException e) { Assert.assertEquals(e.getCode(), ErrorCode.SUB_UNCANCEL_BAD_STATE.getCode()); } } @Test(groups = "slow") public void testUncancelEffectiveCancelledEntitlement() throws AccountApiException, EntitlementApiException, SubscriptionBaseApiException { final LocalDate initialDate = new LocalDate(2013, 8, 7); clock.setDay(initialDate); final Account account = createAccount(getAccountData(7)); final PlanPhaseSpecifier spec = new PlanPhaseSpecifier("Shotgun", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, null); // Keep the same object for the whole test, to make sure we refresh its state before r/w calls testListener.pushExpectedEvents(NextEvent.CREATE, NextEvent.BLOCK); final Entitlement entitlement = entitlementApi.createBaseEntitlement(account.getId(), spec, account.getExternalKey(), null, null, null, false, ImmutableList.<PluginProperty>of(), callContext); assertListenerStatus(); testListener.pushExpectedEvent(NextEvent.PHASE); clock.addDays(30); assertListenerStatus(); subscriptionInternalApi.setChargedThroughDate(entitlement.getId(), clock.getUTCNow().plusMonths(1), internalCallContext); final LocalDate entitlementCancelledDate = clock.getToday(account.getTimeZone()); testListener.pushExpectedEvent(NextEvent.BLOCK); final Entitlement cancelledEntitlement = entitlement.cancelEntitlementWithDateOverrideBillingPolicy(clock.getToday(account.getTimeZone()), BillingActionPolicy.END_OF_TERM, ImmutableList.<PluginProperty>of(), callContext); assertListenerStatus(); Assert.assertEquals(cancelledEntitlement.getEffectiveEndDate(), entitlementCancelledDate); testListener.pushExpectedEvent(NextEvent.UNCANCEL); cancelledEntitlement.uncancelEntitlement(ImmutableList.<PluginProperty>of(), callContext); assertListenerStatus(); final Entitlement reactivatedEntitlement = entitlementApi.getEntitlementForId(cancelledEntitlement.getId(), callContext); Assert.assertNull(reactivatedEntitlement.getEffectiveEndDate()); } @Test(groups = "slow") public void testCreateEntitlementWithCheck() throws AccountApiException, EntitlementApiException { final LocalDate initialDate = new LocalDate(2013, 8, 7); clock.setDay(initialDate); final Account account = createAccount(getAccountData(7)); final PlanPhaseSpecifier spec = new PlanPhaseSpecifier("Shotgun", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, null); // Create entitlement and check each field testListener.pushExpectedEvents(NextEvent.CREATE, NextEvent.BLOCK); final Entitlement entitlement = entitlementApi.createBaseEntitlement(account.getId(), spec, account.getExternalKey(), null, null, null, false, ImmutableList.<PluginProperty>of(), callContext); assertListenerStatus(); assertEquals(entitlement.getAccountId(), account.getId()); assertEquals(entitlement.getExternalKey(), account.getExternalKey()); assertEquals(entitlement.getEffectiveStartDate(), initialDate); assertNull(entitlement.getEffectiveEndDate()); assertEquals(entitlement.getLastActivePriceList().getName(), PriceListSet.DEFAULT_PRICELIST_NAME); assertEquals(entitlement.getLastActiveProduct().getName(), "Shotgun"); assertEquals(entitlement.getLastActivePhase().getName(), "shotgun-monthly-trial"); assertEquals(entitlement.getLastActivePlan().getName(), "shotgun-monthly"); assertEquals(entitlement.getLastActiveProductCategory(), ProductCategory.BASE); assertEquals(entitlement.getState(), EntitlementState.ACTIVE); assertEquals(entitlement.getSourceType(), EntitlementSourceType.NATIVE); assertEquals(entitlement.getLastActivePlan().getName(), "shotgun-monthly"); assertEquals(entitlement.getLastActivePriceList().getName(), PriceListSet.DEFAULT_PRICELIST_NAME); assertEquals(entitlement.getLastActiveProduct().getName(), "Shotgun"); assertEquals(entitlement.getLastActiveProductCategory(), ProductCategory.BASE); assertEquals(entitlement.getState(), EntitlementState.ACTIVE); assertEquals(entitlement.getSourceType(), EntitlementSourceType.NATIVE); // Now retrieve entitlement by id and recheck everything final Entitlement entitlement2 = entitlementApi.getEntitlementForId(entitlement.getId(), callContext); assertEquals(entitlement2.getAccountId(), account.getId()); assertEquals(entitlement2.getExternalKey(), account.getExternalKey()); assertEquals(entitlement2.getEffectiveStartDate(), initialDate); assertNull(entitlement2.getEffectiveEndDate()); assertEquals(entitlement2.getLastActivePriceList().getName(), PriceListSet.DEFAULT_PRICELIST_NAME); assertEquals(entitlement2.getLastActiveProduct().getName(), "Shotgun"); assertEquals(entitlement2.getLastActivePhase().getName(), "shotgun-monthly-trial"); assertEquals(entitlement2.getLastActivePlan().getName(), "shotgun-monthly"); assertEquals(entitlement2.getLastActiveProductCategory(), ProductCategory.BASE); assertEquals(entitlement2.getState(), EntitlementState.ACTIVE); assertEquals(entitlement2.getSourceType(), EntitlementSourceType.NATIVE); assertEquals(entitlement2.getLastActivePlan().getName(), "shotgun-monthly"); assertEquals(entitlement2.getLastActivePriceList().getName(), PriceListSet.DEFAULT_PRICELIST_NAME); assertEquals(entitlement2.getLastActiveProduct().getName(), "Shotgun"); assertEquals(entitlement2.getLastActiveProductCategory(), ProductCategory.BASE); assertEquals(entitlement2.getState(), EntitlementState.ACTIVE); assertEquals(entitlement2.getSourceType(), EntitlementSourceType.NATIVE); // Finally final List<Entitlement> accountEntitlements = entitlementApi.getAllEntitlementsForAccountId(account.getId(), callContext); assertEquals(accountEntitlements.size(), 1); final Entitlement entitlement3 = accountEntitlements.get(0); assertEquals(entitlement3.getAccountId(), account.getId()); assertEquals(entitlement3.getExternalKey(), account.getExternalKey()); assertEquals(entitlement3.getEffectiveStartDate(), initialDate); assertNull(entitlement3.getEffectiveEndDate()); assertEquals(entitlement3.getLastActivePriceList().getName(), PriceListSet.DEFAULT_PRICELIST_NAME); assertEquals(entitlement3.getLastActiveProduct().getName(), "Shotgun"); assertEquals(entitlement3.getLastActivePhase().getName(), "shotgun-monthly-trial"); assertEquals(entitlement3.getLastActivePlan().getName(), "shotgun-monthly"); assertEquals(entitlement3.getLastActiveProductCategory(), ProductCategory.BASE); assertEquals(entitlement3.getState(), EntitlementState.ACTIVE); assertEquals(entitlement3.getSourceType(), EntitlementSourceType.NATIVE); assertEquals(entitlement3.getLastActivePlan().getName(), "shotgun-monthly"); assertEquals(entitlement3.getLastActivePriceList().getName(), PriceListSet.DEFAULT_PRICELIST_NAME); assertEquals(entitlement3.getLastActiveProduct().getName(), "Shotgun"); assertEquals(entitlement3.getLastActiveProductCategory(), ProductCategory.BASE); assertEquals(entitlement3.getState(), EntitlementState.ACTIVE); assertEquals(entitlement3.getSourceType(), EntitlementSourceType.NATIVE); } @Test(groups = "slow") public void testAddEntitlement() throws AccountApiException, EntitlementApiException { final LocalDate initialDate = new LocalDate(2013, 8, 7); clock.setDay(initialDate); final Account account = createAccount(getAccountData(7)); final PlanPhaseSpecifier spec = new PlanPhaseSpecifier("Shotgun", BillingPeriod.ANNUAL, PriceListSet.DEFAULT_PRICELIST_NAME, null); // Create entitlement and check each field testListener.pushExpectedEvents(NextEvent.CREATE, NextEvent.BLOCK); final Entitlement baseEntitlement = entitlementApi.createBaseEntitlement(account.getId(), spec, account.getExternalKey(), null, null, null, false, ImmutableList.<PluginProperty>of(), callContext); assertListenerStatus(); // Add ADD_ON final PlanPhaseSpecifier spec1 = new PlanPhaseSpecifier("Telescopic-Scope", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, null); testListener.pushExpectedEvents(NextEvent.CREATE, NextEvent.BLOCK); final Entitlement telescopicEntitlement = entitlementApi.addEntitlement(baseEntitlement.getBundleId(), spec1, null, initialDate, initialDate, false, ImmutableList.<PluginProperty>of(), callContext); assertListenerStatus(); assertEquals(telescopicEntitlement.getAccountId(), account.getId()); assertEquals(telescopicEntitlement.getExternalKey(), account.getExternalKey()); assertEquals(telescopicEntitlement.getEffectiveStartDate(), initialDate); assertNull(telescopicEntitlement.getEffectiveEndDate()); assertEquals(telescopicEntitlement.getLastActivePriceList().getName(), PriceListSet.DEFAULT_PRICELIST_NAME); assertEquals(telescopicEntitlement.getLastActiveProduct().getName(), "Telescopic-Scope"); assertEquals(telescopicEntitlement.getLastActivePhase().getName(), "telescopic-scope-monthly-discount"); assertEquals(telescopicEntitlement.getLastActivePlan().getName(), "telescopic-scope-monthly"); assertEquals(telescopicEntitlement.getLastActiveProductCategory(), ProductCategory.ADD_ON); List<Entitlement> bundleEntitlements = entitlementApi.getAllEntitlementsForBundle(telescopicEntitlement.getBundleId(), callContext); assertEquals(bundleEntitlements.size(), 2); bundleEntitlements = entitlementApi.getAllEntitlementsForAccountIdAndExternalKey(account.getId(), account.getExternalKey(), callContext); assertEquals(bundleEntitlements.size(), 2); } @Test(groups = "slow") public void testAddEntitlementOnPendingBase() throws AccountApiException, EntitlementApiException { final LocalDate initialDate = new LocalDate(2013, 8, 7); clock.setDay(initialDate); final Account account = createAccount(getAccountData(7)); final PlanPhaseSpecifier spec = new PlanPhaseSpecifier("Shotgun", BillingPeriod.ANNUAL, PriceListSet.DEFAULT_PRICELIST_NAME, null); // Create entitlement and check each field final LocalDate startDate = initialDate.plusDays(10); final Entitlement baseEntitlement = entitlementApi.createBaseEntitlement(account.getId(), spec, account.getExternalKey(), null, startDate, startDate, false, ImmutableList.<PluginProperty>of(), callContext); // Add ADD_ON immediately. Because BASE is PENDING should fail final PlanPhaseSpecifier spec1 = new PlanPhaseSpecifier("Telescopic-Scope", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, null); try { entitlementApi.addEntitlement(baseEntitlement.getBundleId(), spec1, null, initialDate, initialDate, false, ImmutableList.<PluginProperty>of(), callContext); fail("Should not succeed to create ADD_On prior BASE is active"); } catch (final EntitlementApiException e) { assertEquals(e.getCode(), ErrorCode.SUB_GET_NO_SUCH_BASE_SUBSCRIPTION.getCode()); } // Add ADD_ON with a startDate similar to BASE final Entitlement telescopicEntitlement = entitlementApi.addEntitlement(baseEntitlement.getBundleId(), spec1, null, startDate, startDate, false, ImmutableList.<PluginProperty>of(), callContext); testListener.pushExpectedEvents(NextEvent.CREATE, NextEvent.CREATE, NextEvent.BLOCK, NextEvent.BLOCK); clock.addDays(10); assertListenerStatus(); assertEquals(telescopicEntitlement.getAccountId(), account.getId()); assertEquals(telescopicEntitlement.getExternalKey(), account.getExternalKey()); assertEquals(telescopicEntitlement.getEffectiveStartDate(), startDate); assertNull(telescopicEntitlement.getEffectiveEndDate()); assertEquals(telescopicEntitlement.getLastActivePriceList().getName(), PriceListSet.DEFAULT_PRICELIST_NAME); assertEquals(telescopicEntitlement.getLastActiveProduct().getName(), "Telescopic-Scope"); assertEquals(telescopicEntitlement.getLastActivePhase().getName(), "telescopic-scope-monthly-discount"); assertEquals(telescopicEntitlement.getLastActivePlan().getName(), "telescopic-scope-monthly"); assertEquals(telescopicEntitlement.getLastActiveProductCategory(), ProductCategory.ADD_ON); List<Entitlement> bundleEntitlements = entitlementApi.getAllEntitlementsForBundle(telescopicEntitlement.getBundleId(), callContext); assertEquals(bundleEntitlements.size(), 2); bundleEntitlements = entitlementApi.getAllEntitlementsForAccountIdAndExternalKey(account.getId(), account.getExternalKey(), callContext); assertEquals(bundleEntitlements.size(), 2); } @Test(groups = "slow") public void testPauseUnpause() throws AccountApiException, EntitlementApiException { final LocalDate initialDate = new LocalDate(2013, 8, 7); clock.setDay(initialDate); final Account account = createAccount(getAccountData(7)); final PlanPhaseSpecifier spec = new PlanPhaseSpecifier("Shotgun", BillingPeriod.ANNUAL, PriceListSet.DEFAULT_PRICELIST_NAME, null); // Create entitlement and check each field testListener.pushExpectedEvents(NextEvent.CREATE, NextEvent.BLOCK); final Entitlement baseEntitlement = entitlementApi.createBaseEntitlement(account.getId(), spec, account.getExternalKey(), null, null, null, false, ImmutableList.<PluginProperty>of(), callContext); assertListenerStatus(); clock.addDays(1); final LocalDate effectiveDateSpec1 = new LocalDate(clock.getUTCNow(), account.getTimeZone()); final PlanPhaseSpecifier spec1 = new PlanPhaseSpecifier("Telescopic-Scope", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, null); testListener.pushExpectedEvents(NextEvent.CREATE, NextEvent.BLOCK); final Entitlement telescopicEntitlement = entitlementApi.addEntitlement(baseEntitlement.getBundleId(), spec1, null, effectiveDateSpec1, effectiveDateSpec1, false, ImmutableList.<PluginProperty>of(), callContext); assertListenerStatus(); // Block all entitlement in the bundle clock.addDays(5); testListener.pushExpectedEvents(NextEvent.BLOCK); final LocalDate blockingStateDate = new LocalDate(clock.getUTCNow()); entitlementApi.pause(baseEntitlement.getBundleId(), blockingStateDate, ImmutableList .<PluginProperty>of(), callContext); assertListenerStatus(); // Verify blocking state final Entitlement baseEntitlement2 = entitlementApi.getEntitlementForId(baseEntitlement.getId(), callContext); assertEquals(baseEntitlement2.getState(), EntitlementState.BLOCKED); final Entitlement telescopicEntitlement2 = entitlementApi.getEntitlementForId(telescopicEntitlement.getId(), callContext); assertEquals(telescopicEntitlement2.getState(), EntitlementState.BLOCKED); final List<Entitlement> bundleEntitlements2 = entitlementApi.getAllEntitlementsForBundle(telescopicEntitlement2.getBundleId(), callContext); assertEquals(bundleEntitlements2.size(), 2); for (final Entitlement cur : bundleEntitlements2) { assertEquals(cur.getState(), EntitlementState.BLOCKED); } // Try to add an ADD_ON, it should fail because BASE is blocked try { final PlanPhaseSpecifier spec3 = new PlanPhaseSpecifier("Telescopic-Scope", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, null); entitlementApi.addEntitlement(baseEntitlement.getBundleId(), spec3, null, blockingStateDate, effectiveDateSpec1, false, ImmutableList.<PluginProperty>of(), callContext); fail("Should not be able to create ADD-ON because BP is paused"); } catch (EntitlementApiException e) { assertEquals(e.getCode(), ErrorCode.BLOCK_BLOCKED_ACTION.getCode()); } clock.addDays(3); testListener.pushExpectedEvents(NextEvent.BLOCK); entitlementApi.resume(baseEntitlement.getBundleId(), new LocalDate(clock.getUTCNow()), ImmutableList.<PluginProperty>of(), callContext); assertListenerStatus(); // Verify call is idempotent entitlementApi.resume(baseEntitlement.getBundleId(), new LocalDate(clock.getUTCNow()), ImmutableList.<PluginProperty>of(), callContext); assertListenerStatus(); // Verify blocking state final Entitlement baseEntitlement3 = entitlementApi.getEntitlementForId(baseEntitlement.getId(), callContext); assertEquals(baseEntitlement3.getState(), EntitlementState.ACTIVE); final Entitlement telescopicEntitlement3 = entitlementApi.getEntitlementForId(telescopicEntitlement.getId(), callContext); assertEquals(telescopicEntitlement3.getState(), EntitlementState.ACTIVE); final List<Entitlement> bundleEntitlements3 = entitlementApi.getAllEntitlementsForBundle(telescopicEntitlement2.getBundleId(), callContext); assertEquals(bundleEntitlements3.size(), 2); for (Entitlement cur : bundleEntitlements3) { assertEquals(cur.getState(), EntitlementState.ACTIVE); } } @Test(groups = "slow", description = "Test pause / unpause in the future") public void testPauseUnpauseInTheFuture() throws AccountApiException, EntitlementApiException, SubscriptionApiException { final LocalDate initialDate = new LocalDate(2013, 8, 7); clock.setDay(initialDate); final Account account = createAccount(getAccountData(7)); // Create entitlement testListener.pushExpectedEvents(NextEvent.CREATE, NextEvent.BLOCK); final PlanPhaseSpecifier spec = new PlanPhaseSpecifier("Shotgun", BillingPeriod.ANNUAL, PriceListSet.DEFAULT_PRICELIST_NAME, null); final Entitlement baseEntitlement = entitlementApi.createBaseEntitlement(account.getId(), spec, account.getExternalKey(), null, null, null, false, ImmutableList.<PluginProperty>of(), callContext); assertListenerStatus(); // Get the phase event out of the way testListener.pushExpectedEvents(NextEvent.PHASE); clock.setDay(new LocalDate(2013, 9, 7)); assertListenerStatus(); final LocalDate pauseDate = new LocalDate(2013, 9, 17); entitlementApi.pause(baseEntitlement.getBundleId(), pauseDate, ImmutableList.<PluginProperty>of(), callContext); // No event yet assertListenerStatus(); final Entitlement refreshedAfterFuturePause = entitlementApi.getEntitlementForId(baseEntitlement.getId(), callContext); assertEquals(refreshedAfterFuturePause.getState(), EntitlementState.ACTIVE); final LocalDate resumeDate = new LocalDate(2013, 12, 24); entitlementApi.resume(baseEntitlement.getBundleId(), resumeDate, ImmutableList.<PluginProperty>of(), callContext); // No event yet assertListenerStatus(); // Not worth writing another test in TestDefaultSubscriptionApi just for that subscription call. We want to check that future PAUSE/RESUME events are visible final Subscription subscription = subscriptionApi.getSubscriptionForEntitlementId(baseEntitlement.getId(), callContext); Assert.assertEquals(subscription.getSubscriptionEvents().size(), 7); Assert.assertEquals(subscription.getSubscriptionEvents().get(0).getServiceName(), "entitlement-service"); Assert.assertEquals(subscription.getSubscriptionEvents().get(0).getServiceStateName(), "ENT_STARTED"); Assert.assertNull(subscription.getSubscriptionEvents().get(0).getPrevPhase()); Assert.assertEquals(subscription.getSubscriptionEvents().get(0).getNextPhase().getName(), "shotgun-annual-trial"); Assert.assertEquals(subscription.getSubscriptionEvents().get(1).getServiceName(), "billing-service"); Assert.assertEquals(subscription.getSubscriptionEvents().get(1).getServiceStateName(), "START_BILLING"); Assert.assertNull(subscription.getSubscriptionEvents().get(1).getPrevPhase()); Assert.assertEquals(subscription.getSubscriptionEvents().get(1).getNextPhase().getName(), "shotgun-annual-trial"); Assert.assertEquals(subscription.getSubscriptionEvents().get(2).getServiceName(), "entitlement+billing-service"); Assert.assertEquals(subscription.getSubscriptionEvents().get(2).getServiceStateName(), "PHASE"); Assert.assertEquals(subscription.getSubscriptionEvents().get(2).getPrevPhase().getName(), "shotgun-annual-trial"); Assert.assertEquals(subscription.getSubscriptionEvents().get(2).getNextPhase().getName(), "shotgun-annual-evergreen"); Assert.assertEquals(subscription.getSubscriptionEvents().get(3).getServiceName(), "entitlement-service"); Assert.assertEquals(subscription.getSubscriptionEvents().get(3).getServiceStateName(), "ENT_BLOCKED"); Assert.assertEquals(subscription.getSubscriptionEvents().get(3).getPrevPhase().getName(), "shotgun-annual-evergreen"); Assert.assertEquals(subscription.getSubscriptionEvents().get(3).getNextPhase().getName(), "shotgun-annual-evergreen"); Assert.assertEquals(subscription.getSubscriptionEvents().get(4).getServiceName(), "billing-service"); Assert.assertEquals(subscription.getSubscriptionEvents().get(4).getServiceStateName(), "ENT_BLOCKED"); Assert.assertEquals(subscription.getSubscriptionEvents().get(4).getPrevPhase().getName(), "shotgun-annual-evergreen"); Assert.assertEquals(subscription.getSubscriptionEvents().get(4).getNextPhase().getName(), "shotgun-annual-evergreen"); Assert.assertEquals(subscription.getSubscriptionEvents().get(5).getServiceName(), "entitlement-service"); Assert.assertEquals(subscription.getSubscriptionEvents().get(5).getServiceStateName(), "ENT_CLEAR"); Assert.assertEquals(subscription.getSubscriptionEvents().get(5).getPrevPhase().getName(), "shotgun-annual-evergreen"); Assert.assertEquals(subscription.getSubscriptionEvents().get(5).getNextPhase().getName(), "shotgun-annual-evergreen"); Assert.assertEquals(subscription.getSubscriptionEvents().get(6).getServiceName(), "billing-service"); Assert.assertEquals(subscription.getSubscriptionEvents().get(6).getServiceStateName(), "ENT_CLEAR"); Assert.assertEquals(subscription.getSubscriptionEvents().get(6).getPrevPhase().getName(), "shotgun-annual-evergreen"); Assert.assertEquals(subscription.getSubscriptionEvents().get(6).getNextPhase().getName(), "shotgun-annual-evergreen"); testListener.pushExpectedEvents(NextEvent.BLOCK); clock.setDay(pauseDate); assertListenerStatus(); // Verify blocking state final Entitlement baseEntitlementPaused = entitlementApi.getEntitlementForId(baseEntitlement.getId(), callContext); assertEquals(baseEntitlementPaused.getState(), EntitlementState.BLOCKED); testListener.pushExpectedEvents(NextEvent.BLOCK); clock.setDay(resumeDate); assertListenerStatus(); // Verify blocking state final Entitlement baseEntitlementUnpaused = entitlementApi.getEntitlementForId(baseEntitlement.getId(), callContext); assertEquals(baseEntitlementUnpaused.getState(), EntitlementState.ACTIVE); } @Test(groups = "slow") public void testTransferBundle() throws AccountApiException, EntitlementApiException, SubscriptionBaseApiException { final LocalDate initialDate = new LocalDate(2013, 8, 7); clock.setDay(initialDate); final Account accountDesc = createAccount(getAccountData(15)); // internal context will be configured for accountSrc final Account accountSrc = createAccount(getAccountData(7)); final PlanPhaseSpecifier spec = new PlanPhaseSpecifier("Shotgun", BillingPeriod.ANNUAL, PriceListSet.DEFAULT_PRICELIST_NAME, null); // Create entitlement (with migrated flag so we can check later that transferred subscription is in right status) testListener.pushExpectedEvents(NextEvent.CREATE, NextEvent.BLOCK); final Entitlement baseEntitlement = entitlementApi.createBaseEntitlement(accountSrc.getId(), spec, accountSrc.getExternalKey(), null, null, null, true, ImmutableList.<PluginProperty>of(), callContext); assertListenerStatus(); assertEquals(baseEntitlement.getSourceType(), EntitlementSourceType.MIGRATED); // Again to make sure this flag is correctly wrote/set assertEquals(entitlementApi.getEntitlementForId(baseEntitlement.getId(), callContext).getSourceType(), EntitlementSourceType.MIGRATED); final DateTime ctd = clock.getUTCNow().plusDays(30).plusMonths(1); testListener.pushExpectedEvent(NextEvent.PHASE); clock.addDays(32); // Set manually since no invoice subscriptionInternalApi.setChargedThroughDate(baseEntitlement.getId(), ctd, internalCallContext); assertListenerStatus(); // Transfer bundle to dest account final LocalDate effectiveDate = new LocalDate(clock.getUTCNow(), accountSrc.getTimeZone()); testListener.pushExpectedEvents(NextEvent.TRANSFER, NextEvent.BLOCK, NextEvent.BLOCK); final UUID newBundleId = entitlementApi.transferEntitlementsOverrideBillingPolicy(accountSrc.getId(), accountDesc.getId(), baseEntitlement.getExternalKey(), effectiveDate, BillingActionPolicy.END_OF_TERM, ImmutableList.<PluginProperty>of(), callContext); assertListenerStatus(); final Entitlement oldBaseEntitlement = entitlementApi.getAllEntitlementsForAccountIdAndExternalKey(accountSrc.getId(), accountSrc.getExternalKey(), callContext).get(0); assertEquals(oldBaseEntitlement.getEffectiveEndDate(), effectiveDate); assertEquals(oldBaseEntitlement.getState(), EntitlementState.CANCELLED); final List<Entitlement> entitlements = entitlementApi.getAllEntitlementsForBundle(newBundleId, callContext); assertEquals(entitlements.size(), 1); final Entitlement newBaseEntitlement = entitlements.get(0); assertEquals(newBaseEntitlement.getState(), EntitlementState.ACTIVE); assertEquals(newBaseEntitlement.getEffectiveStartDate(), effectiveDate); assertEquals(newBaseEntitlement.getEffectiveEndDate(), null); assertEquals(newBaseEntitlement.getSourceType(), EntitlementSourceType.TRANSFERRED); } @Test(groups = "slow") public void testCreateEntitlementInThePast() throws AccountApiException, EntitlementApiException, SubscriptionBaseApiException { final LocalDate initialDate = new LocalDate(2013, 8, 7); final LocalDate clockDate = new LocalDate(2013, 10, 7); clock.setDay(clockDate); final Account account = createAccount(getAccountData(7)); final PlanPhaseSpecifier spec = new PlanPhaseSpecifier("Shotgun", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, null); // Keep the same object for the whole test, to make sure we refresh its state before r/w calls testListener.pushExpectedEvents(NextEvent.CREATE, NextEvent.BLOCK, NextEvent.PHASE); final Entitlement entitlement = entitlementApi.createBaseEntitlement(account.getId(), spec, account.getExternalKey(), null, initialDate, initialDate, false, ImmutableList.<PluginProperty>of(), callContext); assertListenerStatus(); assertEquals(entitlement.getAccountId(), account.getId()); assertEquals(entitlement.getExternalKey(), account.getExternalKey()); assertEquals(entitlement.getEffectiveStartDate(), initialDate); assertNull(entitlement.getEffectiveEndDate()); assertEquals(entitlement.getLastActivePriceList().getName(), PriceListSet.DEFAULT_PRICELIST_NAME); assertEquals(entitlement.getLastActiveProduct().getName(), "Shotgun"); assertEquals(entitlement.getLastActivePhase().getName(), "shotgun-monthly-evergreen"); assertEquals(entitlement.getLastActivePlan().getName(), "shotgun-monthly"); assertEquals(entitlement.getLastActiveProductCategory(), ProductCategory.BASE); assertEquals(entitlement.getState(), EntitlementState.ACTIVE); assertEquals(entitlement.getSourceType(), EntitlementSourceType.NATIVE); assertEquals(entitlement.getLastActivePlan().getName(), "shotgun-monthly"); assertEquals(entitlement.getLastActivePriceList().getName(), PriceListSet.DEFAULT_PRICELIST_NAME); assertEquals(entitlement.getLastActiveProduct().getName(), "Shotgun"); assertEquals(entitlement.getLastActiveProductCategory(), ProductCategory.BASE); assertEquals(entitlement.getState(), EntitlementState.ACTIVE); assertEquals(entitlement.getSourceType(), EntitlementSourceType.NATIVE); List<Entitlement> bundleEntitlements = entitlementApi.getAllEntitlementsForBundle(entitlement.getBundleId(), callContext); assertEquals(bundleEntitlements.size(), 1); bundleEntitlements = entitlementApi.getAllEntitlementsForAccountIdAndExternalKey(account.getId(), account.getExternalKey(), callContext); assertEquals(bundleEntitlements.size(), 1); } @Test(groups = "slow") public void testCreateBaseWithDifferentStartDate() throws AccountApiException, EntitlementApiException, SubscriptionApiException { final LocalDate initialDate = new LocalDate(2013, 8, 7); clock.setDay(initialDate); final Account account = createAccount(getAccountData(7)); final LocalDate entitlementDate = initialDate.plusDays(3); final LocalDate billingDate = initialDate.plusDays(5); final PlanPhaseSpecifier spec = new PlanPhaseSpecifier("Shotgun", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, null); Entitlement entitlement = entitlementApi.createBaseEntitlement(account.getId(), spec, account.getExternalKey(), null, entitlementDate, billingDate, false, ImmutableList.<PluginProperty>of(), callContext); assertListenerStatus(); assertEquals(entitlement.getState(), EntitlementState.PENDING); assertEquals(entitlement.getEffectiveStartDate(), entitlementDate); // 2013-08-10 : entitlementDate testListener.pushExpectedEvents(NextEvent.BLOCK); clock.addDays(3); assertListenerStatus(); // Once we pass entitlement startDate, state should be ACTIVE (although we did not pass billing startDate) entitlement = entitlementApi.getEntitlementForId(entitlement.getId(), callContext); assertEquals(entitlement.getState(), EntitlementState.ACTIVE); // 2013-08-12 : billingDate testListener.pushExpectedEvents(NextEvent.CREATE); clock.addDays(2); assertListenerStatus(); // effectiveDate = entitlementDate prior billingDate final PlanPhaseSpecifier spec2 = new PlanPhaseSpecifier("Pistol", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, null); try { entitlement.changePlanWithDate(spec2, ImmutableList.<PlanPhasePriceOverride>of(), entitlementDate, ImmutableList.<PluginProperty>of(), callContext); Assert.fail("Change plan prior billingStartDate should fail"); } catch (EntitlementApiException e) { Assert.assertEquals(e.getCode(), ErrorCode.SUB_INVALID_REQUESTED_DATE.getCode()); } // effectiveDate is null (same as first case above), but **did** reach the billing startDate (and entitlement startDate) so will succeed clock.addDeltaFromReality(1000); // Add one sec to make sure CHANGE event does not coincide with CREATE (realistic scenario), and therefore we do expect a CHANGE event testListener.pushExpectedEvents(NextEvent.CHANGE); final Entitlement result = entitlement.changePlanWithDate(spec2, ImmutableList.<PlanPhasePriceOverride>of(), null, ImmutableList.<PluginProperty>of(), callContext); assertListenerStatus(); assertEquals(result.getState(), EntitlementState.ACTIVE); assertEquals(result.getLastActiveProduct().getName(), "Pistol"); } @Test(groups = "slow") public void testCreateBaseWithEntitlementInTheFuture() throws AccountApiException, EntitlementApiException, SubscriptionApiException { final LocalDate initialDate = new LocalDate(2013, 8, 7); clock.setDay(initialDate); final Account account = createAccount(getAccountData(7)); final LocalDate entitlementDate = initialDate.plusDays(3); final LocalDate billingDate = null; final PlanPhaseSpecifier spec = new PlanPhaseSpecifier("Shotgun", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, null); testListener.pushExpectedEvents(NextEvent.CREATE); final Entitlement entitlement = entitlementApi.createBaseEntitlement(account.getId(), spec, account.getExternalKey(), null, entitlementDate, billingDate, false, ImmutableList.<PluginProperty>of(), callContext); assertListenerStatus(); assertEquals(entitlement.getState(), EntitlementState.PENDING); assertEquals(entitlement.getEffectiveStartDate(), entitlementDate); testListener.pushExpectedEvents(NextEvent.BLOCK); clock.addDays(3); assertListenerStatus(); final Entitlement entitlementActive = entitlementApi.getEntitlementForId(entitlement.getId(), callContext); assertEquals(entitlementActive.getState(), EntitlementState.ACTIVE); } @Test(groups = "slow") public void testCreateBaseWithBillingInTheFuture() throws AccountApiException, EntitlementApiException, SubscriptionApiException { final LocalDate initialDate = new LocalDate(2013, 8, 7); clock.setDay(initialDate); final Account account = createAccount(getAccountData(7)); final LocalDate entitlementDate = null; final LocalDate billingDate = initialDate.plusDays(5); final PlanPhaseSpecifier spec = new PlanPhaseSpecifier("Shotgun", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, null); testListener.pushExpectedEvents(NextEvent.BLOCK); final Entitlement entitlement = entitlementApi.createBaseEntitlement(account.getId(), spec, account.getExternalKey(), null, entitlementDate, billingDate, false, ImmutableList.<PluginProperty>of(), callContext); assertListenerStatus(); assertEquals(entitlement.getState(), EntitlementState.ACTIVE); assertEquals(entitlement.getEffectiveStartDate(), initialDate); testListener.pushExpectedEvents(NextEvent.CREATE); clock.addDays(5); assertListenerStatus(); } @Test(groups = "slow") public void testCreateBaseWithDifferentInThePast() throws AccountApiException, EntitlementApiException, SubscriptionApiException { final LocalDate initialDate = new LocalDate(2013, 8, 7); clock.setDay(initialDate); final Account account = createAccount(getAccountData(7)); final LocalDate entitlementDate = initialDate.minusDays(3); final LocalDate billingDate = initialDate.minusDays(5); final PlanPhaseSpecifier spec = new PlanPhaseSpecifier("Shotgun", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, null); testListener.pushExpectedEvents(NextEvent.BLOCK, NextEvent.CREATE); final Entitlement entitlement = entitlementApi.createBaseEntitlement(account.getId(), spec, account.getExternalKey(), null, entitlementDate, billingDate, false, ImmutableList.<PluginProperty>of(), callContext); assertListenerStatus(); assertEquals(entitlement.getState(), EntitlementState.ACTIVE); assertEquals(entitlement.getEffectiveStartDate(), entitlementDate); } @Test(groups = "slow") public void testCreateBaseWithEntitlementInThePast() throws AccountApiException, EntitlementApiException, SubscriptionApiException { final LocalDate initialDate = new LocalDate(2013, 8, 7); clock.setDay(initialDate); final Account account = createAccount(getAccountData(7)); final LocalDate entitlementDate = initialDate.minusDays(3); final LocalDate billingDate = null; final PlanPhaseSpecifier spec = new PlanPhaseSpecifier("Shotgun", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, null); testListener.pushExpectedEvents(NextEvent.BLOCK, NextEvent.CREATE); final Entitlement entitlement = entitlementApi.createBaseEntitlement(account.getId(), spec, account.getExternalKey(), null, entitlementDate, billingDate, false, ImmutableList.<PluginProperty>of(), callContext); assertListenerStatus(); assertEquals(entitlement.getState(), EntitlementState.ACTIVE); assertEquals(entitlement.getEffectiveStartDate(), entitlementDate); } @Test(groups = "slow") public void testCreateBaseWithBillingInThePast() throws AccountApiException, EntitlementApiException, SubscriptionApiException { final LocalDate initialDate = new LocalDate(2013, 8, 7); clock.setDay(initialDate); final Account account = createAccount(getAccountData(7)); final LocalDate entitlementDate = null; final LocalDate billingDate = initialDate.minusDays(5); final PlanPhaseSpecifier spec = new PlanPhaseSpecifier("Shotgun", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, null); testListener.pushExpectedEvents(NextEvent.BLOCK, NextEvent.CREATE); final Entitlement entitlement = entitlementApi.createBaseEntitlement(account.getId(), spec, account.getExternalKey(), null, entitlementDate, billingDate, false, ImmutableList.<PluginProperty>of(), callContext); assertListenerStatus(); assertEquals(entitlement.getState(), EntitlementState.ACTIVE); assertEquals(entitlement.getEffectiveStartDate(), initialDate); } @Test(groups = "slow") public void testCreateBaseSubscriptionsWithAddOns() throws AccountApiException, EntitlementApiException, SubscriptionApiException { final LocalDate initialDate = new LocalDate(2013, 8, 7); clock.setDay(initialDate); final Account account = createAccount(getAccountData(7)); final String bundleKey2 = "bundleKey2"; final PlanPhaseSpecifier spec = new PlanPhaseSpecifier("Shotgun", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, null); testListener.pushExpectedEvents(NextEvent.BLOCK, NextEvent.CREATE); entitlementApi.createBaseEntitlement(account.getId(), spec, bundleKey2, null, null, null, false, ImmutableList.<PluginProperty>of(), callContext); assertListenerStatus(); // First bundle of EntitlementSpecifier will specify all new subscription final String bundleKey1 = "bundleKey1"; final EntitlementSpecifier spec11 = new DefaultEntitlementSpecifier(new PlanPhaseSpecifier("Shotgun", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, null), null); final EntitlementSpecifier spec12 = new DefaultEntitlementSpecifier(new PlanPhaseSpecifier("Telescopic-Scope", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, null), null); final List<EntitlementSpecifier> specs1 = ImmutableList.of(spec11, spec12); final BaseEntitlementWithAddOnsSpecifier baseEntitlementWithAddOnsSpecifier1 = new DefaultBaseEntitlementWithAddOnsSpecifier(null, bundleKey1, specs1, null, null, false); // Second bundle of EntitlementSpecifier will specify the previously created 'existingEntitlement' final EntitlementSpecifier spec22 = new DefaultEntitlementSpecifier(new PlanPhaseSpecifier("Telescopic-Scope", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, null), null); final List<EntitlementSpecifier> specs2 = ImmutableList.of(spec22); final BaseEntitlementWithAddOnsSpecifier baseEntitlementWithAddOnsSpecifier2 = new DefaultBaseEntitlementWithAddOnsSpecifier(null, bundleKey2, specs2, null, null, false); final Iterable<BaseEntitlementWithAddOnsSpecifier> baseEntitlementWithAddOnsSpecifiers = ImmutableList.of(baseEntitlementWithAddOnsSpecifier1, baseEntitlementWithAddOnsSpecifier2); // We expect 3 {BLOCK, CREATE} events for the 3 subscriptions created,. testListener.pushExpectedEvents(NextEvent.BLOCK, NextEvent.CREATE, NextEvent.BLOCK, NextEvent.CREATE, NextEvent.BLOCK, NextEvent.CREATE); final List<Entitlement> entitlements = entitlementApi.createBaseEntitlementsWithAddOns(account.getId(), baseEntitlementWithAddOnsSpecifiers, ImmutableList.<PluginProperty>of(), callContext); assertListenerStatus(); // Retun only the created subscriptions Assert.assertEquals(entitlements.size(), 3); final List<Entitlement> entitlementsForBundle1 = entitlementApi.getAllEntitlementsForAccountIdAndExternalKey(account.getId(), bundleKey1, callContext); Assert.assertEquals(entitlementsForBundle1.size(), 2); // And yet we do have both the BASE and ADD_ON for bundleKey2 final List<Entitlement> entitlementsForBundle2 = entitlementApi.getAllEntitlementsForAccountIdAndExternalKey(account.getId(), bundleKey2, callContext); Assert.assertEquals(entitlementsForBundle2.size(), 2); } @Test(groups = "slow", expectedExceptions = EntitlementApiException.class) public void testCreateBaseSubscriptionsWithAddOnsMissingBase() throws AccountApiException, EntitlementApiException, SubscriptionApiException { final LocalDate initialDate = new LocalDate(2013, 8, 7); clock.setDay(initialDate); final Account account = createAccount(getAccountData(7)); final String bundleKey2 = "bundleKey2"; final EntitlementSpecifier spec22 = new DefaultEntitlementSpecifier(new PlanPhaseSpecifier("Telescopic-Scope", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, null), null); final List<EntitlementSpecifier> specs2 = ImmutableList.of(spec22); final BaseEntitlementWithAddOnsSpecifier baseEntitlementWithAddOnsSpecifier2 = new DefaultBaseEntitlementWithAddOnsSpecifier(null, bundleKey2, specs2, null, null, false); final Iterable<BaseEntitlementWithAddOnsSpecifier> baseEntitlementWithAddOnsSpecifiers = ImmutableList.of(baseEntitlementWithAddOnsSpecifier2); entitlementApi.createBaseEntitlementsWithAddOns(account.getId(), baseEntitlementWithAddOnsSpecifiers, ImmutableList.<PluginProperty>of(), callContext); } @Test(groups = "slow") public void testCreateBaseSubscriptionsWithAddOnsBadOrdering() throws AccountApiException, EntitlementApiException, SubscriptionApiException { final LocalDate initialDate = new LocalDate(2013, 8, 7); clock.setDay(initialDate); final Account account = createAccount(getAccountData(7)); final String bundleKey1 = "bundleKey1"; final EntitlementSpecifier spec11 = new DefaultEntitlementSpecifier(new PlanPhaseSpecifier("Telescopic-Scope", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, null), null); final EntitlementSpecifier spec12 = new DefaultEntitlementSpecifier(new PlanPhaseSpecifier("Shotgun", BillingPeriod.MONTHLY, PriceListSet.DEFAULT_PRICELIST_NAME, null), null); final List<EntitlementSpecifier> specs1 = ImmutableList.of(spec11, spec12); final BaseEntitlementWithAddOnsSpecifier baseEntitlementWithAddOnsSpecifier1 = new DefaultBaseEntitlementWithAddOnsSpecifier(null, bundleKey1, specs1, null, null, false); final Iterable<BaseEntitlementWithAddOnsSpecifier> baseEntitlementWithAddOnsSpecifiers = ImmutableList.of(baseEntitlementWithAddOnsSpecifier1); testListener.pushExpectedEvents(NextEvent.BLOCK, NextEvent.CREATE, NextEvent.BLOCK, NextEvent.CREATE); entitlementApi.createBaseEntitlementsWithAddOns(account.getId(), baseEntitlementWithAddOnsSpecifiers, ImmutableList.<PluginProperty>of(), callContext); assertListenerStatus(); } }