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 © 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.text.Collator;
26 import java.util.ArrayList;
27 import java.util.Comparator;
28 import java.util.List;
29 import java.util.Locale;
30 import javax.ws.rs.core.MediaType;
31 import javax.ws.rs.core.Response;
33 import org.collectionspace.services.MovementJAXBSchema;
34 import org.collectionspace.services.client.CollectionSpaceClient;
35 import org.collectionspace.services.client.MovementClient;
36 import org.collectionspace.services.client.PayloadInputPart;
37 import org.collectionspace.services.client.PayloadOutputPart;
38 import org.collectionspace.services.client.PoxPayloadIn;
39 import org.collectionspace.services.client.PoxPayloadOut;
40 import org.collectionspace.services.common.AbstractCommonListUtils;
41 import org.collectionspace.services.movement.MovementsCommon;
42 import org.collectionspace.services.jaxb.AbstractCommonList;
44 import org.jboss.resteasy.client.ClientResponse;
46 import org.testng.Assert;
47 import org.testng.annotations.AfterClass;
48 import org.testng.annotations.DataProvider;
49 import org.testng.annotations.Test;
51 import org.slf4j.Logger;
52 import org.slf4j.LoggerFactory;
55 * MovementSortByTest, tests sorting of summary lists by fields
56 * of various datatypes.
58 * $LastChangedRevision: 2562 $
59 * $LastChangedDate: 2010-06-22 23:26:51 -0700 (Tue, 22 Jun 2010) $
61 public class MovementSortByTest extends BaseServiceTest {
63 private final String CLASS_NAME = MovementSortByTest.class.getName();
64 private final Logger logger = LoggerFactory.getLogger(CLASS_NAME);
65 final String SERVICE_NAME = "movements";
67 // Instance variables specific to this test.
68 private final String DELIMITER_SCHEMA_AND_FIELD = ":";
69 private final String KEYWORD_DESCENDING_SEARCH = "DESC";
70 private final String SERVICE_PATH_COMPONENT = "movements";
71 private final String TEST_SPECIFIC_KEYWORD = "msotebstpfscn";
72 private List<String> movementIdsCreated = new ArrayList<String>();
73 private final String SORT_FIELD_SEPARATOR = ", ";
74 private final Locale LOCALE = Locale.US;
75 private final String LOCATION_DATE_EL_NAME = "locationDate";
78 * @see org.collectionspace.services.client.test.BaseServiceTest#getClientInstance()
81 protected CollectionSpaceClient getClientInstance() {
82 throw new UnsupportedOperationException(); //method not supported (or needed) in this test class
86 * @see org.collectionspace.services.client.test.BaseServiceTest#getAbstractCommonList(org.jboss.resteasy.client.ClientResponse)
89 protected AbstractCommonList getAbstractCommonList(
90 ClientResponse<AbstractCommonList> response) {
91 throw new UnsupportedOperationException(); //method not supported (or needed) in this test class
94 // ---------------------------------------------------------------
96 // ---------------------------------------------------------------
101 * Tests whether a list of records, sorted by a String field in
102 * ascending order, is returned in the expected order.
104 @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class,
105 dependsOnMethods = {"createList"})
106 public void sortByStringFieldAscending(String testName) throws Exception {
108 if (logger.isDebugEnabled()) {
109 logger.debug(testBanner(testName, CLASS_NAME));
112 String sortFieldName = qualifySortFieldName(MovementJAXBSchema.MOVEMENT_NOTE);
113 if (logger.isDebugEnabled()) {
114 logger.debug("Sorting on field name=" + sortFieldName);
116 AbstractCommonList list = readSortedList(sortFieldName);
117 List<AbstractCommonList.ListItem> items =
120 ArrayList<String> values = new ArrayList<String>();
121 Collator localeSpecificCollator = Collator.getInstance(LOCALE);
123 for (AbstractCommonList.ListItem item : items) {
124 // Because movementNote is not currently a summary field
125 // (returned in summary list items), we will need to verify
126 // sort order by retrieving full records, using the
127 // IDs provided in the summary list items. amd then retriving
128 // the value of that field from each of those records.
129 MovementsCommon movement = read(AbstractCommonListUtils.ListItemGetCSID(item));
130 values.add(i, movement.getMovementNote());
131 if (logger.isDebugEnabled()) {
132 logger.debug("list-item[" + i + "] movementNote=" + values.get(i));
134 // Verify that the value of the specified field in the current record
135 // is equal to or greater than its value in the previous record,
136 // using a locale-specific collator.
138 // (Note: when used with certain text, this test case could potentially
139 // reflect inconsistencies, if any, between Java's collator and the
140 // collator used for ordering by the database. To help avoid this,
141 // it might be useful to keep test strings fairly generic.)
142 if (i > 0 && values.get(i) != null && values.get(i - 1) != null) {
143 Assert.assertTrue(localeSpecificCollator.compare(values.get(i), values.get(i - 1)) >= 0);
151 * Tests whether a list of records, obtained by a keyword search, and
152 * sorted by a String field in ascending order, is returned in the expected order.
154 * This verifies that summary list results from keyword searches, in
155 * addition to 'read list' requests, can be returned in sorted order.
157 @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class,
158 dependsOnMethods = {"createList"})
159 public void sortKeywordSearchResultsByStringFieldAscending(String testName) throws Exception {
161 if (logger.isDebugEnabled()) {
162 logger.debug(testBanner(testName, CLASS_NAME));
165 String sortFieldName = qualifySortFieldName(MovementJAXBSchema.MOVEMENT_NOTE);
166 if (logger.isDebugEnabled()) {
167 logger.debug("Sorting on field name=" + sortFieldName);
169 AbstractCommonList list = keywordSearchSortedBy(TEST_SPECIFIC_KEYWORD, sortFieldName);
170 List<AbstractCommonList.ListItem> items =
173 ArrayList<String> values = new ArrayList<String>();
174 Collator localeSpecificCollator = Collator.getInstance(LOCALE);
176 for (AbstractCommonList.ListItem item : items) {
177 // Because movementNote is not currently a summary field
178 // (returned in summary list items), we will need to verify
179 // sort order by retrieving full records, using the
180 // IDs provided in the summary list items. amd then retriving
181 // the value of that field from each of those records.
182 MovementsCommon movement = read(AbstractCommonListUtils.ListItemGetCSID(item));
183 values.add(i, movement.getMovementNote());
184 if (logger.isDebugEnabled()) {
185 logger.debug("list-item[" + i + "] movementNote=" + values.get(i));
187 // Verify that the value of the specified field in the current record
188 // is equal to or greater than its value in the previous record,
189 // using a locale-specific collator.
191 // (Note: when used with certain text, this test case could potentially
192 // reflect inconsistencies, if any, between Java's collator and the
193 // collator used for ordering by the database. To help avoid this,
194 // it might be useful to keep test strings fairly generic.)
195 if (i > 0 && values.get(i) != null && values.get(i - 1) != null) {
196 Assert.assertTrue(localeSpecificCollator.compare(values.get(i), values.get(i - 1)) >= 0);
204 * Tests whether a list of records, sorted by a String field in
205 * descending order, is returned in the expected order.
207 @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class,
208 dependsOnMethods = {"createList"})
209 public void sortByStringFieldDescending(String testName) throws Exception {
211 if (logger.isDebugEnabled()) {
212 logger.debug(testBanner(testName, CLASS_NAME));
215 String sortFieldName =
216 asDescendingSort(qualifySortFieldName(MovementJAXBSchema.MOVEMENT_NOTE));
217 if (logger.isDebugEnabled()) {
218 logger.debug("Sorting on field name=" + sortFieldName);
220 AbstractCommonList list = readSortedList(sortFieldName);
221 List<AbstractCommonList.ListItem> items =
224 ArrayList<String> values = new ArrayList<String>();
225 Collator localeSpecificCollator = Collator.getInstance(LOCALE);
227 for (AbstractCommonList.ListItem item : items) {
228 // Because movementNote is not currently a summary field
229 // (returned in summary list items), we will need to verify
230 // sort order by retrieving full records, using the
231 // IDs provided in the summary list items. amd then retriving
232 // the value of that field from each of those records.
233 MovementsCommon movement = read(AbstractCommonListUtils.ListItemGetCSID(item));
234 values.add(i, movement.getMovementNote());
235 if (logger.isDebugEnabled()) {
236 logger.debug("list-item[" + i + "] movementNote=" + values.get(i));
238 // Verify that the value of the specified field in the current record
239 // is less than or equal to than its value in the previous record,
240 // using a locale-specific collator.
242 // (Note: when used with certain text, this test case could potentially
243 // reflect inconsistencies, if any, between Java's collator and the
244 // collator used for ordering by the database. To help avoid this,
245 // it might be useful to keep test strings fairly generic.)
246 if (i > 0 && values.get(i) != null && values.get(i - 1) != null) {
247 Assert.assertTrue(localeSpecificCollator.compare(values.get(i), values.get(i - 1)) <= 0);
255 * Tests whether a list of records, sorted by a dateTime field in
256 * ascending order, is returned in the expected order.
258 @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class,
259 dependsOnMethods = {"createList"})
260 public void sortByDateTimeFieldAscending(String testName) throws Exception {
262 if (logger.isDebugEnabled()) {
263 logger.debug(testBanner(testName, CLASS_NAME));
266 String sortFieldName = qualifySortFieldName(MovementJAXBSchema.LOCATION_DATE);
267 if (logger.isDebugEnabled()) {
268 logger.debug("Sorting on field name=" + sortFieldName);
270 AbstractCommonList list = readSortedList(sortFieldName);
271 List<AbstractCommonList.ListItem> items =
274 ArrayList<String> values = new ArrayList<String>();
275 Comparator<String> comparator = String.CASE_INSENSITIVE_ORDER;
277 for (AbstractCommonList.ListItem item : items) {
279 AbstractCommonListUtils.ListItemGetElementValue(item, LOCATION_DATE_EL_NAME);
280 values.add(i, locDate);
281 if (logger.isDebugEnabled()) {
282 logger.debug("list-item[" + i + "] locationDate=" + values.get(i));
284 // Verify that the value of the specified field in the current record
285 // is equal to or greater than its value in the previous record.
286 if (i > 0 && values.get(i) != null && values.get(i - 1) != null) {
287 Assert.assertTrue(comparator.compare(values.get(i), values.get(i - 1)) >= 0);
294 * Tests whether a list of records, sorted by a dateTime field in
295 * descending order, is returned in the expected order.
297 @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class,
298 dependsOnMethods = {"createList"})
299 public void sortByDateTimeFieldDescending(String testName) throws Exception {
301 if (logger.isDebugEnabled()) {
302 logger.debug(testBanner(testName, CLASS_NAME));
305 String sortFieldName =
306 asDescendingSort(qualifySortFieldName(MovementJAXBSchema.LOCATION_DATE));
307 if (logger.isDebugEnabled()) {
308 logger.debug("Sorting on field name=" + sortFieldName);
310 AbstractCommonList list = readSortedList(sortFieldName);
311 List<AbstractCommonList.ListItem> items =
314 ArrayList<String> values = new ArrayList<String>();
315 Comparator<String> comparator = String.CASE_INSENSITIVE_ORDER;
317 for (AbstractCommonList.ListItem item : items) {
319 AbstractCommonListUtils.ListItemGetElementValue(item, LOCATION_DATE_EL_NAME);
320 values.add(i, locDate);
321 if (logger.isDebugEnabled()) {
322 logger.debug("list-item[" + i + "] locationDate=" + values.get(i));
324 // Verify that the value of the specified field in the current record
325 // is less than or equal to its value in the previous record.
326 if (i > 0 && values.get(i) != null && values.get(i - 1) != null) {
327 Assert.assertTrue(comparator.compare(values.get(i), values.get(i - 1)) <= 0);
334 * Tests whether a list of records, sorted by two different fields in
335 * ascending order, is returned in the expected order.
337 @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class,
338 dependsOnMethods = {"createList"})
339 public void sortByTwoFieldsAscending(String testName) throws Exception {
341 if (logger.isDebugEnabled()) {
342 logger.debug(testBanner(testName, CLASS_NAME));
345 String firstSortFieldName = qualifySortFieldName(MovementJAXBSchema.MOVEMENT_NOTE);
346 String secondSortFieldName = qualifySortFieldName(MovementJAXBSchema.LOCATION_DATE);
347 if (logger.isDebugEnabled()) {
348 logger.debug("Sorting on field names=" + firstSortFieldName + " and " + secondSortFieldName);
350 String sortExpression = firstSortFieldName + SORT_FIELD_SEPARATOR + secondSortFieldName;
351 AbstractCommonList list = readSortedList(sortExpression);
352 List<AbstractCommonList.ListItem> items =
355 ArrayList<String> firstFieldValues = new ArrayList<String>();
356 ArrayList<String> secondFieldValues = new ArrayList<String>();
357 Collator localeSpecificCollator = Collator.getInstance(LOCALE);
358 Comparator<String> comparator = String.CASE_INSENSITIVE_ORDER;
360 for (AbstractCommonList.ListItem item : items) {
361 // Because movementNote is not currently a summary field
362 // (returned in summary list items), we will need to verify
363 // sort order by retrieving full records, using the
364 // IDs provided in the summary list items. amd then retriving
365 // the value of that field from each of those records.
366 MovementsCommon movement = read(AbstractCommonListUtils.ListItemGetCSID(item));
367 firstFieldValues.add(i, movement.getMovementNote());
368 secondFieldValues.add(i, movement.getLocationDate());
369 if (logger.isDebugEnabled()) {
370 logger.debug("list-item[" + i + "] movementNote=" + firstFieldValues.get(i));
371 logger.debug("list-item[" + i + "] locationDate=" + secondFieldValues.get(i));
373 // Verify that the value of the specified field in the current record
374 // is less than or greater than its value in the previous record.
375 if (i > 0 && firstFieldValues.get(i) != null && firstFieldValues.get(i - 1) != null) {
376 Assert.assertTrue(localeSpecificCollator.compare(firstFieldValues.get(i), firstFieldValues.get(i - 1)) >= 0);
377 // If the value of the first sort field in the current record is identical to
378 // its value in the previous record, verify that the value of the second sort
379 // field is equal to or greater than its value in the previous record,
380 // using a locale-specific collator.
381 if (localeSpecificCollator.compare(firstFieldValues.get(i), firstFieldValues.get(i - 1)) == 0) {
382 if (i > 0 && secondFieldValues.get(i) != null && secondFieldValues.get(i - 1) != null) {
383 Assert.assertTrue(comparator.compare(secondFieldValues.get(i), secondFieldValues.get(i - 1)) >= 0);
392 * Tests whether a list of records, sorted by one different fields in
393 * descending order and a second field in ascending order, is returned in the expected order.
395 @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class,
396 dependsOnMethods = {"createList"})
397 public void sortByOneFieldAscendingOneFieldsDescending(String testName) throws Exception {
399 if (logger.isDebugEnabled()) {
400 logger.debug(testBanner(testName, CLASS_NAME));
403 String firstSortFieldName =
404 asDescendingSort(qualifySortFieldName(MovementJAXBSchema.LOCATION_DATE));
405 String secondSortFieldName = qualifySortFieldName(MovementJAXBSchema.MOVEMENT_NOTE);
406 if (logger.isDebugEnabled()) {
407 logger.debug("Sorting on field names=" + firstSortFieldName + " and " + secondSortFieldName);
409 String sortExpression = firstSortFieldName + SORT_FIELD_SEPARATOR + secondSortFieldName;
410 AbstractCommonList list = readSortedList(sortExpression);
411 List<AbstractCommonList.ListItem> items =
414 ArrayList<String> firstFieldValues = new ArrayList<String>();
415 ArrayList<String> secondFieldValues = new ArrayList<String>();
416 Collator localeSpecificCollator = Collator.getInstance(LOCALE);
417 Comparator<String> comparator = String.CASE_INSENSITIVE_ORDER;
419 for (AbstractCommonList.ListItem item : items) {
420 // Because movementNote is not currently a summary field
421 // (returned in summary list items), we will need to verify
422 // sort order by retrieving full records, using the
423 // IDs provided in the summary list items. amd then retriving
424 // the value of that field from each of those records.
425 MovementsCommon movement = read(AbstractCommonListUtils.ListItemGetCSID(item));
426 firstFieldValues.add(i, movement.getLocationDate());
427 secondFieldValues.add(i, movement.getMovementNote());
428 if (logger.isDebugEnabled()) {
429 logger.debug("list-item[" + i + "] locationDate=" + firstFieldValues.get(i));
430 logger.debug("list-item[" + i + "] movementNote=" + secondFieldValues.get(i));
432 // Verify that the value of the specified field in the current record
433 // is less than or equal to than its value in the previous record.
434 if (i > 0 && firstFieldValues.get(i) != null && firstFieldValues.get(i - 1) != null) {
435 Assert.assertTrue(comparator.compare(firstFieldValues.get(i), firstFieldValues.get(i - 1)) <= 0);
436 // If the value of the first sort field in the current record is identical to
437 // its value in the previous record, verify that the value of the second sort
438 // field is equal to or greater than its value in the previous record,
439 // using a locale-specific collator.
440 if (comparator.compare(firstFieldValues.get(i), firstFieldValues.get(i - 1)) == 0) {
441 if (i > 0 && secondFieldValues.get(i) != null && secondFieldValues.get(i - 1) != null) {
442 Assert.assertTrue(localeSpecificCollator.compare(secondFieldValues.get(i), secondFieldValues.get(i - 1)) >= 0);
452 * Tests whether a request to sort by an empty field name is handled
453 * as expected: the query parameter is simply ignored, and a list
454 * of records is returned, unsorted, with a success result.
456 @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class)
457 public void sortWithEmptySortFieldName(String testName) throws Exception {
459 if (logger.isDebugEnabled()) {
460 logger.debug(testBanner(testName, CLASS_NAME));
462 testSetup(STATUS_OK, ServiceRequestType.READ);
464 // Submit the request to the service and store the response.
465 MovementClient client = new MovementClient();
466 final String EMPTY_SORT_FIELD_NAME = "";
467 ClientResponse<AbstractCommonList> res =
468 client.readListSortedBy(EMPTY_SORT_FIELD_NAME);
469 int statusCode = res.getStatus();
471 // Check the status code of the response: does it match
472 // the expected response(s)?
473 if (logger.isDebugEnabled()) {
474 logger.debug(testName + ": status = " + statusCode);
476 Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
477 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
478 Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
485 * Tests whether a request to sort by an unqualified field name is
486 * handled as expected. The field name provided in this test is valid,
487 * but has not been qualified by being prefixed by a schema name and delimiter.
489 @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class)
490 public void sortWithUnqualifiedFieldName(String testName) throws Exception {
492 if (logger.isDebugEnabled()) {
493 logger.debug(testBanner(testName, CLASS_NAME));
495 testSetup(STATUS_BAD_REQUEST, ServiceRequestType.READ);
497 // Submit the request to the service and store the response.
498 MovementClient client = new MovementClient();
499 ClientResponse<AbstractCommonList> res =
500 client.readListSortedBy(MovementJAXBSchema.LOCATION_DATE);
501 int statusCode = res.getStatus();
503 // Check the status code of the response: does it match
504 // the expected response(s)?
505 if (logger.isDebugEnabled()) {
506 logger.debug(testName + ": status = " + statusCode);
508 Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
509 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
510 Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
515 * Tests whether a request to sort by an invalid identifier for the
516 * sort order (ascending or descending) is handled as expected.
518 @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class)
519 public void sortWithInvalidSortOrderIdentifier(String testName) throws Exception {
521 if (logger.isDebugEnabled()) {
522 logger.debug(testBanner(testName, CLASS_NAME));
524 testSetup(STATUS_BAD_REQUEST, ServiceRequestType.READ);
526 // Submit the request to the service and store the response.
527 MovementClient client = new MovementClient();
528 final String INVALID_SORT_ORDER_IDENTIFIER = "NO_DIRECTION";
529 ClientResponse<AbstractCommonList> res =
530 client.readListSortedBy(MovementJAXBSchema.LOCATION_DATE
531 + " " + INVALID_SORT_ORDER_IDENTIFIER);
532 int statusCode = res.getStatus();
534 // Check the status code of the response: does it match
535 // the expected response(s)?
536 if (logger.isDebugEnabled()) {
537 logger.debug(testName + ": status = " + statusCode);
539 Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
540 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
541 Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
546 * Tests whether a request to sort by a malformed field name is
547 * handled as expected.
550 @Test(dataProvider="testName", dataProviderClass=AbstractServiceTestImpl.class)
551 public void sortWithMalformedFieldName(String testName) throws Exception {
553 // FIXME: Implement this stub method.
555 // FIXME: Consider splitting this test into various tests, with
556 // different malformed field name formats that might confuse parsers
557 // and/or validation code.
559 // FIXME: Consider fixing DocumentFilter.setSortOrder() to return
560 // an error response to this test case, then revise this test case
561 // to expect that response.
566 // ---------------------------------------------------------------
567 // Cleanup of resources created during testing
568 // ---------------------------------------------------------------
570 * Deletes all resources created by tests, after all tests have been run.
572 * This cleanup method will always be run, even if one or more tests fail.
573 * For this reason, it attempts to remove all resources created
574 * at any point during testing, even if some of those resources
575 * may be expected to be deleted by certain tests.
577 @AfterClass(alwaysRun = true)
578 public void cleanUp() {
579 String noTest = System.getProperty("noTestCleanup");
580 if (Boolean.TRUE.toString().equalsIgnoreCase(noTest)) {
581 if (logger.isDebugEnabled()) {
582 logger.debug("Skipping Cleanup phase ...");
586 if (logger.isDebugEnabled()) {
587 logger.debug("Cleaning up temporary resources created for testing ...");
589 // Delete all Movement resource(s) created during this test.
590 MovementClient movementClient = new MovementClient();
591 for (String resourceId : movementIdsCreated) {
592 // Note: Any non-success responses are ignored and not reported.
593 movementClient.delete(resourceId);
597 // ---------------------------------------------------------------
598 // Utility methods used by tests above
599 // ---------------------------------------------------------------
602 protected String getServiceName() {
607 public String getServicePathComponent() {
608 return SERVICE_PATH_COMPONENT;
611 private String getCommonSchemaName() {
612 // FIXME: While this convention - appending a suffix to the name of
613 // the service's first unique URL path component - works, it would
614 // be preferable to get the common schema name from configuration.
616 // Such configuration is provided for example, on the services side, in
617 // org.collectionspace.services.common.context.AbstractServiceContextImpl
618 return getServicePathComponent() + "_" + "common";
621 public String qualifySortFieldName(String fieldName) {
622 return getCommonSchemaName() + DELIMITER_SCHEMA_AND_FIELD + fieldName;
625 public String asDescendingSort(String qualifiedFieldName) {
626 return qualifiedFieldName + " " + KEYWORD_DESCENDING_SEARCH;
630 * A data provider that provides a set of unsorted values, which are
631 * to be used in populating (seeding) values in test records.
633 * Data elements provided for each test record consist of:
634 * * An integer, reflecting expected sort order.
635 * * US English text, to populate the value of a free text (String) field.
636 * * An ISO 8601 timestamp, to populate the value of a calendar date (dateTime) field.
638 @DataProvider(name = "unsortedValues")
639 public Object[][] unsortedValues() {
640 // FIXME: ADR Add a test record-specific string so we have the option of
641 // constraining tests to only test records, in list or search results.
642 final String TEST_RECORD_SPECIFIC_STRING = CLASS_NAME + " " + TEST_SPECIFIC_KEYWORD;
643 return new Object[][]{
644 {1, "Aardvark and plumeria. " + TEST_RECORD_SPECIFIC_STRING, "2009-01-29T00:00:05Z"},
645 {10, "Zounds! " + TEST_RECORD_SPECIFIC_STRING, "2010-08-31T00:00:00Z"},
646 {3, "Aardvark and plumeria. " + TEST_RECORD_SPECIFIC_STRING, "2010-08-30T00:00:00Z"},
647 {7, "Bat fling off wall. " + TEST_RECORD_SPECIFIC_STRING, "2010-08-30T00:00:00Z"},
648 {4, "Aardvarks and plumeria. " + TEST_RECORD_SPECIFIC_STRING, "2009-01-29T08:00:00Z"},
649 {5, "Aardvarks and plumeria. " + TEST_RECORD_SPECIFIC_STRING, "2009-05-29T00:00:00Z"},
650 {2, "Aardvark and plumeria. " + TEST_RECORD_SPECIFIC_STRING, "2009-05-29T00:00:00Z"},
651 {9, "Zounds! " + TEST_RECORD_SPECIFIC_STRING, "2009-05-29T00:00:00Z"}, // Identical to next record
652 {8, "Zounds! " + TEST_RECORD_SPECIFIC_STRING, "2009-05-29T00:00:00Z"},
653 {6, "Bat flies off ball. " + TEST_RECORD_SPECIFIC_STRING, "2009-05-29T00:00:00Z"}
658 * Create multiple test records, initially in unsorted order,
659 * using values for various fields obtained from the data provider.
661 @Test(dataProvider = "unsortedValues")
662 public void createList(int expectedSortOrder, String movementNote,
663 String locationDate) throws Exception {
665 String testName = "createList";
666 if (logger.isDebugEnabled()) {
667 logger.debug(testBanner(testName, CLASS_NAME));
669 testSetup(STATUS_CREATED, ServiceRequestType.CREATE);
671 // Iterates through the sets of values returned by the data provider,
672 // and creates a corresponding test record for each set of values.
673 create(movementNote, locationDate);
676 private void create(String movementNote, String locationDate) throws Exception {
678 String testName = "create";
679 testSetup(STATUS_CREATED, ServiceRequestType.CREATE);
681 // Submit the request to the service and store the response.
682 PoxPayloadOut multipart = createMovementInstance(createIdentifier(),
683 movementNote, locationDate);
684 MovementClient client = new MovementClient();
685 ClientResponse<Response> res = client.create(multipart);
686 int statusCode = res.getStatus();
688 // Check the status code of the response: does it match
689 // the expected response(s)?
692 // Does it fall within the set of valid status codes?
693 // Does it exactly match the expected status code?
694 if (logger.isDebugEnabled()) {
695 logger.debug(testName + ": status = " + statusCode);
697 Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
698 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
699 Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
701 // Store the IDs from every resource created by tests,
702 // so they can be deleted after tests have been run.
703 movementIdsCreated.add(extractId(res));
706 private MovementsCommon read(String csid) throws Exception {
708 String testName = "read";
709 testSetup(STATUS_OK, ServiceRequestType.READ);
711 // Submit the request to the service and store the response.
712 MovementClient client = new MovementClient();
713 ClientResponse<String> res = client.read(csid);
714 int statusCode = res.getStatus();
716 // Check the status code of the response: does it match
717 // the expected response(s)?
718 if (logger.isDebugEnabled()) {
719 logger.debug(testName + ": status = " + statusCode);
721 Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
722 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
723 Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
725 // Extract and return the common part of the record.
726 PoxPayloadIn input = new PoxPayloadIn(res.getEntity());
727 PayloadInputPart payloadInputPart = input.getPart(client.getCommonPartName());
728 MovementsCommon movementCommon = null;
729 if (payloadInputPart != null) {
730 movementCommon = (MovementsCommon) payloadInputPart.getBody();
733 return movementCommon;
736 private PoxPayloadOut createMovementInstance(
737 String movementReferenceNumber,
739 String locationDate) {
740 MovementsCommon movementCommon = new MovementsCommon();
741 movementCommon.setMovementReferenceNumber(movementReferenceNumber);
742 movementCommon.setMovementNote(movementNote);
743 movementCommon.setLocationDate(locationDate);
745 PoxPayloadOut multipart = new PoxPayloadOut(this.getServicePathComponent());
746 PayloadOutputPart commonPart =
747 multipart.addPart(movementCommon, MediaType.APPLICATION_XML_TYPE);
748 commonPart.setLabel(new MovementClient().getCommonPartName());
749 if (logger.isDebugEnabled()) {
750 logger.debug("to be created, movement common");
751 logger.debug(objectAsXmlString(movementCommon, MovementsCommon.class));
757 private AbstractCommonList readSortedList(String sortFieldName) throws Exception {
759 String testName = "readSortedList";
760 testSetup(STATUS_OK, ServiceRequestType.READ);
762 // Submit the request to the service and store the response.
763 MovementClient client = new MovementClient();
765 ClientResponse<AbstractCommonList> res =
766 client.readListSortedBy(sortFieldName);
767 AbstractCommonList list = res.getEntity();
768 int statusCode = res.getStatus();
770 // Check the status code of the response: does it match
771 // the expected response(s)?
772 if (logger.isDebugEnabled()) {
773 logger.debug(testName + ": status = " + statusCode);
775 Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
776 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
777 Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
783 private AbstractCommonList keywordSearchSortedBy(String keywords,
784 String sortFieldName) throws Exception {
786 String testName = "keywordSearchSortedBy";
787 testSetup(STATUS_OK, ServiceRequestType.READ);
789 // Submit the request to the service and store the response.
790 MovementClient client = new MovementClient();
792 ClientResponse<AbstractCommonList> res =
793 client.keywordSearchSortedBy(keywords, sortFieldName);
794 AbstractCommonList list = res.getEntity();
795 int statusCode = res.getStatus();
797 // Check the status code of the response: does it match
798 // the expected response(s)?
799 if (logger.isDebugEnabled()) {
800 logger.debug(testName + ": status = " + statusCode);
802 Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
803 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
804 Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);