2 * This document is a part of the source code and related artifacts
3 * for CollectionSpace, an open source collections management system
4 * for museums and related institutions:
6 * http://www.collectionspace.org
7 * http://wiki.collectionspace.org
9 * Copyright (c)) 2009 Regents of the University of California
11 * Licensed under the Educational Community License (ECL), Version 2.0.
12 * You may not use this file except in compliance with this License.
14 * You may obtain a copy of the ECL 2.0 License at
15 * https://source.collectionspace.org/collection-space/LICENSE.txt
17 * Unless required by applicable law or agreed to in writing, software
18 * distributed under the License is distributed on an "AS IS" BASIS,
19 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20 * See the License for the specific language governing permissions and
21 * limitations under the License.
23 package org.collectionspace.services.client.test;
25 import java.util.ArrayList;
26 import java.util.HashMap;
27 import java.util.List;
29 import javax.ws.rs.core.Response;
31 import org.collectionspace.services.client.AbstractCommonListUtils;
32 import org.collectionspace.services.client.AuthorityClient;
33 import org.collectionspace.services.client.CollectionSpaceClient;
34 import org.collectionspace.services.client.PayloadOutputPart;
35 import org.collectionspace.services.client.PoxPayloadIn;
36 import org.collectionspace.services.client.PoxPayloadOut;
38 import org.collectionspace.services.client.ContactClient;
39 import org.collectionspace.services.client.ContactClientUtils;
40 import org.collectionspace.services.contact.AddressGroup;
41 import org.collectionspace.services.contact.AddressGroupList;
42 import org.collectionspace.services.contact.ContactsCommon;
44 import org.collectionspace.services.client.PersonAuthorityClient;
45 import org.collectionspace.services.client.PersonAuthorityClientUtils;
46 import org.collectionspace.services.jaxb.AbstractCommonList;
47 import org.collectionspace.services.PersonJAXBSchema;
48 import org.collectionspace.services.common.vocabulary.AuthorityItemJAXBSchema;
49 import org.collectionspace.services.nuxeo.util.NuxeoUtils;
50 import org.collectionspace.services.person.PersonauthoritiesCommon;
51 import org.collectionspace.services.person.PersonTermGroup;
52 import org.collectionspace.services.person.PersonTermGroupList;
53 import org.collectionspace.services.person.PersonsCommon;
55 import org.jboss.resteasy.client.ClientResponse;
56 //import org.jboss.resteasy.plugins.providers.multipart.OutputPart;
57 import org.slf4j.Logger;
58 import org.slf4j.LoggerFactory;
59 import org.testng.Assert;
60 import org.testng.annotations.AfterClass;
61 import org.testng.annotations.Test;
64 * PersonAuthorityServiceTest, carries out tests against a
65 * deployed and running PersonAuthority Service.
67 * $LastChangedRevision: 753 $
68 * $LastChangedDate: 2009-09-23 11:03:36 -0700 (Wed, 23 Sep 2009) $
70 public class PersonAuthorityServiceTest extends AbstractAuthorityServiceTest<PersonauthoritiesCommon, PersonsCommon> { //FIXME: Test classes for Vocab, Person, Org, and Location should have a base class!
73 private final String CLASS_NAME = PersonAuthorityServiceTest.class.getName();
74 private final Logger logger = LoggerFactory.getLogger(CLASS_NAME);
77 public String getServicePathComponent() {
78 return PersonAuthorityClient.SERVICE_PATH_COMPONENT;
82 protected String getServiceName() {
83 return PersonAuthorityClient.SERVICE_NAME;
86 public String getItemServicePathComponent() {
87 return AuthorityClient.ITEMS;
89 /** The test forename. */
90 final String TEST_FORE_NAME = "John";
91 /** The test middle name. */
92 final String TEST_MIDDLE_NAME = null;
93 /** The test surname. */
94 final String TEST_SUR_NAME = "Wayne";
95 /** The test birthdate. */
96 final String TEST_BIRTH_DATE = "May 26, 1907";
97 /** The test death date. */
98 final String TEST_DEATH_DATE = "June 11, 1979";
99 //private String knownResourceRefName = null;
100 private String knownItemResourceShortIdentifer = null;
101 // The resource ID of an item resource used for partial term matching tests.
102 private String knownItemPartialTermResourceId = null;
103 /** The known contact resource id. */
104 private String knownContactResourceId = null;
105 /** The all contact resource ids created. */
106 private Map<String, String> allContactResourceIdsCreated =
107 new HashMap<String, String>();
109 protected void setKnownResource(String id, String shortIdentifer,
111 knownResourceId = id;
112 knownResourceShortIdentifer = shortIdentifer;
113 //knownResourceRefName = refName;
116 protected void setKnownItemResource(String id, String shortIdentifer) {
117 knownItemResourceId = id;
118 knownItemResourceShortIdentifer = shortIdentifer;
122 * @see org.collectionspace.services.client.test.BaseServiceTest#getClientInstance()
125 protected CollectionSpaceClient getClientInstance() {
126 return new PersonAuthorityClient();
129 // ---------------------------------------------------------------
130 // CRUD tests : CREATE tests
131 // ---------------------------------------------------------------
134 * @see org.collectionspace.services.client.test.ServiceTest#create(java.lang.String)
137 // @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class,
138 // groups = {"create"})
139 public void create(String testName) throws Exception {
140 // Perform setup, such as initializing the type of service request
141 // (e.g. CREATE, DELETE), its valid and expected status codes, and
142 // its associated HTTP method name (e.g. POST, DELETE).
145 // Submit the request to the service and store the response.
146 PersonAuthorityClient client = new PersonAuthorityClient();
147 String shortId = createIdentifier();
148 String displayName = "displayName-" + shortId;
149 //String baseRefName = PersonAuthorityClientUtils.createPersonAuthRefName(shortId, null);
150 PoxPayloadOut multipart =
151 PersonAuthorityClientUtils.createPersonAuthorityInstance(
152 displayName, shortId, client.getCommonPartName());
155 ClientResponse<Response> res = client.create(multipart);
157 assertStatusCode(res, testName);
158 newID = extractId(res);
161 res.releaseConnection();
164 // Save values for additional tests
165 if (knownResourceId == null) {
166 setKnownResource(newID, shortId, null ); //baseRefName);
167 if (logger.isDebugEnabled()) {
168 logger.debug(testName + ": knownResourceId=" + knownResourceId);
171 // Store the IDs from every resource created by tests,
172 // so they can be deleted after tests have been run.
173 allResourceIdsCreated.add(newID);
177 protected PoxPayloadOut createInstance(String identifier) {
178 PersonAuthorityClient client = new PersonAuthorityClient();
179 String displayName = "displayName-" + identifier;
180 PoxPayloadOut multipart = PersonAuthorityClientUtils.createPersonAuthorityInstance(
181 displayName, identifier, client.getCommonPartName());
186 protected PoxPayloadOut createItemInstance(String parentCsid, String identifier) {
187 String headerLabel = new PersonAuthorityClient().getItemCommonPartName();
189 HashMap<String, String> personInfo = new HashMap<String, String>();
190 String shortId = "johnWayneTempActor";
191 personInfo.put(PersonJAXBSchema.SHORT_IDENTIFIER, shortId);
193 List<PersonTermGroup> terms = new ArrayList<PersonTermGroup>();
194 PersonTermGroup term = new PersonTermGroup();
195 term.setTermDisplayName("John Wayne Temp");
196 term.setTermName("JohnWayneTemp");
199 return PersonAuthorityClientUtils.createPersonInstance(parentCsid, identifier, personInfo, terms, headerLabel);
203 * Creates an item in an authority, using test data.
205 * @param vcsid the vcsid
206 * @param authRefName the auth ref name
210 protected String createItemInAuthority(String vcsid) {
212 final String testName = "createItemInAuthority";
213 if (logger.isDebugEnabled()) {
214 logger.debug(testName + ":" + vcsid + "...");
217 Map<String, String> johnWayneMap = new HashMap<String, String>();
219 // Fill the property map
221 String shortId = "johnWayneActor";
222 johnWayneMap.put(PersonJAXBSchema.SHORT_IDENTIFIER, shortId);
223 johnWayneMap.put(PersonJAXBSchema.GENDER, "male");
224 johnWayneMap.put(PersonJAXBSchema.BIRTH_DATE, TEST_BIRTH_DATE);
225 johnWayneMap.put(PersonJAXBSchema.BIRTH_PLACE, "Winterset, Iowa");
226 johnWayneMap.put(PersonJAXBSchema.DEATH_DATE, TEST_DEATH_DATE);
227 johnWayneMap.put(PersonJAXBSchema.BIO_NOTE, "born Marion Robert Morrison and better"
228 + "known by his stage name John Wayne, was an American film actor, director "
229 + "and producer. He epitomized rugged masculinity and has become an enduring "
230 + "American icon. He is famous for his distinctive voice, walk and height. "
231 + "He was also known for his conservative political views and his support in "
232 + "the 1950s for anti-communist positions.");
234 List<PersonTermGroup> johnWayneTerms = new ArrayList<PersonTermGroup>();
235 PersonTermGroup term = new PersonTermGroup();
236 term.setTermDisplayName("John Wayne DisplayName");
237 term.setTermName("John Wayne");
238 term.setForeName(TEST_FORE_NAME);
239 term.setSurName(TEST_SUR_NAME);
240 johnWayneTerms.add(term);
242 Map<String, List<String>> johnWayneRepeatablesMap = new HashMap<String, List<String>>();
243 List<String> johnWayneGroups = new ArrayList<String>();
244 johnWayneGroups.add("Irish");
245 johnWayneGroups.add("Scottish");
246 johnWayneRepeatablesMap.put(PersonJAXBSchema.GROUPS, johnWayneGroups);
248 return createItemInAuthority(vcsid, null /*authRefName*/, shortId, johnWayneMap, johnWayneTerms, johnWayneRepeatablesMap);
253 * Creates an item in an authority.
255 * @param vcsid the vcsid
256 * @param authRefName the auth ref name
257 * @param itemFieldProperties a set of properties specifying the values of fields.
258 * @param itemRepeatableFieldProperties a set of properties specifying the values of repeatable fields.
261 private String createItemInAuthority(String vcsid, String authRefName, String shortId,
262 Map itemFieldProperties, List<PersonTermGroup> terms, Map itemRepeatableFieldProperties) {
264 final String testName = "createItemInAuthority";
265 if (logger.isDebugEnabled()) {
266 logger.debug(testName + ":" + vcsid + "...");
269 // Submit the request to the service and store the response.
270 PersonAuthorityClient client = new PersonAuthorityClient();
271 PoxPayloadOut multipart =
272 PersonAuthorityClientUtils.createPersonInstance(vcsid, null /*authRefName*/, itemFieldProperties,
273 terms, itemRepeatableFieldProperties, client.getItemCommonPartName());
275 ClientResponse<Response> res = client.createItem(vcsid, multipart);
278 assertStatusCode(res, testName);
279 newID = PersonAuthorityClientUtils.extractId(res);
282 res.releaseConnection();
286 // Store the ID returned from the first item resource created
287 // for additional tests below.
288 if (knownItemResourceId == null) {
289 setKnownItemResource(newID, shortId);
290 if (logger.isDebugEnabled()) {
291 logger.debug(testName + ": knownItemResourceId=" + knownItemResourceId);
294 if (logger.isDebugEnabled()) {
295 logger.debug(testName + " (created):" + vcsid + "/(" + newID + "," + shortId + ")");
298 // Store the IDs from any item resources created
299 // by tests, along with the IDs of their parents, so these items
300 // can be deleted after all tests have been run.
301 allResourceItemIdsCreated.put(newID, vcsid);
307 * Creates the contact.
309 * @param testName the test name
311 @Test(dataProvider = "testName", groups = {"create"},
312 dependsOnMethods = {"createItem"})
313 public void createContact(String testName) {
315 String newID = createContactInItem(knownResourceId, knownItemResourceId);
319 * Creates the contact in item.
321 * @param parentcsid the parentcsid
322 * @param itemcsid the itemcsid
325 private String createContactInItem(String parentcsid, String itemcsid) {
327 final String testName = "createContactInItem";
328 if (logger.isDebugEnabled()) {
329 logger.debug(testName + ":...");
331 // Submit the request to the service and store the response.
332 PersonAuthorityClient client = new PersonAuthorityClient();
333 String identifier = createIdentifier();
334 PoxPayloadOut multipart = ContactClientUtils.createContactInstance(parentcsid,
335 itemcsid, identifier, new ContactClient().getCommonPartName());
338 ClientResponse<Response> res =
339 client.createContact(parentcsid, itemcsid, multipart);
342 assertStatusCode(res, testName);
343 newID = PersonAuthorityClientUtils.extractId(res);
346 res.releaseConnection();
350 // Store the ID returned from the first contact resource created
351 // for additional tests below.
352 if (knownContactResourceId == null) {
353 knownContactResourceId = newID;
354 if (logger.isDebugEnabled()) {
355 logger.debug(testName + ": knownContactResourceId=" + knownContactResourceId);
359 // Store the IDs from any contact resources created
360 // by tests, along with the IDs of their parent items,
361 // so these items can be deleted after all tests have been run.
362 allContactResourceIdsCreated.put(newID, itemcsid);
368 * Attempts to create an authority with an short identifier that contains
369 * non-word characters.
371 * @param testName the test name
373 @Test(dataProvider = "testName", groups = {"create", "nonWordCharsInShortId"})
374 public void createWithShortIdNonWordChars(String testName) throws Exception {
375 testExpectedStatusCode = STATUS_BAD_REQUEST;
376 testRequestType = ServiceRequestType.CREATE;
377 testSetup(testExpectedStatusCode, testRequestType);
379 // Create the payload to be included in the body of the request
380 PersonAuthorityClient client = new PersonAuthorityClient();
381 String shortId = createIdentifier() + "*" + createIdentifier();
382 String displayName = "displayName-" + shortId;
383 PoxPayloadOut multipart =
384 PersonAuthorityClientUtils.createPersonAuthorityInstance(
385 displayName, shortId, client.getCommonPartName());
387 // Submit the request to the service and store the response.
388 ClientResponse<Response> res = client.create(multipart);
390 // Check the status code of the response: does it match
391 // the expected response(s)?
393 assertStatusCode(res, testName);
396 res.releaseConnection();
402 * Attempts to create an item with an short identifier that contains
403 * non-word characters.
405 * @param testName the test name
407 @Test(dataProvider = "testName", groups = {"create", "nonWordCharsInShortId"},
408 dependsOnMethods = {"org.collectionspace.services.client.test.AbstractServiceTestImpl.create"})
409 public void createItemWithShortIdNonWordChars(String testName) {
410 testExpectedStatusCode = STATUS_BAD_REQUEST;
411 testRequestType = ServiceRequestType.CREATE;
412 testSetup(testExpectedStatusCode, testRequestType);
414 PersonAuthorityClient client = new PersonAuthorityClient();
415 // Create the payload to be included in the body of the request
416 String shortId = "7-Eleven";
417 Map<String, String> fieldProperties = new HashMap<String, String>();
418 fieldProperties.put(PersonJAXBSchema.SHORT_IDENTIFIER, shortId);
420 List<PersonTermGroup> terms = new ArrayList<PersonTermGroup>();
421 PersonTermGroup term = new PersonTermGroup();
422 term.setTermDisplayName(shortId);
423 term.setTermName(shortId);
426 final Map NULL_REPEATABLE_FIELD_PROPERTIES = null;
427 PoxPayloadOut multipart =
428 PersonAuthorityClientUtils.createPersonInstance(knownResourceId,
429 null /*knownResourceRefName*/, fieldProperties, terms,
430 NULL_REPEATABLE_FIELD_PROPERTIES, client.getItemCommonPartName());
432 // Send the request and receive a response
433 ClientResponse<Response> res = client.createItem(knownResourceId, multipart);
434 // Check the status code of the response: does it match
435 // the expected response(s)?
437 assertStatusCode(res, testName);
440 res.releaseConnection();
445 // ---------------------------------------------------------------
446 // CRUD tests : CREATE LIST tests
447 // ---------------------------------------------------------------
450 * @see org.collectionspace.services.client.test.AbstractServiceTestImpl#createList(java.lang.String)
453 // @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class,
454 // groups = {"createList"}, dependsOnGroups = {"create"})
455 public void createList(String testName) throws Exception {
456 for (int i = 0; i < nItemsToCreateInList; i++) {
462 * Creates the contact list.
464 * @param testName the test name
465 * @throws Exception the exception
467 @Test(dataProvider = "testName", groups = {"createList"},
468 dependsOnMethods = {"org.collectionspace.services.client.test.AbstractAuthorityServiceTest.createItemList"})
469 public void createContactList(String testName) throws Exception {
470 // Add contacts to the initially-created, known item record.
471 for (int j = 0; j < nItemsToCreateInList; j++) {
472 createContact(testName);
476 // ---------------------------------------------------------------
477 // CRUD tests : READ tests
478 // ---------------------------------------------------------------
481 * @see org.collectionspace.services.client.test.AbstractServiceTestImpl#read(java.lang.String)
484 // @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class,
485 // groups = {"read"}, dependsOnGroups = {"create"})
486 public void read(String testName) throws Exception {
487 readInternal(testName, knownResourceId, null);
493 * @param testName the test name
494 * @throws Exception the exception
497 // @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class,
498 // groups = {"read"}, dependsOnMethods = {"read"})
499 public void readByName(String testName) throws Exception {
500 readInternal(testName, null, knownResourceShortIdentifer);
503 protected void readInternal(String testName, String CSID, String shortId) {
504 // Submit the request to the service and store the response.
505 PersonAuthorityClient client = new PersonAuthorityClient();
506 ClientResponse<String> res = null;
509 res = client.read(CSID);
510 } else if (shortId != null) {
511 res = client.readByName(shortId);
513 Assert.fail("readInternal: Internal error. One of CSID or shortId must be non-null");
516 assertStatusCode(res, testName);
517 //FIXME: remove the following try catch once Aron fixes signatures
519 PoxPayloadIn input = new PoxPayloadIn(res.getEntity());
520 PersonauthoritiesCommon personAuthority = (PersonauthoritiesCommon) extractPart(input,
521 client.getCommonPartName(), PersonauthoritiesCommon.class);
522 Assert.assertNotNull(personAuthority);
523 } catch (Exception e) {
524 throw new RuntimeException(e);
528 res.releaseConnection();
536 * @param testName the test name
537 * @throws Exception the exception
539 @Test(dataProvider = "testName", groups = {"readItem", "readNamedItemInNamedAuth"},
540 dependsOnMethods = {"readItemInNamedAuth"})
541 public void readNamedItem(String testName) throws Exception {
542 readItemInternal(testName, knownResourceId, null, null, knownItemResourceShortIdentifer);
546 * Read item in Named Auth.
548 * @param testName the test name
549 * @throws Exception the exception
551 @Test(dataProvider = "testName", groups = {"readItem"},
552 dependsOnMethods = {"readItem"})
553 public void readItemInNamedAuth(String testName) throws Exception {
554 readItemInternal(testName, null, knownResourceShortIdentifer, knownItemResourceId, null);
559 * Read Named item in Named Auth.
561 * @param testName the test name
562 * @throws Exception the exception
564 @Test(dataProvider = "testName", groups = {"readItem"},
565 dependsOnMethods = {"readNamedItem"})
566 public void readNamedItemInNamedAuth(String testName) throws Exception {
567 readItemInternal(testName, null, knownResourceShortIdentifer, null, knownItemResourceShortIdentifer);
570 protected void readItemInternal(String testName,
571 String authCSID, String authShortId, String itemCSID, String itemShortId)
574 if (logger.isDebugEnabled()) {
575 logger.debug("Reading:" + ((authCSID != null) ? authCSID : authShortId) + "/"
576 + ((itemCSID != null) ? authCSID : itemShortId));
579 // Submit the request to the service and store the response.
580 PersonAuthorityClient client = new PersonAuthorityClient();
582 ClientResponse<String> res = null;
583 if (authCSID != null) {
584 if (itemCSID != null) {
585 res = client.readItem(authCSID, itemCSID);
586 } else if (itemShortId != null) {
587 res = client.readNamedItem(authCSID, itemShortId);
589 Assert.fail("readInternal: Internal error. One of CSID or shortId must be non-null");
591 } else if (authShortId != null) {
592 if (itemCSID != null) {
593 res = client.readItemInNamedAuthority(authShortId, itemCSID);
594 } else if (itemShortId != null) {
595 res = client.readNamedItemInNamedAuthority(authShortId, itemShortId);
597 Assert.fail("readInternal: Internal error. One of CSID or shortId must be non-null");
600 Assert.fail("readInternal: Internal error. One of authCSID or authShortId must be non-null");
603 assertStatusCode(res, testName);
604 // Check whether we've received a person.
605 PoxPayloadIn input = new PoxPayloadIn(res.getEntity());
606 PersonsCommon person = (PersonsCommon) extractPart(input,
607 client.getItemCommonPartName(), PersonsCommon.class);
608 Assert.assertNotNull(person);
609 boolean showFull = true;
610 if (showFull && logger.isDebugEnabled()) {
611 logger.debug(testName + ": returned payload:");
612 logger.debug(objectAsXmlString(person, PersonsCommon.class));
615 // Check that the person item is within the expected Person Authority.
616 Assert.assertEquals(person.getInAuthority(), knownResourceId);
618 // Verify the number and contents of values in a repeatable field,
619 // as created in the instance record used for testing.
620 List<String> groups = person.getGroups().getGroup();
621 Assert.assertTrue(groups.size() > 0);
622 Assert.assertNotNull(groups.get(0));
625 res.releaseConnection();
630 // FIXME: This test depends on server-side validation logic to require
631 // a non-null (and potentially, non-empty) displayname for each term,
632 // and will fail if that validation is not present.
635 * Verify illegal item display name.
637 * @param testName the test name
638 * @throws Exception the exception
640 @Test(dataProvider = "testName", groups = {"update"})
641 public void verifyIllegalItemDisplayName(String testName) throws Exception {
642 // Perform setup for read.
645 // Submit the request to the service and store the response.
646 PersonAuthorityClient client = new PersonAuthorityClient();
647 ClientResponse<String> res = client.readItem(knownResourceId, knownItemResourceId);
648 PoxPayloadIn input = null;
650 assertStatusCode(res, testName);
651 input = new PoxPayloadIn(res.getEntity());
654 res.releaseConnection();
658 // Make an invalid UPDATE request, without a display name
660 PersonsCommon person = (PersonsCommon) extractPart(input,
661 client.getItemCommonPartName(), PersonsCommon.class);
662 Assert.assertNotNull(person);
663 // Try to Update with no displayName
664 List<PersonTermGroup> johnWayneTerms = new ArrayList<PersonTermGroup>();
665 PersonTermGroup term = new PersonTermGroup();
666 term.setTermDisplayName("John Wayne DisplayName");
667 term.setTermName("John Wayne");
668 term.setForeName(TEST_FORE_NAME);
669 term.setSurName(TEST_SUR_NAME);
670 johnWayneTerms.add(term);
672 PersonTermGroupList termList = person.getPersonTermGroupList();
673 Assert.assertNotNull(termList);
674 List<PersonTermGroup> terms = termList.getPersonTermGroup();
675 Assert.assertNotNull(terms);
676 terms.get(0).setTermDisplayName(null);
677 terms.get(0).setTermName(null);
679 // Submit the updated resource to the service and store the response.
680 PoxPayloadOut output = new PoxPayloadOut(PersonAuthorityClient.SERVICE_ITEM_PAYLOAD_NAME);
681 PayloadOutputPart commonPart = output.addPart(client.getItemCommonPartName(), person);
682 setupUpdateWithInvalidBody();
683 res = client.updateItem(knownResourceId, knownItemResourceId, output);
685 assertStatusCode(res, testName);
688 res.releaseConnection();
696 * @param testName the test name
697 * @throws Exception the exception
699 @Test(dataProvider = "testName", groups = {"readItem"},
700 dependsOnMethods = {"createContact", "org.collectionspace.services.client.test.AbstractAuthorityServiceTest.readItem"})
701 public void readContact(String testName) throws Exception {
705 // Submit the request to the service and store the response.
706 PersonAuthorityClient client = new PersonAuthorityClient();
707 PoxPayloadIn input = null;
708 ClientResponse<String> res =
709 client.readContact(knownResourceId, knownItemResourceId,
710 knownContactResourceId);
712 assertStatusCode(res, testName);
713 // Check whether we've received a contact.
714 input = new PoxPayloadIn(res.getEntity());
717 res.releaseConnection();
721 ContactsCommon contact = (ContactsCommon) extractPart(input,
722 new ContactClient().getCommonPartName(), ContactsCommon.class);
723 Assert.assertNotNull(contact);
724 boolean showFull = true;
725 if (showFull && logger.isDebugEnabled()) {
726 logger.debug(testName + ": returned payload:");
727 logger.debug(objectAsXmlString(contact, ContactsCommon.class));
729 Assert.assertEquals(contact.getInAuthority(), knownResourceId);
730 Assert.assertEquals(contact.getInItem(), knownItemResourceId);
735 * Read contact non existent.
737 * @param testName the test name
739 @Test(dataProvider = "testName", groups = {"readItem"},
740 dependsOnMethods = {"readContact"})
741 public void readContactNonExistent(String testName) {
743 setupReadNonExistent();
745 // Submit the request to the service and store the response.
746 PersonAuthorityClient client = new PersonAuthorityClient();
747 ClientResponse<String> res =
748 client.readContact(knownResourceId, knownItemResourceId, NON_EXISTENT_ID);
750 assertStatusCode(res, testName);
753 res.releaseConnection();
758 // ---------------------------------------------------------------
759 // CRUD tests : READ_LIST tests
760 // ---------------------------------------------------------------
766 // @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class,
767 // groups = {"readList"}, dependsOnMethods = {"readList"})
768 public void readItemList(String testName) {
769 readItemList(knownAuthorityWithItems, null, testName);
773 * Read item list by authority name.
776 // @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class,
777 // groups = {"readList"}, dependsOnMethods = {"readItemList"})
778 public void readItemListByName(String testName) {
779 readItemList(null, READITEMS_SHORT_IDENTIFIER, testName);
785 * @param vcsid the vcsid
786 * @param name the name
788 private void readItemList(String vcsid, String name, String testName) {
790 // Submit the request to the service and store the response.
791 PersonAuthorityClient client = new PersonAuthorityClient();
792 ClientResponse<AbstractCommonList> res = null;
794 res = client.readItemList(vcsid, null, null);
795 } else if (name != null) {
796 res = client.readItemListForNamedAuthority(name, null, null);
798 Assert.fail("readItemList passed null csid and name!");
800 AbstractCommonList list = null;
802 assertStatusCode(res, testName);
803 list = res.getEntity();
806 res.releaseConnection();
810 List<AbstractCommonList.ListItem> items = list.getListItem();
811 int nItemsReturned = items.size();
812 // There will be 'nItemsToCreateInList'
813 // items created by the createItemList test,
814 // all associated with the same parent resource.
815 int nExpectedItems = nItemsToCreateInList;
816 if (logger.isDebugEnabled()) {
817 logger.debug(testName + ": Expected "
818 + nExpectedItems + " items; got: " + nItemsReturned);
820 Assert.assertEquals(nItemsReturned, nExpectedItems);
822 for (AbstractCommonList.ListItem item : items) {
824 AbstractCommonListUtils.ListItemGetElementValue(item, AuthorityItemJAXBSchema.REF_NAME);
825 Assert.assertTrue((null != value), "Item refName is null!");
828 AbstractCommonListUtils.ListItemGetElementValue(item, AuthorityItemJAXBSchema.TERM_DISPLAY_NAME);
829 Assert.assertTrue((null != value), "Item displayName is null!");
831 if (logger.isTraceEnabled()) {
832 AbstractCommonListUtils.ListItemsInAbstractCommonList(list, logger, testName);
839 @Test(groups = {"readList"},
840 dependsOnMethods = {"org.collectionspace.services.client.test.AbstractAuthorityServiceTest.readItemList"})
841 public void readContactList() {
842 readContactList(knownResourceId, knownItemResourceId);
848 * @param parentcsid the parentcsid
849 * @param itemcsid the itemcsid
851 private void readContactList(String parentcsid, String itemcsid) {
852 final String testName = "readContactList";
857 // Submit the request to the service and store the response.
858 PersonAuthorityClient client = new PersonAuthorityClient();
859 AbstractCommonList list = null;
860 ClientResponse<AbstractCommonList> res =
861 client.readContactList(parentcsid, itemcsid);
863 assertStatusCode(res, testName);
864 list = res.getEntity();
867 res.releaseConnection();
871 List<AbstractCommonList.ListItem> listitems =
873 int nItemsReturned = listitems.size();
874 // There will be one item created, associated with a
875 // known parent resource, by the createItem test.
877 // In addition, there will be 'nItemsToCreateInList'
878 // additional items created by the createItemList test,
879 // all associated with the same parent resource.
880 int nExpectedItems = nItemsToCreateInList + 1;
881 if (logger.isDebugEnabled()) {
882 logger.debug(testName + ": Expected "
883 + nExpectedItems + " items; got: " + nItemsReturned);
885 Assert.assertEquals(nItemsReturned, nExpectedItems);
887 // Optionally output additional data about list members for debugging.
888 boolean iterateThroughList = false;
889 if (iterateThroughList && logger.isDebugEnabled()) {
890 AbstractCommonListUtils.ListItemsInAbstractCommonList(list, logger, testName);
895 // There are no failure outcome tests at present.
896 // ---------------------------------------------------------------
897 // CRUD tests : UPDATE tests
898 // ---------------------------------------------------------------
901 * @see org.collectionspace.services.client.test.AbstractServiceTestImpl#update(java.lang.String)
904 // @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class,
905 // groups = {"update"}, dependsOnGroups = {"readItem", "readList"})
906 public void update(String testName) throws Exception {
907 // Retrieve the contents of a resource to update.
908 PersonAuthorityClient client = new PersonAuthorityClient();
909 PoxPayloadIn input = null;
911 ClientResponse<String> res = client.read(knownResourceId);
913 assertStatusCode(res, testName);
914 if (logger.isDebugEnabled()) {
915 logger.debug("got PersonAuthority to update with ID: " + knownResourceId);
917 input = new PoxPayloadIn(res.getEntity());
920 res.releaseConnection();
924 PersonauthoritiesCommon personAuthority = (PersonauthoritiesCommon) extractPart(input,
925 client.getCommonPartName(), PersonauthoritiesCommon.class);
926 Assert.assertNotNull(personAuthority);
928 // Update the contents of this resource.
929 personAuthority.setDisplayName("updated-" + personAuthority.getDisplayName());
930 personAuthority.setVocabType("updated-" + personAuthority.getVocabType());
931 if (logger.isDebugEnabled()) {
932 logger.debug("to be updated PersonAuthority");
933 logger.debug(objectAsXmlString(personAuthority, PersonauthoritiesCommon.class));
936 // Submit the updated resource to the service and store the response.
937 PoxPayloadOut output = new PoxPayloadOut(PersonAuthorityClient.SERVICE_PAYLOAD_NAME);
938 PayloadOutputPart commonPart = output.addPart(client.getCommonPartName(), personAuthority);
940 res = client.update(knownResourceId, output);
942 assertStatusCode(res, testName);
943 // Retrieve the updated resource and verify that its contents exist.
944 input = new PoxPayloadIn(res.getEntity());
947 res.releaseConnection();
951 PersonauthoritiesCommon updatedPersonAuthority =
952 (PersonauthoritiesCommon) extractPart(input,
953 client.getCommonPartName(), PersonauthoritiesCommon.class);
954 Assert.assertNotNull(updatedPersonAuthority);
956 // Verify that the updated resource received the correct data.
957 Assert.assertEquals(updatedPersonAuthority.getDisplayName(),
958 personAuthority.getDisplayName(),
959 "Data in updated object did not match submitted data.");
965 * @param testName the test name
966 * @throws Exception the exception
969 // @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class,
970 // groups = {"update"}, dependsOnMethods = {"update"})
971 public void updateItem(String testName) throws Exception {
972 // Retrieve the contents of a resource to update.
973 PersonAuthorityClient client = new PersonAuthorityClient();
974 PoxPayloadIn input = null;
976 ClientResponse<String> res =
977 client.readItem(knownResourceId, knownItemResourceId);
979 assertStatusCode(res, testName);
980 if (logger.isDebugEnabled()) {
981 logger.debug("got Person to update with ID: "
982 + knownItemResourceId
983 + " in PersonAuthority: " + knownResourceId);
985 input = new PoxPayloadIn(res.getEntity());
988 res.releaseConnection();
992 PersonsCommon person = (PersonsCommon) extractPart(input,
993 client.getItemCommonPartName(), PersonsCommon.class);
994 Assert.assertNotNull(person);
996 if (logger.isDebugEnabled() == true) {
997 logger.debug("About to update the following person...");
998 logger.debug(objectAsXmlString(person, PersonsCommon.class));
1001 // Update the contents of this resource.
1002 person.setCsid(null);
1003 PersonTermGroupList termList = person.getPersonTermGroupList();
1004 Assert.assertNotNull(termList);
1005 List<PersonTermGroup> terms = termList.getPersonTermGroup();
1006 Assert.assertNotNull(terms);
1007 String foreName = terms.get(0).getForeName();
1008 String updatedForeName = "updated-" + foreName;
1009 terms.get(0).setForeName(updatedForeName);
1010 if (logger.isDebugEnabled()) {
1011 logger.debug("to be updated Person");
1012 logger.debug(objectAsXmlString(person,
1013 PersonsCommon.class));
1016 // Submit the updated resource to the service and store the response.
1017 PoxPayloadOut output = new PoxPayloadOut(PersonAuthorityClient.SERVICE_ITEM_PAYLOAD_NAME);
1018 PayloadOutputPart commonPart = output.addPart(client.getItemCommonPartName(), person);
1020 res = client.updateItem(knownResourceId, knownItemResourceId, output);
1022 assertStatusCode(res, testName);
1023 // Retrieve the updated resource and verify that its contents exist.
1024 input = new PoxPayloadIn(res.getEntity());
1027 res.releaseConnection();
1031 PersonsCommon updatedPerson =
1032 (PersonsCommon) extractPart(input,
1033 client.getItemCommonPartName(), PersonsCommon.class);
1034 Assert.assertNotNull(updatedPerson);
1036 if (logger.isDebugEnabled() == true) {
1037 logger.debug("Updated to following person to:");
1038 logger.debug(objectAsXmlString(updatedPerson, PersonsCommon.class));
1041 // Verify that the updated resource received the correct data.
1042 PersonTermGroupList updatedTermList = person.getPersonTermGroupList();
1043 Assert.assertNotNull(updatedTermList);
1044 List<PersonTermGroup> updatedTerms = termList.getPersonTermGroup();
1045 Assert.assertNotNull(updatedTerms);
1046 Assert.assertEquals(updatedTerms.get(0).getForeName(), updatedForeName,
1047 "Data in updated Person did not match submitted data.");
1053 * @param testName the test name
1054 * @throws Exception the exception
1056 @Test(dataProvider = "testName", groups = {"update"},
1057 dependsOnMethods = {"readContact", "testContactSubmitRequest",
1058 "org.collectionspace.services.client.test.AbstractAuthorityServiceTest.updateItem"})
1059 public void updateContact(String testName) throws Exception {
1060 String contactsCommonLabel = new ContactClient().getCommonPartName();
1062 // Retrieve the contents of a resource to update.
1063 PersonAuthorityClient client = new PersonAuthorityClient();
1064 PoxPayloadIn input = null;
1066 ClientResponse<String> res =
1067 client.readContact(knownResourceId, knownItemResourceId, knownContactResourceId);
1069 assertStatusCode(res, testName);
1070 if (logger.isDebugEnabled()) {
1071 logger.debug("got Contact to update with ID: "
1072 + knownContactResourceId
1073 + " in item: " + knownItemResourceId
1074 + " in parent: " + knownResourceId);
1076 input = new PoxPayloadIn(res.getEntity());
1079 res.releaseConnection();
1083 ContactsCommon contact = (ContactsCommon) extractPart(input,
1084 contactsCommonLabel, ContactsCommon.class);
1085 Assert.assertNotNull(contact);
1087 // Verify the contents of this resource
1088 AddressGroupList addressGroupList = contact.getAddressGroupList();
1089 Assert.assertNotNull(addressGroupList);
1090 List<AddressGroup> addressGroups = addressGroupList.getAddressGroup();
1091 Assert.assertNotNull(addressGroups);
1092 Assert.assertTrue(addressGroups.size() > 0);
1093 String addressPlace1 = addressGroups.get(0).getAddressPlace1();
1094 Assert.assertNotNull(addressPlace1);
1096 // Update the contents of this resource.
1097 addressGroups.get(0).setAddressPlace1("updated-" + addressPlace1);
1098 contact.setAddressGroupList(addressGroupList);
1099 if (logger.isDebugEnabled()) {
1100 logger.debug("to be updated Contact");
1101 logger.debug(objectAsXmlString(contact,
1102 ContactsCommon.class));
1105 // Submit the updated resource to the service and store the response.
1106 PoxPayloadOut output = new PoxPayloadOut(ContactClient.SERVICE_PAYLOAD_NAME);
1107 PayloadOutputPart commonPart = output.addPart(contactsCommonLabel, contact);
1109 res = client.updateContact(knownResourceId, knownItemResourceId, knownContactResourceId, output);
1111 assertStatusCode(res, testName);
1112 // Retrieve the updated resource and verify that its contents exist.
1113 input = new PoxPayloadIn(res.getEntity());;
1116 res.releaseConnection();
1119 ContactsCommon updatedContact = (ContactsCommon) extractPart(input,
1120 contactsCommonLabel, ContactsCommon.class);
1121 Assert.assertNotNull(updatedContact);
1123 // Verify that the updated resource received the correct data.
1124 Assert.assertEquals(updatedContact.getAddressGroupList().getAddressGroup().get(0).getAddressPlace1(),
1125 contact.getAddressGroupList().getAddressGroup().get(0).getAddressPlace1(),
1126 "Data in updated object did not match submitted data.");
1130 * Update non existent contact.
1132 * @param testName the test name
1133 * @throws Exception the exception
1135 @Test(dataProvider = "testName", groups = {"update"},
1136 dependsOnMethods = {"updateContact", "testContactSubmitRequest"})
1137 public void updateNonExistentContact(String testName) throws Exception {
1138 // Currently a no-op test
1141 // ---------------------------------------------------------------
1142 // CRUD tests : DELETE tests
1143 // ---------------------------------------------------------------
1145 // Note: delete sub-resources in ascending hierarchical order,
1146 // before deleting their parents.
1150 * @param testName the test name
1151 * @throws Exception the exception
1153 @Test(dataProvider = "testName", groups = {"delete"},
1154 dependsOnMethods = {"updateContact"})
1155 public void deleteContact(String testName) throws Exception {
1156 if (logger.isDebugEnabled()) {
1157 logger.debug("parentcsid =" + knownResourceId
1158 + " itemcsid = " + knownItemResourceId
1159 + " csid = " + knownContactResourceId);
1162 // Submit the request to the service and store the response.
1163 PersonAuthorityClient client = new PersonAuthorityClient();
1165 ClientResponse<Response> res =
1166 client.deleteContact(knownResourceId, knownItemResourceId, knownContactResourceId);
1168 assertStatusCode(res, testName);
1171 res.releaseConnection();
1177 public void delete(String testName) throws Exception {
1178 // Do nothing. See localDelete(). This ensure proper test order.
1181 @Test(dataProvider = "testName", dependsOnMethods = {"localDeleteItem"})
1182 public void localDelete(String testName) throws Exception {
1183 super.delete(testName);
1187 public void deleteItem(String testName) throws Exception {
1188 // Do nothing. We need to wait until after the test "localDelete" gets run. When it does,
1189 // its dependencies will get run first and then we can call the base class' delete method.
1192 @Test(dataProvider = "testName", groups = {"delete"},
1193 dependsOnMethods = {"verifyIllegalItemDisplayName", "testContactSubmitRequest", "deleteContact"})
1194 public void localDeleteItem(String testName) throws Exception {
1195 super.deleteItem(testName);
1199 * Delete non existent contact.
1201 * @param testName the test name
1203 @Test(dataProvider = "testName", groups = {"delete"},
1204 dependsOnMethods = {"deleteContact"})
1205 public void deleteNonExistentContact(String testName) {
1206 // Submit the request to the service and store the response.
1207 PersonAuthorityClient client = new PersonAuthorityClient();
1208 setupDeleteNonExistent();
1209 ClientResponse<Response> res =
1210 client.deleteContact(knownResourceId, knownItemResourceId, NON_EXISTENT_ID);
1212 assertStatusCode(res, testName);
1215 res.releaseConnection();
1221 * Test contact submit request.
1223 @Test(dataProvider = "testName",
1224 dependsOnMethods = {"createContact", "readContact", "testItemSubmitRequest"})
1225 public void testContactSubmitRequest(String testName) {
1227 // Expected status code: 200 OK
1228 final int EXPECTED_STATUS = Response.Status.OK.getStatusCode();
1230 // Submit the request to the service and store the response.
1231 String method = ServiceRequestType.READ.httpMethodName();
1232 String url = getContactResourceURL(knownResourceId,
1233 knownItemResourceId, knownContactResourceId);
1234 int statusCode = submitRequest(method, url);
1236 // Check the status code of the response: does it match
1237 // the expected response(s)?
1238 if (logger.isDebugEnabled()) {
1239 logger.debug("testContactSubmitRequest: url=" + url
1240 + " status=" + statusCode);
1242 Assert.assertEquals(statusCode, EXPECTED_STATUS);
1246 // ---------------------------------------------------------------
1247 // Cleanup of resources created during testing
1248 // ---------------------------------------------------------------
1250 * Deletes all resources created by tests, after all tests have been run.
1252 * This cleanup method will always be run, even if one or more tests fail.
1253 * For this reason, it attempts to remove all resources created
1254 * at any point during testing, even if some of those resources
1255 * may be expected to be deleted by certain tests.
1257 @AfterClass(alwaysRun = true)
1259 public void cleanUp() {
1260 String noTest = System.getProperty("noTestCleanup");
1261 if (Boolean.TRUE.toString().equalsIgnoreCase(noTest)) {
1262 if (logger.isDebugEnabled()) {
1263 logger.debug("Skipping Cleanup phase ...");
1267 if (logger.isDebugEnabled()) {
1268 logger.debug("Cleaning up temporary resources created for testing ...");
1270 String parentResourceId;
1271 String itemResourceId;
1272 String contactResourceId;
1273 // Clean up contact resources.
1274 PersonAuthorityClient client = new PersonAuthorityClient();
1275 parentResourceId = knownResourceId;
1276 for (Map.Entry<String, String> entry : allContactResourceIdsCreated.entrySet()) {
1277 contactResourceId = entry.getKey();
1278 itemResourceId = entry.getValue();
1279 // Note: Any non-success responses from the delete operation
1280 // below are ignored and not reported.
1281 ClientResponse<Response> res =
1282 client.deleteContact(parentResourceId, itemResourceId, contactResourceId);
1283 res.releaseConnection();
1285 // Clean up item resources.
1286 for (Map.Entry<String, String> entry : allResourceItemIdsCreated.entrySet()) {
1287 itemResourceId = entry.getKey();
1288 parentResourceId = entry.getValue();
1289 // Note: Any non-success responses from the delete operation
1290 // below are ignored and not reported.
1291 ClientResponse<Response> res =
1292 client.deleteItem(parentResourceId, itemResourceId);
1293 res.releaseConnection();
1295 // Clean up parent resources.
1299 // ---------------------------------------------------------------
1300 // Utility methods used by tests above
1301 // ---------------------------------------------------------------
1303 * Gets the contact service path component.
1305 * @return the contact service path component
1307 public String getContactServicePathComponent() {
1308 return ContactClient.SERVICE_PATH_COMPONENT;
1312 * Returns the root URL for the item service.
1314 * This URL consists of a base URL for all services, followed by
1315 * a path component for the owning parent, followed by the
1316 * path component for the items.
1318 * @param parentResourceIdentifier An identifier (such as a UUID) for the
1319 * parent authority resource of the relevant item resource.
1321 * @return The root URL for the item service.
1323 protected String getItemServiceRootURL(String parentResourceIdentifier) {
1324 return getResourceURL(parentResourceIdentifier) + "/" + getItemServicePathComponent();
1328 * Returns the URL of a specific item resource managed by a service, and
1329 * designated by an identifier (such as a universally unique ID, or UUID).
1331 * @param parentResourceIdentifier An identifier (such as a UUID) for the
1332 * parent authority resource of the relevant item resource.
1334 * @param itemResourceIdentifier An identifier (such as a UUID) for an
1337 * @return The URL of a specific item resource managed by a service.
1339 protected String getItemResourceURL(String parentResourceIdentifier, String itemResourceIdentifier) {
1340 return getItemServiceRootURL(parentResourceIdentifier) + "/" + itemResourceIdentifier;
1344 * Returns the root URL for the contact service.
1346 * This URL consists of a base URL for all services, followed by
1347 * a path component for the owning authority, followed by the
1348 * path component for the owning item, followed by the path component
1349 * for the contact service.
1351 * @param parentResourceIdentifier An identifier (such as a UUID) for the
1352 * parent authority resource of the relevant item resource.
1354 * @param itemResourceIdentifier An identifier (such as a UUID) for an
1357 * @return The root URL for the contact service.
1359 protected String getContactServiceRootURL(String parentResourceIdentifier,
1360 String itemResourceIdentifier) {
1361 return getItemResourceURL(parentResourceIdentifier, itemResourceIdentifier) + "/"
1362 + getContactServicePathComponent();
1366 * Returns the URL of a specific contact resource managed by a service, and
1367 * designated by an identifier (such as a universally unique ID, or UUID).
1369 * @param parentResourceIdentifier An identifier (such as a UUID) for the
1370 * parent resource of the relevant item resource.
1372 * @param resourceIdentifier An identifier (such as a UUID) for an
1375 * @return The URL of a specific resource managed by a service.
1377 protected String getContactResourceURL(String parentResourceIdentifier,
1378 String itemResourceIdentifier, String contactResourceIdentifier) {
1379 return getContactServiceRootURL(parentResourceIdentifier,
1380 itemResourceIdentifier) + "/" + contactResourceIdentifier;
1384 public void authorityTests(String testName) {
1385 // TODO Auto-generated method stub
1390 protected PersonsCommon updateItemInstance(PersonsCommon authorityItem) {
1391 // TODO Auto-generated method stub
1396 protected void compareUpdatedItemInstances(PersonsCommon original,
1397 PersonsCommon updated) throws Exception {
1398 // TODO Auto-generated method stub
1403 protected PoxPayloadOut createInstance(String commonPartName,
1404 String identifier) {
1405 String shortId = identifier;
1406 String displayName = "displayName-" + shortId;
1407 PoxPayloadOut result =
1408 PersonAuthorityClientUtils.createPersonAuthorityInstance(
1409 displayName, shortId, commonPartName);
1414 protected PoxPayloadOut createNonExistenceInstance(String commonPartName,
1415 String identifier) {
1416 String displayName = "displayName-NON_EXISTENT_ID";
1417 PoxPayloadOut result = PersonAuthorityClientUtils.createPersonAuthorityInstance(
1418 displayName, "NON_EXISTENT_SHORT_ID", commonPartName);
1422 protected PoxPayloadOut createNonExistenceItemInstance(String commonPartName, String identifier) {
1423 Map<String, String> nonexMap = new HashMap<String, String>();
1424 nonexMap.put(PersonJAXBSchema.SHORT_IDENTIFIER, "nonEX");
1425 nonexMap.put(PersonJAXBSchema.GENDER, "male");
1427 List<PersonTermGroup> terms = new ArrayList<PersonTermGroup>();
1428 PersonTermGroup term = new PersonTermGroup();
1429 term.setTermDisplayName("John Wayne");
1430 term.setTermName("John Wayne");
1431 term.setForeName("John");
1432 term.setSurName("Wayne");
1435 Map<String, List<String>> nonexRepeatablesMap = new HashMap<String, List<String>>();
1436 PoxPayloadOut result =
1437 PersonAuthorityClientUtils.createPersonInstance(NON_EXISTENT_ID,
1438 null, //PersonAuthorityClientUtils.createPersonAuthRefName(NON_EXISTENT_ID, null),
1439 nonexMap, terms, nonexRepeatablesMap, commonPartName);
1445 protected PersonauthoritiesCommon updateInstance(
1446 PersonauthoritiesCommon commonPartObject) {
1447 // TODO Auto-generated method stub
1452 protected void compareUpdatedInstances(PersonauthoritiesCommon original,
1453 PersonauthoritiesCommon updated) throws Exception {
1454 // TODO Auto-generated method stub
1458 protected void verifyReadItemInstance(PersonsCommon item) throws Exception {
1459 // Do nothing for now. Add more 'read' validation checks here if applicable.