killbill-memoizeit

server: extract invoice and payment utilities from TestInvoice Signed-off-by:

8/1/2012 6:26:15 PM

Details

diff --git a/server/src/test/java/com/ning/billing/jaxrs/TestInvoice.java b/server/src/test/java/com/ning/billing/jaxrs/TestInvoice.java
index 4dfc5ab..3b0168f 100644
--- a/server/src/test/java/com/ning/billing/jaxrs/TestInvoice.java
+++ b/server/src/test/java/com/ning/billing/jaxrs/TestInvoice.java
@@ -17,157 +17,66 @@
 package com.ning.billing.jaxrs;
 
 import java.math.BigDecimal;
-import java.util.HashMap;
 import java.util.List;
-import java.util.Map;
-
-import javax.ws.rs.core.Response.Status;
 
 import org.joda.time.DateTime;
-import org.joda.time.Interval;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.testng.Assert;
 import org.testng.annotations.Test;
 
-import com.ning.billing.catalog.api.BillingPeriod;
-import com.ning.billing.catalog.api.ProductCategory;
 import com.ning.billing.jaxrs.json.AccountJson;
-import com.ning.billing.jaxrs.json.BundleJsonNoSubscriptions;
 import com.ning.billing.jaxrs.json.InvoiceJsonSimple;
 import com.ning.billing.jaxrs.json.PaymentJsonSimple;
 import com.ning.billing.jaxrs.json.PaymentMethodJson;
-import com.ning.billing.jaxrs.json.SubscriptionJsonNoEvents;
-import com.ning.billing.jaxrs.resources.JaxrsResource;
 import com.ning.billing.payment.provider.ExternalPaymentProviderPlugin;
-import com.ning.http.client.Response;
-
-import com.fasterxml.jackson.core.type.TypeReference;
-import com.google.common.collect.ImmutableMap;
 
 import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertNotNull;
 import static org.testng.Assert.assertNull;
