JAL-4313 Patch AnnotationsMatcher to match nulls
[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("Invalid Regular Expression : '"
159             + REGEX_RUBBISH.substring(2, REGEX_RUBBISH.length() - 2)
160             + "'\n", ul.getInvalidMessage());
161   }
162
163   /**
164    * Test construction of link by substituting sequence id or name
165    */
166   @Test(groups = { "Functional" })
167   public void testMakeUrlNoRegex()
168   {
169     // Single non-regex
170     UrlLink ul = new UrlLink(DB + SEP + URL_PREFIX + DELIM + SEQUENCE_ID
171             + DELIM + URL_SUFFIX);
172     String idstring = "FER_CAPAA";
173     String[] urls = ul.makeUrls(idstring, true);
174
175     assertEquals(2, urls.length);
176     assertEquals(idstring, urls[0]);
177     assertEquals(URL_PREFIX + idstring + URL_SUFFIX, urls[1]);
178
179     urls = ul.makeUrls(idstring, false);
180
181     assertEquals(2, urls.length);
182     assertEquals(idstring, urls[0]);
183     assertEquals(URL_PREFIX + idstring + URL_SUFFIX, urls[1]);
184   }
185
186   /**
187    * Test construction of link by substituting sequence id or name using regular
188    * expression
189    */
190   @Test(groups = { "Functional" })
191   public void testMakeUrlWithRegex()
192   {
193     // Unused regex
194     UrlLink ul = new UrlLink(DB + SEP + URL_PREFIX + DELIM + DB_ACCESSION
195             + REGEX_NESTED + DELIM + URL_SUFFIX);
196     String idstring = "FER_CAPAA";
197     String[] urls = ul.makeUrls(idstring, true);
198
199     assertEquals(2, urls.length);
200     assertEquals(idstring, urls[0]);
201     assertEquals(URL_PREFIX + idstring + URL_SUFFIX, urls[1]);
202     assertTrue(ul.isValid());
203     assertNull(ul.getInvalidMessage());
204
205     urls = ul.makeUrls(idstring, false);
206
207     assertEquals(2, urls.length);
208     assertEquals(idstring, urls[0]);
209     assertEquals(URL_PREFIX + idstring + URL_SUFFIX, urls[1]);
210     assertTrue(ul.isValid());
211     assertNull(ul.getInvalidMessage());
212
213     // nested regex
214     idstring = "Label:gi|9234|pdb|102L|A";
215     urls = ul.makeUrls(idstring, true);
216
217     assertEquals(2, urls.length);
218     assertEquals("9234", urls[0]);
219     assertEquals(URL_PREFIX + "9234" + URL_SUFFIX, urls[1]);
220     assertTrue(ul.isValid());
221     assertNull(ul.getInvalidMessage());
222
223     urls = ul.makeUrls(idstring, false);
224
225     assertEquals(2, urls.length);
226     assertEquals("9234", urls[0]);
227     assertEquals(URL_PREFIX + "9234" + URL_SUFFIX, urls[1]);
228     assertTrue(ul.isValid());
229     assertNull(ul.getInvalidMessage());
230
231     // unmatched regex
232     idstring = "this does not match";
233     urls = ul.makeUrls(idstring, true);
234
235     assertEquals(2, urls.length);
236     assertEquals(idstring, urls[0]);
237     assertEquals(URL_PREFIX + idstring + URL_SUFFIX, urls[1]);
238     assertTrue(ul.isValid());
239     assertNull(ul.getInvalidMessage());
240
241     urls = ul.makeUrls(idstring, false);
242
243     assertEquals(2, urls.length);
244     assertEquals(idstring, urls[0]);
245     assertEquals(URL_PREFIX + idstring + URL_SUFFIX, urls[1]);
246     assertTrue(ul.isValid());
247     assertNull(ul.getInvalidMessage());
248
249     // empty idstring
250     idstring = "";
251     urls = ul.makeUrls(idstring, true);
252
253     assertNull(urls);
254
255     urls = ul.makeUrls(idstring, false);
256
257     assertEquals(2, urls.length);
258     assertEquals("", urls[0]);
259     assertEquals(URL_PREFIX + URL_SUFFIX, urls[1]);
260     assertTrue(ul.isValid());
261     assertNull(ul.getInvalidMessage());
262   }
263
264   /**
265    * Test creating links with null sequence
266    */
267   @Test(groups = { "Functional" })
268   public void testCreateLinksFromNullSequence()
269   {
270     UrlLink ul = new UrlLink(DB + SEP + URL_PREFIX + DELIM + SEQUENCE_ID
271             + DELIM + URL_SUFFIX);
272
273     Map<String, List<String>> linkset = new LinkedHashMap<>();
274     ul.createLinksFromSeq(null, linkset);
275
276     String key = DB + SEP + URL_PREFIX;
277     assertEquals(1, linkset.size());
278     assertTrue(linkset.containsKey(key));
279     assertEquals(DB, linkset.get(key).get(0));
280     assertEquals(DB, linkset.get(key).get(1));
281     assertEquals(null, linkset.get(key).get(2));
282     assertEquals(URL_PREFIX, linkset.get(key).get(3));
283   }
284
285   /**
286    * Test creating links with non-dynamic urlLink
287    */
288   @Test(groups = { "Functional" })
289   public void testCreateLinksForNonDynamic()
290   {
291     UrlLink ul = new UrlLink(DB + SEP + URL_PREFIX + URL_SUFFIX);
292
293     Map<String, List<String>> linkset = new LinkedHashMap<>();
294     ul.createLinksFromSeq(null, linkset);
295
296     String key = DB + SEP + URL_PREFIX + URL_SUFFIX;
297     assertEquals(1, linkset.size());
298     assertTrue(linkset.containsKey(key));
299     assertEquals(DB, linkset.get(key).get(0));
300     assertEquals(DB, linkset.get(key).get(1));
301     assertEquals(null, linkset.get(key).get(2));
302     assertEquals(URL_PREFIX + URL_SUFFIX, linkset.get(key).get(3));
303   }
304
305   /**
306    * Test creating links
307    */
308   @Test(groups = { "Functional" })
309   public void testCreateLinksFromSequence()
310   {
311
312     // create list of links and list of DBRefs
313     List<String> links = new ArrayList<>();
314     List<DBRefEntry> refs = new ArrayList<>();
315
316     // links as might be added into Preferences | Connections dialog
317     links.add(
318             "EMBL-EBI Search | http://www.ebi.ac.uk/ebisearch/search.ebi?db=allebi&query=$"
319                     + SEQUENCE_ID + "$");
320     links.add("UNIPROT | http://www.uniprot.org/uniprot/$" + DB_ACCESSION
321             + "$");
322     links.add("INTERPRO | http://www.ebi.ac.uk/interpro/entry/$"
323             + DB_ACCESSION + "$");
324
325     // make seq0 dbrefs
326     refs.add(new DBRefEntry(DBRefSource.UNIPROT, "1", "P83527"));
327     refs.add(new DBRefEntry("INTERPRO", "1", "IPR001041"));
328     refs.add(new DBRefEntry("INTERPRO", "1", "IPR006058"));
329     refs.add(new DBRefEntry("INTERPRO", "1", "IPR012675"));
330
331     Sequence seq0 = new Sequence("FER1", "AKPNGVL");
332
333     // add all the dbrefs to the sequence
334     seq0.addDBRef(refs.get(0));
335     seq0.addDBRef(refs.get(1));
336     seq0.addDBRef(refs.get(2));
337     seq0.addDBRef(refs.get(3));
338     seq0.createDatasetSequence();
339
340     // Test where link takes a sequence id as replacement
341     UrlLink ul = new UrlLink(DB + SEP + URL_PREFIX + DELIM + SEQUENCE_ID
342             + DELIM + URL_SUFFIX);
343
344     Map<String, List<String>> linkset = new LinkedHashMap<>();
345     ul.createLinksFromSeq(seq0, linkset);
346
347     String key = seq0.getName() + SEP + URL_PREFIX + seq0.getName()
348             + URL_SUFFIX;
349     assertEquals(1, linkset.size());
350     assertTrue(linkset.containsKey(key));
351     assertEquals(DB, linkset.get(key).get(0));
352     assertEquals(DB, linkset.get(key).get(1));
353     assertEquals(seq0.getName(), linkset.get(key).get(2));
354     assertEquals(URL_PREFIX + seq0.getName() + URL_SUFFIX,
355             linkset.get(key).get(3));
356
357     // Test where link takes a db annotation id and only has one dbref
358     ul = new UrlLink(links.get(1));
359     linkset = new LinkedHashMap<>();
360     ul.createLinksFromSeq(seq0, linkset);
361
362     key = "P83527|http://www.uniprot.org/uniprot/P83527";
363     assertEquals(linkset.size(), 1);
364     assertTrue(linkset.containsKey(key));
365     assertEquals(DBRefSource.UNIPROT, linkset.get(key).get(0));
366     assertEquals(DBRefSource.UNIPROT + SEP + "P83527",
367             linkset.get(key).get(1));
368     assertEquals("P83527", linkset.get(key).get(2));
369     assertEquals("http://www.uniprot.org/uniprot/P83527",
370             linkset.get(key).get(3));
371
372     // Test where link takes a db annotation id and has multiple dbrefs
373     ul = new UrlLink(links.get(2));
374     linkset = new LinkedHashMap<>();
375     ul.createLinksFromSeq(seq0, linkset);
376     assertEquals(3, linkset.size());
377
378     // check each link made it in correctly
379     key = "IPR001041|http://www.ebi.ac.uk/interpro/entry/IPR001041";
380     assertTrue(linkset.containsKey(key));
381     assertEquals("INTERPRO", linkset.get(key).get(0));
382     assertEquals("INTERPRO" + SEP + "IPR001041", linkset.get(key).get(1));
383     assertEquals("IPR001041", linkset.get(key).get(2));
384     assertEquals("http://www.ebi.ac.uk/interpro/entry/IPR001041",
385             linkset.get(key).get(3));
386
387     key = "IPR006058|http://www.ebi.ac.uk/interpro/entry/IPR006058";
388     assertTrue(linkset.containsKey(key));
389     assertEquals("INTERPRO", linkset.get(key).get(0));
390     assertEquals("INTERPRO" + SEP + "IPR006058", linkset.get(key).get(1));
391     assertEquals("IPR006058", linkset.get(key).get(2));
392     assertEquals("http://www.ebi.ac.uk/interpro/entry/IPR006058",
393             linkset.get(key).get(3));
394
395     key = "IPR012675|http://www.ebi.ac.uk/interpro/entry/IPR012675";
396     assertTrue(linkset.containsKey(key));
397     assertEquals("INTERPRO", linkset.get(key).get(0));
398     assertEquals("INTERPRO" + SEP + "IPR012675", linkset.get(key).get(1));
399     assertEquals("IPR012675", linkset.get(key).get(2));
400     assertEquals("http://www.ebi.ac.uk/interpro/entry/IPR012675",
401             linkset.get(key).get(3));
402
403     // Test where there are no matching dbrefs for the link
404     ul = new UrlLink(DB + SEP + URL_PREFIX + DELIM + DB_ACCESSION + DELIM
405             + URL_SUFFIX);
406     linkset = new LinkedHashMap<>();
407     ul.createLinksFromSeq(seq0, linkset);
408     assertTrue(linkset.isEmpty());
409   }
410
411   /**
412    * Test links where label and target are both included
413    */
414   @Test(groups = { "Functional" })
415   public void testLinksWithTargets()
416   {
417     UrlLink ul = new UrlLink(
418             "Protein Data Bank | http://www.identifiers.org/pdb/$"
419                     + DB_ACCESSION + "$" + " | pdb");
420
421     assertEquals("Protein Data Bank", ul.getLabel());
422     assertEquals("pdb", ul.getTarget());
423     assertEquals("http://www.identifiers.org/pdb/$" + DB_ACCESSION + "$",
424             ul.getUrlWithToken());
425
426     assertEquals("Protein Data Bank|http://www.identifiers.org/pdb/$"
427             + DB_ACCESSION + "$" + "|pdb", ul.toStringWithTarget());
428
429     ul = new UrlLink("Protein Data Bank",
430             "http://www.identifiers.org/pdb/$" + DB_ACCESSION + "$", "pdb");
431
432     assertEquals("Protein Data Bank", ul.getLabel());
433     assertEquals("pdb", ul.getTarget());
434     assertEquals("http://www.identifiers.org/pdb/$" + DB_ACCESSION + "$",
435             ul.getUrlWithToken());
436
437     assertEquals("Protein Data Bank|http://www.identifiers.org/pdb/$"
438             + DB_ACCESSION + "$" + "|pdb", ul.toStringWithTarget());
439
440   }
441
442   @Test(groups = { "Functional" })
443   public void testLinkComparator()
444   {
445     Comparator<String> c = UrlLink.LINK_COMPARATOR;
446     assertEquals(0, c.compare(null, null));
447     assertEquals(0, c.compare(null, "x"));
448     assertEquals(0, c.compare("y", null));
449
450     /*
451      * SEQUENCE_ID templates should come before DB_ACCESSION templates
452      */
453     String dbRefUrl = "Cath|http://www.cathdb.info/version/v4_2_0/superfamily/$DB_ACCESSION$";
454     String seqIdUrl = "EBI|https://www.ebi.ac.uk/ebisearch/search.ebi?db=allebi&query=$SEQUENCE_ID$";
455     assertTrue(c.compare(seqIdUrl, dbRefUrl) < 0);
456     assertTrue(c.compare(dbRefUrl, seqIdUrl) > 0);
457
458     String interpro = "Interpro|https://www.ebi.ac.uk/interpro/entry/$DB_ACCESSION$";
459     String prosite = "ProSite|https://prosite.expasy.org/PS00197";
460     assertTrue(c.compare(interpro, prosite) < 0);
461     assertTrue(c.compare(prosite, interpro) > 0);
462   }
463 }