diff --git a/invoice/src/test/java/org/killbill/billing/invoice/TestInvoiceHelper.java b/invoice/src/test/java/org/killbill/billing/invoice/TestInvoiceHelper.java index 448b395de1..11391d8701 100644 --- a/invoice/src/test/java/org/killbill/billing/invoice/TestInvoiceHelper.java +++ b/invoice/src/test/java/org/killbill/billing/invoice/TestInvoiceHelper.java @@ -1,7 +1,7 @@ /* * Copyright 2010-2013 Ning, Inc. - * Copyright 2014-2017 Groupon, Inc - * Copyright 2014-2017 The Billing Project, LLC + * Copyright 2014-2018 Groupon, Inc + * Copyright 2014-2018 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 @@ -78,7 +78,6 @@ import org.killbill.billing.subscription.api.SubscriptionBaseInternalApi; import org.killbill.billing.subscription.api.SubscriptionBaseTransitionType; import org.killbill.billing.subscription.api.user.SubscriptionBaseApiException; -import org.killbill.billing.util.cache.CacheControllerDispatcher; import org.killbill.billing.util.callcontext.CallContext; import org.killbill.billing.util.callcontext.InternalCallContextFactory; import org.killbill.billing.util.config.definition.InvoiceConfig; @@ -199,6 +198,12 @@ public TestInvoiceHelper(final InvoiceGenerator generator, final IDBI dbi, } public UUID generateRegularInvoice(final Account account, final LocalDate targetDate, final CallContext callContext) throws Exception { + final BigDecimal fixedPrice = null; + final BigDecimal recurringPrice = BigDecimal.ONE; + return generateRegularInvoice(account, fixedPrice, recurringPrice, targetDate, callContext); + } + + public UUID generateRegularInvoice(final Account account, final BigDecimal fixedPrice, final BigDecimal recurringPrice, final LocalDate targetDate, final CallContext callContext) throws Exception { final SubscriptionBase subscription = Mockito.mock(SubscriptionBase.class); Mockito.when(subscription.getId()).thenReturn(UUID.randomUUID()); Mockito.when(subscription.getBundleId()).thenReturn(new UUID(0L, 0L)); @@ -207,27 +212,21 @@ public UUID generateRegularInvoice(final Account account, final LocalDate target final PlanPhase planPhase = MockPlanPhase.create1USDMonthlyEvergreen(); final DateTime effectiveDate = new DateTime().minusDays(1); final Currency currency = Currency.USD; - final BigDecimal fixedPrice = null; events.add(createMockBillingEvent(account, subscription, effectiveDate, plan, planPhase, - fixedPrice, BigDecimal.ONE, currency, BillingPeriod.MONTHLY, 1, + fixedPrice, recurringPrice, currency, BillingPeriod.MONTHLY, 1, BillingMode.IN_ADVANCE, "", 1L, SubscriptionBaseTransitionType.CREATE)); Mockito.when(billingApi.getBillingEventsForAccountAndUpdateAccountBCD(Mockito.any(), Mockito.any(), Mockito.any())).thenReturn(events); - final InvoiceNotifier invoiceNotifier = new NullInvoiceNotifier(); - final InvoiceDispatcher dispatcher = new InvoiceDispatcher(generator, accountApi, billingApi, subscriptionApi, - invoiceDao, internalCallContextFactory, invoiceNotifier, invoicePluginDispatcher, locker, busService.getBus(), - notificationQueueService, invoiceConfig, clock, parkedAccountsManager); + final InternalCallContext context = internalCallContextFactory.createInternalCallContext(account.getId(), callContext); - Invoice invoice = dispatcher.processAccountFromNotificationOrBusEvent(account.getId(), targetDate, new DryRunFutureDateArguments(), internalCallContext); + Invoice invoice = generateInvoice(account.getId(), targetDate, new DryRunFutureDateArguments(), context); Assert.assertNotNull(invoice); - final InternalCallContext context = internalCallContextFactory.createInternalCallContext(account.getId(), callContext); - List invoices = invoiceDao.getInvoicesByAccount(context); Assert.assertEquals(invoices.size(), 0); - invoice = dispatcher.processAccountFromNotificationOrBusEvent(account.getId(), targetDate, null, context); + invoice = generateInvoice(account.getId(), targetDate, null, context); Assert.assertNotNull(invoice); invoices = invoiceDao.getInvoicesByAccount(context); @@ -236,6 +235,15 @@ public UUID generateRegularInvoice(final Account account, final LocalDate target return invoice.getId(); } + public Invoice generateInvoice(final UUID accountId, @Nullable final LocalDate targetDate, @Nullable final DryRunArguments dryRunArguments, final InternalCallContext internalCallContext) throws InvoiceApiException { + final InvoiceNotifier invoiceNotifier = new NullInvoiceNotifier(); + final InvoiceDispatcher dispatcher = new InvoiceDispatcher(generator, accountApi, billingApi, subscriptionApi, + invoiceDao, internalCallContextFactory, invoiceNotifier, invoicePluginDispatcher, locker, busService.getBus(), + notificationQueueService, invoiceConfig, clock, parkedAccountsManager); + + return dispatcher.processAccountFromNotificationOrBusEvent(accountId, targetDate, dryRunArguments, internalCallContext); + } + public SubscriptionBase createSubscription() throws SubscriptionBaseApiException { final UUID uuid = UUID.randomUUID(); final UUID bundleId = UUID.randomUUID(); diff --git a/invoice/src/test/java/org/killbill/billing/invoice/api/user/TestDefaultInvoiceUserApi.java b/invoice/src/test/java/org/killbill/billing/invoice/api/user/TestDefaultInvoiceUserApi.java index 75221b9cd4..a829edfda6 100644 --- a/invoice/src/test/java/org/killbill/billing/invoice/api/user/TestDefaultInvoiceUserApi.java +++ b/invoice/src/test/java/org/killbill/billing/invoice/api/user/TestDefaultInvoiceUserApi.java @@ -1,7 +1,7 @@ /* * Copyright 2010-2013 Ning, Inc. - * Copyright 2014-2016 Groupon, Inc - * Copyright 2014-2016 The Billing Project, LLC + * Copyright 2014-2018 Groupon, Inc + * Copyright 2014-2018 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 @@ -31,6 +31,7 @@ import org.killbill.billing.callcontext.DefaultCallContext; import org.killbill.billing.catalog.api.Currency; import org.killbill.billing.invoice.InvoiceTestSuiteWithEmbeddedDB; +import org.killbill.billing.invoice.TestInvoiceHelper.DryRunFutureDateArguments; import org.killbill.billing.invoice.api.Invoice; import org.killbill.billing.invoice.api.InvoiceApiException; import org.killbill.billing.invoice.api.InvoiceItem; @@ -237,7 +238,22 @@ public void testAdjustFullInvoiceItem() throws Exception { } @Test(groups = "slow") - public void testAdjustPartialInvoiceItem() throws Exception { + public void testAdjustPartialRecurringInvoiceItem() throws Exception { + testAdjustPartialInvoiceItem(true); + } + + @Test(groups = "slow", description = "https://github.com/killbill/killbill/pull/831") + public void testAdjustPartialFixedInvoiceItem() throws Exception { + testAdjustPartialInvoiceItem(false); + } + + private void testAdjustPartialInvoiceItem(final boolean recurring) throws Exception { + final Account account = invoiceUtil.createAccount(callContext); + final UUID accountId = account.getId(); + final BigDecimal fixedPrice = recurring ? null : BigDecimal.ONE; + final BigDecimal recurringPrice = !recurring ? null : BigDecimal.ONE; + final UUID invoiceId = invoiceUtil.generateRegularInvoice(account, fixedPrice, recurringPrice, null, callContext); + final InvoiceItem invoiceItem = invoiceUserApi.getInvoice(invoiceId, callContext).getInvoiceItems().get(0); // Verify we picked a non zero item Assert.assertEquals(invoiceItem.getAmount().compareTo(BigDecimal.ZERO), 1); @@ -269,6 +285,10 @@ public void testAdjustPartialInvoiceItem() throws Exception { // Verify the adjusted account balance final BigDecimal adjustedAccountBalance = invoiceUserApi.getAccountBalance(accountId, callContext); Assert.assertEquals(adjustedAccountBalance, adjustedInvoiceBalance); + + // Verify future invoice generation + final Invoice invoice = invoiceUtil.generateInvoice(account.getId(), clock.getUTCToday().plusMonths(1), new DryRunFutureDateArguments(), internalCallContext); + Assert.assertNotNull(invoice); } @Test(groups = "slow")