]> git.aero2k.de Git - tmp/jakarta-migration.git/blob
34e9114ba5dad3f1e3a3c6d23dc745b5eceaac7c
[tmp/jakarta-migration.git] /
1 /**
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:
5  *
6  * http://www.collectionspace.org
7  * http://wiki.collectionspace.org
8  *
9  * Copyright © 2009 Regents of the University of California
10  *
11  * Licensed under the Educational Community License (ECL), Version 2.0.
12  * You may not use this file except in compliance with this License.
13  *
14  * You may obtain a copy of the ECL 2.0 License at
15  * https://source.collectionspace.org/collection-space/LICENSE.txt
16  *
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.
22  */
23 package org.collectionspace.services.client.test;
24
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;
32
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.movement.MovementsCommon;
37 import org.collectionspace.services.movement.MovementsCommonList;
38 import org.collectionspace.services.jaxb.AbstractCommonList;
39
40 import org.jboss.resteasy.client.ClientResponse;
41 import org.jboss.resteasy.plugins.providers.multipart.MultipartInput;
42 import org.jboss.resteasy.plugins.providers.multipart.MultipartOutput;
43 import org.jboss.resteasy.plugins.providers.multipart.OutputPart;
44
45 import org.testng.Assert;
46 import org.testng.annotations.AfterClass;
47 import org.testng.annotations.DataProvider;
48 import org.testng.annotations.Test;
49
50 import org.slf4j.Logger;
51 import org.slf4j.LoggerFactory;
52
53 /**
54  * MovementSortByTest, tests sorting of summary lists by fields
55  * of various datatypes.
56  *
57  * $LastChangedRevision: 2562 $
58  * $LastChangedDate: 2010-06-22 23:26:51 -0700 (Tue, 22 Jun 2010) $
59  */
60 public class MovementSortByTest extends BaseServiceTest {
61
62     private final String CLASS_NAME = MovementSortByTest.class.getName();
63     private final Logger logger = LoggerFactory.getLogger(CLASS_NAME);
64
65     // Instance variables specific to this test.
66     final String DELIMITER_SCHEMA_AND_FIELD = ":";
67     final String KEYWORD_DESCENDING_SEARCH = "DESC";
68     final String SERVICE_PATH_COMPONENT = "movements";
69     final String TEST_SPECIFIC_KEYWORD = "msotebstpfscn";
70     private List<String> movementIdsCreated = new ArrayList<String>();
71
72     /* (non-Javadoc)
73      * @see org.collectionspace.services.client.test.BaseServiceTest#getClientInstance()
74      */
75     @Override
76     protected CollectionSpaceClient getClientInstance() {
77         throw new UnsupportedOperationException(); //method not supported (or needed) in this test class
78     }
79
80     /* (non-Javadoc)
81      * @see org.collectionspace.services.client.test.BaseServiceTest#getAbstractCommonList(org.jboss.resteasy.client.ClientResponse)
82      */
83     @Override
84     protected AbstractCommonList getAbstractCommonList(
85             ClientResponse<AbstractCommonList> response) {
86         throw new UnsupportedOperationException(); //method not supported (or needed) in this test class
87     }
88
89     // ---------------------------------------------------------------
90     // Sort tests
91     // ---------------------------------------------------------------
92
93     // Success outcomes
94
95     /*
96      * Tests whether a list of records, sorted by a String field in
97      * ascending order, is returned in the expected order.
98      */
99     @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class,
100     dependsOnMethods = {"createList"})
101     public void sortByStringFieldAscending(String testName) throws Exception {
102
103         if (logger.isDebugEnabled()) {
104             logger.debug(testBanner(testName, CLASS_NAME));
105         }
106
107         String sortFieldName = qualifySortFieldName(MovementJAXBSchema.MOVEMENT_NOTE);
108         if (logger.isDebugEnabled()) {
109             logger.debug("Sorting on field name=" + sortFieldName);
110         }
111         MovementsCommonList list = readSortedList(sortFieldName);
112         List<MovementsCommonList.MovementListItem> items =
113                 list.getMovementListItem();
114
115         ArrayList<String> values = new ArrayList<String>();
116         Collator usEnglishCollator = Collator.getInstance(Locale.US);
117         int i = 0;
118         for (MovementsCommonList.MovementListItem item : items) {
119             // Because movementNote is not currently a summary field
120             // (returned in summary list items), we will need to verify
121             // sort order by retrieving full records, using the
122             // IDs provided in the summary list items. amd then retriving
123             // the value of that field from each of those records.
124             MovementsCommon movement = read(item.getCsid());
125             values.add(i, movement.getMovementNote());
126             if (logger.isDebugEnabled()) {
127                 logger.debug("list-item[" + i + "] movementNote=" + values.get(i));
128             }
129             // Verify that the value of the specified field in the current record
130             // is equal to or greater than its value in the previous record,
131             // using a locale-specific collator.
132             //
133             // (Note: when used with certain text, this test case could potentially
134             // reflect inconsistencies, if any, between Java's collator and the
135             // collator used for ordering by the database.  To help avoid this,
136             // it might be useful to keep test strings fairly generic.)
137             if (i > 0 && values.get(i) != null && values.get(i - 1) != null) {
138                 Assert.assertTrue(usEnglishCollator.compare(values.get(i), values.get(i - 1)) >= 0);
139             }
140             i++;
141         }
142
143     }
144
145     /*
146      * Tests whether a list of records, obtained by a keyword search, and
147      * sorted by a String field in ascending order, is returned in the expected order.
148      *
149      * This verifies that summary list results from keyword searches, in
150      * addition to 'read list' requests, can be returned in sorted order.
151      */
152     @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class,
153     dependsOnMethods = {"createList"})
154     public void sortKeywordSearchResultsByStringFieldAscending(String testName) throws Exception {
155
156         if (logger.isDebugEnabled()) {
157             logger.debug(testBanner(testName, CLASS_NAME));
158         }
159
160         String sortFieldName = qualifySortFieldName(MovementJAXBSchema.MOVEMENT_NOTE);
161         if (logger.isDebugEnabled()) {
162             logger.debug("Sorting on field name=" + sortFieldName);
163         }
164         MovementsCommonList list = keywordSearchSortedBy(TEST_SPECIFIC_KEYWORD, sortFieldName);
165         List<MovementsCommonList.MovementListItem> items =
166                 list.getMovementListItem();
167
168         ArrayList<String> values = new ArrayList<String>();
169         Collator usEnglishCollator = Collator.getInstance(Locale.US);
170         int i = 0;
171         for (MovementsCommonList.MovementListItem item : items) {
172             // Because movementNote is not currently a summary field
173             // (returned in summary list items), we will need to verify
174             // sort order by retrieving full records, using the
175             // IDs provided in the summary list items. amd then retriving
176             // the value of that field from each of those records.
177             MovementsCommon movement = read(item.getCsid());
178             values.add(i, movement.getMovementNote());
179             if (logger.isDebugEnabled()) {
180                 logger.debug("list-item[" + i + "] movementNote=" + values.get(i));
181             }
182             // Verify that the value of the specified field in the current record
183             // is equal to or greater than its value in the previous record,
184             // using a locale-specific collator.
185             //
186             // (Note: when used with certain text, this test case could potentially
187             // reflect inconsistencies, if any, between Java's collator and the
188             // collator used for ordering by the database.  To help avoid this,
189             // it might be useful to keep test strings fairly generic.)
190             if (i > 0 && values.get(i) != null && values.get(i - 1) != null) {
191                 Assert.assertTrue(usEnglishCollator.compare(values.get(i), values.get(i - 1)) >= 0);
192             }
193             i++;
194         }
195
196     }
197
198     /*
199      * Tests whether a list of records, sorted by a String field in
200      * descending order, is returned in the expected order.
201      */
202     @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class,
203     dependsOnMethods = {"createList"})
204     public void sortByStringFieldDescending(String testName) throws Exception {
205
206         if (logger.isDebugEnabled()) {
207             logger.debug(testBanner(testName, CLASS_NAME));
208         }
209
210         String sortFieldName =
211                 asDescendingSort(qualifySortFieldName(MovementJAXBSchema.MOVEMENT_NOTE));
212         if (logger.isDebugEnabled()) {
213             logger.debug("Sorting on field name=" + sortFieldName);
214         }
215         MovementsCommonList list = readSortedList(sortFieldName);
216         List<MovementsCommonList.MovementListItem> items =
217                 list.getMovementListItem();
218
219         ArrayList<String> values = new ArrayList<String>();
220         Collator usEnglishCollator = Collator.getInstance(Locale.US);
221         int i = 0;
222         for (MovementsCommonList.MovementListItem item : items) {
223             // Because movementNote is not currently a summary field
224             // (returned in summary list items), we will need to verify
225             // sort order by retrieving full records, using the
226             // IDs provided in the summary list items. amd then retriving
227             // the value of that field from each of those records.
228             MovementsCommon movement = read(item.getCsid());
229             values.add(i, movement.getMovementNote());
230             if (logger.isDebugEnabled()) {
231                 logger.debug("list-item[" + i + "] movementNote=" + values.get(i));
232             }
233             // Verify that the value of the specified field in the current record
234             // is less than or equal to than its value in the previous record,
235             // using a locale-specific collator.
236             //
237             // (Note: when used with certain text, this test case could potentially
238             // reflect inconsistencies, if any, between Java's collator and the
239             // collator used for ordering by the database.  To help avoid this,
240             // it might be useful to keep test strings fairly generic.)
241             if (i > 0 && values.get(i) != null && values.get(i - 1) != null) {
242                 Assert.assertTrue(usEnglishCollator.compare(values.get(i), values.get(i - 1)) <= 0);
243             }
244             i++;
245         }
246
247     }
248
249     /*
250      * Tests whether a list of records, sorted by a dateTime field in
251      * ascending order, is returned in the expected order.
252      */
253     @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class,
254     dependsOnMethods = {"createList"})
255     public void sortByDateTimeFieldAscending(String testName) throws Exception {
256
257         if (logger.isDebugEnabled()) {
258             logger.debug(testBanner(testName, CLASS_NAME));
259         }
260
261         String sortFieldName = qualifySortFieldName(MovementJAXBSchema.LOCATION_DATE);
262         if (logger.isDebugEnabled()) {
263             logger.debug("Sorting on field name=" + sortFieldName);
264         }
265         MovementsCommonList list = readSortedList(sortFieldName);
266         List<MovementsCommonList.MovementListItem> items =
267                 list.getMovementListItem();
268
269         ArrayList<String> values = new ArrayList<String>();
270         Comparator<String> comparator = String.CASE_INSENSITIVE_ORDER;
271         int i = 0;
272         for (MovementsCommonList.MovementListItem item : items) {
273             values.add(i, item.getLocationDate());
274             if (logger.isDebugEnabled()) {
275                 logger.debug("list-item[" + i + "] locationDate=" + values.get(i));
276             }
277             // Verify that the value of the specified field in the current record
278             // is equal to or greater than its value in the previous record.
279             if (i > 0 && values.get(i) != null && values.get(i - 1) != null) {
280                 Assert.assertTrue(comparator.compare(values.get(i), values.get(i - 1)) >= 0);
281             }
282             i++;
283         }
284     }
285
286     /*
287      * Tests whether a list of records, sorted by a dateTime field in
288      * descending order, is returned in the expected order.
289      */
290     @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class,
291     dependsOnMethods = {"createList"})
292     public void sortByDateTimeFieldDescending(String testName) throws Exception {
293
294         if (logger.isDebugEnabled()) {
295             logger.debug(testBanner(testName, CLASS_NAME));
296         }
297
298         String sortFieldName =
299                 asDescendingSort(qualifySortFieldName(MovementJAXBSchema.LOCATION_DATE));
300         if (logger.isDebugEnabled()) {
301             logger.debug("Sorting on field name=" + sortFieldName);
302         }
303         MovementsCommonList list = readSortedList(sortFieldName);
304         List<MovementsCommonList.MovementListItem> items =
305                 list.getMovementListItem();
306
307         ArrayList<String> values = new ArrayList<String>();
308         Comparator<String> comparator = String.CASE_INSENSITIVE_ORDER;
309         int i = 0;
310         for (MovementsCommonList.MovementListItem item : items) {
311             values.add(i, item.getLocationDate());
312             if (logger.isDebugEnabled()) {
313                 logger.debug("list-item[" + i + "] locationDate=" + values.get(i));
314             }
315             // Verify that the value of the specified field in the current record
316             // is less than or equal to its value in the previous record.
317             if (i > 0 && values.get(i) != null && values.get(i - 1) != null) {
318                 Assert.assertTrue(comparator.compare(values.get(i), values.get(i - 1)) <= 1);
319             }
320             i++;
321         }
322     }
323
324     /*
325      * Tests whether a request to sort by an empty field name is handled
326      * as expected: the query parameter is simply ignored, and a list
327      * of records is returned, unsorted, with a success result.
328      */
329     @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class)
330     public void sortWithEmptySortFieldName(String testName) throws Exception {
331
332         if (logger.isDebugEnabled()) {
333             logger.debug(testBanner(testName, CLASS_NAME));
334         }
335         testSetup(STATUS_OK, ServiceRequestType.READ);
336
337         // Submit the request to the service and store the response.
338         MovementClient client = new MovementClient();
339         final String EMPTY_SORT_FIELD_NAME = "";
340         ClientResponse<MovementsCommonList> res =
341                 client.readListSortedBy(EMPTY_SORT_FIELD_NAME);
342         int statusCode = res.getStatus();
343
344         // Check the status code of the response: does it match
345         // the expected response(s)?
346         if (logger.isDebugEnabled()) {
347             logger.debug(testName + ": status = " + statusCode);
348         }
349         Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
350                 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
351         Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
352
353     }
354
355     // Failure outcomes
356
357     /*
358      * Tests whether a request to sort by an unqualified field name is
359      * handled as expected.  The field name provided in this test is valid,
360      * but has not been qualified by being prefixed by a schema name and delimiter.
361      */
362     @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class)
363     public void sortWithUnqualifiedFieldName(String testName) throws Exception {
364
365         if (logger.isDebugEnabled()) {
366             logger.debug(testBanner(testName, CLASS_NAME));
367         }
368         // FIXME: Ultimately, this should return a BAD_REQUEST status.
369         testSetup(STATUS_INTERNAL_SERVER_ERROR, ServiceRequestType.READ);
370
371         // Submit the request to the service and store the response.
372         MovementClient client = new MovementClient();
373         ClientResponse<MovementsCommonList> res =
374                 client.readListSortedBy(MovementJAXBSchema.LOCATION_DATE);
375         int statusCode = res.getStatus();
376
377         // Check the status code of the response: does it match
378         // the expected response(s)?
379         if (logger.isDebugEnabled()) {
380             logger.debug(testName + ": status = " + statusCode);
381         }
382         Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
383                 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
384         Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
385
386     }
387
388     /*
389      * Tests whether a request to sort by an invalid identifier for the
390      * sort order (ascending or descending) is handled as expected.
391      */
392     @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class)
393     public void sortWithInvalidSortOrderIdentifier(String testName) throws Exception {
394
395         if (logger.isDebugEnabled()) {
396             logger.debug(testBanner(testName, CLASS_NAME));
397         }
398         // FIXME: Ultimately, this should return a BAD_REQUEST status.
399         testSetup(STATUS_INTERNAL_SERVER_ERROR, ServiceRequestType.READ);
400
401         // Submit the request to the service and store the response.
402         MovementClient client = new MovementClient();
403         final String INVALID_SORT_ORDER_IDENTIFIER = "NO_DIRECTION";
404         ClientResponse<MovementsCommonList> res =
405                 client.readListSortedBy(MovementJAXBSchema.LOCATION_DATE
406                 + " " + INVALID_SORT_ORDER_IDENTIFIER);
407         int statusCode = res.getStatus();
408
409         // Check the status code of the response: does it match
410         // the expected response(s)?
411         if (logger.isDebugEnabled()) {
412             logger.debug(testName + ": status = " + statusCode);
413         }
414         Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
415                 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
416         Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
417
418     }
419
420     /*
421      * Tests whether a request to sort by a malformed field name is
422      * handled as expected.
423      */
424 /*
425     @Test(dataProvider="testName", dataProviderClass=AbstractServiceTestImpl.class)
426     public void sortWithMalformedFieldName(String testName) throws Exception {
427
428     // FIXME: Implement this stub method.
429
430     // FIXME: Consider splitting this test into various tests, with
431     // different malformed field name formats that might confuse parsers
432     // and/or validation code.
433
434     // FIXME: Consider fixing DocumentFilter.setSortOrder() to return
435     // an error response to this test case, then revise this test case
436     // to expect that response.
437
438     }
439 */
440
441     // ---------------------------------------------------------------
442     // Cleanup of resources created during testing
443     // ---------------------------------------------------------------
444     /**
445      * Deletes all resources created by tests, after all tests have been run.
446      *
447      * This cleanup method will always be run, even if one or more tests fail.
448      * For this reason, it attempts to remove all resources created
449      * at any point during testing, even if some of those resources
450      * may be expected to be deleted by certain tests.
451      */
452     @AfterClass(alwaysRun = true)
453     public void cleanUp() {
454         String noTest = System.getProperty("noTestCleanup");
455         if (Boolean.TRUE.toString().equalsIgnoreCase(noTest)) {
456             if (logger.isDebugEnabled()) {
457                 logger.debug("Skipping Cleanup phase ...");
458             }
459             return;
460         }
461         if (logger.isDebugEnabled()) {
462             logger.debug("Cleaning up temporary resources created for testing ...");
463         }
464         // Delete all Movement resource(s) created during this test.
465         MovementClient movementClient = new MovementClient();
466         for (String resourceId : movementIdsCreated) {
467             // Note: Any non-success responses are ignored and not reported.
468             movementClient.delete(resourceId);
469         }
470     }
471
472     // ---------------------------------------------------------------
473     // Utility methods used by tests above
474     // ---------------------------------------------------------------
475
476     @Override
477     public String getServicePathComponent() {
478         return SERVICE_PATH_COMPONENT;
479     }
480
481     private String getCommonSchemaName() {
482         // FIXME: While this convention - appending a suffix to the name of
483         // the service's first unique URL path component - works, it would
484         // be preferable to get the common schema name from configuration.
485         //
486         // Such configuration is provided for example, on the services side, in
487         // org.collectionspace.services.common.context.AbstractServiceContextImpl
488         return getServicePathComponent() + "_" + "common";
489     }
490
491     public String qualifySortFieldName(String fieldName) {
492         return getCommonSchemaName() + DELIMITER_SCHEMA_AND_FIELD + fieldName;
493     }
494
495     public String asDescendingSort(String qualifiedFieldName) {
496         return qualifiedFieldName + " " + KEYWORD_DESCENDING_SEARCH;
497     }
498
499     /*
500      * A data provider that provides a set of unsorted values, which are
501      * to be used in populating (seeding) values in test records.
502      *
503      * Data elements provided for each test record consist of:
504      * * An integer, reflecting expected sort order.
505      * * US English text, to populate the value of a free text (String) field.
506      * * An ISO 8601 timestamp, to populate the value of a calendar date (dateTime) field.
507      */
508     @DataProvider(name = "unsortedValues")
509     public Object[][] unsortedValues() {
510         // Add a test record-specific string so we have the option of
511         // constraining tests to only test records, in list or search results.
512         final String TEST_RECORD_SPECIFIC_STRING = CLASS_NAME + " " + TEST_SPECIFIC_KEYWORD;
513         return new Object[][]{
514                     {1, "Aardvark and plumeria. " + TEST_RECORD_SPECIFIC_STRING, "2009-01-29T00:00:05Z"},
515                     {4, "Bat fling off wall. " + TEST_RECORD_SPECIFIC_STRING, "2010-08-30T00:00:00Z"},
516                     {2, "Aardvarks and plumeria. " + TEST_RECORD_SPECIFIC_STRING, "2009-01-29T08:00:00Z"},
517                     {5, "Zounds! " + TEST_RECORD_SPECIFIC_STRING, "2010-08-31T00:00:00Z"},
518                     {3, "Bat flies off ball. " + TEST_RECORD_SPECIFIC_STRING, "2009-05-29T00:00:00Z"}
519                 };
520     }
521
522     /*
523      * Create multiple test records, initially in unsorted order,
524      * using values for various fields obtained from the data provider.
525      */
526     @Test(dataProvider = "unsortedValues")
527     public void createList(int expectedSortOrder, String movementNote,
528             String locationDate) throws Exception {
529
530         String testName = "createList";
531         if (logger.isDebugEnabled()) {
532             logger.debug(testBanner(testName, CLASS_NAME));
533         }
534         testSetup(STATUS_CREATED, ServiceRequestType.CREATE);
535
536         // Iterates through the sets of values returned by the data provider,
537         // and creates a corresponding test record for each set of values.
538         create(movementNote, locationDate);
539     }
540
541     private void create(String movementNote, String locationDate) throws Exception {
542
543         String testName = "create";
544         testSetup(STATUS_CREATED, ServiceRequestType.CREATE);
545
546         // Submit the request to the service and store the response.
547         MovementClient client = new MovementClient();
548         MultipartOutput multipart = createMovementInstance(createIdentifier(),
549                 movementNote, locationDate);
550         ClientResponse<Response> res = client.create(multipart);
551         int statusCode = res.getStatus();
552
553         // Check the status code of the response: does it match
554         // the expected response(s)?
555         //
556         // Specifically:
557         // Does it fall within the set of valid status codes?
558         // Does it exactly match the expected status code?
559         if (logger.isDebugEnabled()) {
560             logger.debug(testName + ": status = " + statusCode);
561         }
562         Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
563                 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
564         Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
565
566         // Store the IDs from every resource created by tests,
567         // so they can be deleted after tests have been run.
568         movementIdsCreated.add(extractId(res));
569     }
570
571     private MovementsCommon read(String csid) throws Exception {
572
573         String testName = "read";
574         testSetup(STATUS_OK, ServiceRequestType.READ);
575
576         // Submit the request to the service and store the response.
577         MovementClient client = new MovementClient();
578         ClientResponse<MultipartInput> res = client.read(csid);
579         int statusCode = res.getStatus();
580
581         // Check the status code of the response: does it match
582         // the expected response(s)?
583         if (logger.isDebugEnabled()) {
584             logger.debug(testName + ": status = " + statusCode);
585         }
586         Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
587                 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
588         Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
589
590         // Extract and return the common part of the record.
591         MultipartInput input = (MultipartInput) res.getEntity();
592         MovementsCommon movement = (MovementsCommon) extractPart(input,
593                 client.getCommonPartName(), MovementsCommon.class);
594
595         return movement;
596     }
597
598     private MultipartOutput createMovementInstance(
599             String movementReferenceNumber,
600             String movementNote,
601             String locationDate) {
602         MovementsCommon movement = new MovementsCommon();
603         movement.setMovementReferenceNumber(movementReferenceNumber);
604         movement.setMovementNote(movementNote);
605         movement.setLocationDate(locationDate);
606         MultipartOutput multipart = new MultipartOutput();
607         OutputPart commonPart =
608                 multipart.addPart(movement, MediaType.APPLICATION_XML_TYPE);
609         commonPart.getHeaders().add("label", new MovementClient().getCommonPartName());
610
611         if (logger.isDebugEnabled()) {
612             logger.debug("to be created, movement common");
613             logger.debug(objectAsXmlString(movement, MovementsCommon.class));
614         }
615
616         return multipart;
617     }
618
619     private MovementsCommonList readSortedList(String sortFieldName) throws Exception {
620
621         String testName = "readSortedList";
622         testSetup(STATUS_OK, ServiceRequestType.READ);
623
624         // Submit the request to the service and store the response.
625         MovementClient client = new MovementClient();
626
627         ClientResponse<MovementsCommonList> res =
628                 client.readListSortedBy(sortFieldName);
629         MovementsCommonList list = res.getEntity();
630         int statusCode = res.getStatus();
631
632         // Check the status code of the response: does it match
633         // the expected response(s)?
634         if (logger.isDebugEnabled()) {
635             logger.debug(testName + ": status = " + statusCode);
636         }
637         Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
638                 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
639         Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
640
641         return list;
642
643     }
644
645     private MovementsCommonList keywordSearchSortedBy(String keywords,
646             String sortFieldName) throws Exception {
647
648         String testName = "keywordSearchSortedBy";
649         testSetup(STATUS_OK, ServiceRequestType.READ);
650
651         // Submit the request to the service and store the response.
652         MovementClient client = new MovementClient();
653
654         ClientResponse<MovementsCommonList> res =
655                 client.keywordSearchSortedBy(keywords, sortFieldName);
656         MovementsCommonList list = res.getEntity();
657         int statusCode = res.getStatus();
658
659         // Check the status code of the response: does it match
660         // the expected response(s)?
661         if (logger.isDebugEnabled()) {
662             logger.debug(testName + ": status = " + statusCode);
663         }
664         Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
665                 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
666         Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
667
668         return list;
669
670     }
671
672 }