Merge branch 'bug/JAL-2682parseId' into develop
[jalview.git] / test / jalview / fts / service / pdb / PDBFTSRestClientTest.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.fts.service.pdb;
22
23 import static org.testng.AssertJUnit.assertEquals;
24 import static org.testng.AssertJUnit.assertTrue;
25
26 import jalview.fts.api.FTSDataColumnI;
27 import jalview.fts.core.FTSRestRequest;
28 import jalview.fts.core.FTSRestResponse;
29 import jalview.gui.JvOptionPane;
30
31 import java.io.BufferedReader;
32 import java.io.FileReader;
33 import java.io.IOException;
34 import java.util.ArrayList;
35 import java.util.Iterator;
36 import java.util.List;
37
38 import javax.ws.rs.core.MediaType;
39
40 import org.json.simple.JSONArray;
41 import org.json.simple.JSONObject;
42 import org.json.simple.parser.JSONParser;
43 import org.json.simple.parser.ParseException;
44 import org.testng.Assert;
45 import org.testng.annotations.AfterMethod;
46 import org.testng.annotations.BeforeClass;
47 import org.testng.annotations.BeforeMethod;
48 import org.testng.annotations.Test;
49
50 import com.sun.jersey.api.client.Client;
51 import com.sun.jersey.api.client.ClientResponse;
52 import com.sun.jersey.api.client.WebResource;
53 import com.sun.jersey.api.client.config.ClientConfig;
54 import com.sun.jersey.api.client.config.DefaultClientConfig;
55
56 public class PDBFTSRestClientTest
57 {
58
59   @BeforeClass(alwaysRun = true)
60   public void setUpJvOptionPane()
61   {
62     JvOptionPane.setInteractiveMode(false);
63     JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
64   }
65
66   @BeforeMethod(alwaysRun = true)
67   public void setUp() throws Exception
68   {
69   }
70
71   @AfterMethod(alwaysRun = true)
72   public void tearDown() throws Exception
73   {
74   }
75
76   @Test(groups = { "External", "Network" })
77   public void executeRequestTest()
78   {
79     List<FTSDataColumnI> wantedFields = new ArrayList<FTSDataColumnI>();
80     try
81     {
82       wantedFields.add(PDBFTSRestClient.getInstance()
83               .getDataColumnByNameOrCode("molecule_type"));
84       wantedFields.add(PDBFTSRestClient.getInstance()
85               .getDataColumnByNameOrCode("pdb_id"));
86       wantedFields.add(PDBFTSRestClient.getInstance()
87               .getDataColumnByNameOrCode("genus"));
88       wantedFields.add(PDBFTSRestClient.getInstance()
89               .getDataColumnByNameOrCode("gene_name"));
90       wantedFields.add(PDBFTSRestClient.getInstance()
91               .getDataColumnByNameOrCode("title"));
92     } catch (Exception e1)
93     {
94       e1.printStackTrace();
95     }
96
97     FTSRestRequest request = new FTSRestRequest();
98     request.setAllowEmptySeq(false);
99     request.setResponseSize(100);
100     request.setFieldToSearchBy("text:");
101     request.setSearchTerm("abc");
102     request.setWantedFields(wantedFields);
103
104     FTSRestResponse response;
105     try
106     {
107       response = PDBFTSRestClient.getInstance().executeRequest(request);
108     } catch (Exception e)
109     {
110       e.printStackTrace();
111       Assert.fail("Couldn't execute webservice call!");
112       return;
113     }
114     assertTrue(response.getNumberOfItemsFound() > 99);
115     assertTrue(response.getSearchSummary() != null);
116     assertTrue(response.getSearchSummary().size() > 99);
117   }
118
119   @Test(groups = { "Functional" })
120   public void getPDBDocFieldsAsCommaDelimitedStringTest()
121   {
122     List<FTSDataColumnI> wantedFields = new ArrayList<FTSDataColumnI>();
123     try
124     {
125       wantedFields.add(PDBFTSRestClient.getInstance()
126               .getDataColumnByNameOrCode("molecule_type"));
127       wantedFields.add(PDBFTSRestClient.getInstance()
128               .getDataColumnByNameOrCode("pdb_id"));
129       wantedFields.add(PDBFTSRestClient.getInstance()
130               .getDataColumnByNameOrCode("genus"));
131       wantedFields.add(PDBFTSRestClient.getInstance()
132               .getDataColumnByNameOrCode("gene_name"));
133       wantedFields.add(PDBFTSRestClient.getInstance()
134               .getDataColumnByNameOrCode("title"));
135     } catch (Exception e)
136     {
137       e.printStackTrace();
138     }
139
140     String expectedResult = "molecule_type,pdb_id,genus,gene_name,title";
141     String actualResult = PDBFTSRestClient.getInstance()
142             .getDataColumnsFieldsAsCommaDelimitedString(wantedFields);
143
144     assertEquals("", expectedResult, actualResult);
145   }
146
147   @Test(groups = { "External, Network" })
148   public void parsePDBJsonExceptionStringTest()
149   {
150     List<FTSDataColumnI> wantedFields = new ArrayList<FTSDataColumnI>();
151     try
152     {
153       wantedFields.add(PDBFTSRestClient.getInstance()
154               .getDataColumnByNameOrCode("molecule_type"));
155       wantedFields.add(PDBFTSRestClient.getInstance()
156               .getDataColumnByNameOrCode("pdb_id"));
157       wantedFields.add(PDBFTSRestClient.getInstance()
158               .getDataColumnByNameOrCode("genus"));
159       wantedFields.add(PDBFTSRestClient.getInstance()
160               .getDataColumnByNameOrCode("gene_name"));
161       wantedFields.add(PDBFTSRestClient.getInstance()
162               .getDataColumnByNameOrCode("title"));
163     } catch (Exception e1)
164     {
165       e1.printStackTrace();
166     }
167
168     FTSRestRequest request = new FTSRestRequest();
169     request.setAllowEmptySeq(false);
170     request.setResponseSize(100);
171     request.setFieldToSearchBy("text:");
172     request.setSearchTerm("abc");
173     request.setWantedFields(wantedFields);
174
175     String jsonErrorResponse = "";
176     try
177     {
178       jsonErrorResponse = readJsonStringFromFile("test/jalview/io/pdb_request_json_error.txt");
179     } catch (IOException e)
180     {
181       e.printStackTrace();
182     }
183
184     String parsedErrorResponse = PDBFTSRestClient
185             .parseJsonExceptionString(jsonErrorResponse);
186
187     String expectedErrorMsg = "\n============= PDB Rest Client RunTime error =============\n"
188             + "Status: 400\n"
189             + "Message: org.apache.solr.search.SyntaxError: Cannot parse 'text:abc OR text:go:abc AND molecule_sequence:['' TO *]': Encountered \" \":\" \": \"\" at line 1, column 19.\n"
190             + "query: text:abc OR text:go:abc AND molecule_sequence:['' TO *]\n"
191             + "fl: pdb_id\n";
192
193     assertEquals(expectedErrorMsg, parsedErrorResponse);
194   }
195
196   @Test(groups = { "External" }, expectedExceptions = Exception.class)
197   public void testForExpectedRuntimeException() throws Exception
198   {
199     List<FTSDataColumnI> wantedFields = new ArrayList<FTSDataColumnI>();
200     wantedFields.add(PDBFTSRestClient.getInstance()
201             .getDataColumnByNameOrCode("pdb_id"));
202
203     FTSRestRequest request = new FTSRestRequest();
204     request.setFieldToSearchBy("text:");
205     request.setSearchTerm("abc OR text:go:abc");
206     request.setWantedFields(wantedFields);
207     PDBFTSRestClient.getInstance().executeRequest(request);
208   }
209
210   // JBP: Is this actually external ? Looks like it is mocked
211   @Test(groups = { "External" })
212   public void parsePDBJsonResponseTest()
213   {
214     List<FTSDataColumnI> wantedFields = new ArrayList<FTSDataColumnI>();
215     try
216     {
217       wantedFields.add(PDBFTSRestClient.getInstance()
218               .getDataColumnByNameOrCode("molecule_type"));
219       wantedFields.add(PDBFTSRestClient.getInstance()
220               .getDataColumnByNameOrCode("pdb_id"));
221       wantedFields.add(PDBFTSRestClient.getInstance()
222               .getDataColumnByNameOrCode("genus"));
223       wantedFields.add(PDBFTSRestClient.getInstance()
224               .getDataColumnByNameOrCode("gene_name"));
225       wantedFields.add(PDBFTSRestClient.getInstance()
226               .getDataColumnByNameOrCode("title"));
227     } catch (Exception e1)
228     {
229       e1.printStackTrace();
230     }
231
232     FTSRestRequest request = new FTSRestRequest();
233     request.setAllowEmptySeq(false);
234     request.setWantedFields(wantedFields);
235
236     String jsonString = "";
237     try
238     {
239       jsonString = readJsonStringFromFile("test/jalview/io/pdb_response_json.txt");
240     } catch (IOException e)
241     {
242       e.printStackTrace();
243     }
244     FTSRestResponse response = PDBFTSRestClient.parsePDBJsonResponse(
245             jsonString, request);
246     assertTrue(response.getSearchSummary() != null);
247     assertTrue(response.getNumberOfItemsFound() == 931);
248     assertTrue(response.getSearchSummary().size() == 14);
249   }
250
251   @Test(groups = { "Functional" })
252   public void getPDBIdColumIndexTest()
253   {
254     List<FTSDataColumnI> wantedFields = new ArrayList<FTSDataColumnI>();
255     try
256     {
257       wantedFields.add(PDBFTSRestClient.getInstance()
258               .getDataColumnByNameOrCode("molecule_type"));
259       wantedFields.add(PDBFTSRestClient.getInstance()
260               .getDataColumnByNameOrCode("genus"));
261       wantedFields.add(PDBFTSRestClient.getInstance()
262               .getDataColumnByNameOrCode("gene_name"));
263       wantedFields.add(PDBFTSRestClient.getInstance()
264               .getDataColumnByNameOrCode("title"));
265       wantedFields.add(PDBFTSRestClient.getInstance()
266               .getDataColumnByNameOrCode("pdb_id"));
267     } catch (Exception e)
268     {
269       e.printStackTrace();
270     }
271     try
272     {
273       assertEquals(5, PDBFTSRestClient.getInstance()
274               .getPrimaryKeyColumIndex(wantedFields, true));
275       assertEquals(4, PDBFTSRestClient.getInstance()
276               .getPrimaryKeyColumIndex(wantedFields, false));
277     } catch (Exception e)
278     {
279       // TODO Auto-generated catch block
280       e.printStackTrace();
281     }
282   }
283
284   @Test(groups = { "External" })
285   public void externalServiceIntegrationTest()
286   {
287     ClientConfig clientConfig = new DefaultClientConfig();
288     Client client = Client.create(clientConfig);
289
290     // Build request parameters for the REST Request
291     WebResource webResource = client
292             .resource(PDBFTSRestClient.PDB_SEARCH_ENDPOINT)
293             .queryParam("wt", "json").queryParam("rows", String.valueOf(1))
294             .queryParam("q", "text:abc AND molecule_sequence:['' TO *]");
295
296     // Execute the REST request
297     ClientResponse clientResponse = webResource.accept(
298             MediaType.APPLICATION_JSON).get(ClientResponse.class);
299
300     // Get the JSON string from the response object
301     String pdbJsonResponseString = clientResponse.getEntity(String.class);
302
303     // Check the response status and report exception if one occurs
304     if (clientResponse.getStatus() != 200)
305     {
306       Assert.fail("Webservice call failed!!!");
307     }
308     else
309     {
310       try
311       {
312         JSONParser jsonParser = new JSONParser();
313         JSONObject jsonObj = (JSONObject) jsonParser
314                 .parse(pdbJsonResponseString);
315         JSONObject pdbResponse = (JSONObject) jsonObj.get("response");
316         String queryTime = ((JSONObject) jsonObj.get("responseHeader"))
317                 .get("QTime").toString();
318         String numFound = pdbResponse.get("numFound").toString();
319         JSONArray docs = (JSONArray) pdbResponse.get("docs");
320         Iterator<JSONObject> docIter = docs.iterator();
321
322         assertTrue("Couldn't Retrieve 'response' object",
323                 pdbResponse != null);
324         assertTrue("Couldn't Retrieve 'QTime' value", queryTime != null);
325         assertTrue("Couldn't Retrieve 'numFound' value", numFound != null);
326         assertTrue("Couldn't Retrieve 'docs' object", docs != null
327                 || !docIter.hasNext());
328
329         JSONObject pdbJsonDoc = docIter.next();
330
331         for (FTSDataColumnI field : PDBFTSRestClient.getInstance()
332                 .getAllFTSDataColumns())
333         {
334           if (field.getName().equalsIgnoreCase("ALL"))
335           {
336             continue;
337           }
338           if (pdbJsonDoc.get(field.getCode()) == null)
339           {
340             // System.out.println(">>>\t" + field.getCode());
341             assertTrue(field.getCode()
342                     + " has been removed from PDB doc Entity",
343                     !pdbJsonResponseString.contains(field.getCode()));
344           }
345         }
346       } catch (ParseException e)
347       {
348         Assert.fail(">>>  Test failed due to exception while parsing pdb response json !!!");
349         e.printStackTrace();
350       }
351     }
352   }
353
354   public String readJsonStringFromFile(String filePath) throws IOException
355   {
356     String fileContent;
357     BufferedReader br = new BufferedReader(new FileReader(filePath));
358     try
359     {
360       StringBuilder sb = new StringBuilder();
361       String line = br.readLine();
362
363       while (line != null)
364       {
365         sb.append(line);
366         sb.append(System.lineSeparator());
367         line = br.readLine();
368       }
369       fileContent = sb.toString();
370     } finally
371     {
372       br.close();
373     }
374     return fileContent;
375   }
376
377 }