killbill-aplcache

Merge branch 'integration' of github.com:ning/killbill

6/8/2012 11:57:45 PM

Details

diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/json/ChargebackJson.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/json/ChargebackJson.java
index 22475d7..f9b681f 100644
--- a/jaxrs/src/main/java/com/ning/billing/jaxrs/json/ChargebackJson.java
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/json/ChargebackJson.java
@@ -51,7 +51,6 @@ public class ChargebackJson {
         this.chargebackAmount = chargeback.getAmount().negate();
         this.paymentId = chargeback.getReversedInvoicePaymentId().toString();
         this.reason = null;
-
     }
 
     public DateTime getRequestedDate() {
@@ -85,10 +84,12 @@ public class ChargebackJson {
 
         final ChargebackJson that = (ChargebackJson) o;
 
-        if (chargebackAmount != null ? !chargebackAmount.equals(that.chargebackAmount) : that.chargebackAmount != null) {
+        if (!((chargebackAmount == null && that.chargebackAmount == null) ||
+                (chargebackAmount != null && that.chargebackAmount != null && chargebackAmount.compareTo(that.chargebackAmount) == 0))) {
             return false;
         }
-        if (effectiveDate != null ? !effectiveDate.equals(that.effectiveDate) : that.effectiveDate != null) {
+        if (!((effectiveDate == null && that.effectiveDate == null) ||
+                (effectiveDate != null && that.effectiveDate != null && effectiveDate.compareTo(that.effectiveDate) == 0))) {
             return false;
         }
         if (paymentId != null ? !paymentId.equals(that.paymentId) : that.paymentId != null) {
@@ -97,7 +98,8 @@ public class ChargebackJson {
         if (reason != null ? !reason.equals(that.reason) : that.reason != null) {
             return false;
         }
-        if (requestedDate != null ? !requestedDate.equals(that.requestedDate) : that.requestedDate != null) {
+        if (!((requestedDate == null && that.requestedDate == null) ||
+                (requestedDate != null && that.requestedDate != null && requestedDate.compareTo(that.requestedDate) == 0))) {
             return false;
         }
 
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/json/CreditJson.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/json/CreditJson.java
index c4c24ad..a63a244 100644
--- a/jaxrs/src/main/java/com/ning/billing/jaxrs/json/CreditJson.java
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/json/CreditJson.java
@@ -100,10 +100,12 @@ public class CreditJson {
 
         final CreditJson that = (CreditJson) o;
 
-        if (creditAmount != null ? !creditAmount.equals(that.creditAmount) : that.creditAmount != null) {
+        if (!((creditAmount == null && that.creditAmount == null) ||
+                (creditAmount != null && that.creditAmount != null && creditAmount.compareTo(that.creditAmount) == 0))) {
             return false;
         }
-        if (effectiveDate != null ? !effectiveDate.equals(that.effectiveDate) : that.effectiveDate != null) {
+        if (!((effectiveDate == null && that.effectiveDate == null) ||
+                (effectiveDate != null && that.effectiveDate != null && effectiveDate.compareTo(that.effectiveDate) == 0))) {
             return false;
         }
         if (invoiceId != null ? !invoiceId.equals(that.invoiceId) : that.invoiceId != null) {
@@ -115,7 +117,8 @@ public class CreditJson {
         if (reason != null ? !reason.equals(that.reason) : that.reason != null) {
             return false;
         }
-        if (requestedDate != null ? !requestedDate.equals(that.requestedDate) : that.requestedDate != null) {
+        if (!((requestedDate == null && that.requestedDate == null) ||
+                (requestedDate != null && that.requestedDate != null && requestedDate.compareTo(that.requestedDate) == 0))) {
             return false;
         }
 
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/json/InvoiceItemJsonSimple.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/json/InvoiceItemJsonSimple.java
index cad2d8b..3273246 100644
--- a/jaxrs/src/main/java/com/ning/billing/jaxrs/json/InvoiceItemJsonSimple.java
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/json/InvoiceItemJsonSimple.java
@@ -126,7 +126,8 @@ public class InvoiceItemJsonSimple {
         if (accountId != null ? !accountId.equals(that.accountId) : that.accountId != null) {
             return false;
         }
-        if (amount != null ? !amount.equals(that.amount) : that.amount != null) {
+        if (!((amount == null && that.amount == null) ||
+                (amount != null && that.amount != null && amount.compareTo(that.amount) == 0))) {
             return false;
         }
         if (bundleId != null ? !bundleId.equals(that.bundleId) : that.bundleId != null) {
@@ -138,7 +139,8 @@ public class InvoiceItemJsonSimple {
         if (description != null ? !description.equals(that.description) : that.description != null) {
             return false;
         }
-        if (endDate != null ? !endDate.equals(that.endDate) : that.endDate != null) {
+        if (!((endDate == null && that.endDate == null) ||
+                (endDate != null && that.endDate != null && endDate.compareTo(that.endDate) == 0))) {
             return false;
         }
         if (invoiceId != null ? !invoiceId.equals(that.invoiceId) : that.invoiceId != null) {
@@ -150,7 +152,8 @@ public class InvoiceItemJsonSimple {
         if (planName != null ? !planName.equals(that.planName) : that.planName != null) {
             return false;
         }
-        if (startDate != null ? !startDate.equals(that.startDate) : that.startDate != null) {
+        if (!((startDate == null && that.startDate == null) ||
+                (startDate != null && that.startDate != null && startDate.compareTo(that.startDate) == 0))) {
             return false;
         }
         if (subscriptionId != null ? !subscriptionId.equals(that.subscriptionId) : that.subscriptionId != null) {
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/json/InvoiceJsonSimple.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/json/InvoiceJsonSimple.java
index 0c50fda..1308f7f 100644
--- a/jaxrs/src/main/java/com/ning/billing/jaxrs/json/InvoiceJsonSimple.java
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/json/InvoiceJsonSimple.java
@@ -109,16 +109,20 @@ public class InvoiceJsonSimple {
         if (accountId != null ? !accountId.equals(that.accountId) : that.accountId != null) {
             return false;
         }
-        if (amount != null ? !amount.equals(that.amount) : that.amount != null) {
+        if (!((amount == null && that.amount == null) ||
+                (amount != null && that.amount != null && amount.compareTo(that.amount) == 0))) {
             return false;
         }
-        if (balance != null ? !balance.equals(that.balance) : that.balance != null) {
+        if (!((balance == null && that.balance == null) ||
+                (balance != null && that.balance != null && balance.compareTo(that.balance) == 0))) {
             return false;
         }
-        if (credit != null ? !credit.equals(that.credit) : that.credit != null) {
+        if (!((credit == null && that.credit == null) ||
+                (credit != null && that.credit != null && credit.compareTo(that.credit) == 0))) {
             return false;
         }
-        if (invoiceDate != null ? !invoiceDate.equals(that.invoiceDate) : that.invoiceDate != null) {
+        if (!((invoiceDate == null && that.invoiceDate == null) ||
+                (invoiceDate != null && that.invoiceDate != null && invoiceDate.compareTo(that.invoiceDate) == 0))) {
             return false;
         }
         if (invoiceId != null ? !invoiceId.equals(that.invoiceId) : that.invoiceId != null) {
@@ -127,7 +131,8 @@ public class InvoiceJsonSimple {
         if (invoiceNumber != null ? !invoiceNumber.equals(that.invoiceNumber) : that.invoiceNumber != null) {
             return false;
         }
-        if (targetDate != null ? !targetDate.equals(that.targetDate) : that.targetDate != null) {
+        if (!((targetDate == null && that.targetDate == null) ||
+                (targetDate != null && that.targetDate != null && targetDate.compareTo(that.targetDate) == 0))) {
             return false;
         }
 
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/json/PaymentJsonSimple.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/json/PaymentJsonSimple.java
index 86b8efd..abde6ac 100644
--- a/jaxrs/src/main/java/com/ning/billing/jaxrs/json/PaymentJsonSimple.java
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/json/PaymentJsonSimple.java
@@ -137,25 +137,29 @@ public class PaymentJsonSimple {
         if (accountId != null ? !accountId.equals(that.accountId) : that.accountId != null) {
             return false;
         }
-        if (amount != null ? !amount.equals(that.amount) : that.amount != null) {
+        if (!((amount == null && that.amount == null) ||
+                (amount != null && that.amount != null && amount.compareTo(that.amount) == 0))) {
             return false;
         }
         if (currency != null ? !currency.equals(that.currency) : that.currency != null) {
             return false;
         }
-        if (effectiveDate != null ? !effectiveDate.equals(that.effectiveDate) : that.effectiveDate != null) {
+        if (!((effectiveDate == null && that.effectiveDate == null) ||
+                (effectiveDate != null && that.effectiveDate != null && effectiveDate.compareTo(that.effectiveDate) == 0))) {
             return false;
         }
         if (invoiceId != null ? !invoiceId.equals(that.invoiceId) : that.invoiceId != null) {
             return false;
         }
-        if (paidAmount != null ? !paidAmount.equals(that.paidAmount) : that.paidAmount != null) {
+        if (!((paidAmount == null && that.paidAmount == null) ||
+                (paidAmount != null && that.paidAmount != null && paidAmount.compareTo(that.paidAmount) == 0))) {
             return false;
         }
         if (paymentId != null ? !paymentId.equals(that.paymentId) : that.paymentId != null) {
             return false;
         }
-        if (requestedDate != null ? !requestedDate.equals(that.requestedDate) : that.requestedDate != null) {
+        if (!((requestedDate == null && that.requestedDate == null) ||
+                (requestedDate != null && that.requestedDate != null && requestedDate.compareTo(that.requestedDate) == 0))) {
             return false;
         }
         if (retryCount != null ? !retryCount.equals(that.retryCount) : that.retryCount != null) {
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/json/SubscriptionJsonNoEvents.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/json/SubscriptionJsonNoEvents.java
index 27c6dc9..9ca0078 100644
--- a/jaxrs/src/main/java/com/ning/billing/jaxrs/json/SubscriptionJsonNoEvents.java
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/json/SubscriptionJsonNoEvents.java
@@ -118,10 +118,17 @@ public class SubscriptionJsonNoEvents extends SubscriptionJsonSimple {
 
     @Override
     public boolean equals(final Object o) {
-        return equalsNoId(o) && super.equals(o);
+        if (equalsNoSubscriptionIdNoStartDateNoCTD(o) && super.equals(o)) {
+            final SubscriptionJsonNoEvents that = (SubscriptionJsonNoEvents) o;
+            return ((startDate == null && that.startDate == null) || (startDate != null && that.startDate != null && startDate.compareTo(that.startDate) == 0)) &&
+                    ((chargedThroughDate == null && that.chargedThroughDate == null) || (chargedThroughDate != null && that.chargedThroughDate != null &&
+                            chargedThroughDate.compareTo(that.chargedThroughDate) == 0));
+        } else {
+            return false;
+        }
     }
 
-    public boolean equalsNoId(final Object o) {
+    public boolean equalsNoSubscriptionIdNoStartDateNoCTD(final Object o) {
         if (this == o) {
             return true;
         }
@@ -137,9 +144,6 @@ public class SubscriptionJsonNoEvents extends SubscriptionJsonSimple {
         if (bundleId != null ? !bundleId.equals(that.bundleId) : that.bundleId != null) {
             return false;
         }
-        if (chargedThroughDate != null ? !chargedThroughDate.equals(that.chargedThroughDate) : that.chargedThroughDate != null) {
-            return false;
-        }
         if (priceList != null ? !priceList.equals(that.priceList) : that.priceList != null) {
             return false;
         }
@@ -149,9 +153,6 @@ public class SubscriptionJsonNoEvents extends SubscriptionJsonSimple {
         if (productName != null ? !productName.equals(that.productName) : that.productName != null) {
             return false;
         }
-        if (startDate != null ? !startDate.equals(that.startDate) : that.startDate != null) {
-            return false;
-        }
 
         return true;
     }
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/ChargebackResource.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/ChargebackResource.java
index c8ff0b2..ec84f70 100644
--- a/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/ChargebackResource.java
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/ChargebackResource.java
@@ -16,12 +16,6 @@
 
 package com.ning.billing.jaxrs.resources;
 
-import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.UUID;
-
 import javax.ws.rs.Consumes;
 import javax.ws.rs.GET;
 import javax.ws.rs.HeaderParam;
@@ -30,6 +24,9 @@ import javax.ws.rs.Path;
 import javax.ws.rs.PathParam;
 import javax.ws.rs.Produces;
 import javax.ws.rs.core.Response;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.UUID;
 
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -46,6 +43,8 @@ import com.ning.billing.jaxrs.util.JaxrsUriBuilder;
 import com.ning.billing.payment.api.PaymentApi;
 import com.ning.billing.payment.api.PaymentApiException;
 
+import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
+
 @Singleton
 @Path(JaxrsResource.CHARGEBACKS_PATH)
 public class ChargebackResource implements JaxrsResource {
@@ -70,10 +69,10 @@ public class ChargebackResource implements JaxrsResource {
     @GET
     @Path("/{chargebackId:" + UUID_PATTERN + "}")
     @Produces(APPLICATION_JSON)
-    public Response getChargeback(@PathParam("chargebackId") String chargebackId) {
+    public Response getChargeback(@PathParam("chargebackId") final String chargebackId) {
         try {
-            InvoicePayment chargeback = invoicePaymentApi.getChargebackById(UUID.fromString(chargebackId));
-            ChargebackJson chargebackJson = new ChargebackJson(chargeback);
+            final InvoicePayment chargeback = invoicePaymentApi.getChargebackById(UUID.fromString(chargebackId));
+            final ChargebackJson chargebackJson = new ChargebackJson(chargeback);
 
             return Response.status(Response.Status.OK).entity(chargebackJson).build();
         } catch (InvoiceApiException e) {
@@ -86,19 +85,19 @@ public class ChargebackResource implements JaxrsResource {
     @GET
     @Path("/accounts/{accountId:" + UUID_PATTERN + "}")
     @Produces(APPLICATION_JSON)
-    public Response getForAccount(@PathParam("accountId") String accountId) {
-        List<InvoicePayment> chargebacks = invoicePaymentApi.getChargebacksByAccountId(UUID.fromString(accountId));
-        List<ChargebackJson> chargebacksJson = convertToJson(chargebacks);
+    public Response getForAccount(@PathParam("accountId") final String accountId) {
+        final List<InvoicePayment> chargebacks = invoicePaymentApi.getChargebacksByAccountId(UUID.fromString(accountId));
+        final List<ChargebackJson> chargebacksJson = convertToJson(chargebacks);
 
-        ChargebackCollectionJson json = new ChargebackCollectionJson(accountId, chargebacksJson);
+        final ChargebackCollectionJson json = new ChargebackCollectionJson(accountId, chargebacksJson);
         return Response.status(Response.Status.OK).entity(json).build();
     }
 
     @GET
     @Path("/payments/{paymentId:" + UUID_PATTERN + "}")
     @Produces(APPLICATION_JSON)
-    public Response getForPayment(@PathParam("paymentId") String paymentId) {
-        UUID paymentAttemptId = null;
+    public Response getForPayment(@PathParam("paymentId") final String paymentId) {
+        final UUID paymentAttemptId;
         try {
             paymentAttemptId = paymentApi.getPaymentAttemptIdFromPaymentId(UUID.fromString(paymentId));
         } catch (PaymentApiException e) {
@@ -107,13 +106,13 @@ public class ChargebackResource implements JaxrsResource {
             return Response.status(Response.Status.NO_CONTENT).build();
         }
 
-        List<InvoicePayment> chargebacks = invoicePaymentApi.getChargebacksByPaymentAttemptId(paymentAttemptId);
-        List<ChargebackJson> chargebacksJson = convertToJson(chargebacks);
+        final List<InvoicePayment> chargebacks = invoicePaymentApi.getChargebacksByPaymentAttemptId(paymentAttemptId);
+        final List<ChargebackJson> chargebacksJson = convertToJson(chargebacks);
 
         try {
-            String accountId = invoicePaymentApi.getAccountIdFromInvoicePaymentId(UUID.fromString(paymentId)).toString();
+            final String accountId = invoicePaymentApi.getAccountIdFromInvoicePaymentId(UUID.fromString(paymentId)).toString();
 
-            ChargebackCollectionJson json = new ChargebackCollectionJson(accountId, chargebacksJson);
+            final ChargebackCollectionJson json = new ChargebackCollectionJson(accountId, chargebacksJson);
             return Response.status(Response.Status.OK).entity(json).build();
         } catch (InvoiceApiException e) {
             final String error = String.format("Failed to locate account for payment id %s", paymentId);
@@ -142,9 +141,9 @@ public class ChargebackResource implements JaxrsResource {
         }
     }
 
-    private List<ChargebackJson> convertToJson(List<InvoicePayment> chargebacks) {
-        List<ChargebackJson> result = new ArrayList<ChargebackJson>();
-        for (InvoicePayment chargeback : chargebacks) {
+    private List<ChargebackJson> convertToJson(final List<InvoicePayment> chargebacks) {
+        final List<ChargebackJson> result = new ArrayList<ChargebackJson>();
+        for (final InvoicePayment chargeback : chargebacks) {
             result.add(new ChargebackJson(chargeback));
         }
 
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/CreditResource.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/CreditResource.java
index 85cae69..74ea6a3 100644
--- a/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/CreditResource.java
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/CreditResource.java
@@ -16,10 +16,6 @@
 
 package com.ning.billing.jaxrs.resources;
 
-import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
-
-import java.util.UUID;
-
 import javax.ws.rs.Consumes;
 import javax.ws.rs.GET;
 import javax.ws.rs.HeaderParam;
@@ -28,6 +24,7 @@ import javax.ws.rs.Path;
 import javax.ws.rs.PathParam;
 import javax.ws.rs.Produces;
 import javax.ws.rs.core.Response;
+import java.util.UUID;
 
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -44,6 +41,8 @@ import com.ning.billing.jaxrs.json.CreditJson;
 import com.ning.billing.jaxrs.util.Context;
 import com.ning.billing.jaxrs.util.JaxrsUriBuilder;
 
+import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
+
 @Singleton
 @Path(JaxrsResource.CREDITS_PATH)
 public class CreditResource implements JaxrsResource {
@@ -55,7 +54,7 @@ public class CreditResource implements JaxrsResource {
     private final Context context;
 
     @Inject
-    public CreditResource(JaxrsUriBuilder uriBuilder, InvoiceUserApi invoiceUserApi, AccountUserApi accountUserApi, Context context) {
+    public CreditResource(final JaxrsUriBuilder uriBuilder, final InvoiceUserApi invoiceUserApi, final AccountUserApi accountUserApi, final Context context) {
         this.uriBuilder = uriBuilder;
         this.invoiceUserApi = invoiceUserApi;
         this.accountUserApi = accountUserApi;
@@ -65,12 +64,15 @@ public class CreditResource implements JaxrsResource {
     @GET
     @Path("/{creditId:" + UUID_PATTERN + "}")
     @Produces(APPLICATION_JSON)
-    public Response getCredit(@PathParam("creditId") String creditId) {
+    public Response getCredit(@PathParam("creditId") final String creditId) {
         try {
-            InvoiceItem credit = invoiceUserApi.getCreditById(UUID.fromString(creditId));
-            CreditJson creditJson = new CreditJson(credit);
-
-            return Response.status(Response.Status.OK).entity(creditJson).build();
+            final InvoiceItem credit = invoiceUserApi.getCreditById(UUID.fromString(creditId));
+            if (credit == null) {
+                return Response.status(Response.Status.NOT_FOUND).build();
+            } else {
+                final CreditJson creditJson = new CreditJson(credit);
+                return Response.status(Response.Status.OK).entity(creditJson).build();
+            }
         } catch (InvoiceApiException e) {
             final String error = String.format("Failed to locate credit for id %s", creditId);
             log.info(error, e);
@@ -82,17 +84,21 @@ public class CreditResource implements JaxrsResource {
     @Consumes(APPLICATION_JSON)
     @Produces(APPLICATION_JSON)
     public Response createCredit(final CreditJson json,
-                                 @PathParam("accountId") final String accountId,
                                  @HeaderParam(HDR_CREATED_BY) final String createdBy,
                                  @HeaderParam(HDR_REASON) final String reason,
                                  @HeaderParam(HDR_COMMENT) final String comment) {
+        final UUID accountId = json.getAccountId();
+        if (accountId == null) {
+            return Response.status(Response.Status.BAD_REQUEST).entity("AccountId cannot be null").build();
+        }
+
         try {
-            Account account = accountUserApi.getAccountById(UUID.fromString(accountId));
+            final Account account = accountUserApi.getAccountById(accountId);
 
-            InvoiceItem credit = invoiceUserApi.insertCredit(account.getId(), json.getCreditAmount(), json.getEffectiveDate(),
-                                                             account.getCurrency(), context.createContext(createdBy, reason, comment));
+            final InvoiceItem credit = invoiceUserApi.insertCredit(account.getId(), json.getCreditAmount(), json.getEffectiveDate(),
+                                                                   account.getCurrency(), context.createContext(createdBy, reason, comment));
 
-            return uriBuilder.buildResponse(ChargebackResource.class, "getCredit", credit.getId());
+            return uriBuilder.buildResponse(CreditResource.class, "getCredit", credit.getId());
         } catch (InvoiceApiException e) {
             final String error = String.format("Failed to create credit %s", json);
             log.info(error, e);
diff --git a/server/src/test/java/com/ning/billing/jaxrs/TestChargeback.java b/server/src/test/java/com/ning/billing/jaxrs/TestChargeback.java
new file mode 100644
index 0000000..c16d926
--- /dev/null
+++ b/server/src/test/java/com/ning/billing/jaxrs/TestChargeback.java
@@ -0,0 +1,128 @@
+/*
+ * Copyright 2010-2012 Ning, Inc.
+ *
+ * Ning 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 com.ning.billing.jaxrs;
+
+import java.io.IOException;
+import java.math.BigDecimal;
+import java.util.UUID;
+
+import org.joda.time.DateTime;
+import org.joda.time.DateTimeZone;
+import org.testng.Assert;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import com.ning.billing.invoice.api.InvoicePayment;
+import com.ning.billing.jaxrs.json.ChargebackCollectionJson;
+import com.ning.billing.jaxrs.json.ChargebackJson;
+import com.ning.billing.jaxrs.resources.JaxrsResource;
+import com.ning.http.client.Response;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNotNull;
+
+public class TestChargeback extends TestJaxrsBase {
+    private final String accountId = UUID.randomUUID().toString();
+    private InvoicePayment invoicePayment;
+
+    @BeforeMethod(groups = "slow")
+    public void setUp() throws Exception {
+        invoicePayment = createInvoicePayment();
+    }
+
+    @Test(groups = "slow", enabled = false)
+    public void testAddChargeback() throws Exception {
+        final ChargebackJson input = new ChargebackJson(new DateTime(DateTimeZone.UTC), new DateTime(DateTimeZone.UTC),
+                                                        BigDecimal.TEN, UUID.randomUUID().toString(), UUID.randomUUID().toString());
+        final String jsonInput = mapper.writeValueAsString(input);
+
+        // Create the chargeback
+        Response response = doPost(JaxrsResource.CHARGEBACKS_PATH, jsonInput, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
+        assertEquals(response.getStatusCode(), javax.ws.rs.core.Response.Status.OK.getStatusCode(), response.getResponseBody());
+
+        // Find the chargeback by location
+        final String location = response.getHeader("Location");
+        assertNotNull(location);
+        response = doGetWithUrl(location, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
+        verifySingleChargebackResponse(response, input);
+
+        // Find the chargeback by account
+        response = doGet(JaxrsResource.CHARGEBACKS_PATH + "/accounts/" + accountId, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
+        verifyCollectionChargebackResponse(response, input);
+
+        // Find the chargeback by payment
+        response = doGet(JaxrsResource.CHARGEBACKS_PATH + "/payments/" + input.getPaymentId(), DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
+        verifyCollectionChargebackResponse(response, input);
+    }
+
+    private void verifyCollectionChargebackResponse(final Response response, final ChargebackJson input) throws IOException {
+        assertEquals(response.getStatusCode(), javax.ws.rs.core.Response.Status.OK.getStatusCode());
+        final ChargebackCollectionJson objFromJson = mapper.readValue(response.getResponseBody(), ChargebackCollectionJson.class);
+        assertEquals(objFromJson.getChargebacks().size(), 1);
+        assertEquals(objFromJson.getChargebacks().get(0), input);
+    }
+
+    private void verifySingleChargebackResponse(final Response response, final ChargebackJson input) throws IOException {
+        assertEquals(response.getStatusCode(), javax.ws.rs.core.Response.Status.OK.getStatusCode());
+        final ChargebackJson objFromJson = mapper.readValue(response.getResponseBody(), ChargebackJson.class);
+        assertEquals(objFromJson, input);
+    }
+
+    @Test(groups = "slow")
+    public void testInvoicePaymentDoesNotExist() throws Exception {
+        final ChargebackJson input = new ChargebackJson(new DateTime(DateTimeZone.UTC), new DateTime(DateTimeZone.UTC),
+                                                        BigDecimal.TEN, UUID.randomUUID().toString(), UUID.randomUUID().toString());
+        final String jsonInput = mapper.writeValueAsString(input);
+
+        // Try to create the chargeback
+        final Response response = doPost(JaxrsResource.CHARGEBACKS_PATH, jsonInput, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
+        assertEquals(response.getStatusCode(), javax.ws.rs.core.Response.Status.BAD_REQUEST.getStatusCode(), response.getResponseBody());
+    }
+
+    @Test(groups = "slow")
+    public void testBadRequest() throws Exception {
+        final ChargebackJson input = new ChargebackJson(null, null, null, null, null);
+        final String jsonInput = mapper.writeValueAsString(input);
+
+        // Try to create the chargeback
+        final Response response = doPost(JaxrsResource.CHARGEBACKS_PATH, jsonInput, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
+        assertEquals(response.getStatusCode(), javax.ws.rs.core.Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), response.getResponseBody());
+    }
+
+    @Test(groups = "slow")
+    public void testNoChargebackForAccount() throws Exception {
+        final String accountId = UUID.randomUUID().toString();
+        final Response response = doGet(JaxrsResource.CHARGEBACKS_PATH + "/accounts/" + accountId, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
+        assertEquals(response.getStatusCode(), javax.ws.rs.core.Response.Status.OK.getStatusCode(), response.getResponseBody());
+
+        final ChargebackCollectionJson chargebackCollectionJson = mapper.readValue(response.getResponseBody(), ChargebackCollectionJson.class);
+        Assert.assertEquals(chargebackCollectionJson.getAccountId(), accountId);
+        Assert.assertEquals(chargebackCollectionJson.getChargebacks().size(), 0);
+    }
+
+    @Test(groups = "slow")
+    public void testNoChargebackForPayment() throws Exception {
+        final String payment = UUID.randomUUID().toString();
+        final Response response = doGet(JaxrsResource.CHARGEBACKS_PATH + "/payments/" + payment, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
+        assertEquals(response.getStatusCode(), javax.ws.rs.core.Response.Status.NO_CONTENT.getStatusCode(), response.getResponseBody());
+    }
+
+    private InvoicePayment createInvoicePayment() {
+        // TODO - blocked on payment resource
+        return null;
+    }
+}
diff --git a/server/src/test/java/com/ning/billing/jaxrs/TestCredit.java b/server/src/test/java/com/ning/billing/jaxrs/TestCredit.java
new file mode 100644
index 0000000..0129225
--- /dev/null
+++ b/server/src/test/java/com/ning/billing/jaxrs/TestCredit.java
@@ -0,0 +1,99 @@
+/*
+ * Copyright 2010-2012 Ning, Inc.
+ *
+ * Ning 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 com.ning.billing.jaxrs;
+
+import java.math.BigDecimal;
+import java.util.UUID;
+
+import org.joda.time.DateTime;
+import org.joda.time.DateTimeZone;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import com.ning.billing.jaxrs.json.AccountJson;
+import com.ning.billing.jaxrs.json.CreditJson;
+import com.ning.billing.jaxrs.resources.JaxrsResource;
+import com.ning.billing.util.clock.DefaultClock;
+import com.ning.http.client.Response;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNotNull;
+
+public class TestCredit extends TestJaxrsBase {
+    AccountJson accountJson;
+
+    @BeforeMethod(groups = "slow")
+    public void setUp() throws Exception {
+        accountJson = createAccount(UUID.randomUUID().toString(), UUID.randomUUID().toString(), "foo@bar.com");
+        assertNotNull(accountJson);
+    }
+
+    @Test(groups = "slow")
+    public void testAddCreditToInvoice() throws Exception {
+        final DateTime requestedDate = DefaultClock.truncateMs(new DateTime(DateTimeZone.UTC));
+        final DateTime effectiveDate = DefaultClock.truncateMs(new DateTime(DateTimeZone.UTC));
+        final CreditJson input = new CreditJson(BigDecimal.TEN, UUID.randomUUID(), UUID.randomUUID().toString(),
+                                                requestedDate, effectiveDate,
+                                                UUID.randomUUID().toString(), UUID.fromString(accountJson.getAccountId()));
+        final String jsonInput = mapper.writeValueAsString(input);
+
+        // Create the credit
+        Response response = doPost(JaxrsResource.CREDITS_PATH, jsonInput, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
+        assertEquals(response.getStatusCode(), javax.ws.rs.core.Response.Status.CREATED.getStatusCode(), response.getResponseBody());
+
+        final String location = response.getHeader("Location");
+        assertNotNull(location);
+
+        // Retrieves by Id based on Location returned
+        response = doGetWithUrl(location, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
+        assertEquals(response.getStatusCode(), javax.ws.rs.core.Response.Status.OK.getStatusCode());
+
+        // We can't just compare the object via .equals() due e.g. to the invoice id
+        final CreditJson objFromJson = mapper.readValue(response.getResponseBody(), CreditJson.class);
+        assertEquals(objFromJson.getAccountId(), input.getAccountId());
+        assertEquals(objFromJson.getCreditAmount().compareTo(input.getCreditAmount()), 0);
+        assertEquals(objFromJson.getEffectiveDate().compareTo(input.getEffectiveDate()), 0);
+    }
+
+    @Test(groups = "slow")
+    public void testAccountDoesNotExist() throws Exception {
+        final CreditJson input = new CreditJson(BigDecimal.TEN, UUID.randomUUID(), UUID.randomUUID().toString(),
+                                                new DateTime(DateTimeZone.UTC), new DateTime(DateTimeZone.UTC),
+                                                UUID.randomUUID().toString(), UUID.randomUUID());
+        final String jsonInput = mapper.writeValueAsString(input);
+
+        // Try to create the credit
+        final Response response = doPost(JaxrsResource.CREDITS_PATH, jsonInput, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
+        assertEquals(response.getStatusCode(), javax.ws.rs.core.Response.Status.BAD_REQUEST.getStatusCode(), response.getResponseBody());
+    }
+
+    @Test(groups = "slow")
+    public void testBadRequest() throws Exception {
+        final CreditJson input = new CreditJson(null, null, null, null, null, null, null);
+        final String jsonInput = mapper.writeValueAsString(input);
+
+        // Try to create the credit
+        final Response response = doPost(JaxrsResource.CREDITS_PATH, jsonInput, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
+        assertEquals(response.getStatusCode(), javax.ws.rs.core.Response.Status.BAD_REQUEST.getStatusCode(), response.getResponseBody());
+    }
+
+    @Test(groups = "slow")
+    public void testCreditDoesNotExist() throws Exception {
+        final Response response = doGet(JaxrsResource.CREDITS_PATH + "/" + UUID.randomUUID().toString(), DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
+        assertEquals(response.getStatusCode(), javax.ws.rs.core.Response.Status.NOT_FOUND.getStatusCode(), response.getResponseBody());
+    }
+}
diff --git a/server/src/test/java/com/ning/billing/jaxrs/TestJaxrsBase.java b/server/src/test/java/com/ning/billing/jaxrs/TestJaxrsBase.java
index a09bf1a..fc79311 100644
--- a/server/src/test/java/com/ning/billing/jaxrs/TestJaxrsBase.java
+++ b/server/src/test/java/com/ning/billing/jaxrs/TestJaxrsBase.java
@@ -30,6 +30,7 @@ import java.util.concurrent.TimeUnit;
 
 import javax.ws.rs.core.Response.Status;
 
+import com.google.common.io.Resources;
 import com.ning.billing.jaxrs.resources.JaxrsResource;
 import com.ning.billing.util.email.EmailModule;
 import com.ning.billing.util.email.templates.TemplateModule;
@@ -124,6 +125,15 @@ public class TestJaxrsBase {
         } catch (IOException e) {
             throw new RuntimeException(e);
         }
+
+        // Use the full path for the catalog
+        final String catalogURI = System.getProperty("killbill.catalog.uri");
+        if (catalogURI != null) {
+            try {
+                System.setProperty("killbill.catalog.uri", Resources.getResource(catalogURI).toExternalForm());
+            } catch (IllegalArgumentException ignored) {
+            }
+        }
     }
 
     public static class TestKillbillGuiceListener extends KillbillGuiceListener {
@@ -368,7 +378,7 @@ public class TestJaxrsBase {
 
         baseJson = response.getResponseBody();
         SubscriptionJsonNoEvents objFromJson = mapper.readValue(baseJson, SubscriptionJsonNoEvents.class);
-        Assert.assertTrue(objFromJson.equalsNoId(input));
+        Assert.assertTrue(objFromJson.equalsNoSubscriptionIdNoStartDateNoCTD(input));
         return objFromJson;
     }
 
diff --git a/server/src/test/java/com/ning/billing/jaxrs/TestSubscription.java b/server/src/test/java/com/ning/billing/jaxrs/TestSubscription.java
index 962352b..e0a951e 100644
--- a/server/src/test/java/com/ning/billing/jaxrs/TestSubscription.java
+++ b/server/src/test/java/com/ning/billing/jaxrs/TestSubscription.java
@@ -89,7 +89,7 @@ public class TestSubscription extends TestJaxrsBase {
         assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
         baseJson = response.getResponseBody();
         objFromJson = mapper.readValue(baseJson, SubscriptionJsonNoEvents.class);
-        assertTrue(objFromJson.equals(newInput));
+        assertTrue(objFromJson.equalsNoSubscriptionIdNoStartDateNoCTD(newInput));
 
         // MOVE AFTER TRIAL
         Interval it = new Interval(clock.getUTCNow(), clock.getUTCNow().plusMonths(3).plusDays(1));
diff --git a/server/src/test/resources/killbill.properties b/server/src/test/resources/killbill.properties
index 9aa3e66..d00e1dd 100644
--- a/server/src/test/resources/killbill.properties
+++ b/server/src/test/resources/killbill.properties
@@ -1,7 +1,7 @@
 # Use killbill util test properties (DbiProvider/MysqltestingHelper) on the test side configured with killbill
 com.ning.billing.dbi.jdbc.url=jdbc:mysql://127.0.0.1:3306/killbill
 
-killbill.catalog.uri=file:src/test/resources/catalog-weapons.xml
+killbill.catalog.uri=catalog-weapons.xml
 
 killbill.payment.engine.events.off=false
 killbill.payment.retry.days=8,8,8