summaryrefslogtreecommitdiff
path: root/src/test
diff options
context:
space:
mode:
Diffstat (limited to 'src/test')
-rw-r--r--src/test/java/com/p4square/ccbapi/CCBAPIClientTest.java229
-rw-r--r--src/test/java/com/p4square/ccbapi/CCBXmlBinderTest.java100
-rw-r--r--src/test/java/com/p4square/ccbapi/model/GetCustomFieldLabelsResponseTest.java39
-rw-r--r--src/test/java/com/p4square/ccbapi/model/GetIndividualProfilesResponseTest.java60
-rw-r--r--src/test/java/com/p4square/ccbapi/model/XmlBinderTestBase.java39
-rw-r--r--src/test/resources/com/p4square/ccbapi/ccb_malformed_response_no_entity.xml8
-rw-r--r--src/test/resources/com/p4square/ccbapi/ccb_malformed_xml.xml9
-rw-r--r--src/test/resources/com/p4square/ccbapi/model/ccb_custom_field_labels_response.xml150
-rw-r--r--src/test/resources/com/p4square/ccbapi/model/ccb_error_response.xml13
-rw-r--r--src/test/resources/com/p4square/ccbapi/model/ccb_individual_profile_response.xml149
10 files changed, 796 insertions, 0 deletions
diff --git a/src/test/java/com/p4square/ccbapi/CCBAPIClientTest.java b/src/test/java/com/p4square/ccbapi/CCBAPIClientTest.java
new file mode 100644
index 0000000..e722e9a
--- /dev/null
+++ b/src/test/java/com/p4square/ccbapi/CCBAPIClientTest.java
@@ -0,0 +1,229 @@
+package com.p4square.ccbapi;
+
+import com.p4square.ccbapi.exception.CCBErrorResponseException;
+import com.p4square.ccbapi.exception.CCBRetryableErrorException;
+import com.p4square.ccbapi.model.GetCustomFieldLabelsResponse;
+import com.p4square.ccbapi.model.GetIndividualProfilesRequest;
+import com.p4square.ccbapi.model.GetIndividualProfilesResponse;
+import org.junit.Before;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URI;
+import java.time.LocalDate;
+import java.util.Collections;
+import java.util.Map;
+
+import org.easymock.EasyMock;
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+/**
+ * Tests for the CCBAPIClient.
+ */
+public class CCBAPIClientTest {
+
+ private HTTPInterface mockHttpClient;
+ private CCBAPIClient client;
+
+ @Before
+ public void setUp() throws Exception {
+ mockHttpClient = EasyMock.mock(HTTPInterface.class);
+ client = new TestCCBAPIClient(new URI("https://localhost:8080/api.php"), mockHttpClient);
+ }
+
+ @Test
+ public void testClose() throws Exception {
+ // Set expectation.
+ mockHttpClient.close();
+ EasyMock.replay(mockHttpClient);
+
+ // Test close.
+ client.close();
+
+ // Verify results.
+ EasyMock.verify(mockHttpClient);
+ }
+
+ @Test
+ public void testGetCustomFieldLabelsSuccess() throws Exception {
+ // Set expectation.
+ URI expectedURI = new URI("https://localhost:8080/api.php?srv=custom_field_labels");
+ InputStream is = getClass().getResourceAsStream("model/ccb_custom_field_labels_response.xml");
+ EasyMock.expect(mockHttpClient.sendPostRequest(expectedURI, Collections.<String, String>emptyMap()))
+ .andReturn(is);
+ EasyMock.replay(mockHttpClient);
+
+ // Test custom_field_labels.
+ GetCustomFieldLabelsResponse response = client.getCustomFieldLabels();
+
+ // Verify results.
+ EasyMock.verify(mockHttpClient);
+ assertNull(response.getErrors());
+ assertEquals(27, response.getCustomFields().size());
+ assertEquals("udf_ind_text_1", response.getCustomFields().get(0).getName());
+ assertEquals("Favorite Movie", response.getCustomFields().get(0).getLabel());
+ assertEquals(false, response.getCustomFields().get(0).isAdminOnly());
+ }
+
+ @Test
+ public void testGetCustomFieldLabelsError() throws Exception {
+ // Set expectation.
+ URI expectedURI = new URI("https://localhost:8080/api.php?srv=custom_field_labels");
+ InputStream is = getClass().getResourceAsStream("model/ccb_error_response.xml");
+ EasyMock.expect(mockHttpClient.sendPostRequest(expectedURI, Collections.<String, String>emptyMap()))
+ .andReturn(is);
+ EasyMock.replay(mockHttpClient);
+
+ try {
+ // Call getCustomFieldLabels() and expect an exception.
+ client.getCustomFieldLabels();
+ fail("No exception thrown.");
+
+ } catch (CCBErrorResponseException e) {
+ // Assert error was received.
+ EasyMock.verify(mockHttpClient);
+ assertEquals(1, e.getErrors().size());
+ assertEquals(2, e.getErrors().get(0).getNumber());
+ }
+ }
+
+ @Test(expected = CCBRetryableErrorException.class)
+ public void testGetCustomFieldLabelsTimeout() throws Exception {
+ // Setup mocks.
+ EasyMock.expect(mockHttpClient.sendPostRequest(EasyMock.anyObject(URI.class), EasyMock.anyObject(Map.class)))
+ .andThrow(new CCBRetryableErrorException("Retryable error"));
+ EasyMock.replay(mockHttpClient);
+
+ // Call getCustomFieldLabels() and expect an exception.
+ client.getCustomFieldLabels();
+ }
+
+ @Test(expected = IOException.class)
+ public void testGetCustomFieldLabelsException() throws Exception {
+ // Setup mocks.
+ EasyMock.expect(mockHttpClient.sendPostRequest(EasyMock.anyObject(URI.class), EasyMock.anyObject(Map.class)))
+ .andThrow(new IOException());
+ EasyMock.replay(mockHttpClient);
+
+ // Call getCustomFieldLabels() and expect an exception.
+ client.getCustomFieldLabels();
+ }
+
+ @Test
+ public void testGetIndividualProfilesById() throws Exception {
+ // Set expectation.
+ URI expectedURI = new URI("https://localhost:8080/api.php?srv=individual_profile_from_id&individual_id=48");
+ InputStream is = getClass().getResourceAsStream("model/ccb_individual_profile_response.xml");
+ EasyMock.expect(mockHttpClient.sendPostRequest(expectedURI, Collections.<String, String>emptyMap()))
+ .andReturn(is);
+ EasyMock.replay(mockHttpClient);
+
+ // Test individual_profile_from_id.
+ GetIndividualProfilesRequest request = new GetIndividualProfilesRequest().withIndividualId(48);
+ GetIndividualProfilesResponse response = client.getIndividualProfiles(request);
+
+ // Verify results.
+ EasyMock.verify(mockHttpClient);
+ assertNull(response.getErrors());
+ assertEquals(1, response.getIndividuals().size());
+ assertEquals(48, response.getIndividuals().get(0).getId());
+ }
+
+ @Test
+ public void testGetIndividualProfilesByLogin() throws Exception {
+ // Set expectation.
+ URI expectedURI = new URI("https://localhost:8080/api.php?"
+ + "srv=individual_profile_from_login_password&password=pass&login=user");
+ InputStream is = getClass().getResourceAsStream("model/ccb_individual_profile_response.xml");
+ EasyMock.expect(mockHttpClient.sendPostRequest(expectedURI, Collections.<String, String>emptyMap()))
+ .andReturn(is);
+ EasyMock.replay(mockHttpClient);
+
+ // Test individual_profile_from_login_password.
+ GetIndividualProfilesRequest request = new GetIndividualProfilesRequest().withLoginPassword("user", "pass");
+ GetIndividualProfilesResponse response = client.getIndividualProfiles(request);
+
+ // Verify results.
+ EasyMock.verify(mockHttpClient);
+ assertNull(response.getErrors());
+ assertEquals(1, response.getIndividuals().size());
+ assertEquals(48, response.getIndividuals().get(0).getId());
+ }
+
+ @Test
+ public void testGetIndividualProfilesByRoutingAndAccount() throws Exception {
+ // Set expectation.
+ URI expectedURI = new URI("https://localhost:8080/api.php?"
+ + "srv=individual_profile_from_micr&account_number=4567&routing_number=1234");
+ InputStream is = getClass().getResourceAsStream("model/ccb_individual_profile_response.xml");
+ EasyMock.expect(mockHttpClient.sendPostRequest(expectedURI, Collections.<String, String>emptyMap()))
+ .andReturn(is);
+ EasyMock.replay(mockHttpClient);
+
+ // Test individual_profile_from_micr.
+ GetIndividualProfilesRequest request = new GetIndividualProfilesRequest().withMICR("1234", "4567");
+ GetIndividualProfilesResponse response = client.getIndividualProfiles(request);
+
+ // Verify results.
+ EasyMock.verify(mockHttpClient);
+ assertNull(response.getErrors());
+ assertEquals(1, response.getIndividuals().size());
+ assertEquals(48, response.getIndividuals().get(0).getId());
+ }
+
+ @Test
+ public void testGetAllIndividualProfiles() throws Exception {
+ // Set expectation.
+ URI expectedURI = new URI("https://localhost:8080/api.php?srv=individual_profiles");
+ InputStream is = getClass().getResourceAsStream("model/ccb_individual_profile_response.xml");
+ EasyMock.expect(mockHttpClient.sendPostRequest(expectedURI, Collections.<String, String>emptyMap()))
+ .andReturn(is);
+ EasyMock.replay(mockHttpClient);
+
+ // Test individual_profiles without any options.
+ GetIndividualProfilesRequest request = new GetIndividualProfilesRequest();
+ GetIndividualProfilesResponse response = client.getIndividualProfiles(request);
+
+ // Verify results.
+ EasyMock.verify(mockHttpClient);
+ assertNull(response.getErrors());
+ assertEquals(1, response.getIndividuals().size());
+ assertEquals(48, response.getIndividuals().get(0).getId());
+ }
+
+ @Test
+ public void testGetAllIndividualProfilesWithOptions() throws Exception {
+ // Set expectation.
+ URI expectedURI = new URI("https://localhost:8080/api.php?srv=individual_profiles"
+ + "&per_page=15&include_inactive=true&modified_since=2016-03-19&page=5");
+ InputStream is = getClass().getResourceAsStream("model/ccb_individual_profile_response.xml");
+ EasyMock.expect(mockHttpClient.sendPostRequest(expectedURI, Collections.<String, String>emptyMap()))
+ .andReturn(is);
+ EasyMock.replay(mockHttpClient);
+
+ // Test individual_profiles with all the options.
+ GetIndividualProfilesRequest request = new GetIndividualProfilesRequest()
+ .withModifiedSince(LocalDate.parse("2016-03-19"))
+ .withIncludeInactive(true)
+ .withPage(5)
+ .withPerPage(15);
+ GetIndividualProfilesResponse response = client.getIndividualProfiles(request);
+
+ // Verify results.
+ EasyMock.verify(mockHttpClient);
+ assertNull(response.getErrors());
+ assertEquals(1, response.getIndividuals().size());
+ assertEquals(48, response.getIndividuals().get(0).getId());
+ }
+
+ /**
+ * Simple extension of CCBAPIClient to swap out the HTTPInterface with a mock.
+ */
+ private final class TestCCBAPIClient extends CCBAPIClient {
+ public TestCCBAPIClient(final URI apiUri, final HTTPInterface mockHttpClient) {
+ super(apiUri, mockHttpClient);
+ }
+ }
+} \ No newline at end of file
diff --git a/src/test/java/com/p4square/ccbapi/CCBXmlBinderTest.java b/src/test/java/com/p4square/ccbapi/CCBXmlBinderTest.java
new file mode 100644
index 0000000..184777a
--- /dev/null
+++ b/src/test/java/com/p4square/ccbapi/CCBXmlBinderTest.java
@@ -0,0 +1,100 @@
+package com.p4square.ccbapi;
+
+import com.p4square.ccbapi.exception.CCBParseException;
+import com.p4square.ccbapi.model.*;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.io.InputStream;
+
+import static org.junit.Assert.*;
+
+/**
+ * Tests for the CCBXmlBinder.
+ */
+public class CCBXmlBinderTest {
+
+ private CCBXmlBinder binder;
+
+ @Before
+ public void setUp() {
+ binder = new CCBXmlBinder();
+ }
+
+ /**
+ * Expect CCBXmlBinder to throw an exception if there is no response element.
+ */
+ @Test(expected = CCBParseException.class)
+ public void testMalformedNoResponseEntity() throws Exception {
+ runTest("ccb_malformed_response_no_entity.xml", GetCustomFieldLabelsResponse.class);
+ }
+
+ /**
+ * Expect CCBXmlBinder to throw an exception if the XML is malformed.
+ */
+ @Test(expected = CCBParseException.class)
+ public void testMalformedXML() throws Exception {
+ runTest("ccb_malformed_xml.xml", GetCustomFieldLabelsResponse.class);
+ }
+
+ /**
+ * Assert CCBXmlBinder correctly parses an error response.
+ */
+ @Test
+ public void testErrorResponse() throws Exception {
+ CCBAPIResponse response = runTest("model/ccb_error_response.xml", GetCustomFieldLabelsResponse.class);
+
+ assertNotNull(response.getErrors());
+ assertEquals(1, response.getErrors().size());
+
+ CCBErrorResponse error = response.getErrors().get(0);
+ assertEquals(2, error.getNumber());
+ assertEquals("Service Permission", error.getType());
+ assertEquals("Invalid username or password.", error.getDescription());
+ }
+
+ /**
+ * Assert CCBXmlBinder correctly parses a more elaborate response.
+ */
+ @Test
+ public void testGetCustomFieldLabelsResponse() throws Exception {
+ GetCustomFieldLabelsResponse response = runTest("model/ccb_custom_field_labels_response.xml",
+ GetCustomFieldLabelsResponse.class);
+
+ assertNull("Response should not have errors", response.getErrors());
+
+ assertNotNull(response.getCustomFields());
+ assertEquals(27, response.getCustomFields().size());
+
+ CustomField field = response.getCustomFields().get(0);
+ assertEquals("udf_ind_text_1", field.getName());
+ assertEquals("Favorite Movie", field.getLabel());
+ assertEquals(false, field.isAdminOnly());
+
+ field = response.getCustomFields().get(1);
+ assertEquals("udf_ind_text_2", field.getName());
+ assertEquals("Another Field", field.getLabel());
+ assertEquals(true, field.isAdminOnly());
+ }
+
+ /**
+ * Helper to test the response stored in a file.
+ *
+ * @param filename The name of the xml file containing the response.
+ * @param clazz The class to bind to.
+ * @param <T> The type of the return value.
+ * @return The parsed response.
+ * @throws Exception If something fails.
+ */
+ private <T extends CCBAPIResponse> T runTest(final String filename, final Class<T> clazz) throws Exception {
+ InputStream in = getClass().getResourceAsStream(filename);
+ if (in == null) {
+ throw new AssertionError("Could not find file " + filename);
+ }
+ try {
+ return binder.bindResponseXML(in, clazz);
+ } finally {
+ in.close();
+ }
+ }
+} \ No newline at end of file
diff --git a/src/test/java/com/p4square/ccbapi/model/GetCustomFieldLabelsResponseTest.java b/src/test/java/com/p4square/ccbapi/model/GetCustomFieldLabelsResponseTest.java
new file mode 100644
index 0000000..549b8e9
--- /dev/null
+++ b/src/test/java/com/p4square/ccbapi/model/GetCustomFieldLabelsResponseTest.java
@@ -0,0 +1,39 @@
+package com.p4square.ccbapi.model;
+
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+/**
+ * Tests for parsing GetCustomFieldLabelsResponse.
+ */
+public class GetCustomFieldLabelsResponseTest extends XmlBinderTestBase {
+
+ /**
+ * Assert that all of the fields bind appropriately in a GetCustomFieldLabelsResponse.
+ */
+ @Test
+ public void testGetCustomFieldLabelsResponse() throws Exception {
+ final GetCustomFieldLabelsResponse response = parseFile("ccb_custom_labels_response.xml",
+ GetCustomFieldLabelsResponse.class);
+
+ assertNull("Response should not have errors", response.getErrors());
+
+ assertNotNull(response.getCustomFields());
+ assertEquals(27, response.getCustomFields().size());
+
+ // Check the first field.
+ CustomField field = response.getCustomFields().get(0);
+ assertEquals("udf_ind_text_1", field.getName());
+ assertEquals("Favorite Movie", field.getLabel());
+ assertEquals(false, field.isAdminOnly());
+
+ // And the second.
+ field = response.getCustomFields().get(1);
+ assertEquals("udf_ind_text_2", field.getName());
+ assertEquals("Another Field", field.getLabel());
+ assertEquals(true, field.isAdminOnly());
+
+ // And that's probably enough for now...
+ }
+} \ No newline at end of file
diff --git a/src/test/java/com/p4square/ccbapi/model/GetIndividualProfilesResponseTest.java b/src/test/java/com/p4square/ccbapi/model/GetIndividualProfilesResponseTest.java
new file mode 100644
index 0000000..743a9f7
--- /dev/null
+++ b/src/test/java/com/p4square/ccbapi/model/GetIndividualProfilesResponseTest.java
@@ -0,0 +1,60 @@
+package com.p4square.ccbapi.model;
+
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+/**
+ * Tests for parsing GetIndividualProfilesResponse.
+ */
+public class GetIndividualProfilesResponseTest extends XmlBinderTestBase {
+
+ /**
+ * Assert that all of the fields bind appropriately for a single profile response.
+ */
+ @Test
+ public void testGetIndividualProfilesResponse() throws Exception {
+ final GetIndividualProfilesResponse response = parseFile("ccb_individual_profile_response.xml",
+ GetIndividualProfilesResponse.class);
+
+ assertNull("Response should not have errors", response.getErrors());
+ assertNotNull(response.getIndividuals());
+ assertEquals(1, response.getIndividuals().size());
+
+ final IndividualProfile profile = response.getIndividuals().get(0);
+
+ // IDs
+ assertEquals(48, profile.getId());
+ assertEquals(123, profile.getSyncId());
+ assertEquals(456, profile.getOtherId());
+
+ // Family
+ assertEquals(36, profile.getFamily().getFamilyId());
+ assertEquals("The Bob Family", profile.getFamily().getName());
+ assertEquals("https://cdn3.ccbchurch.com/preSTABLE/images/group-default.gif", profile.getFamilyImageUrl());
+ assertEquals(FamilyPosition.PRIMARY_CONTACT, profile.getFamilyPosition());
+ assertEquals(1, profile.getFamilyMembers().size());
+
+ // Mrs. Bob
+ assertEquals(49, profile.getFamilyMembers().get(0).getIndividualReference().getIndividualId());
+ assertEquals("Mrs. Bob", profile.getFamilyMembers().get(0).getIndividualReference().getName());
+ assertEquals(FamilyPosition.SPOUSE, profile.getFamilyMembers().get(0).getFamilyPosition());
+
+ // Names
+ assertEquals("Mr.", profile.getSalutation());
+ assertEquals("Larry", profile.getFirstName());
+ assertEquals("", profile.getMiddleName());
+ assertEquals("Bob", profile.getLastName());
+ assertEquals("", profile.getSuffix());
+ assertEquals("Larabar", profile.getLegalFirstName());
+ assertEquals("Larry Bob", profile.getFullName());
+
+ // Other Attributes
+ assertEquals("https://cdn3.ccbchurch.com/preSTABLE/images/profile-default.gif", profile.getImageUrl());
+ assertEquals("tsebastian@churchcommunitybuilder.com", profile.getEmail());
+ assertEquals("", profile.getAllergies());
+ assertEquals(true, profile.isConfirmedNoAllergies());
+ assertEquals(Gender.MALE, profile.getGender());
+ assertEquals("1990-04-05", profile.getBirthday().toString());
+ }
+} \ No newline at end of file
diff --git a/src/test/java/com/p4square/ccbapi/model/XmlBinderTestBase.java b/src/test/java/com/p4square/ccbapi/model/XmlBinderTestBase.java
new file mode 100644
index 0000000..2422d39
--- /dev/null
+++ b/src/test/java/com/p4square/ccbapi/model/XmlBinderTestBase.java
@@ -0,0 +1,39 @@
+package com.p4square.ccbapi.model;
+
+import java.io.InputStream;
+import com.p4square.ccbapi.CCBXmlBinder;
+import org.junit.Before;
+
+/**
+ * Created by jesterpm on 3/14/16.
+ */
+public class XmlBinderTestBase {
+
+ private CCBXmlBinder binder;
+
+ @Before
+ public void setUp() {
+ binder = new CCBXmlBinder();
+ }
+
+ /**
+ * Helper to test the response stored in a file.
+ *
+ * @param filename The name of the xml file containing the response.
+ * @param clazz The class to bind to.
+ * @param <T> The type of the return value.
+ * @return The parsed response.
+ * @throws Exception If something fails.
+ */
+ protected <T extends CCBAPIResponse> T parseFile(final String filename, final Class<T> clazz) throws Exception {
+ InputStream in = getClass().getResourceAsStream(filename);
+ if (in == null) {
+ throw new AssertionError("Could not find file " + filename);
+ }
+ try {
+ return binder.bindResponseXML(in, clazz);
+ } finally {
+ in.close();
+ }
+ }
+}
diff --git a/src/test/resources/com/p4square/ccbapi/ccb_malformed_response_no_entity.xml b/src/test/resources/com/p4square/ccbapi/ccb_malformed_response_no_entity.xml
new file mode 100644
index 0000000..30644eb
--- /dev/null
+++ b/src/test/resources/com/p4square/ccbapi/ccb_malformed_response_no_entity.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ccb_api>
+ <request>
+ <parameters>
+ <argument value="custom_field_labels" name="srv"/>
+ </parameters>
+ </request>
+</ccb_api>
diff --git a/src/test/resources/com/p4square/ccbapi/ccb_malformed_xml.xml b/src/test/resources/com/p4square/ccbapi/ccb_malformed_xml.xml
new file mode 100644
index 0000000..97b109f
--- /dev/null
+++ b/src/test/resources/com/p4square/ccbapi/ccb_malformed_xml.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ccb_api>
+ <request>
+ <parameters>
+ <argument value="custom_field_labels" name="srv"/>
+ </parameters>
+ </request>
+ <response>
+
diff --git a/src/test/resources/com/p4square/ccbapi/model/ccb_custom_field_labels_response.xml b/src/test/resources/com/p4square/ccbapi/model/ccb_custom_field_labels_response.xml
new file mode 100644
index 0000000..0fcc709
--- /dev/null
+++ b/src/test/resources/com/p4square/ccbapi/model/ccb_custom_field_labels_response.xml
@@ -0,0 +1,150 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ccb_api>
+ <request>
+ <parameters>
+ <argument value="custom_field_labels" name="srv"/>
+ </parameters>
+ </request>
+ <response>
+ <service>custom_field_labels</service>
+ <service_action>execute</service_action>
+ <availability>public</availability>
+ <custom_fields count="28">
+ <custom_field>
+ <name>udf_ind_text_1</name>
+ <label>Favorite Movie</label>
+ <admin_only>false</admin_only>
+ </custom_field>
+ <custom_field>
+ <name>udf_ind_text_2</name>
+ <label>Another Field</label>
+ <admin_only>true</admin_only>
+ </custom_field>
+ <custom_field>
+ <name>udf_ind_text_3</name>
+ <label></label>
+ <admin_only>true</admin_only>
+ </custom_field>
+ <custom_field>
+ <name>udf_ind_text_4</name>
+ <label></label>
+ <admin_only>true</admin_only>
+ </custom_field>
+ <custom_field>
+ <name>udf_ind_text_5</name>
+ <label></label>
+ <admin_only>true</admin_only>
+ </custom_field>
+ <custom_field>
+ <name>udf_ind_text_6</name>
+ <label></label>
+ <admin_only>true</admin_only>
+ </custom_field>
+ <custom_field>
+ <name>udf_ind_text_7</name>
+ <label></label>
+ <admin_only>true</admin_only>
+ </custom_field>
+ <custom_field>
+ <name>udf_ind_text_8</name>
+ <label></label>
+ <admin_only>true</admin_only>
+ </custom_field>
+ <custom_field>
+ <name>udf_ind_text_9</name>
+ <label></label>
+ <admin_only>true</admin_only>
+ </custom_field>
+ <custom_field>
+ <name>udf_ind_text_10</name>
+ <label></label>
+ <admin_only>true</admin_only>
+ </custom_field>
+ <custom_field>
+ <name>udf_ind_text_11</name>
+ <label></label>
+ <admin_only>true</admin_only>
+ </custom_field>
+ <custom_field>
+ <name>udf_ind_text_12</name>
+ <label></label>
+ <admin_only>true</admin_only>
+ </custom_field>
+ <custom_field>
+ <name>udf_ind_date_1</name>
+ <label></label>
+ <admin_only>true</admin_only>
+ </custom_field>
+ <custom_field>
+ <name>udf_ind_date_2</name>
+ <label></label>
+ <admin_only>true</admin_only>
+ </custom_field>
+ <custom_field>
+ <name>udf_ind_date_3</name>
+ <label></label>
+ <admin_only>true</admin_only>
+ </custom_field>
+ <custom_field>
+ <name>udf_ind_date_4</name>
+ <label></label>
+ <admin_only>true</admin_only>
+ </custom_field>
+ <custom_field>
+ <name>udf_ind_date_5</name>
+ <label></label>
+ <admin_only>true</admin_only>
+ </custom_field>
+ <custom_field>
+ <name>udf_ind_date_6</name>
+ <label></label>
+ <admin_only>true</admin_only>
+ </custom_field>
+ <custom_field>
+ <name>udf_ind_pulldown_1</name>
+ <label></label>
+ <admin_only>true</admin_only>
+ </custom_field>
+ <custom_field>
+ <name>udf_ind_pulldown_2</name>
+ <label></label>
+ <admin_only>true</admin_only>
+ </custom_field>
+ <custom_field>
+ <name>udf_ind_pulldown_3</name>
+ <label></label>
+ <admin_only>true</admin_only>
+ </custom_field>
+ <custom_field>
+ <name>udf_ind_pulldown_4</name>
+ <label></label>
+ <admin_only>true</admin_only>
+ </custom_field>
+ <custom_field>
+ <name>udf_ind_pulldown_5</name>
+ <label></label>
+ <admin_only>true</admin_only>
+ </custom_field>
+ <custom_field>
+ <name>udf_ind_pulldown_6</name>
+ <label></label>
+ <admin_only>true</admin_only>
+ </custom_field>
+ <custom_field>
+ <name>udf_grp_pulldown_1</name>
+ <label></label>
+ <admin_only>true</admin_only>
+ </custom_field>
+ <custom_field>
+ <name>udf_grp_pulldown_2</name>
+ <label></label>
+ <admin_only>true</admin_only>
+ </custom_field>
+ <custom_field>
+ <name>udf_grp_pulldown_3</name>
+ <label></label>
+ <admin_only>true</admin_only>
+ </custom_field>
+ </custom_fields>
+ </response>
+</ccb_api> \ No newline at end of file
diff --git a/src/test/resources/com/p4square/ccbapi/model/ccb_error_response.xml b/src/test/resources/com/p4square/ccbapi/model/ccb_error_response.xml
new file mode 100644
index 0000000..ced57fa
--- /dev/null
+++ b/src/test/resources/com/p4square/ccbapi/model/ccb_error_response.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ccb_api>
+ <request>
+ <parameters>
+ <argument value="custom_field_labels" name="srv"/>
+ </parameters>
+ </request>
+ <response>
+ <errors>
+ <error number="002" type="Service Permission">Invalid username or password.</error>
+ </errors>
+ </response>
+</ccb_api>
diff --git a/src/test/resources/com/p4square/ccbapi/model/ccb_individual_profile_response.xml b/src/test/resources/com/p4square/ccbapi/model/ccb_individual_profile_response.xml
new file mode 100644
index 0000000..fd3d0f7
--- /dev/null
+++ b/src/test/resources/com/p4square/ccbapi/model/ccb_individual_profile_response.xml
@@ -0,0 +1,149 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ccb_api>
+ <request>
+ <parameters>
+ <argument value="individual_profile_from_id" name="srv"/>
+ <argument value="48" name="individual_id"/>
+ </parameters>
+ </request>
+ <response>
+ <service>individual_profile_from_id</service>
+ <service_action>execute</service_action>
+ <availability>public</availability>
+ <individuals count="1">
+ <individual id="48">
+ <sync_id>123</sync_id>
+ <other_id>456</other_id>
+ <giving_number>ABC123</giving_number>
+ <campus id="1">Church of Cucumbers</campus>
+ <family id="36">The Bob Family</family>
+ <family_image>https://cdn3.ccbchurch.com/preSTABLE/images/group-default.gif</family_image>
+ <family_position>Primary Contact</family_position>
+ <family_members>
+ <family_member>
+ <individual id="49">Mrs. Bob</individual>
+ <family_position>Spouse</family_position>
+ </family_member>
+ </family_members>
+ <first_name>Larry</first_name>
+ <last_name>Bob</last_name>
+ <middle_name></middle_name>
+ <legal_first_name>Larabar</legal_first_name>
+ <full_name>Larry Bob</full_name>
+ <salutation>Mr.</salutation>
+ <suffix></suffix>
+ <image>https://cdn3.ccbchurch.com/preSTABLE/images/profile-default.gif</image>
+ <email>tsebastian@churchcommunitybuilder.com</email>
+ <allergies></allergies>
+ <confirmed_no_allergies>true</confirmed_no_allergies>
+ <addresses>
+ <address type="mailing">
+ <street_address>1234 Village St.</street_address>
+ <city>Denver</city>
+ <state>CO</state>
+ <zip>12345</zip>
+ <country code="US">United States</country>
+ <line_1>1234 Village St.</line_1>
+ <line_2>Denver, CO 12345</line_2>
+ <latitude></latitude>
+ <longitude></longitude>
+ </address>
+ <address type="home">
+ <street_address></street_address>
+ <city></city>
+ <state></state>
+ <zip></zip>
+ <country code=""> </country>
+ <line_1></line_1>
+ <line_2></line_2>
+ </address>
+ <address type="work">
+ <street_address></street_address>
+ <city></city>
+ <state></state>
+ <zip></zip>
+ <country code=""> </country>
+ <line_1></line_1>
+ <line_2></line_2>
+ </address>
+ <address type="other">
+ <street_address></street_address>
+ <city></city>
+ <state></state>
+ <zip></zip>
+ <country code=""> </country>
+ <line_1></line_1>
+ <line_2></line_2>
+ </address>
+ </addresses>
+ <phones>
+ <phone type="contact">(098) 765-4321</phone>
+ <phone type="home"></phone>
+ <phone type="work"></phone>
+ <phone type="mobile"></phone>
+ </phones>
+ <mobile_carrier id="0"> </mobile_carrier>
+ <gender>M</gender>
+ <marital_status></marital_status>
+ <birthday>1990-04-05</birthday>
+ <anniversary></anniversary>
+ <baptized>false</baptized>
+ <deceased></deceased>
+ <membership_type id=""> </membership_type>
+ <membership_date></membership_date>
+ <membership_end></membership_end>
+ <receive_email_from_church>true</receive_email_from_church>
+ <default_new_group_messages>Group Default</default_new_group_messages>
+ <default_new_group_comments>Group Default</default_new_group_comments>
+ <default_new_group_digest>Group Default</default_new_group_digest>
+ <default_new_group_sms>Never</default_new_group_sms>
+ <privacy_settings>
+ <profile_listed>true</profile_listed>
+ <mailing_address id="2">My Friends</mailing_address>
+ <home_address id="2">My Friends</home_address>
+ <contact_phone id="3">My Friends and Group Members</contact_phone>
+ <home_phone id="3">My Friends and Group Members</home_phone>
+ <work_phone id="2">My Friends</work_phone>
+ <mobile_phone id="2">My Friends</mobile_phone>
+ <emergency_phone id="2">My Friends</emergency_phone>
+ <birthday id="4">Everyone</birthday>
+ <anniversary id="4">Everyone</anniversary>
+ <gender id="4">Everyone</gender>
+ <marital_status id="2">My Friends</marital_status>
+ <user_defined_fields id="2">My Friends</user_defined_fields>
+ <allergies id="1">Church Leadership</allergies>
+ </privacy_settings>
+ <active>true</active>
+ <creator id="1">Larry Cucumber</creator>
+ <modifier id="1">Larry Cucumber</modifier>
+ <created>2012-09-25 15:29:15</created>
+ <modified>2012-09-25 15:30:50</modified>
+ <user_defined_text_fields>
+ <user_defined_text_field>
+ <name>udf_text_12</name>
+ <label>Test</label>
+ <text>Test Value</text>
+ <admin_only>false</admin_only>
+ </user_defined_text_field>
+ </user_defined_text_fields>
+ <user_defined_date_fields>
+ <user_defined_date_field>
+ <name>udf_date_6</name>
+ <label>Test Date</label>
+ <date>2016-03-16</date>
+ <admin_only>false</admin_only>
+ </user_defined_date_field>
+ </user_defined_date_fields>
+ <user_defined_pulldown_fields>
+ <user_defined_pulldown_field>
+ <name>udf_pulldown_6</name>
+ <label>Level</label>
+ <selection id="3">Disciple</selection>
+ <admin_only>false</admin_only>
+ </user_defined_pulldown_field>
+ </user_defined_pulldown_fields>
+
+ </individual>
+ </individuals>
+ </response>
+</ccb_api> \ No newline at end of file