/* * $Id$ * Copyright (c) 2006-2011 by Public Library of Science http://plos.org http://ambraproject.org * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.ambraproject.service.search; import org.ambraproject.views.SearchHit; import org.apache.commons.lang.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.util.Assert; import org.testng.annotations.AfterMethod; import org.testng.annotations.BeforeMethod; import org.testng.annotations.DataProvider; import org.testng.annotations.Test; import org.ambraproject.action.BaseTest; import org.ambraproject.testutils.EmbeddedSolrServerFactory; import org.ambraproject.views.SearchResultSinglePage; import java.util.HashMap; import java.util.List; import java.util.Map; /** * @author Scott Sterling */ public class SearchServiceTest extends BaseTest { @Autowired protected SearchService searchService; @Autowired protected EmbeddedSolrServerFactory solrServerFactory; private static final String DOI_1 = "10.1371/journal.pgen.1000096"; private static final String DOI_2 = "10.1371/journal.pbio.1000100"; private static final String DOI_3 = "10.1371/journal.pbio.1000101"; private static final String JOURNAL_KEY_1 = "PLoSGenetics"; private static final String JOURNAL_KEY_2 = "PLoSBiology"; private static final String CATEGORY_1 = "Category1"; private static final String CATEGORY_2 = "Category2"; /** * Seed the solr server with some articles to test * * @throws Exception - if there's a problem */ @BeforeMethod public void sendArticlesToSolr() throws Exception { // delete all documents in solr solrServerFactory.deleteAllDocuments(); // 2 occurrences in "everything": "Spleen" Map<String, String[]> document1 = new HashMap<String, String[]>(); document1.put("id", new String[]{DOI_1}); document1.put("title", new String[]{"The First Title, with Spleen"}); document1.put("author", new String[]{"alpha delta epsilon"}); document1.put("body", new String[]{"Body of the first document: Yak and Spleen"}); document1.put("everything", new String[]{ "body first document yak spleen first title with spleen"}); document1.put("elocation_id", new String[]{"111"}); document1.put("volume", new String[]{"1"}); document1.put("doc_type", new String[]{"full"}); document1.put("publication_date", new String[]{"2008-06-13T00:00:00Z"}); document1.put("cross_published_journal_key", new String[]{JOURNAL_KEY_1}); document1.put("subject", new String[]{CATEGORY_1, CATEGORY_2}); document1.put("article_type_facet", new String[]{"Not an issue image"}); document1.put("abstract_primary_display", new String[]{"<p>The spleen is an organ found in virtually all vertebrate animals.</p>"}); // 2 occurrences in "everything": "Yak" Map<String, String[]> document2 = new HashMap<String, String[]>(); document2.put("id", new String[]{DOI_2}); document2.put("title", new String[]{"The Second Title, with Yak"}); document2.put("author", new String[]{"beta delta epsilon"}); document2.put("body", new String[]{"Description of the second document: Yak and Islets of Langerhans"}); document2.put("everything", new String[]{ "description second document yak islets Langerhans second title with yak"}); document2.put("elocation_id", new String[]{"222"}); document2.put("volume", new String[]{"2"}); document2.put("doc_type", new String[]{"full"}); document2.put("publication_date", new String[]{"2008-06-20T00:00:00Z"}); document2.put("cross_published_journal_key", new String[]{JOURNAL_KEY_2}); document2.put("subject", new String[]{CATEGORY_2}); document2.put("article_type_facet", new String[]{"Not an issue image"}); document2.put("abstract", new String[]{"The yak is a long-haired bovine found throughout the Himalayan region"}); // 2 occurrences in "everything": "Gecko" Map<String, String[]> document3 = new HashMap<String, String[]>(); document3.put("id", new String[]{DOI_3}); document3.put("title", new String[]{"The Third Title, with Gecko"}); document3.put("author", new String[]{"gamma delta"}); document3.put("body", new String[]{"Contents of the second document: Gecko and Islets of Langerhans"}); document3.put("everything", new String[]{ "contents of the second document gecko islets langerhans third title with gecko"}); document3.put("elocation_id", new String[]{"333"}); document3.put("volume", new String[]{"3"}); document3.put("doc_type", new String[]{"full"}); document3.put("publication_date", new String[]{"2008-06-22T00:00:00Z"}); document3.put("cross_published_journal_key", new String[]{JOURNAL_KEY_2}); document3.put("subject", new String[]{CATEGORY_1}); document3.put("article_type_facet", new String[]{"Not an issue image"}); document3.put("abstract", new String[]{"Geckos are lizards belonging to the infraorder Gekkota"}); solrServerFactory.addDocument(document1); solrServerFactory.addDocument(document2); solrServerFactory.addDocument(document3); } @DataProvider(name = "queryAndHitNumberForUnformattedQuery") // Use for Advanced Search. public Object[][] getQueryAndHitNumberForUnformattedQuery() throws Exception { return new Object[][]{ {"*:*", 3}, // Get All Articles {"everything:yak", 2}, {"everything:spleen", 1}, {"everything:document", 3}, {"author:delta", 3}, // Specific Field {"author:alpha", 1}, // Specific Field {"title:title", 3}, // Specific Field {"everything:\"Islets of Langerhans\"", 2}, // Quoted String {"everything:spleen AND everything:yak", 1}, // AND {"everything:spleen OR everything:yak", 2}, // OR {"everything:\"Islets of Langerhans\" NOT everything:gecko", 1} // NOT }; } @DataProvider(name = "queryAndHitNumberForQuery") // Use for Simple Search. public Object[][] getQueryAndHitNumberForQuery() throws Exception { return new Object[][]{ {"alpha", 1}, {"delta", 3}, {"yak", 2}, {"spleen", 1}, {"document", 3}, {"\"Islets of Langerhans\"", 2}, // Quoted String {"yak spleen", 2}, // Two Terms (implicit OR statement) {"thisWordDoesNotExist", 0} }; } @DataProvider(name = "volumeAndELocationIdAndIdAndJournal") // Use for Find An Article Search. public Object[][] getVolumeAndELocationIdAndId() throws Exception { return new Object[][]{ {"1", "111", DOI_1, JOURNAL_KEY_1}, {"2", "222", DOI_2, JOURNAL_KEY_2}, {"3", "333", DOI_3, JOURNAL_KEY_2} }; } /** * Get a SearchParameters with all the required (non-query) values already set. * @return a SearchParameters with all the required (non-query) values already set */ private static final SearchParameters getSearchParameters() { SearchParameters searchParameters = new SearchParameters(); searchParameters.setPageSize(10); searchParameters.setStartPage(0); return searchParameters; } @Test(dataProvider = "queryAndHitNumberForQuery") public void testSimpleSearch(String query, int numberOfHits) throws Exception { SearchParameters searchParameters = getSearchParameters(); searchParameters.setQuery(query); SearchResultSinglePage resultSinglePage = searchService.simpleSearch(searchParameters); Assert.isTrue(resultSinglePage.getHits().size() == numberOfHits, "Simple Search for '" + query + "' returned " + resultSinglePage.getHits().size() + " articles, but it should have returned " + numberOfHits + " articles"); } @Test(dataProvider = "queryAndHitNumberForUnformattedQuery") public void testAdvancedSearch(String query, int numberOfHits) throws Exception { SearchParameters searchParameters = getSearchParameters(); searchParameters.setUnformattedQuery(query); SearchResultSinglePage resultSinglePage = searchService.advancedSearch(searchParameters); Assert.isTrue(resultSinglePage.getHits().size() == numberOfHits, "Advanced Search for '" + query + "' returned " + resultSinglePage.getHits().size() + " articles, but it should have returned " + numberOfHits + " articles"); } @Test(dataProvider = "volumeAndELocationIdAndIdAndJournal") public void testFindAnArticleSearch(String volume, String eLocationId, String id, String journal) throws Exception { SearchParameters searchParameters = getSearchParameters(); searchParameters.setFilterJournals(new String[] {journal}); // Search for just the Id (DOI). searchParameters.setId(id); SearchResultSinglePage resultSinglePage = searchService.findAnArticleSearch(searchParameters); Assert.isTrue(resultSinglePage.getHits().size() == 1, "Find An Article Search found no articles" + " with id = '" + id + "' in journal '" + journal + "'"); // Search for just the Volume searchParameters.setId(null); searchParameters.setVolume(volume); searchParameters.setFilterJournals(new String[] {journal}); resultSinglePage = searchService.findAnArticleSearch(searchParameters); Assert.isTrue(resultSinglePage.getHits().size() == 1, "Find An Article Search found no articles" + " with volume = '" + volume + "' in journal '" + journal + "'"); // Search for the Volume and ELocationId. searchParameters.setId(null); searchParameters.setELocationId(eLocationId); searchParameters.setFilterJournals(new String[] {journal}); resultSinglePage = searchService.findAnArticleSearch(searchParameters); Assert.isTrue(resultSinglePage.getHits().size() == 1, "Find An Article Search found no articles" + " with volume = '" + volume + "' and eLocationId = '" + eLocationId + "' in journal '" + journal + "'"); } @Test public void testGetFilterData() throws Exception { SearchParameters searchParameters = getSearchParameters(); searchParameters.setUnformattedQuery("*:*"); SearchResultSinglePage resultSinglePage = searchService.getFilterData(searchParameters); Assert.isTrue(resultSinglePage.getJournalFacet().size() == 2, "For the query '*:*', get Filter Data expected 2 Journal Facets but, instead, received " + resultSinglePage.getJournalFacet().size()); Assert.isTrue(resultSinglePage.getArticleTypeFacet().size() == 1, "For the query '*:*', get Filter Data expected 1 Article Type Facet but, instead, received " + resultSinglePage.getArticleTypeFacet().size()); Assert.isTrue(resultSinglePage.getSubjectFacet().size() == 2, "For the query '*:*', get Filter Data expected 2 Subject Facets but, instead, received " + resultSinglePage.getSubjectFacet().size()); } @Test(dataProvider = "volumeAndELocationIdAndIdAndJournal") public void testFetchAbstractText(String volume, String eLocationId, String id, String journal) throws Exception { String abstractText = searchService.fetchAbstractText(id); Assert.isTrue(StringUtils.isNotBlank(abstractText)); } }