Project

General

Profile

1
/**
2
 *  '$RCSfile$'
3
 *  Copyright: 2004 Regents of the University of California and the
4
 *              National Center for Ecological Analysis and Synthesis
5
 *  Purpose: To test the Access Controls in metacat by JUnit
6
 *
7
 *   '$Author: leinfelder $'
8
 *     '$Date: 2010-12-22 13:35:44 -0800 (Wed, 22 Dec 2010) $'
9
 * '$Revision: 5754 $'
10
 *
11
 * This program is free software; you can redistribute it and/or modify
12
 * it under the terms of the GNU General Public License as published by
13
 * the Free Software Foundation; either version 2 of the License, or
14
 * (at your option) any later version.
15
 *
16
 * This program is distributed in the hope that it will be useful,
17
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19
 * GNU General Public License for more details.
20
 *
21
 * You should have received a copy of the GNU General Public License
22
 * along with this program; if not, write to the Free Software
23
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
24
 */
25

    
26
package edu.ucsb.nceas.metacattest;
27

    
28
import java.io.InputStream;
29
import java.io.InputStreamReader;
30
import java.io.Reader;
31
import java.io.StringReader;
32
import java.util.Calendar;
33
import java.util.Date;
34
import java.util.GregorianCalendar;
35
import java.util.SimpleTimeZone;
36
import java.util.TimeZone;
37

    
38
import edu.ucsb.nceas.MCTestCase;
39
import edu.ucsb.nceas.metacat.client.InsufficientKarmaException;
40
import edu.ucsb.nceas.metacat.client.Metacat;
41
import edu.ucsb.nceas.metacat.client.MetacatAuthException;
42
import edu.ucsb.nceas.metacat.client.MetacatException;
43
import edu.ucsb.nceas.metacat.client.MetacatFactory;
44
import edu.ucsb.nceas.metacat.client.MetacatInaccessibleException;
45
import edu.ucsb.nceas.metacat.properties.PropertyService;
46
import edu.ucsb.nceas.utilities.FileUtil;
47
import edu.ucsb.nceas.utilities.IOUtil;
48
import edu.ucsb.nceas.utilities.PropertyNotFoundException;
49
import junit.framework.Test;
50
import junit.framework.TestSuite;
51
import java.io.File;
52

    
53
import org.apache.commons.io.IOUtils;
54

    
55
/**
56
 * A JUnit test for testing Metacat when Non Ascii Characters are inserted
57
 */
