Skip to content

Commit e2b3637

Browse files
committed
Override getJson() and getCitation() in MockNcbiPublicationSearchService
1 parent 54a8223 commit e2b3637

3 files changed

Lines changed: 97 additions & 53 deletions

File tree

Lines changed: 85 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,25 @@
11
package org.labkey.panoramapublic.ncbi;
22

3-
import org.apache.logging.log4j.Logger;
4-
import org.jetbrains.annotations.NotNull;
53
import org.jetbrains.annotations.Nullable;
6-
import org.labkey.api.util.Pair;
7-
import org.labkey.panoramapublic.model.ExperimentAnnotations;
4+
import org.json.JSONArray;
5+
import org.json.JSONObject;
86
import org.labkey.panoramapublic.ncbi.NcbiConstants.DB;
97

10-
import java.text.ParseException;
11-
import java.text.SimpleDateFormat;
12-
import java.util.Collections;
13-
import java.util.Date;
14-
import java.util.List;
8+
import java.io.IOException;
159

1610
/**
1711
* Mock implementation of {@link NcbiPublicationSearchService} that returns canned data for PMID 23689285
1812
* (Abbatiello et al., Mol Cell Proteomics 2013). Used by Selenium tests when NCBI is not reachable.
13+
*
14+
* Extends {@link NcbiPublicationSearchServiceImpl} and only overrides the two methods that make HTTP calls
15+
* to NCBI: {@link #getJson(String)} (used by ESearch/ESummary) and {@link #getCitation(String, DB)}
16+
* (used by the Citation Exporter API). All search logic, filtering, author/title verification, and
17+
* priority filtering run through the real implementation code.
1918
*/
20-
public class MockNcbiPublicationSearchService implements NcbiPublicationSearchService
19+
public class MockNcbiPublicationSearchService extends NcbiPublicationSearchServiceImpl
2120
{
2221
private static final String PMID = "23689285";
22+
private static final String PMC_ID = "3769335";
2323

2424
private static final String CITATION = "Abbatiello SE, Mani DR, Schilling B, Maclean B, Zimmerman LJ, " +
2525
"Feng X, Cusack MP, Sedransk N, Hall SC, Addona T, Allen S, Dodder NG, Ghosh M, Held JM, Hedrick V, " +
@@ -32,19 +32,37 @@ public class MockNcbiPublicationSearchService implements NcbiPublicationSearchSe
3232
"Mol Cell Proteomics. 2013 Sep;12(9):2623-39. doi: 10.1074/mcp.M112.027078. Epub 2013 May 20. " +
3333
"PMID: 23689285; PMCID: PMC3769335.";
3434

35-
private static final Date PUBLISHED_DATE;
36-
static
35+
private static final String ARTICLE_TITLE = "Design, implementation and multisite evaluation of a system suitability " +
36+
"protocol for the quantitative assessment of instrument performance in liquid chromatography-multiple " +
37+
"reaction monitoring-MS (LC-MRM-MS).";
38+
39+
/**
40+
* Returns canned JSON for NCBI ESearch and ESummary API requests.
41+
* <ul>
42+
* <li>ESearch for PMC with a query containing "PXD010535" returns PMC ID 3769335</li>
43+
* <li>ESummary for PMC ID 3769335 returns article metadata (authors, title, pubdate, PMID)</li>
44+
* <li>All other requests return empty results</li>
45+
* </ul>
46+
* This allows the real search logic in {@link NcbiPublicationSearchServiceImpl} to run against mock data.
47+
*/
48+
@Override
49+
protected JSONObject getJson(String url) throws IOException
3750
{
38-
try
51+
if (url.contains("esearch.fcgi"))
3952
{
40-
PUBLISHED_DATE = new SimpleDateFormat("yyyy MMM").parse("2013 Sep");
53+
return handleESearch(url);
4154
}
42-
catch (ParseException e)
55+
else if (url.contains("esummary.fcgi"))
4356
{
44-
throw new RuntimeException(e);
57+
return handleESummary(url);
4558
}
59+
throw new IOException("MockNcbiPublicationSearchService: unexpected URL: " + url);
4660
}
4761

62+
/**
63+
* Returns the canned NLM citation for PMID 23689285. Returns null for any other publication ID.
64+
* Overrides the real implementation which makes an HTTP call to the NCBI Citation Exporter API.
65+
*/
4866
@Override
4967
public @Nullable String getCitation(String publicationId, DB database)
5068
{
@@ -55,42 +73,66 @@ public class MockNcbiPublicationSearchService implements NcbiPublicationSearchSe
5573
return null;
5674
}
5775

58-
@Override
59-
public @Nullable Pair<String, String> getPubMedLinkAndCitation(String pubmedId)
76+
/**
77+
* Handle mock ESearch requests. Returns PMC ID 3769335 when query contains "PXD010535",
78+
* empty results otherwise.
79+
*/
80+
private JSONObject handleESearch(String url)
6081
{
61-
if (PMID.equals(pubmedId))
82+
JSONObject result = new JSONObject();
83+
JSONObject esearchResult = new JSONObject();
84+
85+
if (url.contains("PXD010535"))
6286
{
63-
return new Pair<>(NcbiConstants.getPubmedLink(pubmedId), CITATION);
87+
esearchResult.put("idlist", new JSONArray().put(PMC_ID));
88+
}
89+
else
90+
{
91+
esearchResult.put("idlist", new JSONArray());
6492
}
65-
return null;
66-
}
6793

68-
@Override
69-
public @Nullable PublicationMatch searchForPublication(@NotNull ExperimentAnnotations expAnnotations, @Nullable Logger logger)
70-
{
71-
List<PublicationMatch> matches = searchForPublication(expAnnotations, 1, logger, true);
72-
return matches.isEmpty() ? null : matches.get(0);
94+
result.put("esearchresult", esearchResult);
95+
return result;
7396
}
7497

75-
@Override
76-
public List<PublicationMatch> searchForPublication(@NotNull ExperimentAnnotations expAnnotations, int maxResults, @Nullable Logger logger, boolean getCitations)
98+
/**
99+
* Handle mock ESummary requests. Returns article metadata for PMC ID 3769335.
100+
*/
101+
private JSONObject handleESummary(String url)
77102
{
78-
PublicationMatch match = new PublicationMatch(
79-
PMID,
80-
DB.PubMed,
81-
false, // foundByPxId (simulates finding via PXD010535)
82-
false, // foundByUrl
83-
false, // foundByDoi
84-
true, // authorMatch
85-
true, // titleMatch
86-
PUBLISHED_DATE
87-
);
88-
89-
if (getCitations)
103+
JSONObject response = new JSONObject();
104+
JSONObject result = new JSONObject();
105+
106+
if (url.contains(PMC_ID))
90107
{
91-
match.setCitation(CITATION);
108+
JSONObject articleData = new JSONObject();
109+
articleData.put("title", ARTICLE_TITLE);
110+
articleData.put("sorttitle", ARTICLE_TITLE.toLowerCase());
111+
articleData.put("source", "Mol Cell Proteomics");
112+
articleData.put("fulljournalname", "Molecular & cellular proteomics : MCP");
113+
articleData.put("pubdate", "2013 Sep");
114+
articleData.put("epubdate", "2013 May 20");
115+
116+
// Authors — include first 3 plus a few more for realism
117+
JSONArray authors = new JSONArray();
118+
authors.put(new JSONObject().put("name", "Abbatiello SE"));
119+
authors.put(new JSONObject().put("name", "Mani DR"));
120+
authors.put(new JSONObject().put("name", "Schilling B"));
121+
authors.put(new JSONObject().put("name", "Maclean B"));
122+
authors.put(new JSONObject().put("name", "Zimmerman LJ"));
123+
authors.put(new JSONObject().put("name", "Carr SA"));
124+
articleData.put("authors", authors);
125+
126+
// Article IDs — PMC ID and PubMed ID
127+
JSONArray articleIds = new JSONArray();
128+
articleIds.put(new JSONObject().put("idtype", "pmcid").put("value", "PMC" + PMC_ID));
129+
articleIds.put(new JSONObject().put("idtype", "pmid").put("value", PMID));
130+
articleData.put("articleids", articleIds);
131+
132+
result.put(PMC_ID, articleData);
92133
}
93134

94-
return Collections.singletonList(match);
135+
response.put("result", result);
136+
return response;
95137
}
96138
}

