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-27 11:25:59 -0800 (Mon, 27 Dec 2010) $'
9
 * '$Revision: 5757 $'
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 InternationalizationTest
59
    extends MCTestCase {
60
    
61
    /**
62
     * Returns an xml squery that searches for the doc id in the
63
     * title of documents. This function is for eml-2.0.1+ only. For 
64
     * other eml versions, this function might have to modified.
65
     */
66
    private String getTestEmlQuery(String titlePart, String emlVersion) {
67

    
68
    	String docType;
69
    	if (emlVersion.equals(EML2_0_1)) {
70
    		docType = "eml://ecoinformatics.org/eml-2.0.1";
71
    	} else if (emlVersion.equals(EML2_1_0)) {
72
    		docType = "eml://ecoinformatics.org/eml-2.1.0";
73
    	} else { //if (emlVersion.equals(EML2_1_1)) {
74
    		docType = "eml://ecoinformatics.org/eml-2.1.1";
75
    	}
76
    	
77
        String sQuery = "";
78
        sQuery = 
79
        	"<pathquery version=\"1.0\">" +
80
        		"<meta_file_id>unspecified</meta_file_id>" +
81
        		"<querytitle>unspecified</querytitle>" + 
82
        		"<returnfield>dataset/title</returnfield>" +
83
        		"<returnfield>dataset/title/value</returnfield>" +
84
        		"<returndoctype>" + docType + "</returndoctype>" +
85
        		"<querygroup operator=\"UNION\">" +
86
        			"<queryterm casesensitive=\"false\" searchmode=\"contains\">" +
87
        				"<value>" + titlePart + "</value>" +
88
        				"<pathexpr>dataset/title</pathexpr>" +
89
        			"</queryterm>" +
90
        			"<queryterm casesensitive=\"false\" searchmode=\"contains\">" +
91
    				"<value>" + titlePart + "</value>" +
92
    				"<pathexpr>dataset/title/value</pathexpr>" +
93
    			"</queryterm>" +
94
        		"</querygroup>" +
95
        	"</pathquery>";
96

    
97
        return sQuery;
98
    }
99

    
100
    /**
101
     * Constructor to build the test
102
     *
103
     * @param name the name of the test method
104
     */
105
    public InternationalizationTest(String name) {
106
        super(name);
107
    }
108

    
109
    /**
110
     * Establish a testing framework by initializing appropriate objects
111
     */
112
    public void setUp() {
113
        try {
114
            System.err.println("Test Metacat: " + metacatUrl);
115
            m = MetacatFactory.createMetacatConnection(metacatUrl);
116
        }
117
        catch (MetacatInaccessibleException mie) {
118
            System.err.println("Metacat is: " + metacatUrl);
119
            fail("Metacat connection failed." + mie.getMessage());
120
        }
121
    }
122

    
123
    /**
124
     * Release any objects after tests are complete
125
     */
126
    public void tearDown() {
127
    }
128

    
129
    /**
130
     * Create a suite of tests to be run together
131
     */
132
    public static Test suite() {
133
        TestSuite suite = new TestSuite();
134
        suite.addTest(new InternationalizationTest("initialize"));
135
        // Test basic functions
136
        //suite.addTest(new InternationalizationTest("unicodeCharacterTest"));
137
        suite.addTest(new InternationalizationTest("translation211Test"));
138
        return suite;
139
    }
140

    
141
    /**
142
     * Run an initial test that always passes to check that the test
143
     * harness is working.
144
     */
145
    public void initialize() {
146
        assertTrue(1 == 1);
147
    }
148

    
149
    /**
150
     * Test inserting and reading an EML 2.1.0 document with the code representation 
151
     * of a micro sign (&#181). Read should succeed since the same document should be 
152
     * read back from disk that was submitted.  Query should succeed because we look 
153
     * for the converted character (µ).
154
     */
155
    public void numericCharacterReferenceFormat210Test() {
156
    	debug("\nRunning: numericCharacterReferenceFormat210Test");
157
        try {
158
            String newdocid = generateDocid();
159
            m.login(username, password);
160
            
161
            String testTitle = "Checking &#181; in doc: " + newdocid  + ".1";
162
            String convertedTestTitle = "Checking µ in doc: " + newdocid  + ".1";
163
            
164
            testdocument = getTestEmlDoc(testTitle, EML2_1_0);
165
            insertDocid(newdocid + ".1", testdocument, SUCCESS, true);
166
            
167
            // this tests reading the document back from disk
168
            readDocidWhichEqualsDoc(newdocid, testdocument, SUCCESS, true);
169
            
170
            // this tests searching for the document in the database
171
            Thread.sleep(3000);
172
            queryDocWhichHasTitle(newdocid  + ".1", convertedTestTitle, EML2_1_0, SUCCESS);
173
            
174
            deleteDocid(newdocid  + ".1", SUCCESS, false);
175
            
176
            m.logout();
177
        }
178
        catch (MetacatAuthException mae) {
179
            fail("Authorization failed:\n" + mae.getMessage());
180
        }
181
        catch (MetacatInaccessibleException mie) {
182
            fail("Metacat Inaccessible:\n" + mie.getMessage());
183
        }
184
        catch (Exception e) {
185
            fail("General exception:\n" + e.getMessage());
186
        }
187
    }
188

    
189
    /**
190
     * Test inserting and reading an EML 2.1.1 document with the multiple title translations. 
191
     * Read should succeed since the same document should be read back from disk 
192
     * that was submitted.  Query should succeed because we look for the same original and translation
193
     */
194
    public void translation211Test() {
195
    	debug("\nRunning: translation211Test");
196
        try {
197
            String newdocid = generateDocid();
198
            newdocid += ".1";
199
            m.login(username, password);
200
            
201
            String title_en_US = "Translation for document: " + newdocid;
202
            String title_zh_TW = "翻譯的文件: " + newdocid;
203

    
204
            String mixedTitle = 
205
            		title_en_US + 
206
            		"<value xml:lang=\"zh-TW\">" +
207
            		title_zh_TW +
208
            		"</value>";
209
            
210
            testdocument = getTestEmlDoc(mixedTitle, EML2_1_1);
211
            insertDocid(newdocid, testdocument, SUCCESS, false);
212

    
213
            // this tests reading the document back from disk
214
            readDocidWhichEqualsDoc(newdocid, testdocument, SUCCESS, true);
215
            
216
            // this tests searching for the document in the database
217
            Thread.sleep(3000);
218
            queryDocWhichHasTitle(newdocid, title_en_US, EML2_1_1, SUCCESS);
219
            queryDocWhichHasTitle(newdocid, title_zh_TW, EML2_1_1, SUCCESS);
220
            
221
            deleteDocid(newdocid, SUCCESS, false);
222
            
223
            m.logout();
224
        }
225
        catch (MetacatAuthException mae) {
226
            fail("Authorization failed:\n" + mae.getMessage());
227
        }
228
        catch (MetacatInaccessibleException mie) {
229
            fail("Metacat Inaccessible:\n" + mie.getMessage());
230
        }
231
        catch (Exception e) {
232
            fail("General exception:\n" + e.getMessage());
233
        }
234
    }
235
    
236
    /**
237
     * Test inserting and reading an EML 2.1.0 with Chinese
238
     */
239
    public void unicodeCharacterTest() {
240
    	debug("\nRunning: unicodeCharacterTest");
241
        try {
242
            
243
        	String filePath = "test/clienttestfiles/unicodeEML.xml";
244
            String testTitle = "測試中的數據包 (Test Chinese data package) _DOCID_";
245
            String newdocid = generateDocid() + ".1";
246
            testdocument = FileUtil.readFileToString(filePath, "UTF-8");
247
            
248
            // include the docid
249
            testdocument = testdocument.replaceAll("_DOCID_", newdocid);
250
            testTitle = testTitle.replaceAll("_DOCID_", newdocid);
251
            
252
            // login
253
            m.login(username, password);
254
            
255
            // insert
256
            insertDocid(newdocid, testdocument, SUCCESS, false);
257

    
258
            // this tests reading the document back from disk
259
            readDocidWhichEqualsDoc(newdocid, testdocument, SUCCESS, true);
260
            
261
            // this tests searching for the document in the database
262
            Thread.sleep(3000);
263
            queryDocWhichHasTitle(testTitle, testTitle, EML2_1_0, SUCCESS);
264
            
265
            // clean up
266
            //deleteDocid(newdocid, SUCCESS, false);
267
            
268
            m.logout();
269
        }
270
        catch (MetacatAuthException mae) {
271
            fail("Authorization failed:\n" + mae.getMessage());
272
        }
273
        catch (MetacatInaccessibleException mie) {
274
            fail("Metacat Inaccessible:\n" + mie.getMessage());
275
        }
276
        catch (Exception e) {
277
            fail("General exception:\n" + e.getMessage());
278
        }
279
    }
280

    
281
    /**
282
     * Insert a document into metacat. The expected result is passed as result
283
     */
284
    private String insertDocid(String docid, String docText, boolean result,
285
                               boolean expectMetacatException) {
286
        String response = null;
287
        try {
288
        	
289
        	debug("doctext: " + docText);
290
        	
291
            response = m.insert(docid,
292
                                new StringReader(docText), null);
293
            System.err.println(response);
294
            if (result) {
295
                assertTrue( (response.indexOf("<success>") != -1));
296
                assertTrue(response.indexOf(docid) != -1);
297
            }
298
            else {
299
                assertTrue( (response.indexOf("<success>") == -1));
300
            }
301
        }
302
        catch (MetacatInaccessibleException mie) {
303
            fail("Metacat Inaccessible:\n" + mie.getMessage());
304
        }
305
        catch (InsufficientKarmaException ike) {
306
                fail("Insufficient karma:\n" + ike.getMessage());
307
        }
308
        catch (MetacatException me) {
309
            if (!expectMetacatException) {
310
                fail("Metacat Error:\n" + me.getMessage());
311
            }
312
        }
313
        catch (Exception e) {
314
            fail("General exception:\n" + e.getMessage());
315
        }
316
        return response;
317
    }
318

    
319
    /**
320
     * Insert a document into metacat. The expected result is passed as result
321
     */
322
    private String uploadDocid(String docid, String filePath, boolean result,
323
                               boolean expectedKarmaException) {
324
        String response = null;
325
        try {
326
            response = m.upload(docid, new File(filePath));
327
            if (result) {
328
                assertTrue( (response.indexOf("<success>") != -1));
329
                assertTrue(response.indexOf(docid) != -1);
330
            }
331
            else {
332
                assertTrue( (response.indexOf("<success>") == -1));
333
            }
334
            System.err.println("respose from metacat: " + response);
335
        }
336
        catch (MetacatInaccessibleException mie) {
337
            fail("Metacat Inaccessible:\n" + mie.getMessage());
338
        }
339
        catch (InsufficientKarmaException ike) {
340
            if (!expectedKarmaException) {
341
                fail("Insufficient karma:\n" + ike.getMessage());
342
            }
343
        }
344
        catch (MetacatException me) {
345
            if (result) {
346
                fail("Metacat Error:\n" + me.getMessage());
347
            } else {
348
                System.err.println("Metacat Error:\n" + me.getMessage());
349
            }
350
        }
351
        catch (Exception e) {
352
            fail("General exception:\n" + e.getMessage());
353
        }
354
        return response;
355
    }
356

    
357
    /**
358
     * Update a document in metacat. The expected result is passed as result
359
     */
360
    private String updateDocid(String docid, String docText, boolean result,
361
                               boolean expectedKarmaFailure) {
362
        String response = null;
363
        try {
364
            response = m.update(docid,
365
                                new StringReader(testdocument), null);
366

    
367
            if (result) {
368
                assertTrue( (response.indexOf("<success>") != -1));
369
                assertTrue(response.indexOf(docid) != -1);
370
            }
371
            else {
372
                assertTrue( (response.indexOf("<success>") == -1));
373
            }
374
            System.err.println(response);
375
        }
376
        catch (MetacatInaccessibleException mie) {
377
            fail("Metacat Inaccessible:\n" + mie.getMessage());
378
        }
379
        catch (InsufficientKarmaException ike) {
380
            if (!expectedKarmaFailure) {
381
                fail("Insufficient karma:\n" + ike.getMessage());
382
            }
383
        }
384
        catch (MetacatException me) {
385
            if (result) {
386
                fail("Metacat Error:\n" + me.getMessage());
387
            } else {
388
                System.err.println("Metacat Error:\n" + me.getMessage());
389
            }
390
        }
391
        catch (Exception e) {
392
            fail("General exception:\n" + e.getMessage());
393
        }
394

    
395
        return response;
396
    }
397

    
398
    /**
399
     * Delete a document from metacat. The expected result is passed as result
400
     */
401
    private void deleteDocid(String docid, boolean result,
402
                             boolean expextedKarmaFailure) {
403
        try {
404
            String response = m.delete(docid);
405
            if (result) {
406
                assertTrue(response.indexOf("<success>") != -1);
407
            }
408
            else {
409
                assertTrue(response.indexOf("<success>") == -1);
410
            }
411
            System.err.println(response);
412
        }
413
        catch (MetacatInaccessibleException mie) {
414
            fail("Metacat Inaccessible:\n" + mie.getMessage());
415
        }
416
        catch (InsufficientKarmaException ike) {
417
            if(!expextedKarmaFailure){
418
                fail("Insufficient karma:\n" + ike.getMessage());
419
            }
420
        }
421
        catch (MetacatException me) {
422
            if (result) {
423
                fail("Metacat Error:\n" + me.getMessage());
424
            } else {
425
                System.err.println("Metacat Error:\n" + me.getMessage());
426
            }
427
        }
428
        catch (Exception e) {
429
            fail("General exception:\n" + e.getMessage());
430
        }
431
    }
432

    
433
    /**
434
     * Read a document from metacat. The expected result is passed as result
435
     */
436
    private void readDocid(String docid, boolean result,
437
                           boolean expextedKarmaFailure) {
438
        try {
439
            Reader r = new InputStreamReader(m.read(docid));
440
            String response = IOUtil.getAsString(r, true);
441

    
442
            if (!result) {
443
                assertTrue(response.indexOf("<success>") == -1);
444
            }
445
            // System.err.println(response);
446
        }
447
        catch (MetacatInaccessibleException mie) {
448
            fail("Metacat Inaccessible:\n" + mie.getMessage());
449
        }
450
        catch (InsufficientKarmaException ike) {
451
            if (!expextedKarmaFailure) {
452
                fail("Insufficient karma:\n" + ike.getMessage());
453
            }
454
        }
455
        catch (MetacatException me) {
456
            fail("Metacat Error:\n" + me.getMessage());
457
        }
458
        catch (Exception e) {
459
            fail("General exception:\n" + e.getMessage());
460
        }
461
    }
462

    
463
    /**
464
     * Read a document from metacat and check if it is equal to a given string.
465
     * The expected result is passed as result
466
     */
467
    private void readDocidWhichEqualsDoc(String docid, String testDoc,
468
                                         boolean result,
469
                                         boolean expectedKarmaFailure) {
470
        try {
471
            Reader r = new InputStreamReader(m.read(docid), "UTF-8");
472
            //InputStream is = m.read(docid);
473
            String doc = IOUtil.getAsString(r, true);
474
            //String doc = IOUtils.toString(is);
475
            
476
            if (result) {
477

    
478
                if (!testDoc.equals(doc)) {
479
                    debug("doc    :" + doc);
480
                    debug("testDoc:" + testDoc);
481
                }
482

    
483
                assertTrue(testDoc.equals(doc));
484
            }
485
            else {
486
                assertTrue(doc.indexOf("<error>") != -1);
487
            }
488
        }
489
        catch (MetacatInaccessibleException mie) {
490
            fail("Metacat Inaccessible:\n" + mie.getMessage());
491
        }
492
        catch (InsufficientKarmaException ike) {
493
            if (!expectedKarmaFailure) {
494
                fail("Insufficient karma:\n" + ike.getMessage());
495
            }
496
        }
497
        catch (MetacatException me) {
498
            fail("Metacat Error:\n" + me.getMessage());
499
        }
500
        catch (Exception e) {
501
            fail("General exception:\n" + e.getMessage());
502
        }
503

    
504
    }
505
    
506
    /**
507
     * Query a document by looking for a part of the title in the title element.
508
     * Then check if the testTitle exists in the doc.
509
     * @param titlePart the part of the title of the doc to look for
510
     * @param testTitle the title containing special characters
511
     * @param result are we expecting SUCCESS or FAILURE
512
     * @param expextedKarmaFailure
513
     */
514
    private void queryDocWhichHasTitle(String titlePart, String testTitle,
515
                                         String emlVersion, boolean result) {
516
        try {
517
            String sQuery = getTestEmlQuery(titlePart, emlVersion);
518
        	Reader queryReader = new StringReader(sQuery);
519
            Reader resultReader = m.query(queryReader);
520
            String queryResult = IOUtil.getAsString(resultReader, true);
521
            if (result) {
522
                if (!queryResult.contains(testTitle)) {
523
                    debug("queryResult: " + queryResult);
524
                    debug("does not contain title: " + testTitle);
525
                }
526

    
527
                assertTrue(queryResult.contains(testTitle));
528
            }
529
            else {
530
                assertTrue(queryResult.indexOf("<error>") != -1);
531
            }
532
        }
533
        catch (MetacatInaccessibleException mie) {
534
            fail("Metacat Inaccessible:\n" + mie.getMessage());
535
        }
536
        catch (Exception e) {
537
            fail("General exception:\n" + e.getMessage());
538
        }
539

    
540
    }
541

    
542
    /**
543
     * Create a hopefully unique docid for testing insert and update. Does
544
     * not include the 'revision' part of the id.
545
     *
546
     * @return a String docid based on the current date and time
547
     */
548
    private String generateDocid() {
549
        StringBuffer docid = new StringBuffer(prefix);
550
        docid.append(".");
551

    
552
        // Create a calendar to get the date formatted properly
553
        String[] ids = TimeZone.getAvailableIDs( -8 * 60 * 60 * 1000);
554
        SimpleTimeZone pdt = new SimpleTimeZone( -8 * 60 * 60 * 1000, ids[0]);
555
        pdt.setStartRule(Calendar.APRIL, 1, Calendar.SUNDAY, 2 * 60 * 60 * 1000);
556
        pdt.setEndRule(Calendar.OCTOBER, -1, Calendar.SUNDAY,
557
                       2 * 60 * 60 * 1000);
558
        Calendar calendar = new GregorianCalendar(pdt);
559
        Date trialTime = new Date();
560
        calendar.setTime(trialTime);
561
        docid.append(calendar.get(Calendar.YEAR));
562
        docid.append(calendar.get(Calendar.DAY_OF_YEAR));
563
        docid.append(calendar.get(Calendar.HOUR_OF_DAY));
564
        docid.append(calendar.get(Calendar.MINUTE));
565
        docid.append(calendar.get(Calendar.SECOND));
566
   	    //sometimes this number is not unique, so we append a random number
567
    	int random = (new Double(Math.random()*100)).intValue();
568
    	docid.append(random);
569
        return docid.toString();
570
    }
571
}
(8-8/24)