killbill-aplcache

account: fix jdbi exception in AuditedAccountEmailDao AuditedCollectionDaoBase

8/30/2012 2:49:38 PM

Details

diff --git a/account/src/main/java/com/ning/billing/account/dao/AuditedAccountEmailDao.java b/account/src/main/java/com/ning/billing/account/dao/AuditedAccountEmailDao.java
index f5f50ed..ef66d03 100644
--- a/account/src/main/java/com/ning/billing/account/dao/AuditedAccountEmailDao.java
+++ b/account/src/main/java/com/ning/billing/account/dao/AuditedAccountEmailDao.java
@@ -30,6 +30,7 @@ import org.skife.jdbi.v2.sqlobject.mixins.Transmogrifier;
 import com.google.common.collect.ImmutableList;
 import com.google.inject.Inject;
 import com.ning.billing.account.api.AccountEmail;
+import com.ning.billing.account.api.DefaultAccountEmail;
 import com.ning.billing.util.callcontext.CallContext;
 import com.ning.billing.util.dao.AuditedCollectionDaoBase;
 import com.ning.billing.util.dao.ObjectType;
@@ -71,7 +72,10 @@ public class AuditedAccountEmailDao extends AuditedCollectionDaoBase<AccountEmai
                 for (final AccountEmail currentEmail : currentEmails) {
                     newEmails.put(currentEmail.getEmail(), currentEmail);
                 }
-                newEmails.put(email.getEmail(), email);
+                // TODO Note the hack here... saveEntitiesFromTransaction() works by comparing objects in sets, so we
+                // have to use DefaultAccountEmail instances (email is likely to be an inner class from AccountEmailJson
+                // here and will confuse AuditedCollectionDaoBase).
+                newEmails.put(email.getEmail(), new DefaultAccountEmail(email.getAccountId(), email.getEmail()));
 
                 saveEntitiesFromTransaction(getSqlDao(), accountId, ObjectType.ACCOUNT_EMAIL,
                                             ImmutableList.<AccountEmail>copyOf(newEmails.values()), context);
diff --git a/account/src/test/java/com/ning/billing/account/dao/TestAccountDao.java b/account/src/test/java/com/ning/billing/account/dao/TestAccountDao.java
index be8abc4..82c1a62 100644
--- a/account/src/test/java/com/ning/billing/account/dao/TestAccountDao.java
+++ b/account/src/test/java/com/ning/billing/account/dao/TestAccountDao.java
@@ -412,6 +412,19 @@ public class TestAccountDao extends AccountDaoTestBase {
     }
 
     @Test(groups = "slow")