panoramapublic/src/org/labkey/panoramapublic/ncbi/NcbiPublicationSearchServiceImpl.java

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -264,7 +264,7 @@ public List<PublicationMatch> searchForPublication(@NotNull ExperimentAnnotation
264264
/**
265265
* Search PubMed Central
266266
*/
267-
private static @NotNull List<PublicationMatch> searchPmc(@NotNull ExperimentAnnotations expAnnotations, Logger log)
267+
private @NotNull List<PublicationMatch> searchPmc(@NotNull ExperimentAnnotations expAnnotations, Logger log)
268268
{
269269
// Track PMC IDs found by each strategy
270270
Map<String, List<String>> pmcIdsByStrategy = new HashMap<>();
@@ -338,23 +338,23 @@ public List<PublicationMatch> searchForPublication(@NotNull ExperimentAnnotation
338338
/**
339339
* Search PubMed Central with the given query
340340
*/
341-
private static List<String> searchPmc(String query, Logger log)
341+
private List<String> searchPmc(String query, Logger log)
342342
{
343343
return executeSearch(query, "pmc", log);
344344
}
345345

346346
/**
347347
* Search PubMed with the given query
348348
*/
349-
private static List<String> searchPubMed(String query, Logger log)
349+
private List<String> searchPubMed(String query, Logger log)
350350
{
351351
return executeSearch(query, "pubmed", log);
352352
}
353353

354354
/**
355355
* Execute search using NCBI ESearch API
356356
*/
357-
private static List<String> executeSearch(String query, String database, Logger log)
357+
private List<String> executeSearch(String query, String database, Logger log)
358358
{
359359
String encodedQuery = URLEncoder.encode(query, StandardCharsets.UTF_8);
360360
String url = ESEARCH_URL +
@@ -389,7 +389,7 @@ private static List<String> executeSearch(String query, String database, Logger
389389
* @throws IOException if the request fails or the server returns a non-2xx response
390390
* @throws JSONException if the response body is not valid JSON
391391
*/
392-
private static JSONObject getJson(String url) throws IOException
392+
protected JSONObject getJson(String url) throws IOException
393393
{
394394
ConnectionConfig connectionConfig = ConnectionConfig.custom()
395395
.setConnectTimeout(Timeout.ofMilliseconds(TIMEOUT_MS))
@@ -424,23 +424,23 @@ private static JSONObject getJson(String url) throws IOException
424424
/**
425425
* Fetch metadata for PMC articles using ESummary API
426426
*/
427-
private static Map<String, JSONObject> fetchPmcMetadata(Collection<String> pmcIds, Logger log)
427+
private Map<String, JSONObject> fetchPmcMetadata(Collection<String> pmcIds, Logger log)
428428
{
429429
return fetchMetadata(pmcIds, "pmc", log);
430430
}
431431

432432
/**
433433
* Fetch metadata for PubMed articles using ESummary API
434434
*/
435-
private static Map<String, JSONObject> fetchPubMedMetadata(Collection<String> pmids, Logger log)
435+
private Map<String, JSONObject> fetchPubMedMetadata(Collection<String> pmids, Logger log)
436436
{
437437
return fetchMetadata(pmids, "pubmed", log);
438438
}
439439

440440
/**
441441
* Fetch metadata using NCBI ESummary API (batch request)
442442
*/
443-
private static Map<String, JSONObject> fetchMetadata(Collection<String> ids, String database, Logger log)
443+
private Map<String, JSONObject> fetchMetadata(Collection<String> ids, String database, Logger log)
444444
{
445445
if (ids.isEmpty()) return Collections.emptyMap();
446446

@@ -479,7 +479,7 @@ private static Map<String, JSONObject> fetchMetadata(Collection<String> ids, Str
479479
/**
480480
* Fetch and verify PMC articles (filter preprints, check author/title matches)
481481
*/
482-
private static List<PublicationMatch> fetchAndVerifyPmcArticles(
482+
private List<PublicationMatch> fetchAndVerifyPmcArticles(
483483
Set<String> pmcIds,
484484
Map<String, List<String>> idToStrategies,
485485
ExperimentAnnotations expAnnotations,
@@ -612,7 +612,7 @@ private static int countDataIdMatches(PublicationMatch a)
612612
/**
613613
* Fall back to PubMed search if PMC finds nothing
614614
*/
615-
private static List<PublicationMatch> searchPubMed(ExperimentAnnotations expAnnotations, Logger log)
615+
private List<PublicationMatch> searchPubMed(ExperimentAnnotations expAnnotations, Logger log)
616616
{
617617
String firstName = expAnnotations.getSubmitterUser() != null
618618
? expAnnotations.getSubmitterUser().getFirstName() : null;

panoramapublic/test/src/org/labkey/test/tests/panoramapublic/PublicationSearchTest.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,8 @@ protected void doCleanup(boolean afterTest) throws TestTimeoutException
236236
restoreNcbiService();
237237
}
238238

239+
// TODO: Reset the reminder settings to not search for publications.
240+
239241
_userHelper.deleteUsers(false, SUBMITTER_USER, ADMIN_USER);
240242
super.doCleanup(afterTest);
241243
}

0 commit comments

Comments
 (0)