2 * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
3 * Copyright (C) $$Year-Rel$$ The Jalview Authors
5 * This file is part of Jalview.
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.
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.
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.
23 import static org.testng.Assert.assertEquals;
24 import static org.testng.AssertJUnit.assertNotNull;
25 import static org.testng.AssertJUnit.assertTrue;
28 import java.util.Collection;
29 import java.util.List;
30 import java.util.Vector;
32 import org.junit.Assert;
33 import org.testng.annotations.AfterMethod;
34 import org.testng.annotations.BeforeClass;
35 import org.testng.annotations.BeforeMethod;
36 import org.testng.annotations.DataProvider;
37 import org.testng.annotations.Test;
39 import jalview.api.AlignViewportI;
40 import jalview.bin.Cache;
41 import jalview.bin.Jalview;
42 import jalview.datamodel.AlignmentAnnotation;
43 import jalview.datamodel.AlignmentI;
44 import jalview.datamodel.DBRefEntry;
45 import jalview.datamodel.PDBEntry;
46 import jalview.datamodel.Sequence;
47 import jalview.datamodel.SequenceI;
48 import jalview.fts.api.FTSData;
49 import jalview.fts.core.FTSRestClient;
50 import jalview.fts.service.pdb.PDBFTSRestClient;
51 import jalview.fts.service.pdb.PDBFTSRestClientTest;
52 import jalview.fts.service.threedbeacons.TDBeaconsFTSRestClient;
53 import jalview.fts.threedbeacons.TDBeaconsFTSRestClientTest;
54 import jalview.gui.StructureViewer.ViewerType;
55 import jalview.gui.structurechooser.PDBStructureChooserQuerySource;
56 import jalview.io.DataSourceType;
57 import jalview.io.FileFormatException;
58 import jalview.io.FileFormatI;
59 import jalview.io.FileLoader;
60 import jalview.io.IdentifyFile;
61 import jalview.jbgui.FilterOption;
62 import jalview.structure.StructureImportSettings.TFType;
63 import junit.extensions.PA;
65 @Test(singleThreaded = true)
66 public class StructureChooserTest
69 @BeforeClass(alwaysRun = true)
70 public void setUpJvOptionPane()
72 JvOptionPane.setInteractiveMode(false);
73 JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
76 Sequence seq, upSeq, upSeq_nocanonical;
78 @BeforeMethod(alwaysRun = true)
79 public void setUp() throws Exception
81 seq = new Sequence("PDB|4kqy|4KQY|A", "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 1,
83 seq.createDatasetSequence();
84 for (int x = 1; x < 5; x++)
86 DBRefEntry dbRef = new DBRefEntry();
87 dbRef.setAccessionId("XYZ_" + x);
91 PDBEntry dbRef = new PDBEntry();
94 Vector<PDBEntry> pdbIds = new Vector<>();
99 // Uniprot sequence for 3D-Beacons mocks
100 upSeq = new Sequence("P38398",
101 "MDLSALRVEEVQNVINAMQKILECPICLELIKEPVSTKCDHIFCKFCMLKLLNQKKGPSQCPLCKNDITKRS\n"
102 + "LQESTRFSQLVEELLKIICAFQLDTGLEYANSYNFAKKENNSPEHLKDEVSIIQSMGYRNRAKRLLQSEPEN\n"
103 + "PSLQETSLSVQLSNLGTVRTLRTKQRIQPQKTSVYIELGSDSSEDTVNKATYCSVGDQELLQITPQGTRDEI\n"
104 + "SLDSAKKAACEFSETDVTNTEHHQPSNNDLNTTEKRAAERHPEKYQGSSVSNLHVEPCGTNTHASSLQHENS\n"
105 + "SLLLTKDRMNVEKAEFCNKSKQPGLARSQHNRWAGSKETCNDRRTPSTEKKVDLNADPLCERKEWNKQKLPC\n"
106 + "SENPRDTEDVPWITLNSSIQKVNEWFSRSDELLGSDDSHDGESESNAKVADVLDVLNEVDEYSGSSEKIDLL\n"
107 + "ASDPHEALICKSERVHSKSVESNIEDKIFGKTYRKKASLPNLSHVTENLIIGAFVTEPQIIQERPLTNKLKR\n"
108 + "KRRPTSGLHPEDFIKKADLAVQKTPEMINQGTNQTEQNGQVMNITNSGHENKTKGDSIQNEKNPNPIESLEK\n"
109 + "ESAFKTKAEPISSSISNMELELNIHNSKAPKKNRLRRKSSTRHIHALELVVSRNLSPPNCTELQIDSCSSSE\n"
110 + "EIKKKKYNQMPVRHSRNLQLMEGKEPATGAKKSNKPNEQTSKRHDSDTFPELKLTNAPGSFTKCSNTSELKE\n"
111 + "FVNPSLPREEKEEKLETVKVSNNAEDPKDLMLSGERVLQTERSVESSSISLVPGTDYGTQESISLLEVSTLG\n"
112 + "KAKTEPNKCVSQCAAFENPKGLIHGCSKDNRNDTEGFKYPLGHEVNHSRETSIEMEESELDAQYLQNTFKVS\n"
113 + "KRQSFAPFSNPGNAEEECATFSAHSGSLKKQSPKVTFECEQKEENQGKNESNIKPVQTVNITAGFPVVGQKD\n"
114 + "KPVDNAKCSIKGGSRFCLSSQFRGNETGLITPNKHGLLQNPYRIPPLFPIKSFVKTKCKKNLLEENFEEHSM\n"
115 + "SPEREMGNENIPSTVSTISRNNIRENVFKEASSSNINEVGSSTNEVGSSINEIGSSDENIQAELGRNRGPKL\n"
116 + "NAMLRLGVLQPEVYKQSLPGSNCKHPEIKKQEYEEVVQTVNTDFSPYLISDNLEQPMGSSHASQVCSETPDD\n"
117 + "LLDDGEIKEDTSFAENDIKESSAVFSKSVQKGELSRSPSPFTHTHLAQGYRRGAKKLESSEENLSSEDEELP\n"
118 + "CFQHLLFGKVNNIPSQSTRHSTVATECLSKNTEENLLSLKNSLNDCSNQVILAKASQEHHLSEETKCSASLF\n"
119 + "SSQCSELEDLTANTNTQDPFLIGSSKQMRHQSESQGVGLSDKELVSDDEERGTGLEENNQEEQSMDSNLGEA\n"
120 + "ASGCESETSVSEDCSGLSSQSDILTTQQRDTMQHNLIKLQQEMAELEAVLEQHGSQPSNSYPSIISDSSALE\n"
121 + "DLRNPEQSTSEKAVLTSQKSSEYPISQNPEGLSADKFEVSADSSTSKNKEPGVERSSPSKCPSLDDRWYMHS\n"
122 + "CSGSLQNRNYPSQEELIKVVDVEEQQLEESGPHDLTETSYLPRQDLEGTPYLESGISLFSDDPESDPSEDRA\n"
123 + "PESARVGNIPSSTSALKVPQLKVAESAQSPAAAHTTDTAGYNAMEESVSREKPELTASTERVNKRMSMVVSG\n"
124 + "LTPEEFMLVYKFARKHHITLTNLITEETTHVVMKTDAEFVCERTLKYFLGIAGGKWVVSYFWVTQSIKERKM\n"
125 + "LNEHDFEVRGDVVNGRNHQGPKRARESQDRKIFRGLEICCYGPFTNMPTDQLEWMVQLCGASVVKELSSFTL\n"
126 + "GTGVHPIVVVQPDAWTEDNGFHAIGQMCEAPVVTREWVLDSVALYQCQELDTYLIPQIPHSHY\n"
129 upSeq.setDescription("Breast cancer type 1 susceptibility protein");
130 upSeq_nocanonical = new Sequence(upSeq);
131 upSeq.createDatasetSequence();
132 upSeq.addDBRef(new DBRefEntry("UNIPROT", "0", "P38398", null, true));
134 upSeq_nocanonical.createDatasetSequence();
135 // not a canonical reference
136 upSeq_nocanonical.addDBRef(
137 new DBRefEntry("UNIPROT", "0", "P38398", null, false));
141 @AfterMethod(alwaysRun = true)
142 public void tearDown() throws Exception
146 upSeq_nocanonical = null;
149 @Test(groups = { "Functional" })
150 public void populateFilterComboBoxTest() throws InterruptedException
152 TDBeaconsFTSRestClientTest.setMock();
153 PDBFTSRestClientTest.setMock();
155 SequenceI[] selectedSeqs = new SequenceI[] { seq };
156 StructureChooser sc = new StructureChooser(selectedSeqs, seq, null);
157 ThreadwaitFor(200, sc);
159 // if structures are not discovered then don't
160 // populate filter options
161 sc.populateFilterComboBox(false, false);
162 int optionsSize = sc.getCmbFilterOption().getItemCount();
163 System.out.println("Items (no data, no cache): ");
164 StringBuilder items = new StringBuilder();
165 for (int p = 0; p < optionsSize; p++)
168 .append(sc.getCmbFilterOption().getItemAt(p).getName())
172 // report items when this fails - seems to be a race condition
173 Assert.assertEquals(items.toString(), optionsSize, 2);
175 sc.populateFilterComboBox(true, false);
176 optionsSize = sc.getCmbFilterOption().getItemCount();
177 assertTrue(optionsSize > 3); // if structures are found, filter options
178 // should be populated
180 sc.populateFilterComboBox(true, true);
181 assertTrue(sc.getCmbFilterOption().getSelectedItem() != null);
182 FilterOption filterOpt = (FilterOption) sc.getCmbFilterOption()
184 assertEquals("Cached Structures", filterOpt.getName());
186 .unMock((FTSRestClient) TDBeaconsFTSRestClient.getInstance());
187 FTSRestClient.unMock((FTSRestClient) PDBFTSRestClient.getInstance());
191 @Test(groups = { "Functional" })
192 public void displayTDBQueryTest() throws InterruptedException
194 TDBeaconsFTSRestClientTest.setMock();
195 PDBFTSRestClientTest.setMock();
197 SequenceI[] selectedSeqs = new SequenceI[] { upSeq_nocanonical };
198 StructureChooser sc = new StructureChooser(selectedSeqs,
199 upSeq_nocanonical, null);
200 // mock so should be quick. Exceptions from mocked PDBFTS are expected too
201 ThreadwaitFor(500, sc);
203 assertTrue(sc.isCanQueryTDB() && sc.isNotQueriedTDBYet());
206 @Test(groups = { "Network" })
207 public void fetchStructuresInfoTest()
210 .unMock((FTSRestClient) TDBeaconsFTSRestClient.getInstance());
211 PDBFTSRestClient.unMock((FTSRestClient) PDBFTSRestClient.getInstance());
212 SequenceI[] selectedSeqs = new SequenceI[] { seq };
213 StructureChooser sc = new StructureChooser(selectedSeqs, seq, null);
214 // not mocked, wait for 2s
215 ThreadwaitFor(2000, sc);
217 sc.fetchStructuresMetaData();
218 Collection<FTSData> ss = (Collection<FTSData>) PA.getValue(sc,
219 "discoveredStructuresSet");
221 assertTrue(ss.size() > 0);
224 @Test(groups = { "Functional" })
225 public void fetchStructuresInfoMockedTest()
227 TDBeaconsFTSRestClientTest.setMock();
228 PDBFTSRestClientTest.setMock();
229 SequenceI[] selectedSeqs = new SequenceI[] { upSeq };
230 StructureChooser sc = new StructureChooser(selectedSeqs, seq, null);
231 ThreadwaitFor(500, sc);
233 sc.fetchStructuresMetaData();
234 Collection<FTSData> ss = (Collection<FTSData>) PA.getValue(sc,
235 "discoveredStructuresSet");
237 assertTrue(ss.size() > 0);
239 sc.promptForTDBFetch(true);
242 } catch (Exception q) {}
245 Object[] sqandpdb = sc.collectSelectedSeqsAndPDBEntries();
246 assertNotNull(sqandpdb);
247 SequenceI[] selsq = (SequenceI[]) sqandpdb[0];
248 PDBEntry[] selpdb = (PDBEntry[]) sqandpdb[1];
249 assertNotNull(selsq);
250 assertNotNull(selpdb);
251 assertEquals(1, selsq.length);
252 assertEquals(1, selpdb.length);
253 assertTrue(selpdb[0].hasProvider());
254 assertTrue(selpdb[0].hasTempFacType());
259 private void ThreadwaitFor(int i, StructureChooser sc)
261 long timeout = i + System.currentTimeMillis();
262 while (!sc.isDialogVisible() && timeout > System.currentTimeMillis())
267 } catch (InterruptedException x)
275 @Test(groups = { "Functional" })
276 public void sanitizeSeqNameTest()
278 String name = "ab_cdEF|fwxyz012349";
280 PDBStructureChooserQuerySource.sanitizeSeqName(name));
282 // remove a [nn] substring
283 name = "abcde12[345]fg";
284 assertEquals("abcde12fg",
285 PDBStructureChooserQuerySource.sanitizeSeqName(name));
287 // remove characters other than a-zA-Z0-9 | or _
288 name = "ab[cd],.\t£$*!- \\\"@:e";
289 assertEquals("abcde",
290 PDBStructureChooserQuerySource.sanitizeSeqName(name));
292 name = "abcde12[345a]fg";
293 assertEquals("abcde12345afg",
294 PDBStructureChooserQuerySource.sanitizeSeqName(name));
297 @Test(groups = { "Functional" }, dataProvider = "openStructureFileParams")
298 public void openStructureFileForSequenceTest(String alfile, String seqid,
299 String sFilename, TFType tft, String paeFilename,
300 boolean showRefAnnotations, boolean doXferSettings,
301 ViewerType viewerType, int seqNum, int annNum, int viewerNum,
304 Cache.loadProperties(
305 propsFile == null ? "test/jalview/io/testProps.jvprops"
309 propsFile == null ? null : new String[]
310 { "--props", propsFile });
311 if (Desktop.instance != null)
312 Desktop.instance.closeAll_actionPerformed(null);
313 JvOptionPane.setInteractiveMode(false);
314 JvOptionPane.setMockResponse(JvOptionPane.OK_OPTION);
316 FileLoader fileLoader = new FileLoader(true);
317 FileFormatI format = null;
318 File alFile = new File(alfile);
321 format = new IdentifyFile().identify(alFile, DataSourceType.FILE);
322 } catch (FileFormatException e1)
325 "Unknown file format for '" + alFile.getAbsolutePath() + "'");
328 AlignFrame af = fileLoader.LoadFileWaitTillLoaded(alFile,
329 DataSourceType.FILE, format);
330 AlignmentPanel ap = af.alignPanel;
331 Assert.assertNotNull("No alignPanel", ap);
333 AlignmentI al = ap.getAlignment();
334 Assert.assertNotNull(al);
336 SequenceI seq = al.findName(seqid);
337 Assert.assertNotNull("Sequence '" + seqid + "' not found in alignment",
340 StructureChooser.openStructureFileForSequence(null, null, ap, seq,
341 false, sFilename, tft, paeFilename, false, showRefAnnotations,
342 doXferSettings, viewerType);
344 List<SequenceI> seqs = al.getSequences();
345 Assert.assertNotNull(seqs);
347 Assert.assertEquals("Wrong number of sequences", seqNum, seqs.size());
349 AlignViewportI av = ap.getAlignViewport();
350 Assert.assertNotNull(av);
352 AlignmentAnnotation[] aas = al.getAlignmentAnnotation();
354 for (AlignmentAnnotation aa : aas)
359 Assert.assertEquals("Wrong number of viewed annotations", annNum,
367 } catch (InterruptedException e)
369 // TODO Auto-generated catch block
372 List<StructureViewerBase> openViewers = Desktop.instance
373 .getStructureViewers(ap, null);
374 Assert.assertNotNull(openViewers);
376 for (StructureViewerBase svb : openViewers)
381 Assert.assertEquals("Wrong number of structure viewers opened",
388 af.setVisible(false);
393 @DataProvider(name = "openStructureFileParams")
394 public Object[][] openStructureFileParams()
399 String structureFilename,
402 boolean showRefAnnotations,
403 boolean doXferSettings, // false for Commands
404 ViewerType viewerType,
410 return new Object[][] {
413 { "examples/uniref50.fa", "FER1_SPIOL",
414 "examples/AlphaFold/AF-P00221-F1-model_v4.cif", TFType.DEFAULT,
415 "examples/AlphaFold/AF-P00221-F1-predicted_aligned_error_v4.json",
416 true, false, null, 15, 7, 0, null },
417 { "examples/uniref50.fa", "FER1_SPIOL",
418 "examples/AlphaFold/AF-P00221-F1-model_v4.cif", TFType.PLDDT,
419 "examples/AlphaFold/AF-P00221-F1-predicted_aligned_error_v4.json",
420 true, false, null, 15, 7, 0, null },
421 { "examples/uniref50.fa", "FER1_SPIOL",
422 "examples/AlphaFold/AF-P00221-F1-model_v4.cif", TFType.PLDDT,
423 "examples/AlphaFold/AF-P00221-F1-predicted_aligned_error_v4.json",
424 false, false, null, 15, 4, 0, null },
425 { "examples/uniref50.fa", "FER1_SPIOL",
426 "examples/AlphaFold/AF-P00221-F1-model_v4.cif", TFType.DEFAULT,
427 "examples/AlphaFold/AF-P00221-F1-predicted_aligned_error_v4.json",
428 true, false, ViewerType.JMOL, 15, 7, 1, null },
429 { "examples/uniref50.fa", "FER1_SPIOL",
430 "examples/AlphaFold/AF-P00221-F1-model_v4.cif", TFType.PLDDT,
431 "examples/AlphaFold/AF-P00221-F1-predicted_aligned_error_v4.json",
432 true, false, ViewerType.JMOL, 15, 7, 1, null },
433 { "examples/uniref50.fa", "FER1_SPIOL",
434 "examples/AlphaFold/AF-P00221-F1-model_v4.cif", TFType.PLDDT,
435 "examples/AlphaFold/AF-P00221-F1-predicted_aligned_error_v4.json",
436 false, false, ViewerType.JMOL, 15, 4, 1, null }, };