]> git.aero2k.de Git - tmp/jakarta-migration.git/blob
2a10656982183af6f33719502be320d41ed5d0e0
[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.DateFormat;
26 import java.text.SimpleDateFormat;
27 import java.util.Calendar;
28 import java.util.Date;
29 import java.util.List;
30 import java.util.TimeZone;
31 import javax.ws.rs.core.MediaType;
32 import javax.ws.rs.core.Response;
33
34 import org.collectionspace.services.common.AbstractCommonListUtils;
35 import org.collectionspace.services.common.datetime.GregorianCalendarDateTimeUtils;
36 import org.collectionspace.services.client.CollectionSpaceClient;
37 import org.collectionspace.services.client.MovementClient;
38 import org.collectionspace.services.jaxb.AbstractCommonList;
39 import org.collectionspace.services.movement.MovementsCommon;
40 import org.collectionspace.services.movement.MovementMethodsList;
41
42 import org.jboss.resteasy.client.ClientResponse;
43
44 import org.collectionspace.services.client.PayloadInputPart;
45 import org.collectionspace.services.client.PayloadOutputPart;
46 import org.collectionspace.services.client.PoxPayloadIn;
47 import org.collectionspace.services.client.PoxPayloadOut;
48 import org.testng.Assert;
49 import org.testng.annotations.Test;
50
51 import org.slf4j.Logger;
52 import org.slf4j.LoggerFactory;
53
54 /**
55  * MovementServiceTest, carries out tests against a
56  * deployed and running Movement Service.
57  *
58  * $LastChangedRevision$
59  * $LastChangedDate$
60  */
61 public class MovementServiceTest extends AbstractServiceTestImpl {
62
63    /** The logger. */
64     private final String CLASS_NAME = MovementServiceTest.class.getName();
65     private final Logger logger = LoggerFactory.getLogger(CLASS_NAME);
66
67     final String SERVICE_NAME = "movements";
68     final String SERVICE_PATH_COMPONENT = "movements";
69
70     // Instance variables specific to this test.
71     private String knownResourceId = null;
72     private final static String TIMESTAMP_UTC = GregorianCalendarDateTimeUtils.timestampUTC();
73     
74     /* (non-Javadoc)
75      * @see org.collectionspace.services.client.test.BaseServiceTest#getClientInstance()
76      */
77     @Override
78     protected CollectionSpaceClient getClientInstance() {
79         return new MovementClient();
80     }
81     
82     // ---------------------------------------------------------------
83     // CRUD tests : CREATE tests
84     // ---------------------------------------------------------------
85     // Success outcomes
86     /* (non-Javadoc)
87      * @see org.collectionspace.services.client.test.ServiceTest#create(java.lang.String)
88      */
89     @Override
90     @Test(dataProvider="testName", dataProviderClass=AbstractServiceTestImpl.class)
91     public void create(String testName) throws Exception {
92
93         if (logger.isDebugEnabled()) {
94             logger.debug(testBanner(testName, CLASS_NAME));
95         }
96         // Perform setup, such as initializing the type of service request
97         // (e.g. CREATE, DELETE), its valid and expected status codes, and
98         // its associated HTTP method name (e.g. POST, DELETE).
99         setupCreate();
100
101         // Submit the request to the service and store the response.
102         MovementClient client = new MovementClient();
103         String identifier = createIdentifier();
104         PoxPayloadOut multipart = createMovementInstance(identifier);
105         ClientResponse<Response> res = client.create(multipart);
106
107         int statusCode = res.getStatus();
108
109         // Check the status code of the response: does it match
110         // the expected response(s)?
111         //
112         // Specifically:
113         // Does it fall within the set of valid status codes?
114         // Does it exactly match the expected status code?
115         if(logger.isDebugEnabled()){
116             logger.debug(testName + ": status = " + statusCode);
117         }
118         Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
119                 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
120         Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
121
122         // Store the ID returned from the first resource created
123         // for additional tests below.
124         if (knownResourceId == null){
125             knownResourceId = extractId(res);
126             if (logger.isDebugEnabled()) {
127                 logger.debug(testName + ": knownResourceId=" + knownResourceId);
128             }
129         }
130         
131         // Store the IDs from every resource created by tests,
132         // so they can be deleted after tests have been run.
133         allResourceIdsCreated.add(extractId(res));
134     }
135
136     /* (non-Javadoc)
137      * @see org.collectionspace.services.client.test.AbstractServiceTestImpl#createList(java.lang.String)
138      */
139     @Override
140     @Test(dataProvider="testName", dataProviderClass=AbstractServiceTestImpl.class,
141         dependsOnMethods = {"create"})
142     public void createList(String testName) throws Exception {
143         for(int i = 0; i < 3; i++){
144             create(testName);
145         }
146     }
147
148     // Failure outcomes
149     // Placeholders until the three tests below can be uncommented.
150     // See Issue CSPACE-401.
151     /* (non-Javadoc)
152      * @see org.collectionspace.services.client.test.AbstractServiceTestImpl#createWithEmptyEntityBody(java.lang.String)
153      */
154     @Override
155     public void createWithEmptyEntityBody(String testName) throws Exception {
156         //Should this really be empty?
157     }
158
159     /* (non-Javadoc)
160      * @see org.collectionspace.services.client.test.AbstractServiceTestImpl#createWithMalformedXml(java.lang.String)
161      */
162     @Override
163     public void createWithMalformedXml(String testName) throws Exception {
164         //Should this really be empty?
165     }
166
167     /* (non-Javadoc)
168      * @see org.collectionspace.services.client.test.AbstractServiceTestImpl#createWithWrongXmlSchema(java.lang.String)
169      */
170     @Override
171     public void createWithWrongXmlSchema(String testName) throws Exception {
172         //Should this really be empty?
173     }
174
175     /*
176     @Override
177     @Test(dataProvider="testName", dataProviderClass=AbstractServiceTest.class,
178         dependsOnMethods = {"create", "testSubmitRequest"})
179     public void createWithEmptyEntityBody(String testName) throws Exception {
180
181         if (logger.isDebugEnabled()) {
182             logger.debug(testBanner(testName, CLASS_NAME));
183         }
184         // Perform setup.
185         setupCreateWithEmptyEntityBody();
186
187         // Submit the request to the service and store the response.
188         String method = REQUEST_TYPE.httpMethodName();
189         String url = getServiceRootURL();
190         String mediaType = MediaType.APPLICATION_XML;
191         final String entity = "";
192         int statusCode = submitRequest(method, url, mediaType, entity);
193
194         // Check the status code of the response: does it match
195         // the expected response(s)?
196         if(logger.isDebugEnabled()){
197             logger.debug("createWithEmptyEntityBody url=" + url +
198                 " status=" + statusCode);
199          }
200         Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
201         invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
202         Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
203     }
204
205     @Override
206     @Test(dataProvider="testName", dataProviderClass=AbstractServiceTest.class,
207         dependsOnMethods = {"create", "testSubmitRequest"})
208     public void createWithMalformedXml(String testName) throws Exception {
209
210         if (logger.isDebugEnabled()) {
211             logger.debug(testBanner(testName, CLASS_NAME));
212         }
213         // Perform setup.
214         setupCreateWithMalformedXml();
215
216         // Submit the request to the service and store the response.
217         String method = REQUEST_TYPE.httpMethodName();
218         String url = getServiceRootURL();
219         String mediaType = MediaType.APPLICATION_XML;
220         final String entity = MALFORMED_XML_DATA; // Constant from base class.
221         int statusCode = submitRequest(method, url, mediaType, entity);
222
223         // Check the status code of the response: does it match
224         // the expected response(s)?
225         if(logger.isDebugEnabled()){
226             logger.debug(testName + ": url=" + url +
227                 " status=" + statusCode);
228          }
229         Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
230         invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
231         Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
232     }
233
234     @Override
235     @Test(dataProvider="testName", dataProviderClass=AbstractServiceTest.class,
236         dependsOnMethods = {"create", "testSubmitRequest"})
237     public void createWithWrongXmlSchema(String testName) throws Exception {
238
239         if (logger.isDebugEnabled()) {
240             logger.debug(testBanner(testName, CLASS_NAME));
241         }
242         // Perform setup.
243         setupCreateWithWrongXmlSchema();
244
245         // Submit the request to the service and store the response.
246         String method = REQUEST_TYPE.httpMethodName();
247         String url = getServiceRootURL();
248         String mediaType = MediaType.APPLICATION_XML;
249         final String entity = WRONG_XML_SCHEMA_DATA;
250         int statusCode = submitRequest(method, url, mediaType, entity);
251
252         // Check the status code of the response: does it match
253         // the expected response(s)?
254         if(logger.isDebugEnabled()){
255             logger.debug(testName + ": url=" + url +
256                 " status=" + statusCode);
257          }
258         Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
259         invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
260         Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
261     }
262      */
263
264     // ---------------------------------------------------------------
265     // CRUD tests : READ tests
266     // ---------------------------------------------------------------
267     // Success outcomes
268     /* (non-Javadoc)
269      * @see org.collectionspace.services.client.test.AbstractServiceTestImpl#read(java.lang.String)
270      */
271     @Override
272     @Test(dataProvider="testName", dataProviderClass=AbstractServiceTestImpl.class,
273         dependsOnMethods = {"create"})
274     public void read(String testName) throws Exception {
275
276         if (logger.isDebugEnabled()) {
277             logger.debug(testBanner(testName, CLASS_NAME));
278         }
279         // Perform setup.
280         setupRead();
281
282         // Submit the request to the service and store the response.
283         MovementClient client = new MovementClient();
284         ClientResponse<String> res = client.read(knownResourceId);
285         int statusCode = res.getStatus();
286
287         // Check the status code of the response: does it match
288         // the expected response(s)?
289         if(logger.isDebugEnabled()){
290             logger.debug(testName + ": status = " + statusCode);
291         }
292         Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
293                 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
294         Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
295
296         // Get the common part of the response and verify that it is not null.
297         PoxPayloadIn input = new PoxPayloadIn(res.getEntity());
298         PayloadInputPart payloadInputPart = input.getPart(client.getCommonPartName());
299         MovementsCommon movementCommon = null;
300         if (payloadInputPart != null) {
301                 movementCommon = (MovementsCommon) payloadInputPart.getBody();
302         }
303         Assert.assertNotNull(movementCommon);
304
305         // Check selected fields.
306
307         // Check the values of one or more date/time fields.
308         if (logger.isDebugEnabled()) {
309             logger.debug("locationDate=" + movementCommon.getLocationDate());
310             logger.debug("TIMESTAMP_UTC=" + TIMESTAMP_UTC);
311         }
312         Assert.assertTrue(movementCommon.getLocationDate().equals(TIMESTAMP_UTC));
313         Assert.assertTrue(movementCommon.getPlannedRemovalDate().equals(TIMESTAMP_UTC));
314         Assert.assertNull(movementCommon.getRemovalDate());
315         
316         // Check the values of fields containing Unicode UTF-8 (non-Latin-1) characters.
317        if(logger.isDebugEnabled()){
318             logger.debug("UTF-8 data sent=" + getUTF8DataFragment() + "\n"
319                     + "UTF-8 data received=" + movementCommon.getMovementNote());
320     }
321         Assert.assertEquals(movementCommon.getMovementNote(), getUTF8DataFragment(),
322                 "UTF-8 data retrieved '" + movementCommon.getMovementNote()
323                 + "' does not match expected data '" + getUTF8DataFragment());
324
325     }
326
327     // Failure outcomes
328     /* (non-Javadoc)
329      * @see org.collectionspace.services.client.test.AbstractServiceTestImpl#readNonExistent(java.lang.String)
330      */
331     @Override
332     @Test(dataProvider="testName", dataProviderClass=AbstractServiceTestImpl.class,
333         dependsOnMethods = {"read"})
334     public void readNonExistent(String testName) throws Exception {
335
336         if (logger.isDebugEnabled()) {
337             logger.debug(testBanner(testName, CLASS_NAME));
338         }
339         // Perform setup.
340         setupReadNonExistent();
341
342         // Submit the request to the service and store the response.
343         MovementClient client = new MovementClient();
344         ClientResponse<String> res = client.read(NON_EXISTENT_ID);
345         int statusCode = res.getStatus();
346
347         // Check the status code of the response: does it match
348         // the expected response(s)?
349         if(logger.isDebugEnabled()){
350             logger.debug(testName + ": status = " + statusCode);
351         }
352         Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
353                 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
354         Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
355     }
356
357     // ---------------------------------------------------------------
358     // CRUD tests : READ_LIST tests
359     // ---------------------------------------------------------------
360     // Success outcomes
361     /* (non-Javadoc)
362      * @see org.collectionspace.services.client.test.AbstractServiceTestImpl#readList(java.lang.String)
363      */
364     @Override
365     @Test(dataProvider="testName", dataProviderClass=AbstractServiceTestImpl.class,
366         dependsOnMethods = {"createList", "read"})
367     public void readList(String testName) throws Exception {
368
369         if (logger.isDebugEnabled()) {
370             logger.debug(testBanner(testName, CLASS_NAME));
371         }
372         // Perform setup.
373         setupReadList();
374
375         // Submit the request to the service and store the response.
376         MovementClient client = new MovementClient();
377         ClientResponse<AbstractCommonList> res = client.readList();
378         AbstractCommonList list = res.getEntity();
379         int statusCode = res.getStatus();
380
381         // Check the status code of the response: does it match
382         // the expected response(s)?
383         if(logger.isDebugEnabled()){
384             logger.debug(testName + ": status = " + statusCode);
385         }
386         Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
387                 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
388         Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
389
390         // Optionally output additional data about list members for debugging.
391         if(logger.isTraceEnabled()){
392                 AbstractCommonListUtils.ListItemsInAbstractCommonList(list, logger, testName);
393         }
394     }
395
396     // Failure outcomes
397     // None at present.
398     // ---------------------------------------------------------------
399     // CRUD tests : UPDATE tests
400     // ---------------------------------------------------------------
401     // Success outcomes
402     /* (non-Javadoc)
403      * @see org.collectionspace.services.client.test.AbstractServiceTestImpl#update(java.lang.String)
404      */
405     @Override
406     @Test(dataProvider="testName", dataProviderClass=AbstractServiceTestImpl.class,
407         dependsOnMethods = {"read"})
408     public void update(String testName) throws Exception {
409
410         if (logger.isDebugEnabled()) {
411             logger.debug(testBanner(testName, CLASS_NAME));
412         }
413         // Perform setup.
414         setupUpdate();
415
416         // Retrieve the contents of a resource to update.
417         MovementClient client = new MovementClient();
418         ClientResponse<String> res = client.read(knownResourceId);
419         if(logger.isDebugEnabled()){
420             logger.debug(testName + ": read status = " + res.getStatus());
421         }
422         Assert.assertEquals(res.getStatus(), EXPECTED_STATUS_CODE);
423         if(logger.isDebugEnabled()){
424             logger.debug("got object to update with ID: " + knownResourceId);
425         }
426
427         // Extract the common part from the response.
428         PoxPayloadIn input = new PoxPayloadIn(res.getEntity());
429         PayloadInputPart payloadInputPart = input.getPart(client.getCommonPartName());
430         MovementsCommon movementCommon = null;
431         if (payloadInputPart != null) {
432                 movementCommon = (MovementsCommon) payloadInputPart.getBody();
433         }
434         Assert.assertNotNull(movementCommon);
435
436         // Update its content.
437         movementCommon.setMovementReferenceNumber("updated-" + movementCommon.getMovementReferenceNumber());
438         movementCommon.setMovementNote("updated movement note-" + movementCommon.getMovementNote());
439         movementCommon.setNormalLocation(""); // Test deletion of existing string value
440
441         String currentTimestamp = GregorianCalendarDateTimeUtils.timestampUTC();
442         movementCommon.setPlannedRemovalDate(""); // Test deletion of existing date or date/time value
443         movementCommon.setRemovalDate(currentTimestamp);
444
445         if(logger.isDebugEnabled()){
446             logger.debug("to be updated object");
447             logger.debug(objectAsXmlString(movementCommon, MovementsCommon.class));
448         }
449
450         // Submit the request to the service and store the response.
451         PoxPayloadOut output = new PoxPayloadOut(this.getServicePathComponent());
452         PayloadOutputPart commonPart = output.addPart(movementCommon, MediaType.APPLICATION_XML_TYPE);
453         commonPart.setLabel(client.getCommonPartName());
454         res = client.update(knownResourceId, output);
455
456         // Check the status code of the response: does it match the expected response(s)?
457         int statusCode = res.getStatus();
458         if(logger.isDebugEnabled()){
459             logger.debug(testName + ": status = " + statusCode);
460         }
461         Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
462                 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
463         Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
464
465        // Extract the updated common part from the response.
466         input = new PoxPayloadIn(res.getEntity());
467         payloadInputPart = input.getPart(client.getCommonPartName());
468         MovementsCommon updatedMovementCommon = null;
469         if (payloadInputPart != null) {
470                 updatedMovementCommon = (MovementsCommon) payloadInputPart.getBody();
471         }
472         Assert.assertNotNull(movementCommon);
473         if(logger.isDebugEnabled()){
474             logger.debug("updated object");
475             logger.debug(objectAsXmlString(updatedMovementCommon, MovementsCommon.class));
476         }
477
478         // Check selected fields in the updated common part.
479         
480         // By submitting an empty string in the update payload, the value of this field
481         // in the object created from the response payload will be null.
482         Assert.assertNull(updatedMovementCommon.getNormalLocation(), "Data in updated object did not match submitted data.");
483         if(logger.isDebugEnabled()){
484             logger.debug("Normal location after update=|" + updatedMovementCommon.getNormalLocation() + "|");
485         }
486
487         Assert.assertEquals(updatedMovementCommon.getMovementReferenceNumber(),
488             movementCommon.getMovementReferenceNumber(),
489             "Data in updated object did not match submitted data.");
490         Assert.assertEquals(updatedMovementCommon.getMovementNote(),
491             movementCommon.getMovementNote(),
492             "Data in updated object did not match submitted data.");
493         Assert.assertNull(updatedMovementCommon.getPlannedRemovalDate());
494         Assert.assertEquals(updatedMovementCommon.getRemovalDate(),
495             movementCommon.getRemovalDate(),
496             "Data in updated object did not match submitted data.");
497
498         if(logger.isDebugEnabled()){
499             logger.debug("UTF-8 data sent=" + movementCommon.getMovementNote() + "\n"
500                     + "UTF-8 data received=" + updatedMovementCommon.getMovementNote());
501     }
502         Assert.assertTrue(updatedMovementCommon.getMovementNote().contains(getUTF8DataFragment()),
503                 "UTF-8 data retrieved '" + updatedMovementCommon.getMovementNote()
504                 + "' does not contain expected data '" + getUTF8DataFragment());
505         Assert.assertEquals(updatedMovementCommon.getMovementNote(),
506                 movementCommon.getMovementNote(),
507                 "Data in updated object did not match submitted data.");
508
509     }
510
511     // Failure outcomes
512     // Placeholders until the three tests below can be uncommented.
513     // See Issue CSPACE-401.
514     /* (non-Javadoc)
515      * @see org.collectionspace.services.client.test.AbstractServiceTestImpl#updateWithEmptyEntityBody(java.lang.String)
516      */
517     @Override
518     public void updateWithEmptyEntityBody(String testName) throws Exception{
519         //Should this really be empty?
520     }
521     
522     /* (non-Javadoc)
523      * @see org.collectionspace.services.client.test.AbstractServiceTestImpl#updateWithMalformedXml(java.lang.String)
524      */
525     @Override
526     public void updateWithMalformedXml(String testName) throws Exception {
527         //Should this really be empty?
528     }
529     
530     /* (non-Javadoc)
531      * @see org.collectionspace.services.client.test.AbstractServiceTestImpl#updateWithWrongXmlSchema(java.lang.String)
532      */
533     @Override
534     public void updateWithWrongXmlSchema(String testName) throws Exception {
535         //Should this really be empty?
536     }
537
538     /*
539     @Override
540     @Test(dataProvider="testName", dataProviderClass=AbstractServiceTest.class,
541         dependsOnMethods = {"create", "update", "testSubmitRequest"})
542     public void updateWithEmptyEntityBody(String testName) throws Exception {
543
544         if (logger.isDebugEnabled()) {
545             logger.debug(testBanner(testName, CLASS_NAME));
546         }
547         // Perform setup.
548         setupUpdateWithEmptyEntityBody();
549
550         // Submit the request to the service and store the response.
551         String method = REQUEST_TYPE.httpMethodName();
552         String url = getResourceURL(knownResourceId);
553         String mediaType = MediaType.APPLICATION_XML;
554         final String entity = "";
555         int statusCode = submitRequest(method, url, mediaType, entity);
556
557         // Check the status code of the response: does it match
558         // the expected response(s)?
559         if(logger.isDebugEnabled()){
560             logger.debug(testName + ": url=" + url +
561                 " status=" + statusCode);
562          }
563         Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
564         invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
565         Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
566     }
567
568     @Override
569     @Test(dataProvider="testName", dataProviderClass=AbstractServiceTest.class,
570         dependsOnMethods = {"create", "update", "testSubmitRequest"})
571     public void updateWithMalformedXml(String testName) throws Exception {
572
573         if (logger.isDebugEnabled()) {
574             logger.debug(testBanner(testName, CLASS_NAME));
575         }
576         // Perform setup.
577         setupUpdateWithMalformedXml();
578
579         // Submit the request to the service and store the response.
580         String method = REQUEST_TYPE.httpMethodName();
581         String url = getResourceURL(knownResourceId);
582         String mediaType = MediaType.APPLICATION_XML;
583         final String entity = MALFORMED_XML_DATA;
584         int statusCode = submitRequest(method, url, mediaType, entity);
585
586         // Check the status code of the response: does it match
587         // the expected response(s)?
588         if(logger.isDebugEnabled()){
589             logger.debug(testName + ": url=" + url +
590              " status=" + statusCode);
591          }
592         Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
593         invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
594         Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
595     }
596
597     @Override
598     @Test(dataProvider="testName", dataProviderClass=AbstractServiceTest.class,
599         dependsOnMethods = {"create", "update", "testSubmitRequest"})
600     public void updateWithWrongXmlSchema(String testName) throws Exception {
601
602         if (logger.isDebugEnabled()) {
603             logger.debug(testBanner(testName, CLASS_NAME));
604         }
605         // Perform setup.
606         setupUpdateWithWrongXmlSchema();
607
608         // Submit the request to the service and store the response.
609         String method = REQUEST_TYPE.httpMethodName();
610         String url = getResourceURL(knownResourceId);
611         String mediaType = MediaType.APPLICATION_XML;
612         final String entity = WRONG_XML_SCHEMA_DATA;
613         int statusCode = submitRequest(method, url, mediaType, entity);
614
615         // Check the status code of the response: does it match
616         // the expected response(s)?
617         if(logger.isDebugEnabled()){
618             logger.debug(testName + ": url=" + url +
619             " status=" + statusCode);
620          }
621         Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
622         invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
623         Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
624     }
625      */
626
627     /* (non-Javadoc)
628      * @see org.collectionspace.services.client.test.AbstractServiceTestImpl#updateNonExistent(java.lang.String)
629      */
630     @Override
631     @Test(dataProvider="testName", dataProviderClass=AbstractServiceTestImpl.class,
632         dependsOnMethods = {"update", "testSubmitRequest"})
633     public void updateNonExistent(String testName) throws Exception {
634
635         if (logger.isDebugEnabled()) {
636             logger.debug(testBanner(testName, CLASS_NAME));
637         }
638         // Perform setup.
639         setupUpdateNonExistent();
640
641         // Submit the request to the service and store the response.
642         // Note: The ID used in this 'create' call may be arbitrary.
643         // The only relevant ID may be the one used in update(), below.
644         MovementClient client = new MovementClient();
645         PoxPayloadOut multipart = createMovementInstance(NON_EXISTENT_ID);
646         ClientResponse<String> res = client.update(NON_EXISTENT_ID, multipart);
647         int statusCode = res.getStatus();
648
649         // Check the status code of the response: does it match
650         // the expected response(s)?
651         if(logger.isDebugEnabled()){
652             logger.debug(testName + ": status = " + statusCode);
653         }
654         Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
655                 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
656         Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
657     }
658
659     // ---------------------------------------------------------------
660     // CRUD tests : DELETE tests
661     // ---------------------------------------------------------------
662     // Success outcomes
663     /* (non-Javadoc)
664      * @see org.collectionspace.services.client.test.AbstractServiceTestImpl#delete(java.lang.String)
665      */
666
667     @Override
668     @Test(dataProvider="testName", dataProviderClass=AbstractServiceTestImpl.class,
669         dependsOnMethods = {"create", "readList", "testSubmitRequest", "update"})
670     public void delete(String testName) throws Exception {
671
672         if (logger.isDebugEnabled()) {
673             logger.debug(testBanner(testName, CLASS_NAME));
674         }
675         /*
676         // Perform setup.
677         setupDelete();
678
679         // Submit the request to the service and store the response.
680         MovementClient client = new MovementClient();
681         ClientResponse<Response> res = client.delete(knownResourceId);
682         int statusCode = res.getStatus();
683
684         // Check the status code of the response: does it match
685         // the expected response(s)?
686         if(logger.isDebugEnabled()){
687             logger.debug(testName + ": status = " + statusCode);
688         }
689         Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
690                 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
691         Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
692      *
693      */
694     }
695
696
697     // Failure outcomes
698     /* (non-Javadoc)
699      * @see org.collectionspace.services.client.test.AbstractServiceTestImpl#deleteNonExistent(java.lang.String)
700      */
701     @Override
702     @Test(dataProvider="testName", dataProviderClass=AbstractServiceTestImpl.class,
703         dependsOnMethods = {"delete"})
704     public void deleteNonExistent(String testName) throws Exception {
705
706         if (logger.isDebugEnabled()) {
707             logger.debug(testBanner(testName, CLASS_NAME));
708         }
709         // Perform setup.
710         setupDeleteNonExistent();
711
712         // Submit the request to the service and store the response.
713         MovementClient client = new MovementClient();
714         ClientResponse<Response> res = client.delete(NON_EXISTENT_ID);
715         int statusCode = res.getStatus();
716
717         // Check the status code of the response: does it match
718         // the expected response(s)?
719         if(logger.isDebugEnabled()){
720             logger.debug(testName + ": status = " + statusCode);
721         }
722         Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
723                 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
724         Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
725     }
726
727     // ---------------------------------------------------------------
728     // Utility tests : tests of code used in tests above
729     // ---------------------------------------------------------------
730     /**
731      * Tests the code for manually submitting data that is used by several
732      * of the methods above.
733      */
734     @Test(dependsOnMethods = {"create", "read"})
735     public void testSubmitRequest() {
736
737         // Expected status code: 200 OK
738         final int EXPECTED_STATUS = Response.Status.OK.getStatusCode();
739
740         // Submit the request to the service and store the response.
741         String method = ServiceRequestType.READ.httpMethodName();
742         String url = getResourceURL(knownResourceId);
743         int statusCode = submitRequest(method, url);
744
745         // Check the status code of the response: does it match
746         // the expected response(s)?
747         if(logger.isDebugEnabled()){
748             logger.debug("testSubmitRequest: url=" + url +
749                 " status=" + statusCode);
750         }
751         Assert.assertEquals(statusCode, EXPECTED_STATUS);
752
753     }
754
755     // ---------------------------------------------------------------
756     // Utility methods used by tests above
757     // ---------------------------------------------------------------
758
759     @Override
760     protected String getServiceName() {
761         return SERVICE_NAME;
762     }
763
764     /* (non-Javadoc)
765      * @see org.collectionspace.services.client.test.BaseServiceTest#getServicePathComponent()
766      */
767     @Override
768     public String getServicePathComponent() {
769         return SERVICE_PATH_COMPONENT;
770     }
771
772     /**
773      * Creates the movement instance.
774      *
775      * @param identifier the identifier
776      * @return the multipart output
777      */
778     private PoxPayloadOut createMovementInstance(String identifier) {
779         return createInstance("movementReferenceNumber-" + identifier);
780     }
781
782     /**
783      * Creates an instance of a Movement record for testing.
784      *
785      * @param movementReferenceNumber A movement reference number.
786      * @return Multipart output suitable for use as a payload
787      *     in a create or update request.
788      */
789     @Override
790     public PoxPayloadOut createInstance(String movementReferenceNumber) {
791         MovementsCommon movementCommon = new MovementsCommon();
792         // FIXME: Values of currentLocation, normalLocation,
793         // and movementContact should be refNames.
794         movementCommon.setCurrentLocation("currentLocation value");
795         movementCommon.setCurrentLocationFitness("currentLocationFitness value");
796         movementCommon.setCurrentLocationNote("currentLocationNote value");
797         movementCommon.setLocationDate(TIMESTAMP_UTC);
798         movementCommon.setNormalLocation("normalLocation value");
799         movementCommon.setMovementContact("movementContact value");
800         MovementMethodsList movementMethodsList = new MovementMethodsList();
801         List<String> methods = movementMethodsList.getMovementMethod();
802         // @TODO Use properly formatted refNames for representative movement
803         // methods in this example record. The values below are placeholders.
804         String identifier = createIdentifier();
805         methods.add("First Movement Method-" + identifier);
806         methods.add("Second Movement Method-" + identifier);
807         movementCommon.setMovementMethods(movementMethodsList);
808         movementCommon.setMovementNote(getUTF8DataFragment());
809         movementCommon.setMovementReferenceNumber(movementReferenceNumber);
810         movementCommon.setPlannedRemovalDate(TIMESTAMP_UTC);
811         movementCommon.setRemovalDate(""); // Test empty date value
812         movementCommon.setReasonForMove("reasonForMove value");
813
814         PoxPayloadOut multipart = new PoxPayloadOut(this.getServicePathComponent());
815         PayloadOutputPart commonPart =
816             multipart.addPart(movementCommon, MediaType.APPLICATION_XML_TYPE);
817         commonPart.setLabel(new MovementClient().getCommonPartName());
818
819         if(logger.isDebugEnabled()){
820             logger.debug("to be created, movement common");
821             logger.debug(objectAsXmlString(movementCommon, MovementsCommon.class));
822         }
823
824         return multipart;
825     }
826
827     // FIXME Should be moved to a common class, as these are general utilities.
828     // FIXME Should be refactored to become a convenience variant of a
829     // general method to return a current datestamp or timestamp in any
830     // provided time zone.
831
832    /**
833     * Returns an ISO 8601 formatted timestamp of the
834     * current time instance in the UTC time zone.
835     */
836     public String datestampUTC() {
837         final String ISO_8601_DATE_FORMAT_PATTERN = "yyyy-MM-dd";
838         final DateFormat ISO_8601_DATE_FORMAT =
839             new SimpleDateFormat(ISO_8601_DATE_FORMAT_PATTERN);
840
841         final String UTC_TIMEZONE_IDENTIFIER = "UTC";
842         final TimeZone UTC_TIMEZONE = TimeZone.getTimeZone(UTC_TIMEZONE_IDENTIFIER);
843
844         Date timestamp = new Date();
845         return formatDate(timestamp, UTC_TIMEZONE, ISO_8601_DATE_FORMAT);
846     }
847
848    /**
849     * Returns an ISO 8601 formatted timestamp of the
850     * current time instance in the UTC time zone.
851     */
852     public String timestampUTC() {
853         final String ISO_8601_FORMAT_PATTERN = "yyyy-MM-dd'T'HH:mm:ss'Z'";
854         final DateFormat ISO_8601_FORMAT =
855             new SimpleDateFormat(ISO_8601_FORMAT_PATTERN);
856
857         final String UTC_TIMEZONE_IDENTIFIER = "UTC";
858         final TimeZone UTC_TIMEZONE = TimeZone.getTimeZone(UTC_TIMEZONE_IDENTIFIER);
859
860         Date timestamp = new Date();
861         return formatDate(timestamp, UTC_TIMEZONE, ISO_8601_FORMAT);
862     }
863
864    /**
865     * Formats a provided date using a provided date formatter,
866     * in the default system time zone.
867     *
868     * @param date  A date to format.
869     * @param df    A date formatter to apply.
870     * @return      A formatted date string.
871     */
872     public String formatDate(Date date, DateFormat df) {
873         return formatDate(date, TimeZone.getDefault(), df);
874     }
875
876     // FIXME Add error handling.
877
878    /**
879     * Formats a provided date using a provided date formatter,
880     * in a provided time zone.
881     *
882     * @param date  A date to format.
883     * @param tz    The time zone qualifier for the date to format.
884     * @param df    A date formatter to apply.
885     *
886     * @return      A formatted date string.
887     */
888     public String formatDate(Date date, TimeZone tz, DateFormat df) {
889         df.setTimeZone(tz);
890         return df.format(date);
891     }
892
893 }