58
public class NonAsciiCharacterTest
59
    extends MCTestCase {
60

    
61
    private static String metacatUrl;
62
    private static String username;
63
	private static String password;
64
	private static String anotheruser;
65
	private static String anotherpassword;
66
	static {
67
		try {
68
		    metacatUrl = PropertyService.getProperty("test.metacatUrl");
69
			username = PropertyService.getProperty("test.mcUser");
70
			password = PropertyService.getProperty("test.mcPassword");
71
			anotheruser = PropertyService.getProperty("test.mcAnotherUser");
72
			anotherpassword = PropertyService.getProperty("test.mcAnotherPassword");
73
		} catch (PropertyNotFoundException pnfe) {
74
			System.err.println("Could not get property in static block: " 
75
					+ pnfe.getMessage());
76
		}
77
	}
78

    
79
    private String prefix = "test";
80
    private String testdocument = "";
81

    
82
    private Metacat m;
83

    
84
    /**
85
     * These variables are for eml-2.0.1 only. For other eml versions,
86
     * this function might have to modified
87
     */
88

    
89
    private String testEml_201_Header =
90
        "<?xml version=\"1.0\"?><eml:eml" +
91
        " xmlns:eml=\"eml://ecoinformatics.org/eml-2.0.1\"" +
92
        " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"" +
93
        " packageId=\"eml.1.1\" system=\"knb\"" +
94
        " xsi:schemaLocation=\"eml://ecoinformatics.org/eml-2.0.1 eml.xsd\"" +
95
        " scope=\"system\">";
96
    
97
    private String testEml_210_Header =
98
        "<?xml version=\"1.0\"?><eml:eml" +
99
        " xmlns:eml=\"eml://ecoinformatics.org/eml-2.1.0\"" +
100
        " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"" +
101
        " packageId=\"eml.1.1\" system=\"knb\"" +
102
        " xsi:schemaLocation=\"eml://ecoinformatics.org/eml-2.1.0 eml.xsd\"" +
103
        " scope=\"system\">";
104

    
105
    private String testEmlCreatorBlock =
106
        "<creator scope=\"document\">                                       " +
107
        " <individualName>                                                  " +
108
        "    <surName>Smith</surName>                                       " +
109
        " </individualName>                                                 " +
110
        "</creator>                                                         ";
111

    
112
    private String testEmlContactBlock =
113
        "<contact scope=\"document\">                                       " +
114
        " <individualName>                                                  " +
115
        "    <surName>Jackson</surName>                                     " +
116
        " </individualName>                                                 " +
117
        "</contact>                                                         ";
118

    
119
    /**
120
     * This function returns an access block based on the params passed
121
     */
122
    protected String getAccessBlock(String principal, boolean grantAccess,
123
                                  boolean read, boolean write,
124
                                  boolean changePermission, boolean all) {
125
        String accessBlock = "<access " +
126
            "authSystem=\"ldap://ldap.ecoinformatics.org:389/dc=ecoinformatics,dc=org\"" +
127
            " order=\"allowFirst\" scope=\"document\">";
128

    
129
        if (grantAccess) {
130
            accessBlock += "<allow>";
131
        }
132
        else {
133
            accessBlock += "<deny>";
134
        }
135

    
136
        accessBlock = accessBlock + "<principal>" + principal + "</principal>";
137

    
138
        if (all) {
139
            accessBlock += "<permission>all</permission>";
140
        }
141
        else {
142
            if (read) {
143
                accessBlock += "<permission>read</permission>";
144
            }
145
            if (write) {
146
                accessBlock += "<permission>write</permission>";
147
            }
148
            if (changePermission) {
149
                accessBlock += "<permission>changePermission</permission>";
150
            }
151
        }
152

    
153
        if (grantAccess) {
154
            accessBlock += "</allow>";
155
        }
156
        else {
157
            accessBlock += "</deny>";
158
        }
159
        accessBlock += "</access>";
160

    
161
        return accessBlock;
162

    
163
    }
164

    
165
    /**
166
     * This function returns a valid eml document with no access rules
167
     * This function is for eml-2.0.1 only. For other eml versions,
168
     * this function might have to modified
169
     */
170
    private String getTestEmlDoc(String title, String emlVersion) {
171

    
172
        String testDocument = "";
173

    
174
        String header;
175
		if (emlVersion == EML2_0_1) {
176
			header = testEml_201_Header;
177
		} else if (emlVersion == EML2_1_0) {
178
			header = testEml_210_Header;
179
		} else { // if (emlVersion == EML2_1_1) {
180
			header = testEml_211_Header;
181
		}
182
        
183
        testDocument += header;
184
        
185
        // if this is an EML 2.1.0 or later document, the document level access is
186
        // before the dataset element.
187
        if (emlVersion == EML2_1_0 || emlVersion == EML2_1_1) {
188
        	testDocument += getAccessBlock("public", true, true, false, false, false);
189
        }
190
        testDocument += "<dataset scope=\"document\"><title>" + title + "</title>"
191
				+ testEmlCreatorBlock;
192

    
193
        testDocument += testEmlContactBlock;
194
        
195
        // if this is an EML 2.0.1 or earlier document, the document level access is
196
        // inside the dataset element.
197
        if (emlVersion != EML2_1_0) {
198
        	testDocument += getAccessBlock("public", true, true, false, false, false);
199
        }
200
        testDocument += "</dataset>";
201
        testDocument += "</eml:eml>";
202

    
203
        return testDocument;
204
    }
205
    
206
    /**
207
     * Returns an xml squery that searches for the doc id in the
208
     * title of documents. This function is for eml-2.0.1+ only. For 
209
     * other eml versions, this function might have to modified.
210
     */
211
    private String getTestEmlQuery(String titlePart, String emlVersion) {
212

    
213
    	String docType;
214
    	if (emlVersion.equals(EML2_0_1)) {
215
    		docType = "eml://ecoinformatics.org/eml-2.0.1";
216
    	} else if (emlVersion.equals(EML2_1_0)) {
217
    		docType = "eml://ecoinformatics.org/eml-2.1.0";
218
    	} else { //if (emlVersion.equals(EML2_1_1)) {
219
    		docType = "eml://ecoinformatics.org/eml-2.1.1";
220
    	}
221
    	
222
        String sQuery = "";
223
        sQuery = 
224
        	"<pathquery version=\"1.0\">" +
225
        		"<meta_file_id>unspecified</meta_file_id>" +
226
        		"<querytitle>unspecified</querytitle>" + 
227
        		"<returnfield>dataset/title</returnfield>" +
228
        		"<returndoctype>" + docType + "</returndoctype>" +
229
        		"<querygroup operator=\"UNION\">" +
230
        			"<queryterm casesensitive=\"false\" searchmode=\"contains\">" +
231
        				"<value>" + titlePart + "</value>" +
232
        				"<pathexpr>dataset/title</pathexpr>" +
233
        			"</queryterm>" +
234
        		"</querygroup>" +
235
        	"</pathquery>";
236

    
237
        return sQuery;
238
    }
239

    
240
    /**
241
     * Constructor to build the test
242
     *
243
     * @param name the name of the test method
244
     */
245
    public NonAsciiCharacterTest(String name) {
246
        super(name);
247
    }
248

    
249
    /**
250
     * Establish a testing framework by initializing appropriate objects
251
     */
252
    public void setUp() {
253
        try {
254
            System.err.println("Test Metacat: " + metacatUrl);
255
            m = MetacatFactory.createMetacatConnection(metacatUrl);
256
        }
257
        catch (MetacatInaccessibleException mie) {
258
            System.err.println("Metacat is: " + metacatUrl);
259
            fail("Metacat connection failed." + mie.getMessage());
260
        }
261
    }
262

    
263
    /**
264
     * Release any objects after tests are complete
265
     */
266
    public void tearDown() {
267
    }
268

    
269
    /**
270
     * Create a suite of tests to be run together
271
     */
272
    public static Test suite() {
273
        TestSuite suite = new TestSuite();
274
        suite.addTest(new NonAsciiCharacterTest("initialize"));
275
        // Test basic functions
276
        suite.addTest(new NonAsciiCharacterTest("invalidXMLCharacters201Test"));
277
        suite.addTest(new NonAsciiCharacterTest("invalidXMLCharacters210Test"));
278
        suite.addTest(new NonAsciiCharacterTest("symbolEncodedFormat201Test"));
279
        suite.addTest(new NonAsciiCharacterTest("symbolEncodedFormat210Test"));
280
        suite.addTest(new NonAsciiCharacterTest("quote201Test"));
281
        suite.addTest(new NonAsciiCharacterTest("quote210Test"));
282
        suite.addTest(new NonAsciiCharacterTest("numericCharacterReferenceFormat201Test"));
283
        suite.addTest(new NonAsciiCharacterTest("numericCharacterReferenceFormat210Test"));
284
        suite.addTest(new NonAsciiCharacterTest("nonLatinUnicodeCharacter201Test"));
285
        suite.addTest(new NonAsciiCharacterTest("nonLatinUnicodeCharacter210Test"));
286
        suite.addTest(new NonAsciiCharacterTest("unicodeCharacterTest"));
287

    
288
        return suite;
289
    }
290

    
291
    /**
292
     * Run an initial test that always passes to check that the test
293
     * harness is working.
294
     */
295
    public void initialize() {
296
        assertTrue(1 == 1);
297
    }
298

    
299
    /**
300
     * Test inserting an EML 2.0.1 document with > & <
301
     * should fail because this means an invalid xml document is being inserted
302
     */
303
    public void invalidXMLCharacters201Test() {
304
    	debug("\nRunning: invalidXMLCharacters201Test");
305
        try {
306
            String newdocid = generateDocid();
307
            m.login(username, password);
308
            testdocument = getTestEmlDoc("Checking > & < in doc: " + newdocid, EML2_0_1);
309
            insertDocid(newdocid + ".1", testdocument, FAILURE, true);
310
            m.logout();
311
        }
312
        catch (MetacatAuthException mae) {
313
            fail("Authorization failed:\n" + mae.getMessage());
314
        }
315
        catch (MetacatInaccessibleException mie) {
316
            fail("Metacat Inaccessible:\n" + mie.getMessage());
317
        }
318
        catch (Exception e) {
319
            fail("General exception:\n" + e.getMessage());
320
        }
321
    }
322
    
323
    /**
324
     * Test inserting an EML 2.1.0 document with > & <
325
     * should fail because this means an invalid xml document is being inserted
326
     */
327
    public void invalidXMLCharacters210Test() {
328
    	debug("\nRunning: invalidXMLCharacters210Test");
329
        try {
330
            String newdocid = generateDocid();
331
            m.login(username, password);
332
            testdocument = getTestEmlDoc("Checking > & < in doc: " + newdocid, EML2_1_0);
333
            insertDocid(newdocid + ".1", testdocument, FAILURE, true);
334
            m.logout();
335
        }
336
        catch (MetacatAuthException mae) {
337
            fail("Authorization failed:\n" + mae.getMessage());
338
        }
339
        catch (MetacatInaccessibleException mie) {
340
            fail("Metacat Inaccessible:\n" + mie.getMessage());
341
        }
342
        catch (Exception e) {
343
            fail("General exception:\n" + e.getMessage());
344
        }
345
    }
346

    
347
    /**
348
     * Test inserting and reading an EML 2.0.1 document with &gt; &amp; &lt;
349
     * Read should succeed since the same document should be read 
350
     * back from disk that was submitted. Query should succeed as 
351
     * well because the characters in this test are not changed in
352
     * the database.
353
     */
354
    public void symbolEncodedFormat201Test() {
355
    	debug("\nRunning: symbolEncodedFormat201Test");
356
        try {
357
            String newdocid = generateDocid();
358
            m.login(username, password);
359
            
360
            String testTitle = 
361
            	"Checking &gt; &lt; &quot; &apos; &amp; in doc: " + newdocid  + ".1";
362
            testdocument = getTestEmlDoc(testTitle, EML2_0_1);
363
            insertDocid(newdocid  + ".1", testdocument, SUCCESS, false);
364
            
365
            // this tests reading the document back from disk
366
            readDocidWhichEqualsDoc(newdocid, testdocument, SUCCESS, false);
367
            
368
            // this tests searching for the document in the database
369
            Thread.sleep(3000);
370
            queryDocWhichHasTitle(newdocid  + ".1", testTitle, EML2_0_1, SUCCESS);
371
            
372
            deleteDocid(newdocid  + ".1", SUCCESS, false);
373
            
374
            m.logout();
375
        }
376
        catch (MetacatAuthException mae) {
377
            fail("Authorization failed:\n" + mae.getMessage());
378
        }
379
        catch (MetacatInaccessibleException mie) {
380
            fail("Metacat Inaccessible:\n" + mie.getMessage());
381
        }
382
        catch (Exception e) {
383
            fail("General exception:\n" + e.getMessage());
384
        }
385
    }
386
    
387
    /**
388
     * Test inserting and reading an EML 2.1.0 document with &gt; &amp; &lt;
389
     * Read should succeed since the same document should be read 
390
     * back from disk that was submitted. Query should succeed as 
391
     * well because the characters in this test are not changed in
392
     * the database.
393
     */
394
    public void symbolEncodedFormat210Test() {
395
    	debug("\nRunning: symbolEncodedFormat210Test");
396
        try {
397
            String newdocid = generateDocid();
398
            m.login(username, password);
399
            
400
            String testTitle = 
401
            	"Checking &gt; &lt; &quot; &apos; &amp; in doc: " + newdocid + ".1";
402
            testdocument = getTestEmlDoc(testTitle, EML2_1_0);
403
            insertDocid(newdocid  + ".1", testdocument, SUCCESS, false);
404
            
405
            // this tests reading the document back from disk
406
            readDocidWhichEqualsDoc(newdocid, testdocument, SUCCESS, false);
407
            
408
            // this tests searching for the document in the database
409
            Thread.sleep(3000);
410
            queryDocWhichHasTitle(newdocid  + ".1", testTitle, EML2_1_0, SUCCESS);
411
            
412
            deleteDocid(newdocid  + ".1", SUCCESS, false);
413
            
414
            m.logout();
415
        }
416
        catch (MetacatAuthException mae) {
417
            fail("Authorization failed:\n" + mae.getMessage());
418
        }
419
        catch (MetacatInaccessibleException mie) {
420
            fail("Metacat Inaccessible:\n" + mie.getMessage());
421
        }
422
        catch (Exception e) {
423
            fail("General exception:\n" + e.getMessage());
424
        }
425
    }
426

    
427
    /**
428
     * Test inserting and reading an EML 2.0.1 document with single quote and double quote.
429
     * Read should succeed since the same document should be read back from disk 
430
     * that was submitted.  Query should succeed because we look for the converted
431
     * character (&apos; and &quot;).
432
     */
433
    public void quote201Test() {
434
    	debug("\nRunning: quote201Test");
435
        try {
436
            String newdocid = generateDocid();
437
            m.login(username, password);
438
            
439
            String testTitle = "Checking ' ` \" in doc: " + newdocid  + ".1";
440
            String convertedTestTitle = "Checking &apos; ` &quot; in doc: " + newdocid  + ".1";
441
            
442
            testdocument = getTestEmlDoc(testTitle, EML2_0_1);
443
            insertDocid(newdocid + ".1", testdocument, SUCCESS, true);
444
            
445
            // this tests reading the document back from disk
446
            readDocidWhichEqualsDoc(newdocid, testdocument, SUCCESS, true);
447
            
448
            // this tests searching for the document in the database
449
            Thread.sleep(3000);
450
            queryDocWhichHasTitle(newdocid  + ".1", convertedTestTitle, EML2_0_1, SUCCESS);
451
            
452
            deleteDocid(newdocid  + ".1", SUCCESS, false);
453
            
454
            m.logout();
455
        }
456
        catch (MetacatAuthException mae) {
457
            fail("Authorization failed:\n" + mae.getMessage());
458
        }
459
        catch (MetacatInaccessibleException mie) {
460
            fail("Metacat Inaccessible:\n" + mie.getMessage());
461
        }
462
        catch (Exception e) {
463
            fail("General exception:\n" + e.getMessage());
464
        }
465
    }
466
    
467
    /**
468
     * Test inserting and reading an EML 2.1.0 document with single quote and double quote.
469
     * Read should succeed since the same document should be read back from disk 
470
     * that was submitted.  Query shoud succeed because we look for the converted
471
     * character (&apos; and &quot;).
472
     */
473
    public void quote210Test() {
474
    	debug("\nRunning: quote210Test");
475
        try {
476
            String newdocid = generateDocid();
477
            m.login(username, password);
478
            
479
            String testTitle = "Checking ' ` \" in doc: " + newdocid  + ".1";
480
            String convertedTestTitle = "Checking &apos; ` &quot; in doc: " + newdocid  + ".1";
481
            
482
            testdocument = getTestEmlDoc(testTitle, EML2_1_0);
483
            insertDocid(newdocid + ".1", testdocument, SUCCESS, true);
484
            
485
            // this tests reading the document back from disk
486
            readDocidWhichEqualsDoc(newdocid, testdocument, SUCCESS, true);
487
            
488
            // this tests searching for the document in the database
489
            Thread.sleep(3000);
490
            queryDocWhichHasTitle(newdocid  + ".1", convertedTestTitle, EML2_1_0, SUCCESS);
491
            
492
            deleteDocid(newdocid  + ".1", SUCCESS, false);
493
            
494
            m.logout();
495
        }
496
        catch (MetacatAuthException mae) {
497
            fail("Authorization failed:\n" + mae.getMessage());
498
        }
499
        catch (MetacatInaccessibleException mie) {
500
            fail("Metacat Inaccessible:\n" + mie.getMessage());
501
        }
502
        catch (Exception e) {
503
            fail("General exception:\n" + e.getMessage());
504
        }
505
    }
506

    
507
    /**
508
     * Test inserting and reading an EML 2.0.1 document with the code representation 
509
     * of a micro sign (&#181). Read should succeed since the same document should be 
510
     * read back from disk that was submitted.  Query should succeed because we look 
511
     * for the converted character (µ).
512
     */
513
    public void numericCharacterReferenceFormat201Test() {
514
    	debug("\nRunning: numericCharacterReferenceFormat201Test");
515
        try {
516
            String newdocid = generateDocid();
517
            m.login(username, password);
518
            
519
            String testTitle = "Checking &#181; in doc: " + newdocid  + ".1";
520
            String convertedTestTitle = "Checking µ in doc: " + newdocid  + ".1";
521
            
522
            testdocument = getTestEmlDoc(testTitle, EML2_0_1);
523
            insertDocid(newdocid + ".1", testdocument, SUCCESS, true);
524

    
525
            // this tests reading the document back from disk
526
            readDocidWhichEqualsDoc(newdocid, testdocument, SUCCESS, true);
527
            
528
            // this tests searching for the document in the database
529
            Thread.sleep(3000);
530
            queryDocWhichHasTitle(newdocid  + ".1", convertedTestTitle, EML2_0_1, SUCCESS);
531
            
532
            deleteDocid(newdocid  + ".1", SUCCESS, false);
533
  
534
            m.logout();
535
        }
536
        catch (MetacatAuthException mae) {
537
            fail("Authorization failed:\n" + mae.getMessage());
538
        }
539
        catch (MetacatInaccessibleException mie) {
540
            fail("Metacat Inaccessible:\n" + mie.getMessage());
541
        }
542
        catch (Exception e) {
543
            fail("General exception:\n" + e.getMessage());
544
        }
545
    }
546

    
547
    /**
548
     * Test inserting and reading an EML 2.1.0 document with the code representation 
549
     * of a micro sign (&#181). Read should succeed since the same document should be 
550
     * read back from disk that was submitted.  Query should succeed because we look 
551
     * for the converted character (µ).
552
     */
553
    public void numericCharacterReferenceFormat210Test() {
554
    	debug("\nRunning: numericCharacterReferenceFormat210Test");
555
        try {
556
            String newdocid = generateDocid();
557
            m.login(username, password);
558
            
559
            String testTitle = "Checking &#181; in doc: " + newdocid  + ".1";
560
            String convertedTestTitle = "Checking µ in doc: " + newdocid  + ".1";
561
            
562
            testdocument = getTestEmlDoc(testTitle, EML2_1_0);
563
            insertDocid(newdocid + ".1", testdocument, SUCCESS, true);
564
            
565
            // this tests reading the document back from disk
566
            readDocidWhichEqualsDoc(newdocid, testdocument, SUCCESS, true);
567
            
568
            // this tests searching for the document in the database
569
            Thread.sleep(3000);
570
            queryDocWhichHasTitle(newdocid  + ".1", convertedTestTitle, EML2_1_0, SUCCESS);
571
            
572
            deleteDocid(newdocid  + ".1", SUCCESS, false);
573
            
574
            m.logout();
575
        }
576
        catch (MetacatAuthException mae) {
577
            fail("Authorization failed:\n" + mae.getMessage());
578
        }
579
        catch (MetacatInaccessibleException mie) {
580
            fail("Metacat Inaccessible:\n" + mie.getMessage());
581
        }
582
        catch (Exception e) {
583
            fail("General exception:\n" + e.getMessage());
584
        }
585
    }
586

    
587
    /**
588
     * Test inserting and reading an EML 2.0.1 document with the micro sign (µ). 
589
     * Read should succeed since the same document should be read back from disk 
590
     * that was submitted.  Query should succeed because we look for the same 
591
     * character (µ).
592
     */
593
    public void nonLatinUnicodeCharacter201Test() {
594
    	debug("\nRunning: nonLatinUnicodeCharacter201Test");
595
        try {
596
            String newdocid = generateDocid();
597
            m.login(username, password);
598
            
599
            String testTitle = "Checking characters like µ in doc: " + newdocid  + ".1";
600
            
601
            testdocument = getTestEmlDoc(testTitle, EML2_0_1);
602
            
603
            debug("original test document:	" + testdocument);
604
            
605
            insertDocid(newdocid + ".1", testdocument, SUCCESS, false);
606
            
607
            // this tests reading the document back from disk
608
            readDocidWhichEqualsDoc(newdocid, testdocument, SUCCESS, true);
609
            
610
            // this tests searching for the document in the database
611
            Thread.sleep(3000);
612
            queryDocWhichHasTitle(newdocid  + ".1", testTitle, EML2_0_1, SUCCESS);
613
            
614
            deleteDocid(newdocid  + ".1", SUCCESS, false);
615
            
616
            m.logout();
617
        }
618
        catch (MetacatAuthException mae) {
619
            fail("Authorization failed:\n" + mae.getMessage());
620
        }
621
        catch (MetacatInaccessibleException mie) {
622
            fail("Metacat Inaccessible:\n" + mie.getMessage());
623
        }
624
        catch (Exception e) {
625
            fail("General exception:\n" + e.getMessage());
626
        }
627
    }
628
    
629
    /**
630
     * Test inserting and reading an EML 2.1.0 document with the micro sign (µ). 
631
     * Read should succeed since the same document should be read back from disk 
632
     * that was submitted.  Query should succeed because we look for the same 
633
     * character (µ).
634
     */
635
    public void nonLatinUnicodeCharacter210Test() {
636
    	debug("\nRunning: nonLatinUnicodeCharacter210Test");
637
        try {
638
            String newdocid = generateDocid();
639
            m.login(username, password);
640
            
641
            String testTitle = "Checking characters like µ in doc: " + newdocid  + ".1";
642
            
643
            testdocument = getTestEmlDoc(testTitle, EML2_1_0);
644
            insertDocid(newdocid + ".1", testdocument, SUCCESS, false);
645

    
646
            // this tests reading the document back from disk
647
            readDocidWhichEqualsDoc(newdocid, testdocument, SUCCESS, true);
648
            
649
            // this tests searching for the document in the database
650
            Thread.sleep(3000);
651
            queryDocWhichHasTitle(newdocid  + ".1", testTitle, EML2_1_0, SUCCESS);
652
            
653
            deleteDocid(newdocid  + ".1", SUCCESS, false);
654
            
655
            m.logout();
656
        }
657
        catch (MetacatAuthException mae) {
658
            fail("Authorization failed:\n" + mae.getMessage());
659
        }
660
        catch (MetacatInaccessibleException mie) {
661
            fail("Metacat Inaccessible:\n" + mie.getMessage());
662
        }
663
        catch (Exception e) {
664
            fail("General exception:\n" + e.getMessage());
665
        }
666
    }
667
    
668
    /**
669
     * Test inserting and reading an EML 2.1.0 with Chinese
670
     */
671
    public void unicodeCharacterTest() {
672
    	debug("\nRunning: unicodeCharacterTest");
673
        try {
674
            
675
        	String filePath = "test/clienttestfiles/unicodeEML.xml";
676
            String testTitle = "測試中的數據包 (Test Chinese data package) _DOCID_";
677
            String newdocid = generateDocid() + ".1";
678
            testdocument = FileUtil.readFileToString(filePath, "UTF-8");
679
            
680
            // include the docid
681
            testdocument = testdocument.replaceAll("_DOCID_", newdocid);
682
            testTitle = testTitle.replaceAll("_DOCID_", newdocid);
683
            
684
            // login
685
            m.login(username, password);
686
            
687
            // insert
688
            insertDocid(newdocid, testdocument, SUCCESS, false);
689

    
690
            // this tests reading the document back from disk
691
            readDocidWhichEqualsDoc(newdocid, testdocument, SUCCESS, true);
692
            
693
            // this tests searching for the document in the database
694
            Thread.sleep(3000);
695
            queryDocWhichHasTitle(testTitle, testTitle, EML2_1_0, SUCCESS);
696
            
697
            // clean up
698
            deleteDocid(newdocid, SUCCESS, false);
699
            
700
            m.logout();
701
        }
702
        catch (MetacatAuthException mae) {
703
            fail("Authorization failed:\n" + mae.getMessage());
704
        }
705
        catch (MetacatInaccessibleException mie) {
706
            fail("Metacat Inaccessible:\n" + mie.getMessage());
707
        }
708
        catch (Exception e) {
709
            fail("General exception:\n" + e.getMessage());
710
        }
711
    }
712

    
713
    /**
714
     * Insert a document into metacat. The expected result is passed as result
715
     */
716
    private String insertDocid(String docid, String docText, boolean result,
717
                               boolean expectMetacatException) {
718
        String response = null;
719
        try {
720
        	
721
        	debug("doctext: " + docText);
722
        	
723
            response = m.insert(docid,
724
                                new StringReader(docText), null);
725
            System.err.println(response);
726
            if (result) {
727
                assertTrue( (response.indexOf("<success>") != -1));
728
                assertTrue(response.indexOf(docid) != -1);
729
            }
730
            else {
731
                assertTrue( (response.indexOf("<success>") == -1));
732
            }
733
        }
734
        catch (MetacatInaccessibleException mie) {
735
            fail("Metacat Inaccessible:\n" + mie.getMessage());
736
        }
737
        catch (InsufficientKarmaException ike) {
738
                fail("Insufficient karma:\n" + ike.getMessage());
739
        }
740
        catch (MetacatException me) {
741
            if (!expectMetacatException) {
742
                fail("Metacat Error:\n" + me.getMessage());
743
            }
744
        }
745
        catch (Exception e) {
746
            fail("General exception:\n" + e.getMessage());
747
        }
748
        return response;
749
    }
750

    
751
    /**
752
     * Insert a document into metacat. The expected result is passed as result
753
     */
754
    private String uploadDocid(String docid, String filePath, boolean result,
755
                               boolean expectedKarmaException) {
756
        String response = null;
757
        try {
758
            response = m.upload(docid, new File(filePath));
759
            if (result) {
760
                assertTrue( (response.indexOf("<success>") != -1));
761
                assertTrue(response.indexOf(docid) != -1);
762
            }
763
            else {
764
                assertTrue( (response.indexOf("<success>") == -1));
765
            }
766
            System.err.println("respose from metacat: " + response);
767
        }
768
        catch (MetacatInaccessibleException mie) {
769
            fail("Metacat Inaccessible:\n" + mie.getMessage());
770
        }
771
        catch (InsufficientKarmaException ike) {
772
            if (!expectedKarmaException) {
773
                fail("Insufficient karma:\n" + ike.getMessage());
774
            }
775
        }
776
        catch (MetacatException me) {
777
            if (result) {
778
                fail("Metacat Error:\n" + me.getMessage());
779
            } else {
780
                System.err.println("Metacat Error:\n" + me.getMessage());
781
            }
782
        }
783
        catch (Exception e) {
784
            fail("General exception:\n" + e.getMessage());
785
        }
786
        return response;
787
    }
788

    
789
    /**
790
     * Update a document in metacat. The expected result is passed as result
791
     */
792
    private String updateDocid(String docid, String docText, boolean result,
793
                               boolean expectedKarmaFailure) {
794
        String response = null;
795
        try {
796
            response = m.update(docid,
797
                                new StringReader(testdocument), null);
798

    
799
            if (result) {
800
                assertTrue( (response.indexOf("<success>") != -1));
801
                assertTrue(response.indexOf(docid) != -1);
802
            }
803
            else {
804
                assertTrue( (response.indexOf("<success>") == -1));
805
            }
806
            System.err.println(response);
807
        }
808
        catch (MetacatInaccessibleException mie) {
809
            fail("Metacat Inaccessible:\n" + mie.getMessage());
810
        }
811
        catch (InsufficientKarmaException ike) {
812
            if (!expectedKarmaFailure) {
813
                fail("Insufficient karma:\n" + ike.getMessage());
814
            }
815
        }
816
        catch (MetacatException me) {
817
            if (result) {
818
                fail("Metacat Error:\n" + me.getMessage());
819
            } else {
820
                System.err.println("Metacat Error:\n" + me.getMessage());
821
            }
822
        }
823
        catch (Exception e) {
824
            fail("General exception:\n" + e.getMessage());
825
        }
826

    
827
        return response;
828
    }
829

    
830
    /**
831
     * Delete a document from metacat. The expected result is passed as result
832
     */
833
    private void deleteDocid(String docid, boolean result,
834
                             boolean expextedKarmaFailure) {
835
        try {
836
            String response = m.delete(docid);
837
            if (result) {
838
                assertTrue(response.indexOf("<success>") != -1);
839
            }
840
            else {
841
                assertTrue(response.indexOf("<success>") == -1);
842
            }
843
            System.err.println(response);
844
        }
845
        catch (MetacatInaccessibleException mie) {
846
            fail("Metacat Inaccessible:\n" + mie.getMessage());
847
        }
848
        catch (InsufficientKarmaException ike) {
849
            if(!expextedKarmaFailure){
850
                fail("Insufficient karma:\n" + ike.getMessage());
851
            }
852
        }
853
        catch (MetacatException me) {
854
            if (result) {
855
                fail("Metacat Error:\n" + me.getMessage());
856
            } else {
857
                System.err.println("Metacat Error:\n" + me.getMessage());
858
            }
859
        }
860
        catch (Exception e) {
861
            fail("General exception:\n" + e.getMessage());
862
        }
863
    }
864

    
865
    /**
866
     * Read a document from metacat. The expected result is passed as result
867
     */
868
    private void readDocid(String docid, boolean result,
869
                           boolean expextedKarmaFailure) {
870
        try {
871
            Reader r = new InputStreamReader(m.read(docid));
872
            String response = IOUtil.getAsString(r, true);
873

    
874
            if (!result) {
875
                assertTrue(response.indexOf("<success>") == -1);
876
            }
877
            // System.err.println(response);
878
        }
879
        catch (MetacatInaccessibleException mie) {
880
            fail("Metacat Inaccessible:\n" + mie.getMessage());
881
        }
882
        catch (InsufficientKarmaException ike) {
883
            if (!expextedKarmaFailure) {
884
                fail("Insufficient karma:\n" + ike.getMessage());
885
            }
886
        }
887
        catch (MetacatException me) {
888
            fail("Metacat Error:\n" + me.getMessage());
889
        }
890
        catch (Exception e) {
891
            fail("General exception:\n" + e.getMessage());
892
        }
893
    }
894

    
895
    /**
896
     * Read a document from metacat and check if it is equal to a given string.
897
     * The expected result is passed as result
898
     */
899
    private void readDocidWhichEqualsDoc(String docid, String testDoc,
900
                                         boolean result,
901
                                         boolean expectedKarmaFailure) {
902
        try {
903
            Reader r = new InputStreamReader(m.read(docid), "UTF-8");
904
            //InputStream is = m.read(docid);
905
            String doc = IOUtil.getAsString(r, true);
906
            //String doc = IOUtils.toString(is);
907
            
908
            if (result) {
909

    
910
                if (!testDoc.equals(doc)) {
911
                    debug("doc    :" + doc);
912
                    debug("testDoc:" + testDoc);
913
                }
914

    
915
                assertTrue(testDoc.equals(doc));
916
            }
917
            else {
918
                assertTrue(doc.indexOf("<error>") != -1);
919
            }
920
        }
921
        catch (MetacatInaccessibleException mie) {
922
            fail("Metacat Inaccessible:\n" + mie.getMessage());
923
        }
924
        catch (InsufficientKarmaException ike) {
925
            if (!expectedKarmaFailure) {
926
                fail("Insufficient karma:\n" + ike.getMessage());
927
            }
928
        }
929
        catch (MetacatException me) {
930
            fail("Metacat Error:\n" + me.getMessage());
931
        }
932
        catch (Exception e) {
933
            fail("General exception:\n" + e.getMessage());
934
        }
935

    
936
    }
937
    
938
    /**
939
     * Query a document by looking for a part of the title in the title element.
940
     * Then check if the testTitle exists in the doc.
941
     * @param titlePart the part of the title of the doc to look for
942
     * @param testTitle the title containing special characters
943
     * @param result are we expecting SUCCESS or FAILURE
944
     * @param expextedKarmaFailure
945
     */
946
    private void queryDocWhichHasTitle(String titlePart, String testTitle,
947
                                         String emlVersion, boolean result) {
948
        try {
949
            String sQuery = getTestEmlQuery(titlePart, emlVersion);
950
        	Reader queryReader = new StringReader(sQuery);
951
            Reader resultReader = m.query(queryReader);
952
            String queryResult = IOUtil.getAsString(resultReader, true);
953
            if (result) {
954
                if (!queryResult.contains(testTitle)) {
955
                    debug("queryResult: " + queryResult);
956
                    debug("does not contain title: " + testTitle);
957
                }
958

    
959
                assertTrue(queryResult.contains(testTitle));
960
            }
961
            else {
962
                assertTrue(queryResult.indexOf("<error>") != -1);
963
            }
964
        }
965
        catch (MetacatInaccessibleException mie) {
966
            fail("Metacat Inaccessible:\n" + mie.getMessage());
967
        }
968
        catch (Exception e) {
969
            fail("General exception:\n" + e.getMessage());
970
        }
971

    
972
    }
973

    
974
    /**
975
     * Create a hopefully unique docid for testing insert and update. Does
976
     * not include the 'revision' part of the id.
977
     *
978
     * @return a String docid based on the current date and time
979
     */
980
    private String generateDocid() {
981
        StringBuffer docid = new StringBuffer(prefix);
982
        docid.append(".");
983

    
984
        // Create a calendar to get the date formatted properly
985
        String[] ids = TimeZone.getAvailableIDs( -8 * 60 * 60 * 1000);
986
        SimpleTimeZone pdt = new SimpleTimeZone( -8 * 60 * 60 * 1000, ids[0]);
987
        pdt.setStartRule(Calendar.APRIL, 1, Calendar.SUNDAY, 2 * 60 * 60 * 1000);
988
        pdt.setEndRule(Calendar.OCTOBER, -1, Calendar.SUNDAY,
989
                       2 * 60 * 60 * 1000);
990
        Calendar calendar = new GregorianCalendar(pdt);
991
        Date trialTime = new Date();
992
        calendar.setTime(trialTime);
993
        docid.append(calendar.get(Calendar.YEAR));
994
        docid.append(calendar.get(Calendar.DAY_OF_YEAR));
995
        docid.append(calendar.get(Calendar.HOUR_OF_DAY));
996
        docid.append(calendar.get(Calendar.MINUTE));
997
        docid.append(calendar.get(Calendar.SECOND));
998
   	    //sometimes this number is not unique, so we append a random number
999
    	int random = (new Double(Math.random()*100)).intValue();
1000
    	docid.append(random);
1001
        return docid.toString();
1002
    }
1003
}
(11-11/23)