-import static org.testng.Assert.assertTrue;
 
 public class TestInvoice extends TestJaxrsBase {
 
-    private static final Logger log = LoggerFactory.getLogger(TestInvoice.class);
-
     @Test(groups = "slow")
     public void testInvoiceOk() throws Exception {
         final DateTime initialDate = new DateTime(2012, 4, 25, 0, 3, 42, 0);
         clock.setDeltaFromReality(initialDate.getMillis() - clock.getUTCNow().getMillis());
 
-        final AccountJson accountJson = createAccountWithDefaultPaymentMethod("poupou", "qhddffrwe", "poupou@yahoo.com");
-        assertNotNull(accountJson);
-
-        final BundleJsonNoSubscriptions bundleJson = createBundle(accountJson.getAccountId(), "9967599");
-        assertNotNull(bundleJson);
-
-        final SubscriptionJsonNoEvents subscriptionJson = createSubscription(bundleJson.getBundleId(), "Shotgun", ProductCategory.BASE.toString(), BillingPeriod.MONTHLY.toString(), true);
-        assertNotNull(subscriptionJson);
-
-        // MOVE AFTER TRIAL
-        final Interval it = new Interval(clock.getUTCNow(), clock.getUTCNow().plusDays(30));
-        clock.addDeltaFromReality(it.toDurationMillis());
-        crappyWaitForLackOfProperSynchonization();
-
-        String uri = JaxrsResource.INVOICES_PATH;
-        final Map<String, String> queryParams = new HashMap<String, String>();
-        queryParams.put(JaxrsResource.QUERY_ACCOUNT_ID, accountJson.getAccountId());
+        final AccountJson accountJson = createAccountWithPMBundleAndSubscriptionAndWaitForFirstInvoice();
 
-        Response response = doGet(uri, queryParams, DEFAULT_HTTP_TIMEOUT_SEC);
-        Assert.assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
-        String baseJson = response.getResponseBody();
-        List<InvoiceJsonSimple> objFromJson = mapper.readValue(baseJson, new TypeReference<List<InvoiceJsonSimple>>() {});
-        assertNotNull(objFromJson);
-        log.info(baseJson);
-        assertEquals(objFromJson.size(), 2);
+        final List<InvoiceJsonSimple> invoices = getInvoicesForAccount(accountJson.getAccountId());
+        assertEquals(invoices.size(), 2);
 
         // Check we can retrieve an individual invoice
-        uri = JaxrsResource.INVOICES_PATH + "/" + objFromJson.get(0).getInvoiceId();
-        response = doGet(uri, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
-        Assert.assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
-        baseJson = response.getResponseBody();
-        final InvoiceJsonSimple firstInvoiceJson = mapper.readValue(baseJson, InvoiceJsonSimple.class);
-        assertNotNull(objFromJson);
-        assertEquals(firstInvoiceJson, objFromJson.get(0));
+        final InvoiceJsonSimple invoiceJsonSimple = invoices.get(0);
+        final InvoiceJsonSimple firstInvoiceJson = getInvoice(invoiceJsonSimple.getInvoiceId());
+        assertEquals(firstInvoiceJson, invoiceJsonSimple);
 
         // Then create a dryRun Invoice
         final DateTime futureDate = clock.getUTCNow().plusMonths(1).plusDays(3);
-        uri = JaxrsResource.INVOICES_PATH;
-        queryParams.put(JaxrsResource.QUERY_TARGET_DATE, futureDate.toString());
-        queryParams.put(JaxrsResource.QUERY_DRY_RUN, "true");
-        response = doPost(uri, null, queryParams, DEFAULT_HTTP_TIMEOUT_SEC);
-        Assert.assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
-        baseJson = response.getResponseBody();
-        final InvoiceJsonSimple futureInvoice = mapper.readValue(baseJson, InvoiceJsonSimple.class);
-        assertNotNull(futureInvoice);
-        log.info(baseJson);
+        createDryRunInvoice(accountJson.getAccountId(), futureDate);
 
         // The one more time with no DryRun
-        queryParams.remove(JaxrsResource.QUERY_DRY_RUN);
-        response = doPost(uri, null, queryParams, DEFAULT_HTTP_TIMEOUT_SEC);
-        Assert.assertEquals(response.getStatusCode(), Status.CREATED.getStatusCode());
-
-        final String location = response.getHeader("Location");
-        Assert.assertNotNull(location);
+        createInvoice(accountJson.getAccountId(), futureDate);
 
-        // Check again # invoices, should be 5 this time
-        uri = JaxrsResource.INVOICES_PATH;
-        response = doGet(uri, queryParams, DEFAULT_HTTP_TIMEOUT_SEC);
-        assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
-        baseJson = response.getResponseBody();
-        objFromJson = mapper.readValue(baseJson, new TypeReference<List<InvoiceJsonSimple>>() {});
-        assertNotNull(objFromJson);
-        log.info(baseJson);
-        assertEquals(objFromJson.size(), 3);
+        // Check again # invoices, should be 3 this time
+        final List<InvoiceJsonSimple> newInvoiceList = getInvoicesForAccount(accountJson.getAccountId());
+        assertEquals(newInvoiceList.size(), 3);
     }
 
     @Test(groups = "slow")
     public void testInvoicePayments() throws Exception {
         clock.setTime(new DateTime(2012, 4, 25, 0, 3, 42, 0));
 
-        final AccountJson accountJson = createAccountWithDefaultPaymentMethod("nohup", "shtergyhwF", "nohup@yahoo.com");
-        assertNotNull(accountJson);
-
-        final BundleJsonNoSubscriptions bundleJson = createBundle(accountJson.getAccountId(), "391193");
-        assertNotNull(bundleJson);
-
-        final SubscriptionJsonNoEvents subscriptionJson = createSubscription(bundleJson.getBundleId(), "Shotgun", ProductCategory.BASE.toString(), BillingPeriod.MONTHLY.toString(), true);
-        assertNotNull(subscriptionJson);
-
-        clock.addDays(31);
-
-        crappyWaitForLackOfProperSynchonization();
+        final AccountJson accountJson = createAccountWithPMBundleAndSubscriptionAndWaitForFirstInvoice();
 
-        final Map<String, String> queryParams = new HashMap<String, String>();
-        queryParams.put(JaxrsResource.QUERY_ACCOUNT_ID, accountJson.getAccountId());
-        String uri = JaxrsResource.INVOICES_PATH;
-        Response response = doGet(uri, queryParams, DEFAULT_HTTP_TIMEOUT_SEC);
-        assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
-        String baseJson = response.getResponseBody();
-        final List<InvoiceJsonSimple> invoices = mapper.readValue(baseJson, new TypeReference<List<InvoiceJsonSimple>>() {});
-        assertNotNull(invoices);
-        log.info(baseJson);
+        final List<InvoiceJsonSimple> invoices = getInvoicesForAccount(accountJson.getAccountId());
         assertEquals(invoices.size(), 2);
 
         for (final InvoiceJsonSimple cur : invoices) {
+            final List<PaymentJsonSimple> objFromJson = getPaymentsForInvoice(cur.getInvoiceId());
 
-            uri = JaxrsResource.INVOICES_PATH + "/" + cur.getInvoiceId() + "/" + JaxrsResource.PAYMENTS;
-            response = doGet(uri, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
-
-            Assert.assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
-            baseJson = response.getResponseBody();
-            final List<PaymentJsonSimple> objFromJson = mapper.readValue(baseJson, new TypeReference<List<PaymentJsonSimple>>() {});
-            assertNotNull(objFromJson);
-            log.info(cur.getAmount().toString());
             if (cur.getAmount().compareTo(BigDecimal.ZERO) == 0) {
                 assertEquals(objFromJson.size(), 0);
             } else {
                 assertEquals(objFromJson.size(), 1);
-                assertTrue(cur.getAmount().compareTo(objFromJson.get(0).getAmount()) == 0);
+                assertEquals(cur.getAmount().compareTo(objFromJson.get(0).getAmount()), 0);
             }
         }
     }
@@ -176,31 +85,11 @@ public class TestInvoice extends TestJaxrsBase {
     public void testInvoiceCreatePayment() throws Exception {
         clock.setTime(new DateTime(2012, 4, 25, 0, 3, 42, 0));
 
-        final AccountJson accountJson = createAccountWithDefaultPaymentMethod("nohup", "shtergyhwF", "nohup@yahoo.com");
-        assertNotNull(accountJson);
-
         // STEPH MISSING SET ACCOUNT AUTO_PAY_OFF
+        final AccountJson accountJson = createAccountWithPMBundleAndSubscriptionAndWaitForFirstInvoice();
 
-        final BundleJsonNoSubscriptions bundleJson = createBundle(accountJson.getAccountId(), "391193");
-        assertNotNull(bundleJson);
-
-        final SubscriptionJsonNoEvents subscriptionJson = createSubscription(bundleJson.getBundleId(), "Shotgun", ProductCategory.BASE.toString(), BillingPeriod.MONTHLY.toString(), true);
-        assertNotNull(subscriptionJson);
-
-        // MOVE AFTER TRIAL
-        clock.addDays(31);
-
-        crappyWaitForLackOfProperSynchonization();
-
-        final Map<String, String> queryParams = new HashMap<String, String>();
-        queryParams.put(JaxrsResource.QUERY_ACCOUNT_ID, accountJson.getAccountId());
-        String uri = JaxrsResource.INVOICES_PATH;
-        Response response = doGet(uri, queryParams, DEFAULT_HTTP_TIMEOUT_SEC);
-        assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
-        String baseJson = response.getResponseBody();
-        final List<InvoiceJsonSimple> invoices = mapper.readValue(baseJson, new TypeReference<List<InvoiceJsonSimple>>() {});
-        assertNotNull(invoices);
-        log.info(baseJson);
+        // Get the invoices
+        final List<InvoiceJsonSimple> invoices = getInvoicesForAccount(accountJson.getAccountId());
         assertEquals(invoices.size(), 2);
 
         for (final InvoiceJsonSimple cur : invoices) {
@@ -209,86 +98,38 @@ public class TestInvoice extends TestJaxrsBase {
             }
 
             // CREATE INSTA PAYMENT
-            final PaymentJsonSimple payment = new PaymentJsonSimple(cur.getAmount(), BigDecimal.ZERO, accountJson.getAccountId(),
-                                                                    cur.getInvoiceId(), null, null, null, null, 0, null, null, null, null, null, null, null);
-            final String postJson = mapper.writeValueAsString(payment);
-
-            uri = JaxrsResource.INVOICES_PATH + "/" + cur.getInvoiceId() + "/" + JaxrsResource.PAYMENTS;
-            doPost(uri, postJson, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
-
-            response = doGet(uri, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
-
-            Assert.assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
-            baseJson = response.getResponseBody();
-            final List<PaymentJsonSimple> objFromJson = mapper.readValue(baseJson, new TypeReference<List<PaymentJsonSimple>>() {});
-            assertNotNull(objFromJson);
-            log.info(cur.getAmount().toString());
+            final List<PaymentJsonSimple> objFromJson = createInstaPayment(accountJson, cur);
             assertEquals(objFromJson.size(), 1);
-            assertTrue(cur.getAmount().compareTo(objFromJson.get(0).getAmount()) == 0);
+            assertEquals(cur.getAmount().compareTo(objFromJson.get(0).getAmount()), 0);
         }
     }
 
     @Test(groups = "slow")
     public void testExternalPayment() throws Exception {
-        // Create an account with no payment method
-        final AccountJson accountJson = createAccount("eraahahildo", "sheqrgfhwe", "eraahahildo@yahoo.com");
-        assertNotNull(accountJson);
-
-        // Add a bundle, subscription and move the clock to get the first invoice
-        final BundleJsonNoSubscriptions bundleJson = createBundle(accountJson.getAccountId(), "317199");
-        assertNotNull(bundleJson);
-        final SubscriptionJsonNoEvents subscriptionJson = createSubscription(bundleJson.getBundleId(), "Shotgun", ProductCategory.BASE.toString(), BillingPeriod.MONTHLY.toString(), true);
-        assertNotNull(subscriptionJson);
-        clock.addMonths(1);
-        crappyWaitForLackOfProperSynchonization();
-
-        final String paymentsURI = JaxrsResource.ACCOUNTS_PATH + "/" + accountJson.getAccountId() + "/" + JaxrsResource.PAYMENTS;
+        final AccountJson accountJson = createAccountNoPMBundleAndSubscriptionAndWaitForFirstInvoice();
 
         // Verify we didn't get any payment
-        final Response noPaymentsResponse = doGet(paymentsURI, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
-        assertEquals(noPaymentsResponse.getStatusCode(), Status.OK.getStatusCode());
-        final String noPaymentsBaseJson = noPaymentsResponse.getResponseBody();
-        final List<PaymentJsonSimple> noPaymentsFromJson = mapper.readValue(noPaymentsBaseJson, new TypeReference<List<PaymentJsonSimple>>() {});
+        final List<PaymentJsonSimple> noPaymentsFromJson = getPaymentsForAccount(accountJson.getAccountId());
         assertEquals(noPaymentsFromJson.size(), 0);
 
         // Get the invoices
-        final Map<String, String> queryParams = new HashMap<String, String>();
-        queryParams.put(JaxrsResource.QUERY_ACCOUNT_ID, accountJson.getAccountId());
-        final String invoicesURI = JaxrsResource.INVOICES_PATH;
-        final Response invoicesResponse = doGet(invoicesURI, queryParams, DEFAULT_HTTP_TIMEOUT_SEC);
-        assertEquals(invoicesResponse.getStatusCode(), Status.OK.getStatusCode());
-        final String invoicesBaseJson = invoicesResponse.getResponseBody();
-        final List<InvoiceJsonSimple> invoices = mapper.readValue(invoicesBaseJson, new TypeReference<List<InvoiceJsonSimple>>() {});
-        assertNotNull(invoices);
+        final List<InvoiceJsonSimple> invoices = getInvoicesForAccount(accountJson.getAccountId());
         // 2 invoices but look for the non zero dollar one
         assertEquals(invoices.size(), 2);
         final String invoiceId = invoices.get(1).getInvoiceId();
 
         // Post an external payment
         final BigDecimal paidAmount = BigDecimal.TEN;
-        final PaymentJsonSimple payment = new PaymentJsonSimple(paidAmount, BigDecimal.ZERO, accountJson.getAccountId(),
-                                                                invoiceId, null, null, null, null, 0,
-                                                                null, null, null, null, null, null, null);
-        final String postJson = mapper.writeValueAsString(payment);
-        final String paymentURI = JaxrsResource.INVOICES_PATH + "/" + invoiceId + "/" + JaxrsResource.PAYMENTS;
-        final Response paymentResponse = doPost(paymentURI, postJson, ImmutableMap.<String, String>of("externalPayment", "true"), DEFAULT_HTTP_TIMEOUT_SEC);
-        assertEquals(paymentResponse.getStatusCode(), Status.CREATED.getStatusCode());
+        createExternalPayment(accountJson, invoiceId, paidAmount);
 
         // Verify we indeed got the payment
-        final Response paymentsResponse = doGet(paymentsURI, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
-        assertEquals(paymentsResponse.getStatusCode(), Status.OK.getStatusCode());
-        final String paymentsBaseJson = paymentsResponse.getResponseBody();
-        final List<PaymentJsonSimple> paymentsFromJson = mapper.readValue(paymentsBaseJson, new TypeReference<List<PaymentJsonSimple>>() {});
+        final List<PaymentJsonSimple> paymentsFromJson = getPaymentsForAccount(accountJson.getAccountId());
         assertEquals(paymentsFromJson.size(), 1);
         assertEquals(paymentsFromJson.get(0).getPaidAmount().compareTo(paidAmount), 0);
 
         // Check the PaymentMethod from paymentMethodId returned in the Payment object
         final String paymentMethodId = paymentsFromJson.get(0).getPaymentMethodId();
-        final String paymentMethodURI = JaxrsResource.PAYMENT_METHODS_PATH + "/" + paymentMethodId;
-
-        final Response paymentMethodResponse = doGet(paymentMethodURI, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
-        assertEquals(paymentMethodResponse.getStatusCode(), Status.OK.getStatusCode());
-        final PaymentMethodJson paymentMethodJson = mapper.readValue(paymentMethodResponse.getResponseBody(), PaymentMethodJson.class);
+        final PaymentMethodJson paymentMethodJson = getPaymentMethod(paymentMethodId);
         assertEquals(paymentMethodJson.getPaymentMethodId(), paymentMethodId);
         assertEquals(paymentMethodJson.getAccountId(), accountJson.getAccountId());
         assertEquals(paymentMethodJson.getPluginName(), ExternalPaymentProviderPlugin.PLUGIN_NAME);
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 aba8426..3e007b3 100644
--- a/server/src/test/java/com/ning/billing/jaxrs/TestJaxrsBase.java
+++ b/server/src/test/java/com/ning/billing/jaxrs/TestJaxrsBase.java
@@ -19,6 +19,7 @@ import javax.annotation.Nullable;
 import javax.ws.rs.core.Response.Status;
 import java.io.IOException;
 import java.lang.reflect.Method;
+import java.math.BigDecimal;
 import java.net.URL;
 import java.util.ArrayList;
 import java.util.EventListener;
@@ -31,6 +32,7 @@ import java.util.UUID;
 import java.util.concurrent.TimeUnit;
 
 import org.eclipse.jetty.servlet.FilterHolder;
+import org.joda.time.DateTime;
 import org.skife.config.ConfigurationObjectFactory;
 import org.skife.jdbi.v2.IDBI;
 import org.slf4j.Logger;
@@ -42,9 +44,11 @@ import org.testng.annotations.BeforeClass;
 import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.BeforeSuite;
 
+import com.fasterxml.jackson.core.type.TypeReference;
 import com.fasterxml.jackson.databind.ObjectMapper;
 import com.fasterxml.jackson.databind.SerializationFeature;
 import com.fasterxml.jackson.datatype.joda.JodaModule;
+import com.google.common.collect.ImmutableMap;
 import com.google.inject.Module;
 import com.ning.billing.KillbillTestSuiteWithEmbeddedDB;
 import com.ning.billing.account.api.BillCycleDay;
@@ -53,7 +57,9 @@ import com.ning.billing.analytics.setup.AnalyticsModule;
 import com.ning.billing.api.TestApiListener;
 import com.ning.billing.beatrix.glue.BeatrixModule;
 import com.ning.billing.beatrix.integration.TestIntegration;
+import com.ning.billing.catalog.api.BillingPeriod;
 import com.ning.billing.catalog.api.PriceListSet;
+import com.ning.billing.catalog.api.ProductCategory;
 import com.ning.billing.catalog.glue.CatalogModule;
 import com.ning.billing.config.PaymentConfig;
 import com.ning.billing.dbi.DBIProvider;
@@ -66,6 +72,8 @@ import com.ning.billing.invoice.notification.NullInvoiceNotifier;
 import com.ning.billing.jaxrs.json.AccountJson;
 import com.ning.billing.jaxrs.json.BillCycleDayJson;
 import com.ning.billing.jaxrs.json.BundleJsonNoSubscriptions;
+import com.ning.billing.jaxrs.json.InvoiceJsonSimple;
+import com.ning.billing.jaxrs.json.PaymentJsonSimple;
 import com.ning.billing.jaxrs.json.PaymentMethodJson;
 import com.ning.billing.jaxrs.json.PaymentMethodJson.PaymentMethodPluginDetailJson;
 import com.ning.billing.jaxrs.json.PaymentMethodJson.PaymentMethodProperties;
@@ -98,6 +106,7 @@ import com.ning.http.client.Response;
 import com.ning.jetty.core.CoreConfig;
 import com.ning.jetty.core.server.HttpServer;
 
+import static org.testng.Assert.assertEquals;
 import static org.testng.Assert.assertNotNull;
 
 public class TestJaxrsBase extends ServerTestSuiteWithEmbeddedDB {
@@ -326,6 +335,10 @@ public class TestJaxrsBase extends ServerTestSuiteWithEmbeddedDB {
         return new PaymentMethodJson(null, accountId, true, PLUGIN_NAME, info);
     }
 
+    //
+    // ACCOUNT UTILITIES
+    //
+
     protected AccountJson createAccountWithDefaultPaymentMethod(final String name, final String key, final String email) throws Exception {
 
         final AccountJson input = createAccount(name, key, email);
@@ -414,6 +427,164 @@ public class TestJaxrsBase extends ServerTestSuiteWithEmbeddedDB {
         return objFromJson;
     }
 
+    //
+    // INVOICE UTILITIES
+    //
+
+    protected AccountJson createAccountWithPMBundleAndSubscriptionAndWaitForFirstInvoice() throws Exception {
+        final AccountJson accountJson = createAccountWithDefaultPaymentMethod("nohup", "shtergyhwF", "nohup@yahoo.com");
+        assertNotNull(accountJson);
+
+        // Add a bundle, subscription and move the clock to get the first invoice
+        final BundleJsonNoSubscriptions bundleJson = createBundle(accountJson.getAccountId(), "391193");
+        assertNotNull(bundleJson);
+        final SubscriptionJsonNoEvents subscriptionJson = createSubscription(bundleJson.getBundleId(), "Shotgun", ProductCategory.BASE.toString(), BillingPeriod.MONTHLY.toString(), true);
+        assertNotNull(subscriptionJson);
+        clock.addMonths(1);
+        crappyWaitForLackOfProperSynchonization();
+
+        return accountJson;
+    }
+
+    protected AccountJson createAccountNoPMBundleAndSubscriptionAndWaitForFirstInvoice() throws Exception {
+        // Create an account with no payment method
+        final AccountJson accountJson = createAccount("eraahahildo", "sheqrgfhwe", "eraahahildo@yahoo.com");
+        assertNotNull(accountJson);
+
+        // Add a bundle, subscription and move the clock to get the first invoice
+        final BundleJsonNoSubscriptions bundleJson = createBundle(accountJson.getAccountId(), "317199");
+        assertNotNull(bundleJson);
+        final SubscriptionJsonNoEvents subscriptionJson = createSubscription(bundleJson.getBundleId(), "Shotgun", ProductCategory.BASE.toString(), BillingPeriod.MONTHLY.toString(), true);
+        assertNotNull(subscriptionJson);
+        clock.addMonths(1);
+        crappyWaitForLackOfProperSynchonization();
+
+        // No payment will be triggered as the account doesn't have a payment method
+
+        return accountJson;
+    }
+
+    protected InvoiceJsonSimple getInvoice(final String invoiceId) throws IOException {
+        final String uri = JaxrsResource.INVOICES_PATH + "/" + invoiceId;
+        final Response response = doGet(uri, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
+        Assert.assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
+        final String baseJson = response.getResponseBody();
+
+        final InvoiceJsonSimple firstInvoiceJson = mapper.readValue(baseJson, InvoiceJsonSimple.class);
+        assertNotNull(firstInvoiceJson);
+
+        return firstInvoiceJson;
+    }
+
+    protected List<InvoiceJsonSimple> getInvoicesForAccount(final String accountId) throws IOException {
+        final Map<String, String> queryParams = new HashMap<String, String>();
+        queryParams.put(JaxrsResource.QUERY_ACCOUNT_ID, accountId);
+        final String invoicesURI = JaxrsResource.INVOICES_PATH;
+        final Response invoicesResponse = doGet(invoicesURI, queryParams, DEFAULT_HTTP_TIMEOUT_SEC);
+        assertEquals(invoicesResponse.getStatusCode(), Status.OK.getStatusCode());
+        final String invoicesBaseJson = invoicesResponse.getResponseBody();
+
+        final List<InvoiceJsonSimple> invoices = mapper.readValue(invoicesBaseJson, new TypeReference<List<InvoiceJsonSimple>>() {});
+        assertNotNull(invoices);
+
+        return invoices;
+    }
+
+    protected InvoiceJsonSimple createDryRunInvoice(final String accountId, final DateTime futureDate) throws IOException {
+        final String uri = JaxrsResource.INVOICES_PATH;
+
+        final Map<String, String> queryParams = new HashMap<String, String>();
+        queryParams.put(JaxrsResource.QUERY_ACCOUNT_ID, accountId);
+        queryParams.put(JaxrsResource.QUERY_TARGET_DATE, futureDate.toString());
+        queryParams.put(JaxrsResource.QUERY_DRY_RUN, "true");
+
+        final Response response = doPost(uri, null, queryParams, DEFAULT_HTTP_TIMEOUT_SEC);
+        Assert.assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
+
+        final String baseJson = response.getResponseBody();
+        final InvoiceJsonSimple futureInvoice = mapper.readValue(baseJson, InvoiceJsonSimple.class);
+        assertNotNull(futureInvoice);
+
+        return futureInvoice;
+    }
+
+    protected void createInvoice(final String accountId, final DateTime futureDate) throws IOException {
+        final String uri = JaxrsResource.INVOICES_PATH;
+
+        final Map<String, String> queryParams = new HashMap<String, String>();
+        queryParams.put(JaxrsResource.QUERY_ACCOUNT_ID, accountId);
+        queryParams.put(JaxrsResource.QUERY_TARGET_DATE, futureDate.toString());
+
+        final Response response = doPost(uri, null, queryParams, DEFAULT_HTTP_TIMEOUT_SEC);
+        Assert.assertEquals(response.getStatusCode(), Status.CREATED.getStatusCode());
+
+        final String location = response.getHeader("Location");
+        Assert.assertNotNull(location);
+    }
+
+    //
+    // PAYMENT UTILITIES
+    //
+
+    protected PaymentMethodJson getPaymentMethod(final String paymentMethodId) throws IOException {
+        final String paymentMethodURI = JaxrsResource.PAYMENT_METHODS_PATH + "/" + paymentMethodId;
+        final Response paymentMethodResponse = doGet(paymentMethodURI, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
+        assertEquals(paymentMethodResponse.getStatusCode(), Status.OK.getStatusCode());
+
+        final PaymentMethodJson paymentMethodJson = mapper.readValue(paymentMethodResponse.getResponseBody(), PaymentMethodJson.class);
+        assertNotNull(paymentMethodJson);
+
+        return paymentMethodJson;
+    }
+
+    protected List<PaymentJsonSimple> getPaymentsForAccount(final String accountId) throws IOException {
+        final String paymentsURI = JaxrsResource.ACCOUNTS_PATH + "/" + accountId + "/" + JaxrsResource.PAYMENTS;
+        final Response paymentsResponse = doGet(paymentsURI, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
+        assertEquals(paymentsResponse.getStatusCode(), Status.OK.getStatusCode());
+        final String paymentsBaseJson = paymentsResponse.getResponseBody();
+
+        final List<PaymentJsonSimple> paymentJsonSimples = mapper.readValue(paymentsBaseJson, new TypeReference<List<PaymentJsonSimple>>() {});
+        assertNotNull(paymentJsonSimples);
+
+        return paymentJsonSimples;
+    }
+
+    protected List<PaymentJsonSimple> getPaymentsForInvoice(final String invoiceId) throws IOException {
+        final String uri = JaxrsResource.INVOICES_PATH + "/" + invoiceId + "/" + JaxrsResource.PAYMENTS;
+        final Response response = doGet(uri, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
+
+        Assert.assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
+        final String baseJson = response.getResponseBody();
+        final List<PaymentJsonSimple> objFromJson = mapper.readValue(baseJson, new TypeReference<List<PaymentJsonSimple>>() {});
+        assertNotNull(objFromJson);
+
+        return objFromJson;
+    }
+
+    protected List<PaymentJsonSimple> createInstaPayment(final AccountJson accountJson, final InvoiceJsonSimple invoice) throws IOException {
+        final PaymentJsonSimple payment = new PaymentJsonSimple(invoice.getAmount(), BigDecimal.ZERO, accountJson.getAccountId(),
+                                                                invoice.getInvoiceId(), null, null, null, null, 0, null, null, null, null, null, null, null);
+        final String postJson = mapper.writeValueAsString(payment);
+
+        final String uri = JaxrsResource.INVOICES_PATH + "/" + invoice.getInvoiceId() + "/" + JaxrsResource.PAYMENTS;
+        doPost(uri, postJson, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
+
+        return getPaymentsForInvoice(invoice.getInvoiceId());
+    }
+
+    protected List<PaymentJsonSimple> createExternalPayment(final AccountJson accountJson, final String invoiceId, final BigDecimal paidAmount) throws IOException {
+        final PaymentJsonSimple payment = new PaymentJsonSimple(paidAmount, BigDecimal.ZERO, accountJson.getAccountId(),
+                                                                invoiceId, null, null, null, null, 0,
+                                                                null, null, null, null, null, null, null);
+        final String postJson = mapper.writeValueAsString(payment);
+
+        final String paymentURI = JaxrsResource.INVOICES_PATH + "/" + invoiceId + "/" + JaxrsResource.PAYMENTS;
+        final Response paymentResponse = doPost(paymentURI, postJson, ImmutableMap.<String, String>of("externalPayment", "true"), DEFAULT_HTTP_TIMEOUT_SEC);
+        assertEquals(paymentResponse.getStatusCode(), Status.CREATED.getStatusCode());
+
+        return getPaymentsForInvoice(invoiceId);
+    }
+
     protected Map<String, String> getQueryParamsForCallCompletion(final String timeoutSec) {
         final Map<String, String> queryParams = new HashMap<String, String>();
         queryParams.put(JaxrsResource.QUERY_CALL_COMPLETION, "true");