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);
240 private void ThreadwaitFor(int i, StructureChooser sc)
242 long timeout = i + System.currentTimeMillis();
243 while (!sc.isDialogVisible() && timeout > System.currentTimeMillis())
248 } catch (InterruptedException x)
256 @Test(groups = { "Functional" })
257 public void sanitizeSeqNameTest()
259 String name = "ab_cdEF|fwxyz012349";
261 PDBStructureChooserQuerySource.sanitizeSeqName(name));
263 // remove a [nn] substring
264 name = "abcde12[345]fg";
265 assertEquals("abcde12fg",
266 PDBStructureChooserQuerySource.sanitizeSeqName(name));
268 // remove characters other than a-zA-Z0-9 | or _
269 name = "ab[cd],.\t£$*!- \\\"@:e";
270 assertEquals("abcde",
271 PDBStructureChooserQuerySource.sanitizeSeqName(name));
273 name = "abcde12[345a]fg";
274 assertEquals("abcde12345afg",
275 PDBStructureChooserQuerySource.sanitizeSeqName(name));
278 @Test(groups = { "Functional" }, dataProvider = "openStructureFileParams")
279 public void openStructureFileForSequenceTest(String alfile, String seqid,
280 String sFilename, TFType tft, String paeFilename,
281 boolean showRefAnnotations, boolean doXferSettings,
282 ViewerType viewerType, int seqNum, int annNum, int viewerNum,
285 Cache.loadProperties(
286 propsFile == null ? "test/jalview/io/testProps.jvprops"
290 propsFile == null ? null : new String[]
291 { "--props", propsFile });
292 if (Desktop.instance != null)
293 Desktop.instance.closeAll_actionPerformed(null);
294 JvOptionPane.setInteractiveMode(false);
295 JvOptionPane.setMockResponse(JvOptionPane.OK_OPTION);
297 FileLoader fileLoader = new FileLoader(true);
298 FileFormatI format = null;
299 File alFile = new File(alfile);
302 format = new IdentifyFile().identify(alFile, DataSourceType.FILE);
303 } catch (FileFormatException e1)
306 "Unknown file format for '" + alFile.getAbsolutePath() + "'");
309 AlignFrame af = fileLoader.LoadFileWaitTillLoaded(alFile,
310 DataSourceType.FILE, format);
311 AlignmentPanel ap = af.alignPanel;
312 Assert.assertNotNull("No alignPanel", ap);
314 AlignmentI al = ap.getAlignment();
315 Assert.assertNotNull(al);
317 SequenceI seq = al.findName(seqid);
318 Assert.assertNotNull("Sequence '" + seqid + "' not found in alignment",
321 StructureChooser.openStructureFileForSequence(null, null, ap, seq,
322 false, sFilename, tft, paeFilename, false, showRefAnnotations,
323 doXferSettings, viewerType);
325 List<SequenceI> seqs = al.getSequences();
326 Assert.assertNotNull(seqs);
328 Assert.assertEquals("Wrong number of sequences", seqNum, seqs.size());
330 AlignViewportI av = ap.getAlignViewport();
331 Assert.assertNotNull(av);
333 AlignmentAnnotation[] aas = al.getAlignmentAnnotation();
335 for (AlignmentAnnotation aa : aas)
340 Assert.assertEquals("Wrong number of viewed annotations", annNum,
348 } catch (InterruptedException e)
350 // TODO Auto-generated catch block
353 List<StructureViewerBase> openViewers = Desktop.instance
354 .getStructureViewers(ap, null);
355 Assert.assertNotNull(openViewers);
357 for (StructureViewerBase svb : openViewers)
362 Assert.assertEquals("Wrong number of structure viewers opened",
369 af.setVisible(false);
374 @DataProvider(name = "openStructureFileParams")
375 public Object[][] openStructureFileParams()
380 String structureFilename,
383 boolean showRefAnnotations,
384 boolean doXferSettings, // false for Commands
385 ViewerType viewerType,
391 return new Object[][] {
394 { "examples/uniref50.fa", "FER1_SPIOL",
395 "examples/AlphaFold/AF-P00221-F1-model_v4.cif", TFType.DEFAULT,
396 "examples/AlphaFold/AF-P00221-F1-predicted_aligned_error_v4.json",
397 true, false, null, 15, 7, 0, null },
398 { "examples/uniref50.fa", "FER1_SPIOL",
399 "examples/AlphaFold/AF-P00221-F1-model_v4.cif", TFType.PLDDT,
400 "examples/AlphaFold/AF-P00221-F1-predicted_aligned_error_v4.json",
401 true, false, null, 15, 7, 0, null },
402 { "examples/uniref50.fa", "FER1_SPIOL",
403 "examples/AlphaFold/AF-P00221-F1-model_v4.cif", TFType.PLDDT,
404 "examples/AlphaFold/AF-P00221-F1-predicted_aligned_error_v4.json",
405 false, false, null, 15, 4, 0, null },
406 { "examples/uniref50.fa", "FER1_SPIOL",
407 "examples/AlphaFold/AF-P00221-F1-model_v4.cif", TFType.DEFAULT,
408 "examples/AlphaFold/AF-P00221-F1-predicted_aligned_error_v4.json",
409 true, false, ViewerType.JMOL, 15, 7, 1, null },
410 { "examples/uniref50.fa", "FER1_SPIOL",
411 "examples/AlphaFold/AF-P00221-F1-model_v4.cif", TFType.PLDDT,
412 "examples/AlphaFold/AF-P00221-F1-predicted_aligned_error_v4.json",
413 true, false, ViewerType.JMOL, 15, 7, 1, null },
414 { "examples/uniref50.fa", "FER1_SPIOL",
415 "examples/AlphaFold/AF-P00221-F1-model_v4.cif", TFType.PLDDT,
416 "examples/AlphaFold/AF-P00221-F1-predicted_aligned_error_v4.json",
417 false, false, ViewerType.JMOL, 15, 4, 1, null }, };