]> git.aero2k.de Git - tmp/jakarta-migration.git/blob
a2619f28de619ad9ee0c148973b81985bcd1efd0
[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         Assert.assertEquals(updatedMovementCommon.getNormalLocation(),
480             movementCommon.getNormalLocation(), "Data in updated object did not match submitted data.");
481         if(logger.isDebugEnabled()){
482             logger.debug("Normal location after update=|" + updatedMovementCommon.getNormalLocation() + "|");
483         }
484
485         Assert.assertEquals(updatedMovementCommon.getMovementReferenceNumber(),
486             movementCommon.getMovementReferenceNumber(),
487             "Data in updated object did not match submitted data.");
488         Assert.assertEquals(updatedMovementCommon.getMovementNote(),
489             movementCommon.getMovementNote(),
490             "Data in updated object did not match submitted data.");
491         Assert.assertNull(updatedMovementCommon.getPlannedRemovalDate());
492         Assert.assertEquals(updatedMovementCommon.getRemovalDate(),
493             movementCommon.getRemovalDate(),
494             "Data in updated object did not match submitted data.");
495
496         if(logger.isDebugEnabled()){
497             logger.debug("UTF-8 data sent=" + movementCommon.getMovementNote() + "\n"
498                     + "UTF-8 data received=" + updatedMovementCommon.getMovementNote());
499     }
500         Assert.assertTrue(updatedMovementCommon.getMovementNote().contains(getUTF8DataFragment()),
501                 "UTF-8 data retrieved '" + updatedMovementCommon.getMovementNote()
502                 + "' does not contain expected data '" + getUTF8DataFragment());
503         Assert.assertEquals(updatedMovementCommon.getMovementNote(),
504                 movementCommon.getMovementNote(),
505                 "Data in updated object did not match submitted data.");
506
507     }
508
509     // Failure outcomes
510     // Placeholders until the three tests below can be uncommented.
511     // See Issue CSPACE-401.
512     /* (non-Javadoc)
513      * @see org.collectionspace.services.client.test.AbstractServiceTestImpl#updateWithEmptyEntityBody(java.lang.String)
514      */
515     @Override
516     public void updateWithEmptyEntityBody(String testName) throws Exception{
517         //Should this really be empty?
518     }
519     
520     /* (non-Javadoc)
521      * @see org.collectionspace.services.client.test.AbstractServiceTestImpl#updateWithMalformedXml(java.lang.String)
522      */
523     @Override
524     public void updateWithMalformedXml(String testName) throws Exception {
525         //Should this really be empty?
526     }
527     
528     /* (non-Javadoc)
529      * @see org.collectionspace.services.client.test.AbstractServiceTestImpl#updateWithWrongXmlSchema(java.lang.String)
530      */
531     @Override
532     public void updateWithWrongXmlSchema(String testName) throws Exception {
533         //Should this really be empty?
534     }
535
536     /*
537     @Override
538     @Test(dataProvider="testName", dataProviderClass=AbstractServiceTest.class,
539         dependsOnMethods = {"create", "update", "testSubmitRequest"})
540     public void updateWithEmptyEntityBody(String testName) throws Exception {
541
542         if (logger.isDebugEnabled()) {
543             logger.debug(testBanner(testName, CLASS_NAME));
544         }
545         // Perform setup.
546         setupUpdateWithEmptyEntityBody();
547
548         // Submit the request to the service and store the response.
549         String method = REQUEST_TYPE.httpMethodName();
550         String url = getResourceURL(knownResourceId);
551         String mediaType = MediaType.APPLICATION_XML;
552         final String entity = "";
553         int statusCode = submitRequest(method, url, mediaType, entity);
554
555         // Check the status code of the response: does it match
556         // the expected response(s)?
557         if(logger.isDebugEnabled()){
558             logger.debug(testName + ": url=" + url +
559                 " status=" + statusCode);
560          }
561         Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
562         invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
563         Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
564     }
565
566     @Override
567     @Test(dataProvider="testName", dataProviderClass=AbstractServiceTest.class,
568         dependsOnMethods = {"create", "update", "testSubmitRequest"})
569     public void updateWithMalformedXml(String testName) throws Exception {
570
571         if (logger.isDebugEnabled()) {
572             logger.debug(testBanner(testName, CLASS_NAME));
573         }
574         // Perform setup.
575         setupUpdateWithMalformedXml();
576
577         // Submit the request to the service and store the response.
578         String method = REQUEST_TYPE.httpMethodName();
579         String url = getResourceURL(knownResourceId);
580         String mediaType = MediaType.APPLICATION_XML;
581         final String entity = MALFORMED_XML_DATA;
582         int statusCode = submitRequest(method, url, mediaType, entity);
583
584         // Check the status code of the response: does it match
585         // the expected response(s)?
586         if(logger.isDebugEnabled()){
587             logger.debug(testName + ": url=" + url +
588              " status=" + statusCode);
589          }
590         Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
591         invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
592         Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
593     }
594
595     @Override
596     @Test(dataProvider="testName", dataProviderClass=AbstractServiceTest.class,
597         dependsOnMethods = {"create", "update", "testSubmitRequest"})
598     public void updateWithWrongXmlSchema(String testName) throws Exception {
599
600         if (logger.isDebugEnabled()) {
601             logger.debug(testBanner(testName, CLASS_NAME));
602         }
603         // Perform setup.
604         setupUpdateWithWrongXmlSchema();
605
606         // Submit the request to the service and store the response.
607         String method = REQUEST_TYPE.httpMethodName();
608         String url = getResourceURL(knownResourceId);
609         String mediaType = MediaType.APPLICATION_XML;
610         final String entity = WRONG_XML_SCHEMA_DATA;
611         int statusCode = submitRequest(method, url, mediaType, entity);
612
613         // Check the status code of the response: does it match
614         // the expected response(s)?
615         if(logger.isDebugEnabled()){
616             logger.debug(testName + ": url=" + url +
617             " status=" + statusCode);
618          }
619         Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
620         invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
621         Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
622     }
623      */
624
625     /* (non-Javadoc)
626      * @see org.collectionspace.services.client.test.AbstractServiceTestImpl#updateNonExistent(java.lang.String)
627      */
628     @Override
629     @Test(dataProvider="testName", dataProviderClass=AbstractServiceTestImpl.class,
630         dependsOnMethods = {"update", "testSubmitRequest"})
631     public void updateNonExistent(String testName) throws Exception {
632
633         if (logger.isDebugEnabled()) {
634             logger.debug(testBanner(testName, CLASS_NAME));
635         }
636         // Perform setup.
637         setupUpdateNonExistent();
638
639         // Submit the request to the service and store the response.
640         // Note: The ID used in this 'create' call may be arbitrary.
641         // The only relevant ID may be the one used in update(), below.
642         MovementClient client = new MovementClient();
643         PoxPayloadOut multipart = createMovementInstance(NON_EXISTENT_ID);
644         ClientResponse<String> res = client.update(NON_EXISTENT_ID, multipart);
645         int statusCode = res.getStatus();
646
647         // Check the status code of the response: does it match
648         // the expected response(s)?
649         if(logger.isDebugEnabled()){
650             logger.debug(testName + ": status = " + statusCode);
651         }
652         Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
653                 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
654         Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
655     }
656
657     // ---------------------------------------------------------------
658     // CRUD tests : DELETE tests
659     // ---------------------------------------------------------------
660     // Success outcomes
661     /* (non-Javadoc)
662      * @see org.collectionspace.services.client.test.AbstractServiceTestImpl#delete(java.lang.String)
663      */
664
665     @Override
666     @Test(dataProvider="testName", dataProviderClass=AbstractServiceTestImpl.class,
667         dependsOnMethods = {"create", "readList", "testSubmitRequest", "update"})
668     public void delete(String testName) throws Exception {
669
670         if (logger.isDebugEnabled()) {
671             logger.debug(testBanner(testName, CLASS_NAME));
672         }
673         /*
674         // Perform setup.
675         setupDelete();
676
677         // Submit the request to the service and store the response.
678         MovementClient client = new MovementClient();
679         ClientResponse<Response> res = client.delete(knownResourceId);
680         int statusCode = res.getStatus();
681
682         // Check the status code of the response: does it match
683         // the expected response(s)?
684         if(logger.isDebugEnabled()){
685             logger.debug(testName + ": status = " + statusCode);
686         }
687         Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
688                 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
689         Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
690      *
691      */
692     }
693
694
695     // Failure outcomes
696     /* (non-Javadoc)
697      * @see org.collectionspace.services.client.test.AbstractServiceTestImpl#deleteNonExistent(java.lang.String)
698      */
699     @Override
700     @Test(dataProvider="testName", dataProviderClass=AbstractServiceTestImpl.class,
701         dependsOnMethods = {"delete"})
702     public void deleteNonExistent(String testName) throws Exception {
703
704         if (logger.isDebugEnabled()) {
705             logger.debug(testBanner(testName, CLASS_NAME));
706         }
707         // Perform setup.
708         setupDeleteNonExistent();
709
710         // Submit the request to the service and store the response.
711         MovementClient client = new MovementClient();
712         ClientResponse<Response> res = client.delete(NON_EXISTENT_ID);
713         int statusCode = res.getStatus();
714
715         // Check the status code of the response: does it match
716         // the expected response(s)?
717         if(logger.isDebugEnabled()){
718             logger.debug(testName + ": status = " + statusCode);
719         }
720         Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
721                 invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
722         Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
723     }
724
725     // ---------------------------------------------------------------
726     // Utility tests : tests of code used in tests above
727     // ---------------------------------------------------------------
728     /**
729      * Tests the code for manually submitting data that is used by several
730      * of the methods above.
731      */
732     @Test(dependsOnMethods = {"create", "read"})
733     public void testSubmitRequest() {
734
735         // Expected status code: 200 OK
736         final int EXPECTED_STATUS = Response.Status.OK.getStatusCode();
737
738         // Submit the request to the service and store the response.
739         String method = ServiceRequestType.READ.httpMethodName();
740         String url = getResourceURL(knownResourceId);
741         int statusCode = submitRequest(method, url);
742
743         // Check the status code of the response: does it match
744         // the expected response(s)?
745         if(logger.isDebugEnabled()){
746             logger.debug("testSubmitRequest: url=" + url +
747                 " status=" + statusCode);
748         }
749         Assert.assertEquals(statusCode, EXPECTED_STATUS);
750
751     }
752
753     // ---------------------------------------------------------------
754     // Utility methods used by tests above
755     // ---------------------------------------------------------------
756
757     @Override
758     protected String getServiceName() {
759         return SERVICE_NAME;
760     }
761
762     /* (non-Javadoc)
763      * @see org.collectionspace.services.client.test.BaseServiceTest#getServicePathComponent()
764      */
765     @Override
766     public String getServicePathComponent() {
767         return SERVICE_PATH_COMPONENT;
768     }
769
770     /**
771      * Creates the movement instance.
772      *
773      * @param identifier the identifier
774      * @return the multipart output
775      */
776     private PoxPayloadOut createMovementInstance(String identifier) {
777         return createInstance("movementReferenceNumber-" + identifier);
778     }
779
780     /**
781      * Creates an instance of a Movement record for testing.
782      *
783      * @param movementReferenceNumber A movement reference number.
784      * @return Multipart output suitable for use as a payload
785      *     in a create or update request.
786      */
787     @Override
788     public PoxPayloadOut createInstance(String movementReferenceNumber) {
789         MovementsCommon movementCommon = new MovementsCommon();
790         // FIXME: Values of currentLocation, normalLocation,
791         // and movementContact should be refNames.
792         movementCommon.setCurrentLocation("currentLocation value");
793         movementCommon.setCurrentLocationFitness("currentLocationFitness value");
794         movementCommon.setCurrentLocationNote("currentLocationNote value");
795         movementCommon.setLocationDate(TIMESTAMP_UTC);
796         movementCommon.setNormalLocation("normalLocation value");
797         movementCommon.setMovementContact("movementContact value");
798         MovementMethodsList movementMethodsList = new MovementMethodsList();
799         List<String> methods = movementMethodsList.getMovementMethod();
800         // @TODO Use properly formatted refNames for representative movement
801         // methods in this example record. The values below are placeholders.
802         String identifier = createIdentifier();
803         methods.add("First Movement Method-" + identifier);
804         methods.add("Second Movement Method-" + identifier);
805         movementCommon.setMovementMethods(movementMethodsList);
806         movementCommon.setMovementNote(getUTF8DataFragment());
807         movementCommon.setMovementReferenceNumber(movementReferenceNumber);
808         movementCommon.setPlannedRemovalDate(TIMESTAMP_UTC);
809         movementCommon.setRemovalDate(""); // Test empty date value
810         movementCommon.setReasonForMove("reasonForMove value");
811
812         PoxPayloadOut multipart = new PoxPayloadOut(this.getServicePathComponent());
813         PayloadOutputPart commonPart =
814             multipart.addPart(movementCommon, MediaType.APPLICATION_XML_TYPE);
815         commonPart.setLabel(new MovementClient().getCommonPartName());
816
817         if(logger.isDebugEnabled()){
818             logger.debug("to be created, movement common");
819             logger.debug(objectAsXmlString(movementCommon, MovementsCommon.class));
820         }
821
822         return multipart;
823     }
824
825     // FIXME Should be moved to a common class, as these are general utilities.
826     // FIXME Should be refactored to become a convenience variant of a
827     // general method to return a current datestamp or timestamp in any
828     // provided time zone.
829
830    /**
831     * Returns an ISO 8601 formatted timestamp of the
832     * current time instance in the UTC time zone.
833     */
834     public String datestampUTC() {
835         final String ISO_8601_DATE_FORMAT_PATTERN = "yyyy-MM-dd";
836         final DateFormat ISO_8601_DATE_FORMAT =
837             new SimpleDateFormat(ISO_8601_DATE_FORMAT_PATTERN);
838
839         final String UTC_TIMEZONE_IDENTIFIER = "UTC";
840         final TimeZone UTC_TIMEZONE = TimeZone.getTimeZone(UTC_TIMEZONE_IDENTIFIER);
841
842         Date timestamp = new Date();
843         return formatDate(timestamp, UTC_TIMEZONE, ISO_8601_DATE_FORMAT);
844     }
845
846    /**
847     * Returns an ISO 8601 formatted timestamp of the
848     * current time instance in the UTC time zone.
849     */
850     public String timestampUTC() {
851         final String ISO_8601_FORMAT_PATTERN = "yyyy-MM-dd'T'HH:mm:ss'Z'";
852         final DateFormat ISO_8601_FORMAT =
853             new SimpleDateFormat(ISO_8601_FORMAT_PATTERN);
854
855         final String UTC_TIMEZONE_IDENTIFIER = "UTC";
856         final TimeZone UTC_TIMEZONE = TimeZone.getTimeZone(UTC_TIMEZONE_IDENTIFIER);
857
858         Date timestamp = new Date();
859         return formatDate(timestamp, UTC_TIMEZONE, ISO_8601_FORMAT);
860     }
861
862    /**
863     * Formats a provided date using a provided date formatter,
864     * in the default system time zone.
865     *
866     * @param date  A date to format.
867     * @param df    A date formatter to apply.
868     * @return      A formatted date string.
869     */
870     public String formatDate(Date date, DateFormat df) {
871         return formatDate(date, TimeZone.getDefault(), df);
872     }
873
874     // FIXME Add error handling.
875
876    /**
877     * Formats a provided date using a provided date formatter,
878     * in a provided time zone.
879     *
880     * @param date  A date to format.
881     * @param tz    The time zone qualifier for the date to format.
882     * @param df    A date formatter to apply.
883     *
884     * @return      A formatted date string.
885     */
886     public String formatDate(Date date, TimeZone tz, DateFormat df) {
887         df.setTimeZone(tz);
888         return df.format(date);
889     }
890
891 }