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.movement.MovementsCommon;
41 import org.collectionspace.services.movement.MovementsCommonList;
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;
77 * @see org.collectionspace.services.client.test.BaseServiceTest#getClientInstance()
80 protected CollectionSpaceClient getClientInstance() {
81 throw new UnsupportedOperationException(); //method not supported (or needed) in this test class
85 * @see org.collectionspace.services.client.test.BaseServiceTest#getAbstractCommonList(org.jboss.resteasy.client.ClientResponse)
88 protected AbstractCommonList getAbstractCommonList(
89 ClientResponse<AbstractCommonList> response) {
90 throw new UnsupportedOperationException(); //method not supported (or needed) in this test class
93 // ---------------------------------------------------------------
95 // ---------------------------------------------------------------
100 * Tests whether a list of records, sorted by a String field in
101 * ascending order, is returned in the expected order.
103 @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class,
104 dependsOnMethods = {"createList"})
105 public void sortByStringFieldAscending(String testName) throws Exception {
107 if (logger.isDebugEnabled()) {
108 logger.debug(testBanner(testName, CLASS_NAME));
111 String sortFieldName = qualifySortFieldName(MovementJAXBSchema.MOVEMENT_NOTE);
112 if (logger.isDebugEnabled()) {
113 logger.debug("Sorting on field name=" + sortFieldName);
115 MovementsCommonList list = readSortedList(sortFieldName);
116 List<MovementsCommonList.MovementListItem> items =
117 list.getMovementListItem();
119 ArrayList<String> values = new ArrayList<String>();
120 Collator localeSpecificCollator = Collator.getInstance(LOCALE);
122 for (MovementsCommonList.MovementListItem item : items) {
123 // Because movementNote is not currently a summary field
124 // (returned in summary list items), we will need to verify
125 // sort order by retrieving full records, using the
126 // IDs provided in the summary list items. amd then retriving
127 // the value of that field from each of those records.
128 MovementsCommon movement = read(item.getCsid());
129 values.add(i, movement.getMovementNote());
130 if (logger.isDebugEnabled()) {
131 logger.debug("list-item[" + i + "] movementNote=" + values.get(i));
133 // Verify that the value of the specified field in the current record
134 // is equal to or greater than its value in the previous record,
135 // using a locale-specific collator.
137 // (Note: when used with certain text, this test case could potentially
138 // reflect inconsistencies, if any, between Java's collator and the
139 // collator used for ordering by the database. To help avoid this,
140 // it might be useful to keep test strings fairly generic.)
141 if (i > 0 && values.get(i) != null && values.get(i - 1) != null) {
142 Assert.assertTrue(localeSpecificCollator.compare(values.get(i), values.get(i - 1)) >= 0);
150 * Tests whether a list of records, obtained by a keyword search, and
151 * sorted by a String field in ascending order, is returned in the expected order.
153 * This verifies that summary list results from keyword searches, in
154 * addition to 'read list' requests, can be returned in sorted order.
156 @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class,
157 dependsOnMethods = {"createList"})
158 public void sortKeywordSearchResultsByStringFieldAscending(String testName) throws Exception {
160 if (logger.isDebugEnabled()) {
161 logger.debug(testBanner(testName, CLASS_NAME));
164 String sortFieldName = qualifySortFieldName(MovementJAXBSchema.MOVEMENT_NOTE);
165 if (logger.isDebugEnabled()) {
166 logger.debug("Sorting on field name=" + sortFieldName);
168 MovementsCommonList list = keywordSearchSortedBy(TEST_SPECIFIC_KEYWORD, sortFieldName);
169 List<MovementsCommonList.MovementListItem> items =
170 list.getMovementListItem();
172 ArrayList<String> values = new ArrayList<String>();
173 Collator localeSpecificCollator = Collator.getInstance(LOCALE);
175 for (MovementsCommonList.MovementListItem item : items) {
176 // Because movementNote is not currently a summary field
177 // (returned in summary list items), we will need to verify
178 // sort order by retrieving full records, using the
179 // IDs provided in the summary list items. amd then retriving
180 // the value of that field from each of those records.
181 MovementsCommon movement = read(item.getCsid());
182 values.add(i, movement.getMovementNote());
183 if (logger.isDebugEnabled()) {
184 logger.debug("list-item[" + i + "] movementNote=" + values.get(i));
186 // Verify that the value of the specified field in the current record
187 // is equal to or greater than its value in the previous record,
188 // using a locale-specific collator.
190 // (Note: when used with certain text, this test case could potentially
191 // reflect inconsistencies, if any, between Java's collator and the
192 // collator used for ordering by the database. To help avoid this,
193 // it might be useful to keep test strings fairly generic.)
194 if (i > 0 && values.get(i) != null && values.get(i - 1) != null) {
195 Assert.assertTrue(localeSpecificCollator.compare(values.get(i), values.get(i - 1)) >= 0);
203 * Tests whether a list of records, sorted by a String field in
204 * descending order, is returned in the expected order.
206 @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class,
207 dependsOnMethods = {"createList"})
208 public void sortByStringFieldDescending(String testName) throws Exception {
210 if (logger.isDebugEnabled()) {
211 logger.debug(testBanner(testName, CLASS_NAME));
214 String sortFieldName =
215 asDescendingSort(qualifySortFieldName(MovementJAXBSchema.MOVEMENT_NOTE));
216 if (logger.isDebugEnabled()) {
217 logger.debug("Sorting on field name=" + sortFieldName);
219 MovementsCommonList list = readSortedList(sortFieldName);
220 List<MovementsCommonList.MovementListItem> items =
221 list.getMovementListItem();
223 ArrayList<String> values = new ArrayList<String>();
224 Collator localeSpecificCollator = Collator.getInstance(LOCALE);
226 for (MovementsCommonList.MovementListItem item : items) {
227 // Because movementNote is not currently a summary field
228 // (returned in summary list items), we will need to verify
229 // sort order by retrieving full records, using the
230 // IDs provided in the summary list items. amd then retriving
231 // the value of that field from each of those records.
232 MovementsCommon movement = read(item.getCsid());
233 values.add(i, movement.getMovementNote());
234 if (logger.isDebugEnabled()) {
235 logger.debug("list-item[" + i + "] movementNote=" + values.get(i));
237 // Verify that the value of the specified field in the current record
238 // is less than or equal to than its value in the previous record,
239 // using a locale-specific collator.
241 // (Note: when used with certain text, this test case could potentially
242 // reflect inconsistencies, if any, between Java's collator and the
243 // collator used for ordering by the database. To help avoid this,
244 // it might be useful to keep test strings fairly generic.)
245 if (i > 0 && values.get(i) != null && values.get(i - 1) != null) {
246 Assert.assertTrue(localeSpecificCollator.compare(values.get(i), values.get(i - 1)) <= 0);
254 * Tests whether a list of records, sorted by a dateTime field in
255 * ascending order, is returned in the expected order.
257 @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class,
258 dependsOnMethods = {"createList"})
259 public void sortByDateTimeFieldAscending(String testName) throws Exception {
261 if (logger.isDebugEnabled()) {
262 logger.debug(testBanner(testName, CLASS_NAME));
265 String sortFieldName = qualifySortFieldName(MovementJAXBSchema.LOCATION_DATE);
266 if (logger.isDebugEnabled()) {
267 logger.debug("Sorting on field name=" + sortFieldName);
269 MovementsCommonList list = readSortedList(sortFieldName);
270 List<MovementsCommonList.MovementListItem> items =
271 list.getMovementListItem();
273 ArrayList<String> values = new ArrayList<String>();
274 Comparator<String> comparator = String.CASE_INSENSITIVE_ORDER;
276 for (MovementsCommonList.MovementListItem item : items) {
277 values.add(i, item.getLocationDate());
278 if (logger.isDebugEnabled()) {
279 logger.debug("list-item[" + i + "] locationDate=" + values.get(i));
281 // Verify that the value of the specified field in the current record
282 // is equal to or greater than its value in the previous record.
283 if (i > 0 && values.get(i) != null && values.get(i - 1) != null) {
284 Assert.assertTrue(comparator.compare(values.get(i), values.get(i - 1)) >= 0);
291 * Tests whether a list of records, sorted by a dateTime field in
292 * descending order, is returned in the expected order.
294 @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class,
295 dependsOnMethods = {"createList"})
296 public void sortByDateTimeFieldDescending(String testName) throws Exception {
298 if (logger.isDebugEnabled()) {
299 logger.debug(testBanner(testName, CLASS_NAME));
302 String sortFieldName =
303 asDescendingSort(qualifySortFieldName(MovementJAXBSchema.LOCATION_DATE));
304 if (logger.isDebugEnabled()) {
305 logger.debug("Sorting on field name=" + sortFieldName);
307 MovementsCommonList list = readSortedList(sortFieldName);
308 List<MovementsCommonList.MovementListItem> items =
309 list.getMovementListItem();
311 ArrayList<String> values = new ArrayList<String>();
312 Comparator<String> comparator = String.CASE_INSENSITIVE_ORDER;
314 for (MovementsCommonList.MovementListItem item : items) {
315 values.add(i, item.getLocationDate());
316 if (logger.isDebugEnabled()) {
317 logger.debug("list-item[" + i + "] locationDate=" + values.get(i));
319 // Verify that the value of the specified field in the current record
320 // is less than or equal to its value in the previous record.
321 if (i > 0 && values.get(i) != null && values.get(i - 1) != null) {
322 Assert.assertTrue(comparator.compare(values.get(i), values.get(i - 1)) <= 0);
329 * Tests whether a list of records, sorted by two different fields in
330 * ascending order, is returned in the expected order.
332 @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class,
333 dependsOnMethods = {"createList"})
334 public void sortByTwoFieldsAscending(String testName) throws Exception {
336 if (logger.isDebugEnabled()) {
337 logger.debug(testBanner(testName, CLASS_NAME));
340 String firstSortFieldName = qualifySortFieldName(MovementJAXBSchema.MOVEMENT_NOTE);
341 String secondSortFieldName = qualifySortFieldName(MovementJAXBSchema.LOCATION_DATE);
342 if (logger.isDebugEnabled()) {
343 logger.debug("Sorting on field names=" + firstSortFieldName + " and " + secondSortFieldName);
345 String sortExpression = firstSortFieldName + SORT_FIELD_SEPARATOR + secondSortFieldName;
346 MovementsCommonList list = readSortedList(sortExpression);
347 List<MovementsCommonList.MovementListItem> items =
348 list.getMovementListItem();
350 ArrayList<String> firstFieldValues = new ArrayList<String>();
351 ArrayList<String> secondFieldValues = new ArrayList<String>();
352 Collator localeSpecificCollator = Collator.getInstance(LOCALE);
353 Comparator<String> comparator = String.CASE_INSENSITIVE_ORDER;
355 for (MovementsCommonList.MovementListItem item : items) {
356 // Because movementNote is not currently a summary field
357 // (returned in summary list items), we will need to verify
358 // sort order by retrieving full records, using the
359 // IDs provided in the summary list items. amd then retriving
360 // the value of that field from each of those records.
361 MovementsCommon movement = read(item.getCsid());
362 firstFieldValues.add(i, movement.getMovementNote());
363 secondFieldValues.add(i, movement.getLocationDate());
364 if (logger.isDebugEnabled()) {
365 logger.debug("list-item[" + i + "] movementNote=" + firstFieldValues.get(i));
366 logger.debug("list-item[" + i + "] locationDate=" + secondFieldValues.get(i));
368 // Verify that the value of the specified field in the current record
369 // is less than or greater than its value in the previous record.
370 if (i > 0 && firstFieldValues.get(i) != null && firstFieldValues.get(i - 1) != null) {
371 Assert.assertTrue(localeSpecificCollator.compare(firstFieldValues.get(i), firstFieldValues.get(i - 1)) >= 0);
372 // If the value of the first sort field in the current record is identical to
373 // its value in the previous record, verify that the value of the second sort
374 // field is equal to or greater than its value in the previous record,
375 // using a locale-specific collator.
376 if (localeSpecificCollator.compare(firstFieldValues.get(i), firstFieldValues.get(i - 1)) == 0) {
377 if (i > 0 && secondFieldValues.get(i) != null && secondFieldValues.get(i - 1) != null) {
378 Assert.assertTrue(comparator.compare(secondFieldValues.get(i), secondFieldValues.get(i - 1)) >= 0);
387 * Tests whether a list of records, sorted by one different fields in
388 * descending order and a second field in ascending order, is returned in the expected order.
390 @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class,
391 dependsOnMethods = {"createList"})
392 public void sortByOneFieldAscendingOneFieldsDescending(String testName) throws Exception {
394 if (logger.isDebugEnabled()) {
395 logger.debug(testBanner(testName, CLASS_NAME));
398 String firstSortFieldName =
399 asDescendingSort(qualifySortFieldName(MovementJAXBSchema.LOCATION_DATE));
400 String secondSortFieldName = qualifySortFieldName(MovementJAXBSchema.MOVEMENT_NOTE);
401 if (logger.isDebugEnabled()) {
402 logger.debug("Sorting on field names=" + firstSortFieldName + " and " + secondSortFieldName);
404 String sortExpression = firstSortFieldName + SORT_FIELD_SEPARATOR + secondSortFieldName;
405 MovementsCommonList list = readSortedList(sortExpression);
406 List<MovementsCommonList.MovementListItem> items =
407 list.getMovementListItem();
409 ArrayList<String> firstFieldValues = new ArrayList<String>();
410 ArrayList<String> secondFieldValues = new ArrayList<String>();
411 Collator localeSpecificCollator = Collator.getInstance(LOCALE);
412 Comparator<String> comparator = String.CASE_INSENSITIVE_ORDER;
414 for (MovementsCommonList.MovementListItem item : items) {
415 // Because movementNote is not currently a summary field
416 // (returned in summary list items), we will need to verify
417 // sort order by retrieving full records, using the
418 // IDs provided in the summary list items. amd then retriving
419 // the value of that field from each of those records.
420 MovementsCommon movement = read(item.getCsid());
421 firstFieldValues.add(i, movement.getLocationDate());
422 secondFieldValues.add(i, movement.getMovementNote());
423 if (logger.isDebugEnabled()) {
424 logger.debug("list-item[" + i + "] locationDate=" + firstFieldValues.get(i));
425 logger.debug("list-item[" + i + "] movementNote=" + secondFieldValues.get(i));
427 // Verify that the value of the specified field in the current record
428 // is less than or equal to than its value in the previous record.
429 if (i > 0 && firstFieldValues.get(i) != null && firstFieldValues.get(i - 1) != null) {
430 Assert.assertTrue(comparator.compare(firstFieldValues.get(i), firstFieldValues.get(i - 1)) <= 0);
431 // If the value of the first sort field in the current record is identical to
432 // its value in the previous record, verify that the value of the second sort
433 // field is equal to or greater than its value in the previous record,
434 // using a locale-specific collator.
435 if (comparator.compare(firstFieldValues.get(i), firstFieldValues.get(i - 1)) == 0) {
436 if (i > 0 && secondFieldValues.get(i) != null && secondFieldValues.get(i - 1) != null) {
437 Assert.assertTrue(localeSpecificCollator.compare(secondFieldValues.get(i), secondFieldValues.get(i - 1)) >= 0);
447 * Tests whether a request to sort by an empty field name is handled
448 * as expected: the query parameter is simply ignored, and a list
449 * of records is returned, unsorted, with a success result.
451 @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class)
452 public void sortWithEmptySortFieldName(String testName) throws Exception {
454 if (logger.isDebugEnabled()) {
455 logger.debug(testBanner(testName, CLASS_NAME));
457 testSetup(STATUS_OK, ServiceRequestType.READ);
459 // Submit the request to the service and store the response.
460 MovementClient client = new MovementClient();
461 final String EMPTY_SORT_FIELD_NAME = "";
462 ClientResponse<MovementsCommonList> res =
463 client.readListSortedBy(EMPTY_SORT_FIELD_NAME);
464 int statusCode = res.getStatus();
466 // Check the status code of the response: does it match
467 // the expected response(s)?
468 if (logger.isDebugEnabled()) {
469 logger.debug(testName + ": status = " + statusCode);
471 Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
472 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
473 Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
480 * Tests whether a request to sort by an unqualified field name is
481 * handled as expected. The field name provided in this test is valid,
482 * but has not been qualified by being prefixed by a schema name and delimiter.
484 @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class)
485 public void sortWithUnqualifiedFieldName(String testName) throws Exception {
487 if (logger.isDebugEnabled()) {
488 logger.debug(testBanner(testName, CLASS_NAME));
490 testSetup(STATUS_BAD_REQUEST, ServiceRequestType.READ);
492 // Submit the request to the service and store the response.
493 MovementClient client = new MovementClient();
494 ClientResponse<MovementsCommonList> res =
495 client.readListSortedBy(MovementJAXBSchema.LOCATION_DATE);
496 int statusCode = res.getStatus();
498 // Check the status code of the response: does it match
499 // the expected response(s)?
500 if (logger.isDebugEnabled()) {
501 logger.debug(testName + ": status = " + statusCode);
503 Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
504 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
505 Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
510 * Tests whether a request to sort by an invalid identifier for the
511 * sort order (ascending or descending) is handled as expected.
513 @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class)
514 public void sortWithInvalidSortOrderIdentifier(String testName) throws Exception {
516 if (logger.isDebugEnabled()) {
517 logger.debug(testBanner(testName, CLASS_NAME));
519 testSetup(STATUS_BAD_REQUEST, ServiceRequestType.READ);
521 // Submit the request to the service and store the response.
522 MovementClient client = new MovementClient();
523 final String INVALID_SORT_ORDER_IDENTIFIER = "NO_DIRECTION";
524 ClientResponse<MovementsCommonList> res =
525 client.readListSortedBy(MovementJAXBSchema.LOCATION_DATE
526 + " " + INVALID_SORT_ORDER_IDENTIFIER);
527 int statusCode = res.getStatus();
529 // Check the status code of the response: does it match
530 // the expected response(s)?
531 if (logger.isDebugEnabled()) {
532 logger.debug(testName + ": status = " + statusCode);
534 Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
535 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
536 Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
541 * Tests whether a request to sort by a malformed field name is
542 * handled as expected.
545 @Test(dataProvider="testName", dataProviderClass=AbstractServiceTestImpl.class)
546 public void sortWithMalformedFieldName(String testName) throws Exception {
548 // FIXME: Implement this stub method.
550 // FIXME: Consider splitting this test into various tests, with
551 // different malformed field name formats that might confuse parsers
552 // and/or validation code.
554 // FIXME: Consider fixing DocumentFilter.setSortOrder() to return
555 // an error response to this test case, then revise this test case
556 // to expect that response.
561 // ---------------------------------------------------------------
562 // Cleanup of resources created during testing
563 // ---------------------------------------------------------------
565 * Deletes all resources created by tests, after all tests have been run.
567 * This cleanup method will always be run, even if one or more tests fail.
568 * For this reason, it attempts to remove all resources created
569 * at any point during testing, even if some of those resources
570 * may be expected to be deleted by certain tests.
572 @AfterClass(alwaysRun = true)
573 public void cleanUp() {
574 String noTest = System.getProperty("noTestCleanup");
575 if (Boolean.TRUE.toString().equalsIgnoreCase(noTest)) {
576 if (logger.isDebugEnabled()) {
577 logger.debug("Skipping Cleanup phase ...");
581 if (logger.isDebugEnabled()) {
582 logger.debug("Cleaning up temporary resources created for testing ...");
584 // Delete all Movement resource(s) created during this test.
585 MovementClient movementClient = new MovementClient();
586 for (String resourceId : movementIdsCreated) {
587 // Note: Any non-success responses are ignored and not reported.
588 movementClient.delete(resourceId);
592 // ---------------------------------------------------------------
593 // Utility methods used by tests above
594 // ---------------------------------------------------------------
597 protected String getServiceName() {
602 public String getServicePathComponent() {
603 return SERVICE_PATH_COMPONENT;
606 private String getCommonSchemaName() {
607 // FIXME: While this convention - appending a suffix to the name of
608 // the service's first unique URL path component - works, it would
609 // be preferable to get the common schema name from configuration.
611 // Such configuration is provided for example, on the services side, in
612 // org.collectionspace.services.common.context.AbstractServiceContextImpl
613 return getServicePathComponent() + "_" + "common";
616 public String qualifySortFieldName(String fieldName) {
617 return getCommonSchemaName() + DELIMITER_SCHEMA_AND_FIELD + fieldName;
620 public String asDescendingSort(String qualifiedFieldName) {
621 return qualifiedFieldName + " " + KEYWORD_DESCENDING_SEARCH;
625 * A data provider that provides a set of unsorted values, which are
626 * to be used in populating (seeding) values in test records.
628 * Data elements provided for each test record consist of:
629 * * An integer, reflecting expected sort order.
630 * * US English text, to populate the value of a free text (String) field.
631 * * An ISO 8601 timestamp, to populate the value of a calendar date (dateTime) field.
633 @DataProvider(name = "unsortedValues")
634 public Object[][] unsortedValues() {
635 // FIXME: ADR Add a test record-specific string so we have the option of
636 // constraining tests to only test records, in list or search results.
637 final String TEST_RECORD_SPECIFIC_STRING = CLASS_NAME + " " + TEST_SPECIFIC_KEYWORD;
638 return new Object[][]{
639 {1, "Aardvark and plumeria. " + TEST_RECORD_SPECIFIC_STRING, "2009-01-29T00:00:05Z"},
640 {10, "Zounds! " + TEST_RECORD_SPECIFIC_STRING, "2010-08-31T00:00:00Z"},
641 {3, "Aardvark and plumeria. " + TEST_RECORD_SPECIFIC_STRING, "2010-08-30T00:00:00Z"},
642 {7, "Bat fling off wall. " + TEST_RECORD_SPECIFIC_STRING, "2010-08-30T00:00:00Z"},
643 {4, "Aardvarks and plumeria. " + TEST_RECORD_SPECIFIC_STRING, "2009-01-29T08:00:00Z"},
644 {5, "Aardvarks and plumeria. " + TEST_RECORD_SPECIFIC_STRING, "2009-05-29T00:00:00Z"},
645 {2, "Aardvark and plumeria. " + TEST_RECORD_SPECIFIC_STRING, "2009-05-29T00:00:00Z"},
646 {9, "Zounds! " + TEST_RECORD_SPECIFIC_STRING, "2009-05-29T00:00:00Z"}, // Identical to next record
647 {8, "Zounds! " + TEST_RECORD_SPECIFIC_STRING, "2009-05-29T00:00:00Z"},
648 {6, "Bat flies off ball. " + TEST_RECORD_SPECIFIC_STRING, "2009-05-29T00:00:00Z"}
653 * Create multiple test records, initially in unsorted order,
654 * using values for various fields obtained from the data provider.
656 @Test(dataProvider = "unsortedValues")
657 public void createList(int expectedSortOrder, String movementNote,
658 String locationDate) throws Exception {
660 String testName = "createList";
661 if (logger.isDebugEnabled()) {
662 logger.debug(testBanner(testName, CLASS_NAME));
664 testSetup(STATUS_CREATED, ServiceRequestType.CREATE);
666 // Iterates through the sets of values returned by the data provider,
667 // and creates a corresponding test record for each set of values.
668 create(movementNote, locationDate);
671 private void create(String movementNote, String locationDate) throws Exception {
673 String testName = "create";
674 testSetup(STATUS_CREATED, ServiceRequestType.CREATE);
676 // Submit the request to the service and store the response.
677 PoxPayloadOut multipart = createMovementInstance(createIdentifier(),
678 movementNote, locationDate);
679 MovementClient client = new MovementClient();
680 ClientResponse<Response> res = client.create(multipart);
681 int statusCode = res.getStatus();
683 // Check the status code of the response: does it match
684 // the expected response(s)?
687 // Does it fall within the set of valid status codes?
688 // Does it exactly match the expected status code?
689 if (logger.isDebugEnabled()) {
690 logger.debug(testName + ": status = " + statusCode);
692 Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
693 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
694 Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
696 // Store the IDs from every resource created by tests,
697 // so they can be deleted after tests have been run.
698 movementIdsCreated.add(extractId(res));
701 private MovementsCommon read(String csid) throws Exception {
703 String testName = "read";
704 testSetup(STATUS_OK, ServiceRequestType.READ);
706 // Submit the request to the service and store the response.
707 MovementClient client = new MovementClient();
708 ClientResponse<String> res = client.read(csid);
709 int statusCode = res.getStatus();
711 // Check the status code of the response: does it match
712 // the expected response(s)?
713 if (logger.isDebugEnabled()) {
714 logger.debug(testName + ": status = " + statusCode);
716 Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
717 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
718 Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
720 // Extract and return the common part of the record.
721 PoxPayloadIn input = new PoxPayloadIn(res.getEntity());
722 PayloadInputPart payloadInputPart = input.getPart(client.getCommonPartName());
723 MovementsCommon movementCommon = null;
724 if (payloadInputPart != null) {
725 movementCommon = (MovementsCommon) payloadInputPart.getBody();
728 return movementCommon;
731 private PoxPayloadOut createMovementInstance(
732 String movementReferenceNumber,
734 String locationDate) {
735 MovementsCommon movementCommon = new MovementsCommon();
736 movementCommon.setMovementReferenceNumber(movementReferenceNumber);
737 movementCommon.setMovementNote(movementNote);
738 movementCommon.setLocationDate(locationDate);
740 PoxPayloadOut multipart = new PoxPayloadOut(this.getServicePathComponent());
741 PayloadOutputPart commonPart =
742 multipart.addPart(movementCommon, MediaType.APPLICATION_XML_TYPE);
743 commonPart.setLabel(new MovementClient().getCommonPartName());
744 if (logger.isDebugEnabled()) {
745 logger.debug("to be created, movement common");
746 logger.debug(objectAsXmlString(movementCommon, MovementsCommon.class));
752 private MovementsCommonList readSortedList(String sortFieldName) throws Exception {
754 String testName = "readSortedList";
755 testSetup(STATUS_OK, ServiceRequestType.READ);
757 // Submit the request to the service and store the response.
758 MovementClient client = new MovementClient();
760 ClientResponse<MovementsCommonList> res =
761 client.readListSortedBy(sortFieldName);
762 MovementsCommonList list = res.getEntity();
763 int statusCode = res.getStatus();
765 // Check the status code of the response: does it match
766 // the expected response(s)?
767 if (logger.isDebugEnabled()) {
768 logger.debug(testName + ": status = " + statusCode);
770 Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
771 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
772 Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
778 private MovementsCommonList keywordSearchSortedBy(String keywords,
779 String sortFieldName) throws Exception {
781 String testName = "keywordSearchSortedBy";
782 testSetup(STATUS_OK, ServiceRequestType.READ);
784 // Submit the request to the service and store the response.
785 MovementClient client = new MovementClient();
787 ClientResponse<MovementsCommonList> res =
788 client.keywordSearchSortedBy(keywords, sortFieldName);
789 MovementsCommonList list = res.getEntity();
790 int statusCode = res.getStatus();
792 // Check the status code of the response: does it match
793 // the expected response(s)?
794 if (logger.isDebugEnabled()) {
795 logger.debug(testName + ": status = " + statusCode);
797 Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
798 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
799 Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);