Skip to content

Commit

Permalink
Fix test errors from catalog changes (91d7d5d)
Browse files Browse the repository at this point in the history
Clone default catalog for tenants that did not upload a specific catalog (test mode)
  • Loading branch information
sbrossie committed Mar 30, 2015
1 parent 843f9de commit 37c073f
Show file tree
Hide file tree
Showing 9 changed files with 105 additions and 21 deletions.
Expand Up @@ -27,7 +27,6 @@
import org.killbill.billing.api.TestApiListener.NextEvent;
import org.killbill.billing.beatrix.util.InvoiceChecker.ExpectedInvoiceItemCheck;
import org.killbill.billing.catalog.DefaultPlanPhasePriceOverride;
import org.killbill.billing.catalog.DefaultPriceListSet;
import org.killbill.billing.catalog.api.BillingActionPolicy;
import org.killbill.billing.catalog.api.BillingPeriod;
import org.killbill.billing.catalog.api.PlanPhasePriceOverride;
Expand Down Expand Up @@ -59,7 +58,6 @@ public void testCreatWithFixedPriceOverride() throws Exception {
invoiceChecker.checkInvoice(account.getId(), 1, callContext, new ExpectedInvoiceItemCheck(clock.getUTCToday(), null, InvoiceItemType.FIXED, new BigDecimal("1")));
}


