/*
* C O P Y R I G H T N O T I C E
* -----------------------------------------------------------------------
* Copyright (c) 2011-2012 InfoClinika, Inc. 5901 152nd Ave SE, Bellevue, WA 98006,
* United States of America. (425) 442-8058. http://www.infoclinika.com.
* All Rights Reserved. Reproduction, adaptation, or translation without prior written permission of InfoClinika, Inc. is prohibited.
* Unpublished--rights reserved under the copyright laws of the United States. RESTRICTED RIGHTS LEGEND Use, duplication or disclosure by the
*/
package com.infoclinika.mssharing.search;
import com.google.common.base.Optional;
import com.google.common.base.Predicate;
import com.google.common.collect.ImmutableCollection;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterables;
import com.infoclinika.mssharing.fileserver.StoredObject;
import com.infoclinika.mssharing.model.PaginationItems;
import com.infoclinika.mssharing.model.PredefinedDataCreator;
import com.infoclinika.mssharing.model.Searcher;
import com.infoclinika.mssharing.model.helper.DictionaryItem;
import com.infoclinika.mssharing.model.helper.ExperimentCreationHelper;
import com.infoclinika.mssharing.model.helper.InstrumentCreationHelper;
import com.infoclinika.mssharing.model.read.DashboardReader;
import com.infoclinika.mssharing.model.write.*;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.testng.AbstractTestNGSpringContextTests;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
import javax.inject.Inject;
import java.util.*;
import static com.google.common.collect.Iterables.any;
import static com.google.common.collect.Sets.newHashSet;
import static org.apache.commons.lang.builder.ToStringBuilder.reflectionToString;
import static org.mockito.Mockito.mock;
import static org.testng.Assert.*;
/**
* @author Stanislav Kurilin
*/
@ContextConfiguration(classes = SpringConfig.class)
public class SearcherImplTest extends AbstractTestNGSpringContextTests {
long bob;
long lab;
Optional<Long> labInstrument = Optional.absent();
long kate;
@Test
public void testSearcherAvailable() {
assertNotNull(searcher);
}
@Test(dependsOnMethods = "testSearcherAvailable", timeOut = 3000)
public void testSearchBecomeEnable() {
while (true) if (searcher.isSearchEnabled()) return;
}
@Test(dependsOnMethods = "testSearchBecomeEnable")
public void testUserCanSearchHisProjects() {
final long proj = studyManagement.newProject(bob, lab, new StudyManagement.ProjectInfo("foo bar2", anyStr(), anyStr()));
final ImmutableCollection<DashboardReader.ProjectLine> res = searcher.projects(bob, "foo");
assertTrue(any(res, new Predicate<DashboardReader.ProjectLine>() {
@Override
public boolean apply(DashboardReader.ProjectLine input) {
return input.id == proj && input.name.equals("foo bar2");
}
}), reflectionToString(res));
}
@Test(dependsOnMethods = "testSearchBecomeEnable")
public void testUserCanSearchHisExperiments() {
final long proj = studyManagement.newProject(bob, lab, new StudyManagement.ProjectInfo("foo bar1", anyStr(), anyStr()));
final long experiment = experiment(proj, "H study", anyStr());
ImmutableList<DashboardReader.ExperimentLine> experiments = searcher.experiments(bob, "study");
assertTrue(any(experiments, new Predicate<DashboardReader.ExperimentLine>() {
@Override
public boolean apply(DashboardReader.ExperimentLine input) {
return input.id == experiment && input.name.equals("H study");
}
}));
}
@Test(dependsOnMethods = "testSearchBecomeEnable")
public void testUserCanSearchHisInstruments() {
final long instrument = instrumentManagement.newInstrument(bob, lab, anyInstrumentModel()
, new InstrumentManagement.InstrumentDetails("fooooo", anyStr(), anyStr(), anyStr())).get();
ImmutableList<DashboardReader.InstrumentItem> instruments = searcher.instruments(bob, "fooo");
assertTrue(any(instruments, new Predicate<DashboardReader.InstrumentItem>() {
@Override
public boolean apply(DashboardReader.InstrumentItem input) {
return input.id == instrument;
}
}));
}
@Test(dependsOnMethods = "testSearchBecomeEnable")
public void testCountItems() {
instrumentManagement.newInstrument(bob, lab, anyInstrumentModel()
, new InstrumentManagement.InstrumentDetails("fooo", anyStr(), anyStr(), anyStr())).get();
final Searcher.Count fooo = searcher.getItemsCount(new PaginationItems.PagedItemInfo(25, 0, "", true, "fooo"), bob);
assertTrue(fooo.instruments == 1);
}
@Test(dependsOnMethods = "testSearchBecomeEnable")
public void testUserCanSearchHisFiles() {
final Long instrument = instrumentManagement.newInstrument(bob, lab, anyInstrumentModel(), new InstrumentManagement.InstrumentDetails("foo", anyStr(), anyStr(), anyStr())).get();
final long file = instrumentManagement.attachFile(bob, "c15092005_007.RAW", 0, instrument, anySpecie(), anyStr(), false);
instrumentManagement.setContent(bob, file, mock(StoredObject.class));
checkCanFindFileWithQuery(file, "2005");
checkCanFindFileWithQuery(file, "raw");
checkCanFindFileWithQuery(file, "RAW");
}
private void checkCanFindFileWithQuery(final long file, String query) {
final ImmutableCollection<DashboardReader.FileLine> res = searcher.files(bob, query);
assertTrue(any(res, new Predicate<DashboardReader.FileLine>() {
@Override
public boolean apply(DashboardReader.FileLine input) {
return input.id == file;
}
}), reflectionToString(res));
}
@Test(dependsOnMethods = "testSearchBecomeEnable")
public void testUserCanSearchUsingSubStringOnName() {
final long proj = studyManagement.newProject(bob, lab, new StudyManagement.ProjectInfo("foo bar4", anyStr(), anyStr()));
final ImmutableCollection<DashboardReader.ProjectLine> res = searcher.projects(bob, "oo");
assertTrue(any(res, new Predicate<DashboardReader.ProjectLine>() {
@Override
public boolean apply(DashboardReader.ProjectLine input) {
return input.id == proj;
}
}), reflectionToString(res));
}
@Test(dependsOnMethods = "testSearchBecomeEnable")
public void testUserCanSearchUsingSubStringOnNotNameFields() {
final long proj = studyManagement.newProject(bob, lab, new StudyManagement.ProjectInfo(anyStr(), "foo bar", anyStr()));
final ImmutableCollection<DashboardReader.ProjectLine> res = searcher.projects(bob, "oo");
assertTrue(any(res, new Predicate<DashboardReader.ProjectLine>() {
@Override
public boolean apply(DashboardReader.ProjectLine input) {
return input.id == proj;
}
}), reflectionToString(res));
}
//
@Test(dependsOnMethods = "testSearchBecomeEnable")
public void testUserCanSearchInUpperCase() {
final long proj = studyManagement.newProject(bob, lab, new StudyManagement.ProjectInfo("Foo", anyStr(), anyStr()));
final ImmutableCollection<DashboardReader.ProjectLine> res = searcher.projects(bob, "foo");
assertTrue(any(res, new Predicate<DashboardReader.ProjectLine>() {
@Override
public boolean apply(DashboardReader.ProjectLine input) {
return input.id == proj;
}
}), reflectionToString(res));
}
@Test(dependsOnMethods = "testSearchBecomeEnable")
public void testUserCanSearchSeveralSameEntities() {
final long projBar = studyManagement.newProject(bob, lab, new StudyManagement.ProjectInfo("foo bar3", anyStr(), anyStr()));
final long projFoo = studyManagement.newProject(bob, lab, new StudyManagement.ProjectInfo("foo foo1", anyStr(), anyStr()));
final ImmutableCollection<DashboardReader.ProjectLine> res = searcher.projects(bob, "foo");
assertTrue(any(res, new Predicate<DashboardReader.ProjectLine>() {
@Override
public boolean apply(DashboardReader.ProjectLine input) {
return input.id == projBar;
}
}), reflectionToString(res));
assertTrue(any(res, new Predicate<DashboardReader.ProjectLine>() {
@Override
public boolean apply(DashboardReader.ProjectLine input) {
return input.id == projFoo;
}
}), reflectionToString(res));
}
@Test(dependsOnMethods = "testSearchBecomeEnable")
public void testNotAllEntitiesGoesToResultSearch() {
studyManagement.newProject(bob, lab, new StudyManagement.ProjectInfo("foo bar", anyStr(), anyStr()));
final long projFoo = studyManagement.newProject(bob, lab, new StudyManagement.ProjectInfo("foo foo", anyStr(), anyStr()));
final ImmutableCollection<DashboardReader.ProjectLine> res = searcher.projects(bob, "bar");
assertFalse(any(res, new Predicate<DashboardReader.ProjectLine>() {
@Override
public boolean apply(DashboardReader.ProjectLine input) {
return input.id == projFoo;
}
}), reflectionToString(res));
}
@Test(dependsOnMethods = "testSearchBecomeEnable")
public void testUserCanSearchByProjectDescriptions() {
final long proj = studyManagement.newProject(bob, lab, new StudyManagement.ProjectInfo(anyStr(), anyStr(), "desc"));
final ImmutableCollection<DashboardReader.ProjectLine> res = searcher.projects(bob, "de");
assertTrue(any(res, new Predicate<DashboardReader.ProjectLine>() {
@Override
public boolean apply(DashboardReader.ProjectLine input) {
return input.id == proj;
}
}), reflectionToString(res));
}
@Test(dependsOnMethods = "testSearchBecomeEnable")
public void testUserCanSearchBySeveralWords() {
final long proj = studyManagement.newProject(bob, lab, new StudyManagement.ProjectInfo(anyStr(), anyStr(), "my project"));
studyManagement.newProject(bob, lab, new StudyManagement.ProjectInfo(anyStr(), anyStr(), "shared project"));
final ImmutableCollection<DashboardReader.ProjectLine> res = searcher.projects(bob, "my project");
assertTrue(any(res, new Predicate<DashboardReader.ProjectLine>() {
@Override
public boolean apply(DashboardReader.ProjectLine input) {
return input.id == proj;
}
}), reflectionToString(res));
}
@Test(dependsOnMethods = "testSearchBecomeEnable")
public void testUserCanSearchByAreaOfResearch() {
final long proj = studyManagement.newProject(bob, lab, new StudyManagement.ProjectInfo(anyStr(), "story", anyStr()));
final ImmutableCollection<DashboardReader.ProjectLine> res = searcher.projects(bob, "story");
assertTrue(any(res, new Predicate<DashboardReader.ProjectLine>() {
@Override
public boolean apply(DashboardReader.ProjectLine input) {
return input.id == proj && input.areaOfResearch.contains("story");
}
}), reflectionToString(res));
}
@Test(dependsOnMethods = "testSearchBecomeEnable")
public void testUserCanSearchPagedUsingSpecialSymbolsInTitle(){
final long proj = studyManagement.newProject(bob, lab, new StudyManagement.ProjectInfo("some-project", anyStr(), anyStr()));
final Set<DashboardReader.ProjectLine> res = searcher.pagedProjects(bob, getPageItem("some-project", false)).items;
assertTrue(any(res, new Predicate<DashboardReader.ProjectLine>() {
@Override
public boolean apply(DashboardReader.ProjectLine input) {
return input.id == proj;
}
}), reflectionToString(res));
}
private PaginationItems.PagedItemInfo getPageItem(String query, boolean inversed) {
return new PaginationItems.PagedItemInfo(10, 0, "name", !inversed, query);
}
@Test(dependsOnMethods = "testSearchBecomeEnable")
public void testHibernateSearchPaging() {
searcher.setHibernateSearchPaging(true);
createTestData();
final Set<DashboardReader.ProjectLine> res = searcher.pagedProjects(bob, getPageItem("some", false)).items;
//Ok, true
assertSame(res.size(), 10);
//Now search and sort by name inversed
final Set<DashboardReader.ProjectLine> res2 = searcher.pagedProjects(kate, getPageItem("some", true)).items;
//Ok, true - one public project match the search expression
assertSame(res2.size(), 1);
//Now search and sort by name not inversed
final Set<DashboardReader.ProjectLine> res3 = searcher.pagedProjects(kate, getPageItem("some", false)).items;
//Assertion failed. Some confusion
//assertSame(res3.size(), 1);
}
private void createTestData() {
final long publicProject = studyManagement.newProject(bob, lab, new StudyManagement.ProjectInfo("some-public-project", anyStr(), anyStr()));
sharingManagement.makeProjectPublic(bob, publicProject);
for(int i = 0; i < 10; i++) {
studyManagement.newProject(bob, lab, new StudyManagement.ProjectInfo("some-project-"+ i, anyStr(), anyStr()));
}
//Now for kate available 1 project
sharingManagement.makeProjectPublic(bob, publicProject);
}
@BeforeClass
public void setUp() {
predefinedDataCreator.instrumentModel(anyStr(), anyStr(), anyStr(), false, false, newHashSet(new DashboardReader.FileExtensionItem(".raw", Collections.<String, DashboardReader.AdditionalExtensionImportance>emptyMap())));
predefinedDataCreator.experimentTypes("Unspecified");
predefinedDataCreator.workflowType("Unspecified", "Unspecified", true);
predefinedDataCreator.species("Human", "Rat");
predefinedDataCreator.allUsersGroup();
final long admin = predefinedDataCreator.admin(anyStr(), anyStr(), anyStr(), anyStr());
lab = labManagement.createLab(admin, new LabManagement.LabInfo(anyStr(), new LabManagement.PersonInfo(anyStr(), anyStr(), anyStr()), anyStr()), anyStr());
bob = userManagement.createPersonAndApproveMembership(new UserManagement.PersonInfo(anyStr(), anyStr(), anyStr()), anyStr(), lab, null);
kate = userManagement.createPersonAndApproveMembership(new UserManagement.PersonInfo(anyStr(), anyStr(), anyStr()), anyStr(), lab, null);
instrumentManagement.newInstrument(bob, lab, anyInstrumentModel(), new InstrumentManagement.InstrumentDetails(anyStr(), anyStr(), anyStr(), anyStr()));
}
private long experiment(long proj, String name, String description) {
final DictionaryItem type = experimentCreationHelper.experimentTypes().iterator().next();
final ExperimentCreationHelper.WorkflowTypeItem workflowType = experimentCreationHelper.workflowTypes(type.id).iterator().next();
DictionaryItem specie = experimentCreationHelper.species().iterator().next();
final long file = saveFile();
return studyManagement.newExperiment(bob, proj, lab,
new StudyManagement.ExperimentInfo(name, description, workflowType.id, specie.id), false,
new StudyManagement.Restriction(experimentCreationHelper.availableInstrumentModels(bob, null).get(0).id, Optional.<Long>absent()),
Collections.<StudyManagement.MetaFactor>emptyList(), noFactoredFile(file), new AnalysisBounds(), new ArrayList<Double>());
}
@Inject
Searcher searcher;
@Inject
PredefinedDataCreator predefinedDataCreator;
@Inject
LabManagement labManagement;
@Inject
UserManagement userManagement;
@Inject
StudyManagement studyManagement;
@Inject
ExperimentCreationHelper experimentCreationHelper;
@Inject
InstrumentManagement instrumentManagement;
@Inject
InstrumentCreationHelper instrumentCreationHelper;
@Inject
SharingManagement sharingManagement;
protected String anyStr() {
return UUID.randomUUID().toString();
}
protected long anyInstrumentModel() {
return randElement(instrumentCreationHelper.models(anyVendor())).id;
}
private long anyVendor() {
return randElement(instrumentCreationHelper.vendors()).id;
}
private long anySpecie() {
return randElement(experimentCreationHelper.species()).id;
}
private <T> T randElement(Set<T> all) {
final Random random = new Random();
return Iterables.get(all, random.nextInt(all.size()));
}
public long saveFile() {
if (!labInstrument.isPresent())
labInstrument = instrumentManagement.newInstrument(bob, lab, anyInstrumentModel(), new InstrumentManagement.InstrumentDetails(anyStr(), anyStr(), anyStr(), anyStr()));
return saveFile(labInstrument.get());
}
public long saveFile(long instrument) {
final long file = instrumentManagement.attachFile(bob, UUID.randomUUID().toString(), 0, instrument, anySpecie(), "", false);
instrumentManagement.setContent(bob, file, mock(StoredObject.class));
return file;
}
private ImmutableList<StudyManagement.FileItem> noFactoredFile(long file) {
return ImmutableList.of(new StudyManagement.FileItem(file, ImmutableList.<String>of(), Optional.<StudyManagement.Annotations>absent()));
}
}