Merge branch 'patch/JAL-3561_JAL-3660_fileformatexport_CLI' into releases/Release_2_1...
[jalview.git] / test / jalview / util / UrlLinkTest.java
1 /*
2  * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
3  * Copyright (C) $$Year-Rel$$ The Jalview Authors
4  * 
5  * This file is part of Jalview.
6  * 
7  * Jalview is free software: you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License 
9  * as published by the Free Software Foundation, either version 3
10  * of the License, or (at your option) any later version.
11  *  
12  * Jalview is distributed in the hope that it will be useful, but 
13  * WITHOUT ANY WARRANTY; without even the implied warranty 
14  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
15  * PURPOSE.  See the GNU General Public License for more details.
16  * 
17  * You should have received a copy of the GNU General Public License
18  * along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
19  * The Jalview Authors are detailed in the 'AUTHORS' file.
20  */
21 package jalview.util;
22
23 import static jalview.util.UrlConstants.DB_ACCESSION;
24 import static jalview.util.UrlConstants.SEQUENCE_ID;
25 import static org.testng.AssertJUnit.assertEquals;
26 import static org.testng.AssertJUnit.assertFalse;
27 import static org.testng.AssertJUnit.assertNull;
28 import static org.testng.AssertJUnit.assertTrue;
29
30 import jalview.datamodel.DBRefEntry;
31 import jalview.datamodel.DBRefSource;
32 import jalview.datamodel.Sequence;
33 import jalview.gui.JvOptionPane;
34
35 import java.util.ArrayList;
36 import java.util.Comparator;
37 import java.util.LinkedHashMap;
38 import java.util.List;
39 import java.util.Map;
40
41 import org.testng.annotations.BeforeClass;
42 import org.testng.annotations.Test;
43
44 public class UrlLinkTest
45 {
46
47   @BeforeClass(alwaysRun = true)
48   public void setUpJvOptionPane()
49   {
50     JvOptionPane.setInteractiveMode(false);
51     JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
52   }
53
54   final static String DB = "Test";
55
56   final static String URL_PREFIX = "http://www.jalview.org/";
57
58   final static String URL_SUFFIX = "/blah";
59
60   final static String SEP = "|";
61
62   final static String DELIM = "$";
63
64   final static String REGEX_NESTED = "=/^(?:Label:)?(?:(?:gi\\|(\\d+))|([^:]+))/=";
65   
66   final static String REGEX_RUBBISH = "=/[0-9]++/=";
67
68   /**
69    * Test URL link creation when the input string has no regex
70    */
71   @Test(groups = { "Functional" })
72   public void testUrlLinkCreationNoRegex()
73   {
74     // SEQUENCE_ID
75     UrlLink ul = new UrlLink(DB + SEP + URL_PREFIX + DELIM + SEQUENCE_ID
76             + DELIM + URL_SUFFIX);
77     assertEquals(DB, ul.getTarget());
78     assertEquals(DB, ul.getLabel());
79     assertEquals(URL_PREFIX, ul.getUrlPrefix());
80     assertEquals(URL_SUFFIX, ul.getUrlSuffix());
81     assertTrue(ul.isDynamic());
82     assertFalse(ul.usesDBAccession());
83     assertNull(ul.getRegexReplace());
84     assertTrue(ul.isValid());
85     assertNull(ul.getInvalidMessage());
86
87     // DB_ACCESSION
88     ul = new UrlLink(DB + SEP + URL_PREFIX + DELIM + DB_ACCESSION + DELIM
89             + URL_SUFFIX);
90     assertEquals(DB, ul.getTarget());
91     assertEquals(DB, ul.getLabel());
92     assertEquals(URL_PREFIX, ul.getUrlPrefix());
93     assertEquals(URL_SUFFIX, ul.getUrlSuffix());
94     assertTrue(ul.isDynamic());
95     assertTrue(ul.usesDBAccession());
96     assertNull(ul.getRegexReplace());
97     assertTrue(ul.isValid());
98     assertNull(ul.getInvalidMessage());
99
100     // Not dynamic
101     ul = new UrlLink(DB + SEP + URL_PREFIX + URL_SUFFIX.substring(1));
102     assertEquals(DB, ul.getTarget());
103     assertEquals(DB, ul.getLabel());
104     assertEquals(URL_PREFIX + URL_SUFFIX.substring(1), ul.getUrlPrefix());
105     assertFalse(ul.isDynamic());
106     assertFalse(ul.usesDBAccession());
107     assertNull(ul.getRegexReplace());
108     assertTrue(ul.isValid());
109     assertNull(ul.getInvalidMessage());
110   }
111
112   /**
113    * Test URL link creation when the input string has regex
114    */
115   @Test(groups = { "Functional" })
116   public void testUrlLinkCreationWithRegex()
117   {
118     // SEQUENCE_ID
119     UrlLink ul = new UrlLink(DB + SEP + URL_PREFIX + DELIM + SEQUENCE_ID
120             + REGEX_NESTED + DELIM + URL_SUFFIX);
121     assertEquals(DB, ul.getTarget());
122     assertEquals(DB, ul.getLabel());
123     assertEquals(URL_PREFIX, ul.getUrlPrefix());
124     assertEquals(URL_SUFFIX, ul.getUrlSuffix());
125     assertTrue(ul.isDynamic());
126     assertFalse(ul.usesDBAccession());
127     assertEquals(REGEX_NESTED.substring(2, REGEX_NESTED.length() - 2),
128             ul.getRegexReplace());
129     assertTrue(ul.isValid());
130     assertNull(ul.getInvalidMessage());
131
132     // DB_ACCESSION
133     ul = new UrlLink(DB + SEP + URL_PREFIX + DELIM + DB_ACCESSION
134             + REGEX_NESTED + DELIM + URL_SUFFIX);
135     assertEquals(DB, ul.getTarget());
136     assertEquals(DB, ul.getLabel());
137     assertEquals(URL_PREFIX, ul.getUrlPrefix());
138     assertEquals(URL_SUFFIX, ul.getUrlSuffix());
139     assertTrue(ul.isDynamic());
140     assertTrue(ul.usesDBAccession());
141     assertEquals(REGEX_NESTED.substring(2, REGEX_NESTED.length() - 2),
142             ul.getRegexReplace());
143     assertTrue(ul.isValid());
144     assertNull(ul.getInvalidMessage());
145
146     // invalid regex
147     ul = new UrlLink(DB + SEP + URL_PREFIX + DELIM + DB_ACCESSION
148             + REGEX_RUBBISH + DELIM + URL_SUFFIX);
149     assertEquals(DB, ul.getTarget());
150     assertEquals(DB, ul.getLabel());
151     assertEquals(URL_PREFIX, ul.getUrlPrefix());
152     assertEquals(URL_SUFFIX, ul.getUrlSuffix());
153     assertTrue(ul.isDynamic());
154     assertTrue(ul.usesDBAccession());
155     assertEquals(REGEX_RUBBISH.substring(2, REGEX_RUBBISH.length() - 2),
156             ul.getRegexReplace());
157     assertFalse(ul.isValid());
158     assertEquals(
159             "Invalid Regular Expression : '"
160                     + REGEX_RUBBISH.substring(2, REGEX_RUBBISH.length() - 2)
161                     + "'\n",
162             ul.getInvalidMessage());
163   }
164
165   /**
166    * Test construction of link by substituting sequence id or name
167    */
168   @Test(groups = { "Functional" })
169   public void testMakeUrlNoRegex()
170   {
171     // Single non-regex
172     UrlLink ul = new UrlLink(DB + SEP + URL_PREFIX + DELIM + SEQUENCE_ID
173             + DELIM + URL_SUFFIX);
174     String idstring = "FER_CAPAA";
175     String[] urls = ul.makeUrls(idstring, true);
176
177     assertEquals(2, urls.length);
178     assertEquals(idstring, urls[0]);
179     assertEquals(URL_PREFIX + idstring + URL_SUFFIX, urls[1]);
180
181     urls = ul.makeUrls(idstring, false);
182
183     assertEquals(2, urls.length);
184     assertEquals(idstring, urls[0]);
185     assertEquals(URL_PREFIX + idstring + URL_SUFFIX, urls[1]);
186   }
187
188   /**
189    * Test construction of link by substituting sequence id or name using regular
190    * expression
191    */
192   @Test(groups = { "Functional" })
193   public void testMakeUrlWithRegex()
194   {
195     // Unused regex
196     UrlLink ul = new UrlLink(DB + SEP + URL_PREFIX + DELIM + DB_ACCESSION
197             + REGEX_NESTED + DELIM + URL_SUFFIX);
198     String idstring = "FER_CAPAA";
199     String[] urls = ul.makeUrls(idstring, true);
200
201     assertEquals(2, urls.length);
202     assertEquals(idstring, urls[0]);
203     assertEquals(URL_PREFIX + idstring + URL_SUFFIX, urls[1]);
204     assertTrue(ul.isValid());
205     assertNull(ul.getInvalidMessage());
206
207     urls = ul.makeUrls(idstring, false);
208
209     assertEquals(2, urls.length);
210     assertEquals(idstring, urls[0]);
211     assertEquals(URL_PREFIX + idstring + URL_SUFFIX, urls[1]);
212     assertTrue(ul.isValid());
213     assertNull(ul.getInvalidMessage());
214
215     // nested regex
216     idstring = "Label:gi|9234|pdb|102L|A";
217     urls = ul.makeUrls(idstring, true);
218
219     assertEquals(2, urls.length);
220     assertEquals("9234", urls[0]);
221     assertEquals(URL_PREFIX + "9234" + URL_SUFFIX, urls[1]);
222     assertTrue(ul.isValid());
223     assertNull(ul.getInvalidMessage());
224
225     urls = ul.makeUrls(idstring, false);
226
227     assertEquals(2, urls.length);
228     assertEquals("9234", urls[0]);
229     assertEquals(URL_PREFIX + "9234" + URL_SUFFIX, urls[1]);
230     assertTrue(ul.isValid());
231     assertNull(ul.getInvalidMessage());
232
233     // unmatched regex
234     idstring = "this does not match";
235     urls = ul.makeUrls(idstring, true);
236
237     assertEquals(2, urls.length);
238     assertEquals(idstring, urls[0]);
239     assertEquals(URL_PREFIX + idstring + URL_SUFFIX, urls[1]);
240     assertTrue(ul.isValid());
241     assertNull(ul.getInvalidMessage());
242
243     urls = ul.makeUrls(idstring, false);
244
245     assertEquals(2, urls.length);
246     assertEquals(idstring, urls[0]);
247     assertEquals(URL_PREFIX + idstring + URL_SUFFIX, urls[1]);
248     assertTrue(ul.isValid());
249     assertNull(ul.getInvalidMessage());
250
251     // empty idstring
252     idstring = "";
253     urls = ul.makeUrls(idstring, true);
254
255     assertNull(urls);
256
257     urls = ul.makeUrls(idstring, false);
258
259     assertEquals(2, urls.length);
260     assertEquals("", urls[0]);
261     assertEquals(URL_PREFIX + URL_SUFFIX, urls[1]);
262     assertTrue(ul.isValid());
263     assertNull(ul.getInvalidMessage());
264   }
265
266   /**
267    * Test creating links with null sequence
268    */
269   @Test(groups = { "Functional" })
270   public void testCreateLinksFromNullSequence()
271   {
272     UrlLink ul = new UrlLink(DB + SEP + URL_PREFIX + DELIM + SEQUENCE_ID
273             + DELIM + URL_SUFFIX);
274
275     Map<String, List<String>> linkset = new LinkedHashMap<>();
276     ul.createLinksFromSeq(null, linkset);
277
278     String key = DB + SEP + URL_PREFIX;
279     assertEquals(1, linkset.size());
280     assertTrue(linkset.containsKey(key));
281     assertEquals(DB, linkset.get(key).get(0));
282     assertEquals(DB, linkset.get(key).get(1));
283     assertEquals(null, linkset.get(key).get(2));
284     assertEquals(URL_PREFIX, linkset.get(key).get(3));
285   }
286
287   /**
288    * Test creating links with non-dynamic urlLink
289    */
290   @Test(groups = { "Functional" })
291   public void testCreateLinksForNonDynamic()
292   {
293     UrlLink ul = new UrlLink(DB + SEP + URL_PREFIX + URL_SUFFIX);
294
295     Map<String, List<String>> linkset = new LinkedHashMap<>();
296     ul.createLinksFromSeq(null, linkset);
297
298     String key = DB + SEP + URL_PREFIX + URL_SUFFIX;
299     assertEquals(1, linkset.size());
300     assertTrue(linkset.containsKey(key));
301     assertEquals(DB, linkset.get(key).get(0));
302     assertEquals(DB, linkset.get(key).get(1));
303     assertEquals(null, linkset.get(key).get(2));
304     assertEquals(URL_PREFIX + URL_SUFFIX, linkset.get(key).get(3));
305   }
306
307   /**
308    * Test creating links
309    */
310   @Test(groups = { "Functional" })
311   public void testCreateLinksFromSequence()
312   {
313
314     // create list of links and list of DBRefs
315     List<String> links = new ArrayList<>();
316     List<DBRefEntry> refs = new ArrayList<>();
317
318     // links as might be added into Preferences | Connections dialog
319     links.add("EMBL-EBI Search | http://www.ebi.ac.uk/ebisearch/search.ebi?db=allebi&query=$"
320             + SEQUENCE_ID + "$");
321     links.add("UNIPROT | http://www.uniprot.org/uniprot/$" + DB_ACCESSION
322             + "$");
323     links.add("INTERPRO | http://www.ebi.ac.uk/interpro/entry/$"
324             + DB_ACCESSION + "$");
325
326     // make seq0 dbrefs
327     refs.add(new DBRefEntry(DBRefSource.UNIPROT, "1", "P83527"));
328     refs.add(new DBRefEntry("INTERPRO", "1", "IPR001041"));
329     refs.add(new DBRefEntry("INTERPRO", "1", "IPR006058"));
330     refs.add(new DBRefEntry("INTERPRO", "1", "IPR012675"));
331
332     Sequence seq0 = new Sequence("FER1", "AKPNGVL");
333
334     // add all the dbrefs to the sequence
335     seq0.addDBRef(refs.get(0));
336     seq0.addDBRef(refs.get(1));
337     seq0.addDBRef(refs.get(2));
338     seq0.addDBRef(refs.get(3));
339     seq0.createDatasetSequence();
340
341     // Test where link takes a sequence id as replacement
342     UrlLink ul = new UrlLink(DB + SEP + URL_PREFIX + DELIM + SEQUENCE_ID
343             + DELIM + URL_SUFFIX);
344
345     Map<String, List<String>> linkset = new LinkedHashMap<>();
346     ul.createLinksFromSeq(seq0, linkset);
347
348     String key = seq0.getName() + SEP + URL_PREFIX + seq0.getName()
349             + URL_SUFFIX;
350     assertEquals(1, linkset.size());
351     assertTrue(linkset.containsKey(key));
352     assertEquals(DB, linkset.get(key).get(0));
353     assertEquals(DB, linkset.get(key).get(1));
354     assertEquals(seq0.getName(), linkset.get(key).get(2));
355     assertEquals(URL_PREFIX + seq0.getName() + URL_SUFFIX, linkset.get(key)
356             .get(3));
357
358     // Test where link takes a db annotation id and only has one dbref
359     ul = new UrlLink(links.get(1));
360     linkset = new LinkedHashMap<>();
361     ul.createLinksFromSeq(seq0, linkset);
362
363     key = "P83527|http://www.uniprot.org/uniprot/P83527";
364     assertEquals(linkset.size(), 1);
365     assertTrue(linkset.containsKey(key));
366     assertEquals(DBRefSource.UNIPROT, linkset.get(key).get(0));
367     assertEquals(DBRefSource.UNIPROT + SEP + "P83527", linkset.get(key)
368             .get(1));
369     assertEquals("P83527", linkset.get(key).get(2));
370     assertEquals("http://www.uniprot.org/uniprot/P83527", linkset.get(key)
371             .get(3));
372
373     // Test where link takes a db annotation id and has multiple dbrefs
374     ul = new UrlLink(links.get(2));
375     linkset = new LinkedHashMap<>();
376     ul.createLinksFromSeq(seq0, linkset);
377     assertEquals(3, linkset.size());
378
379     // check each link made it in correctly
380     key = "IPR001041|http://www.ebi.ac.uk/interpro/entry/IPR001041";
381     assertTrue(linkset.containsKey(key));
382     assertEquals("INTERPRO", linkset.get(key).get(0));
383     assertEquals("INTERPRO" + SEP + "IPR001041", linkset.get(key).get(1));
384     assertEquals("IPR001041", linkset.get(key).get(2));
385     assertEquals("http://www.ebi.ac.uk/interpro/entry/IPR001041", linkset
386             .get(key).get(3));
387
388     key = "IPR006058|http://www.ebi.ac.uk/interpro/entry/IPR006058";
389     assertTrue(linkset.containsKey(key));
390     assertEquals("INTERPRO", linkset.get(key).get(0));
391     assertEquals("INTERPRO" + SEP + "IPR006058", linkset.get(key).get(1));
392     assertEquals("IPR006058", linkset.get(key).get(2));
393     assertEquals("http://www.ebi.ac.uk/interpro/entry/IPR006058", linkset
394             .get(key).get(3));
395
396     key = "IPR012675|http://www.ebi.ac.uk/interpro/entry/IPR012675";
397     assertTrue(linkset.containsKey(key));
398     assertEquals("INTERPRO", linkset.get(key).get(0));
399     assertEquals("INTERPRO" + SEP + "IPR012675", linkset.get(key).get(1));
400     assertEquals("IPR012675", linkset.get(key).get(2));
401     assertEquals("http://www.ebi.ac.uk/interpro/entry/IPR012675", linkset
402             .get(key).get(3));
403
404     // Test where there are no matching dbrefs for the link
405     ul = new UrlLink(DB + SEP + URL_PREFIX + DELIM + DB_ACCESSION + DELIM
406             + URL_SUFFIX);
407     linkset = new LinkedHashMap<>();
408     ul.createLinksFromSeq(seq0, linkset);
409     assertTrue(linkset.isEmpty());
410   }
411
412   /**
413    * Test links where label and target are both included
414    */
415   @Test(groups = { "Functional" })
416   public void testLinksWithTargets()
417   {
418     UrlLink ul = new UrlLink(
419             "Protein Data Bank | http://www.identifiers.org/pdb/$"
420                     + DB_ACCESSION + "$" + " | pdb");
421
422     assertEquals("Protein Data Bank", ul.getLabel());
423     assertEquals("pdb", ul.getTarget());
424     assertEquals("http://www.identifiers.org/pdb/$" + DB_ACCESSION + "$",
425             ul.getUrlWithToken());
426
427     assertEquals("Protein Data Bank|http://www.identifiers.org/pdb/$"
428             + DB_ACCESSION + "$" + "|pdb", ul.toStringWithTarget());
429
430     ul = new UrlLink("Protein Data Bank",
431             "http://www.identifiers.org/pdb/$" + DB_ACCESSION + "$", "pdb");
432
433     assertEquals("Protein Data Bank", ul.getLabel());
434     assertEquals("pdb", ul.getTarget());
435     assertEquals("http://www.identifiers.org/pdb/$" + DB_ACCESSION + "$",
436             ul.getUrlWithToken());
437
438     assertEquals("Protein Data Bank|http://www.identifiers.org/pdb/$"
439             + DB_ACCESSION + "$" + "|pdb", ul.toStringWithTarget());
440
441   }
442
443   @Test(groups = { "Functional" })
444   public void testLinkComparator()
445   {
446     Comparator<String> c = UrlLink.LINK_COMPARATOR;
447     assertEquals(0, c.compare(null, null));
448     assertEquals(0, c.compare(null, "x"));
449     assertEquals(0, c.compare("y", null));
450
451     /*
452      * SEQUENCE_ID templates should come before DB_ACCESSION templates
453      */
454     String dbRefUrl = "Cath|http://www.cathdb.info/version/v4_2_0/superfamily/$DB_ACCESSION$";
455     String seqIdUrl = "EBI|https://www.ebi.ac.uk/ebisearch/search.ebi?db=allebi&query=$SEQUENCE_ID$";
456     assertTrue(c.compare(seqIdUrl, dbRefUrl) < 0);
457     assertTrue(c.compare(dbRefUrl, seqIdUrl) > 0);
458
459     String interpro = "Interpro|https://www.ebi.ac.uk/interpro/entry/$DB_ACCESSION$";
460     String prosite = "ProSite|https://prosite.expasy.org/PS00197";
461     assertTrue(c.compare(interpro, prosite) < 0);
462     assertTrue(c.compare(prosite, interpro) > 0);
463   }
464 }