+    public void testHandleDuplicateEmails() {
+        final UUID accountId = UUID.randomUUID();
+        final AccountEmail email = new DefaultAccountEmail(accountId, "test@gmail.com");
+        Assert.assertEquals(accountEmailDao.getEmails(accountId).size(), 0);
+
+        accountEmailDao.addEmail(accountId, email, context);
+        Assert.assertEquals(accountEmailDao.getEmails(accountId).size(), 1);
+
+        accountEmailDao.addEmail(accountId, email, context);
+        Assert.assertEquals(accountEmailDao.getEmails(accountId).size(), 1);
+    }
+
+    @Test(groups = "slow")
     public void testAccountEmail() {
         List<AccountEmail> emails = new ArrayList<AccountEmail>();
 
diff --git a/server/src/test/java/com/ning/billing/jaxrs/TestAccountEmail.java b/server/src/test/java/com/ning/billing/jaxrs/TestAccountEmail.java
index fccecbf..581053a 100644
--- a/server/src/test/java/com/ning/billing/jaxrs/TestAccountEmail.java
+++ b/server/src/test/java/com/ning/billing/jaxrs/TestAccountEmail.java
@@ -22,15 +22,11 @@ import java.util.UUID;
 import org.testng.Assert;
 import org.testng.annotations.Test;
 
-import com.fasterxml.jackson.core.type.TypeReference;
 import com.ning.billing.jaxrs.json.AccountEmailJson;
 import com.ning.billing.jaxrs.json.AccountJson;
-import com.ning.billing.jaxrs.resources.JaxrsResource;
-import com.ning.http.client.Response;
-
-import static org.testng.Assert.assertEquals;
 
 public class TestAccountEmail extends TestJaxrsBase {
+
     @Test(groups = "slow")
     public void testAddAndRemoveAccountEmail() throws Exception {
         final AccountJson input = createAccount(UUID.randomUUID().toString(), UUID.randomUUID().toString(), UUID.randomUUID().toString());
@@ -41,36 +37,24 @@ public class TestAccountEmail extends TestJaxrsBase {
         final AccountEmailJson accountEmailJson1 = new AccountEmailJson(accountId, email1);
         final AccountEmailJson accountEmailJson2 = new AccountEmailJson(accountId, email2);
 
-        final String baseUri = JaxrsResource.ACCOUNTS_PATH + "/" + accountId + "/" + JaxrsResource.EMAILS;
-
         // Verify the initial state
-        final Response firstResponse = doGet(baseUri, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
-        Assert.assertEquals(firstResponse.getStatusCode(), javax.ws.rs.core.Response.Status.OK.getStatusCode());
-        final List<AccountEmailJson> firstEmails = mapper.readValue(firstResponse.getResponseBody(), new TypeReference<List<AccountEmailJson>>() {});
+        final List<AccountEmailJson> firstEmails = getEmailsForAccount(accountId);
         Assert.assertEquals(firstEmails.size(), 0);
 
         // Add an email
-        final String firstEmailString = mapper.writeValueAsString(accountEmailJson1);
-        final Response secondResponse = doPost(baseUri, firstEmailString, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
-        assertEquals(secondResponse.getStatusCode(), javax.ws.rs.core.Response.Status.CREATED.getStatusCode());
+        addEmailToAccount(accountId, accountEmailJson1);
 
         // Verify we can retrieve it
-        final Response thirdResponse = doGet(baseUri, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
-        Assert.assertEquals(thirdResponse.getStatusCode(), javax.ws.rs.core.Response.Status.OK.getStatusCode());
-        final List<AccountEmailJson> secondEmails = mapper.readValue(thirdResponse.getResponseBody(), new TypeReference<List<AccountEmailJson>>() {});
+        final List<AccountEmailJson> secondEmails = getEmailsForAccount(accountId);
         Assert.assertEquals(secondEmails.size(), 1);
         Assert.assertEquals(secondEmails.get(0).getAccountId(), accountId);
         Assert.assertEquals(secondEmails.get(0).getEmail(), email1);
 
         // Add another email
-        final String secondEmailString = mapper.writeValueAsString(accountEmailJson2);
-        final Response thridResponse = doPost(baseUri, secondEmailString, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
-        assertEquals(thridResponse.getStatusCode(), javax.ws.rs.core.Response.Status.CREATED.getStatusCode());
+        addEmailToAccount(accountId, accountEmailJson2);
 
         // Verify we can retrieve both
-        final Response fourthResponse = doGet(baseUri, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
-        Assert.assertEquals(fourthResponse.getStatusCode(), javax.ws.rs.core.Response.Status.OK.getStatusCode());
-        final List<AccountEmailJson> thirdEmails = mapper.readValue(fourthResponse.getResponseBody(), new TypeReference<List<AccountEmailJson>>() {});
+        final List<AccountEmailJson> thirdEmails = getEmailsForAccount(accountId);
         Assert.assertEquals(thirdEmails.size(), 2);
         Assert.assertEquals(thirdEmails.get(0).getAccountId(), accountId);
         Assert.assertEquals(thirdEmails.get(1).getAccountId(), accountId);
@@ -78,15 +62,16 @@ public class TestAccountEmail extends TestJaxrsBase {
         Assert.assertTrue(thirdEmails.get(1).getEmail().equals(email1) || thirdEmails.get(1).getEmail().equals(email2));
 
         // Delete the first email
-        final Response fifthResponse = doDelete(baseUri + "/" + email1, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
-        assertEquals(fifthResponse.getStatusCode(), javax.ws.rs.core.Response.Status.OK.getStatusCode());
+        removeEmailFromAccount(accountId, email1);
 
         // Verify it has been deleted
-        final Response sixthResponse = doGet(baseUri, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
-        Assert.assertEquals(sixthResponse.getStatusCode(), javax.ws.rs.core.Response.Status.OK.getStatusCode());
-        final List<AccountEmailJson> fourthEmails = mapper.readValue(sixthResponse.getResponseBody(), new TypeReference<List<AccountEmailJson>>() {});
+        final List<AccountEmailJson> fourthEmails = getEmailsForAccount(accountId);
         Assert.assertEquals(fourthEmails.size(), 1);
         Assert.assertEquals(fourthEmails.get(0).getAccountId(), accountId);
         Assert.assertEquals(fourthEmails.get(0).getEmail(), email2);
+
+        // Try to add the same email
+        addEmailToAccount(accountId, accountEmailJson2);
+        Assert.assertEquals(getEmailsForAccount(accountId), fourthEmails);
     }
 }
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 cd2cf90..f1ae5b0 100644
--- a/server/src/test/java/com/ning/billing/jaxrs/TestJaxrsBase.java
+++ b/server/src/test/java/com/ning/billing/jaxrs/TestJaxrsBase.java
@@ -65,6 +65,7 @@ import com.ning.billing.entitlement.glue.DefaultEntitlementModule;
 import com.ning.billing.invoice.api.InvoiceNotifier;
 import com.ning.billing.invoice.glue.DefaultInvoiceModule;
 import com.ning.billing.invoice.notification.NullInvoiceNotifier;
+import com.ning.billing.jaxrs.json.AccountEmailJson;
 import com.ning.billing.jaxrs.json.AccountJson;
 import com.ning.billing.jaxrs.json.AccountTimelineJson;
 import com.ning.billing.jaxrs.json.BillCycleDayJson;
@@ -459,6 +460,30 @@ public class TestJaxrsBase extends ServerTestSuiteWithEmbeddedDB {
         return objFromJson;
     }
 
+    protected List<AccountEmailJson> getEmailsForAccount(final String accountId) throws Exception {
+        final String uri = JaxrsResource.ACCOUNTS_PATH + "/" + accountId + "/" + JaxrsResource.EMAILS;
+
+        final Response response = doGet(uri, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
+        Assert.assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
+
+        return mapper.readValue(response.getResponseBody(), new TypeReference<List<AccountEmailJson>>() {});
+    }
+
+    protected void addEmailToAccount(final String accountId, final AccountEmailJson email) throws Exception {
+        final String uri = JaxrsResource.ACCOUNTS_PATH + "/" + accountId + "/" + JaxrsResource.EMAILS;
+
+        final String emailString = mapper.writeValueAsString(email);
+        final Response response = doPost(uri, emailString, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
+        assertEquals(response.getStatusCode(), Status.CREATED.getStatusCode());
+    }
+
+    protected void removeEmailFromAccount(final String accountId, final String email) throws Exception {
+        final String uri = JaxrsResource.ACCOUNTS_PATH + "/" + accountId + "/" + JaxrsResource.EMAILS;
+
+        final Response fifthResponse = doDelete(uri + "/" + email, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
+        assertEquals(fifthResponse.getStatusCode(), javax.ws.rs.core.Response.Status.OK.getStatusCode());
+    }
+
     protected BundleJsonNoSubscriptions createBundle(final String accountId, final String key) throws Exception {
         final BundleJsonNoSubscriptions input = new BundleJsonNoSubscriptions(null, accountId, key, null, null);
         String baseJson = mapper.writeValueAsString(input);