@Test(groups = "slow")
public void testCreateWithRecurringPriceOverride() throws Exception {

Expand Down Expand Up @@ -95,9 +93,6 @@ public void testCreateWithRecurringPriceOverride() throws Exception {
invoiceChecker.checkInvoice(account.getId(), 3, callContext, new ExpectedInvoiceItemCheck(new LocalDate(2012, 6, 1), new LocalDate(2012, 7, 1), InvoiceItemType.RECURRING, BigDecimal.TEN));
}




@Test(groups = "slow")
public void testChangePlanWithRecurringPriceOverride() throws Exception {

Expand All @@ -109,7 +104,6 @@ public void testChangePlanWithRecurringPriceOverride() throws Exception {
// Set clock to the initial start date - we implicitly assume here that the account timezone is UTC
clock.setDay(new LocalDate(2012, 4, 1));


final DefaultEntitlement bpSubscription = createBaseEntitlementAndCheckForCompletion(account.getId(), "bundleKey", "Shotgun", ProductCategory.BASE, BillingPeriod.MONTHLY, NextEvent.CREATE, NextEvent.INVOICE);
// Check bundle after BP got created otherwise we get an error from auditApi.
subscriptionChecker.checkSubscriptionCreated(bpSubscription.getId(), internalCallContext);
Expand Down
Expand Up @@ -52,13 +52,18 @@
import org.killbill.xmlloader.ValidatingConfig;
import org.killbill.xmlloader.ValidationErrors;

import com.fasterxml.jackson.annotation.JsonIgnore;

public class StandaloneCatalogWithPriceOverride extends ValidatingConfig<StandaloneCatalogWithPriceOverride> implements StaticCatalog {

private final StandaloneCatalog standaloneCatalog;
private final PriceOverride priceOverride;
private final Long tenantRecordId;

/* Since we offer endpoints that attempt to serialize catalog objects, we need to explicitly tell Jackson to ignore those fields */
@JsonIgnore
private final InternalCallContextFactory internalCallContextFactory;
@JsonIgnore
private final PriceOverride priceOverride;

public StandaloneCatalogWithPriceOverride(final StandaloneCatalog staticCatalog, final PriceOverride priceOverride, final Long tenantRecordId, final InternalCallContextFactory internalCallContextFactory) {
this.tenantRecordId = tenantRecordId;
Expand All @@ -67,6 +72,29 @@ public StandaloneCatalogWithPriceOverride(final StandaloneCatalog staticCatalog,
this.internalCallContextFactory = internalCallContextFactory;
}

public StandaloneCatalogWithPriceOverride(final StandaloneCatalogWithPriceOverride cur, final InternalTenantContext tenantContext) {
this.tenantRecordId = tenantContext.getTenantRecordId();
this.priceOverride = cur.getPriceOverride();
this.standaloneCatalog = cur.getStandaloneCatalog();
this.internalCallContextFactory = cur.getInternalCallContextFactory();
}

public StandaloneCatalog getStandaloneCatalog() {
return standaloneCatalog;
}

public PriceOverride getPriceOverride() {
return priceOverride;
}

public Long getTenantRecordId() {
return tenantRecordId;
}

public InternalCallContextFactory getInternalCallContextFactory() {
return internalCallContextFactory;
}

@Override
public String getCatalogName() {
return standaloneCatalog.getCatalogName();
Expand Down
Expand Up @@ -34,6 +34,7 @@

import org.joda.time.DateTime;
import org.killbill.billing.ErrorCode;
import org.killbill.billing.callcontext.InternalTenantContext;
import org.killbill.billing.catalog.api.BillingActionPolicy;
import org.killbill.billing.catalog.api.BillingAlignment;
import org.killbill.billing.catalog.api.BillingMode;
Expand Down Expand Up @@ -66,22 +67,28 @@ public class VersionedCatalog extends ValidatingConfig<StandaloneCatalogWithPric
private final Clock clock;
private String catalogName;
private BillingMode recurringBillingMode;
private final Long tenantRecordId;

@XmlElement(name = "catalogVersion", required = true)
private final List<StandaloneCatalogWithPriceOverride> versions = new ArrayList<StandaloneCatalogWithPriceOverride>();

// Required for JAXB deserialization
public VersionedCatalog() {
this.clock = null;
this.tenantRecordId = null;
}

public VersionedCatalog(final Clock clock, final Long tenantRecordId) {
public VersionedCatalog(final Clock clock) {
this.clock = clock;
this.tenantRecordId = tenantRecordId;
}

public VersionedCatalog(final VersionedCatalog inputCatalog, final InternalTenantContext tenantContext) {
this.clock = inputCatalog.getClock();
this.catalogName = inputCatalog.getCatalogName();
this.recurringBillingMode = inputCatalog.getRecurringBillingMode();
for (final StandaloneCatalogWithPriceOverride cur : inputCatalog.getVersions()) {
final StandaloneCatalogWithPriceOverride catalogWithTenantInfo = new StandaloneCatalogWithPriceOverride(cur, tenantContext);
versions.add(catalogWithTenantInfo);
}
}

//
// Private methods
Expand Down Expand Up @@ -177,6 +184,14 @@ private Plan findPlan(final PlanRequestWrapper wrapper,
throw new CatalogApiException(ErrorCode.CAT_NO_CATALOG_FOR_GIVEN_DATE, requestedDate.toDate().toString());
}

public Clock getClock() {
return clock;
}

public List<StandaloneCatalogWithPriceOverride> getVersions() {
return versions;
}

//
// Public methods not exposed in interface
//
Expand Down
Expand Up @@ -70,8 +70,14 @@ public VersionedCatalog getCatalog(final InternalTenantContext tenantContext) th
// The cache loader might choke on some bad xml -- unlikely since we check its validity prior storing it,
// but to be on the safe side;;
try {
final VersionedCatalog tenantCatalog = (VersionedCatalog) cacheController.get(tenantContext.getTenantRecordId(), cacheLoaderArgument);
return (tenantCatalog != null) ? tenantCatalog : defaultCatalog;
VersionedCatalog tenantCatalog = (VersionedCatalog) cacheController.get(tenantContext.getTenantRecordId(), cacheLoaderArgument);
// It means we are using a default catalog in a multi-tenant deployment, that does not really match a real use case, but we want to support it
// for test purpose.
if (tenantCatalog == null) {
tenantCatalog = new VersionedCatalog(defaultCatalog, tenantContext);
cacheController.add(tenantContext.getTenantRecordId(), tenantCatalog);
}
return tenantCatalog;
} catch (final IllegalStateException e) {
throw new CatalogApiException(ErrorCode.CAT_INVALID_FOR_TENANT, tenantContext.getTenantRecordId());
}
Expand Down
Expand Up @@ -82,7 +82,7 @@ public VersionedCatalog loadDefaultCatalog(final String uriString) throws Catalo
xmlURIs = findXmlReferences(directoryContents, new URL(uriString));
}

final VersionedCatalog result = new VersionedCatalog(clock, InternalCallContextFactory.INTERNAL_TENANT_RECORD_ID);
final VersionedCatalog result = new VersionedCatalog(clock);
for (final URI u : xmlURIs) {
final StandaloneCatalog catalog = XMLLoader.getObjectFromUri(u, StandaloneCatalog.class);
result.add(new StandaloneCatalogWithPriceOverride(catalog, priceOverride, InternalCallContextFactory.INTERNAL_TENANT_RECORD_ID, internalCallContextFactory));
Expand All @@ -94,7 +94,7 @@ public VersionedCatalog loadDefaultCatalog(final String uriString) throws Catalo
}

public VersionedCatalog load(final List<String> catalogXMLs, final Long tenantRecordId) throws CatalogApiException {
final VersionedCatalog result = new VersionedCatalog(clock, tenantRecordId);
final VersionedCatalog result = new VersionedCatalog(clock);
final URI uri;
try {
uri = new URI("/tenantCatalog");
Expand Down
Expand Up @@ -83,10 +83,12 @@ public void testDefaultCatalog() throws CatalogApiException {
Assert.assertEquals(products.length, 3);

// Verify the lookup with other contexts
Assert.assertEquals(catalogCache.getCatalog(multiTenantContext), result);
Assert.assertEquals(catalogCache.getCatalog(otherMultiTenantContext), result);
Assert.assertEquals(catalogCache.getCatalog(Mockito.mock(InternalTenantContext.class)), result);
Assert.assertEquals(catalogCache.getCatalog(Mockito.mock(InternalCallContext.class)), result);
final VersionedCatalog resultForMultiTenantContext = new VersionedCatalog(result, multiTenantContext);
Assert.assertEquals(catalogCache.getCatalog(multiTenantContext).getCatalogName(), resultForMultiTenantContext.getCatalogName());
Assert.assertEquals(catalogCache.getCatalog(multiTenantContext).getVersions().size(), resultForMultiTenantContext.getVersions().size());
for (int i = 0; i < catalogCache.getCatalog(multiTenantContext).getVersions().size(); i++) {
Assert.assertEquals(catalogCache.getCatalog(multiTenantContext).getVersions().get(i).getTenantRecordId(), resultForMultiTenantContext.getVersions().get(i).getTenantRecordId());
}
}

//
Expand Down
2 changes: 1 addition & 1 deletion pom.xml
Expand Up @@ -20,7 +20,7 @@
<parent>
<artifactId>killbill-oss-parent</artifactId>
<groupId>org.kill-bill.billing</groupId>
<version>0.10.0</version>
<version>0.10.1</version>
</parent>
<artifactId>killbill</artifactId>
<version>0.13.6-SNAPSHOT</version>
Expand Down
Expand Up @@ -40,7 +40,7 @@

public abstract class KillbillClient extends GuicyKillbillTestSuiteWithEmbeddedDB {

private final int DEFAULT_WAIT_COMPLETION_TIMEOUT_SEC = 5;
protected final int DEFAULT_WAIT_COMPLETION_TIMEOUT_SEC = 5;

protected static final String PLUGIN_NAME = "noop";

Expand Down
Expand Up @@ -18,19 +18,27 @@

package org.killbill.billing.jaxrs;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

import org.joda.time.DateTime;
import org.joda.time.Interval;
import org.joda.time.LocalDate;
import org.killbill.billing.catalog.api.BillingActionPolicy;
import org.killbill.billing.catalog.api.BillingPeriod;
import org.killbill.billing.catalog.api.PhaseType;
import org.killbill.billing.catalog.api.PriceListSet;
import org.killbill.billing.catalog.api.ProductCategory;
import org.killbill.billing.catalog.override.PriceOverride;
import org.killbill.billing.client.KillBillClientException;
import org.killbill.billing.client.model.Account;
import org.killbill.billing.client.model.Invoice;
import org.killbill.billing.client.model.PhasePriceOverride;
import org.killbill.billing.client.model.Subscription;
import org.killbill.billing.entitlement.api.Entitlement.EntitlementActionPolicy;
import org.killbill.billing.util.api.AuditLevel;
import org.testng.Assert;
import org.testng.annotations.Test;

Expand Down Expand Up @@ -189,4 +197,35 @@ public void testOverridePolicy() throws Exception {
Assert.assertNotNull(objFromJson);
assertEquals(objFromJson.getBillingPeriod(), BillingPeriod.MONTHLY);
}


@Test(groups = "slow", description = "Can override a price when creating a subscription")
public void testOverridePrice() throws Exception {
final DateTime initialDate = new DateTime(2012, 4, 25, 0, 3, 42, 0);
clock.setDeltaFromReality(initialDate.getMillis() - clock.getUTCNow().getMillis());

final Account accountJson = createAccountWithDefaultPaymentMethod();

final String productName = "Shotgun";
final BillingPeriod term = BillingPeriod.ANNUAL;


final Subscription input = new Subscription();
input.setAccountId(accountJson.getAccountId());
input.setExternalKey("identical");
input.setProductName(productName);
input.setProductCategory(ProductCategory.BASE);
input.setBillingPeriod(BillingPeriod.MONTHLY);
input.setPriceList(PriceListSet.DEFAULT_PRICELIST_NAME);
final List<PhasePriceOverride> overrides = new ArrayList<PhasePriceOverride>();
overrides.add(new PhasePriceOverride(null, PhaseType.TRIAL.toString(), BigDecimal.TEN, null));
input.setPriceOverrides(overrides);

final Subscription subscription = killBillClient.createSubscription(input, DEFAULT_WAIT_COMPLETION_TIMEOUT_SEC, createdBy, reason, comment);

final List<Invoice> invoices = killBillClient.getInvoicesForAccount(accountJson.getAccountId(), true, false, AuditLevel.FULL);
assertEquals(invoices.size(), 1);
assertEquals(invoices.get(0).getAmount().compareTo(BigDecimal.TEN), 0);
}

}

1 comment on commit 37c073f

@pierre
Copy link
Member

@pierre pierre commented on 37c073f Mar 31, 2015

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

Please sign in to comment.