package com.constellio.app.ui.pages.search;
import static com.constellio.model.services.search.query.logical.LogicalSearchQueryOperators.from;
import static java.util.Arrays.asList;
import static org.assertj.core.api.Assertions.assertThat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.assertj.core.api.Condition;
import org.joda.time.LocalDateTime;
import org.junit.Before;
import org.junit.Test;
import com.constellio.app.modules.rm.RMTestRecords;
import com.constellio.app.modules.rm.model.enums.CopyType;
import com.constellio.app.modules.rm.services.RMSchemasRecordsServices;
import com.constellio.app.modules.rm.wrappers.AdministrativeUnit;
import com.constellio.app.modules.rm.wrappers.Document;
import com.constellio.app.modules.rm.wrappers.Folder;
import com.constellio.app.modules.rm.wrappers.RetentionRule;
import com.constellio.app.modules.rm.wrappers.type.DocumentType;
import com.constellio.app.ui.entities.FacetVO;
import com.constellio.app.ui.entities.FacetValueVO;
import com.constellio.model.entities.Language;
import com.constellio.model.entities.records.Record;
import com.constellio.model.entities.records.wrappers.Facet;
import com.constellio.model.entities.records.wrappers.User;
import com.constellio.model.entities.records.wrappers.structure.FacetOrderType;
import com.constellio.model.services.records.RecordServices;
import com.constellio.model.services.schemas.builders.MetadataSchemaTypesBuilder;
import com.constellio.model.services.search.SearchServices;
import com.constellio.model.services.search.query.logical.LogicalSearchQuery;
import com.constellio.sdk.tests.ConstellioTest;
import com.constellio.sdk.tests.setups.Users;
public class SearchPresenterServiceAcceptTest extends ConstellioTest {
LocalDateTime threeYearsAgo = new LocalDateTime().minusYears(3);
LogicalSearchQuery allFolders;
LogicalSearchQuery allFoldersAndDocuments;
RMSchemasRecordsServices rm;
Users users = new Users();
RMTestRecords records = new RMTestRecords(zeCollection);
RecordServices recordServices;
SearchServices searchServices;
SearchPresenterService searchPresenterService;
Map<String, Boolean> facetStatus;
@Before
public void setUp()
throws Exception {
prepareSystem(withZeCollection().withConstellioRMModule().withAllTest(users).withRMTest(records)
.withFoldersAndContainersOfEveryStatus().withDocumentsHavingContent());
recordServices = getModelLayerFactory().newRecordServices();
searchServices = getModelLayerFactory().newSearchServices();
rm = new RMSchemasRecordsServices(zeCollection, getAppLayerFactory());
searchPresenterService = new SearchPresenterService(zeCollection, getModelLayerFactory());
allFolders = new LogicalSearchQuery(from(rm.folderSchemaType()).returnAll());
allFoldersAndDocuments = new LogicalSearchQuery(from(asList(rm.folderSchemaType(), rm.documentSchemaType())).returnAll());
facetStatus = new HashMap<>();
clearExistingFacets();
}
@Test
public void givenFieldAndQueryFacetsConfiguredWhenSearchingFoldersThenReturnThoseWithValues()
throws Exception {
recordServices.add(rm.newFacetQuery().setOrder(0).setTitle("Type")
.withQuery("schema_s:folder*", "Dossiers")
.withQuery("schema_s:document*", "Documents")
.withQuery("schema_s:containerRecord*", "Contenants"));
recordServices.add(rm.newFacetField().setOrder(1).setFieldDataStoreCode("retentionRuleId_s")
.setTitle("Règles de conservations"));
recordServices.add(rm.newFacetField().setOrder(2).setFieldDataStoreCode("copyStatus_s").setTitle("Statut d'exemplaire"));
recordServices.add(rm.newFacetField().setOrder(3).setFieldDataStoreCode("keywords_ss").setTitle("Mots-clés"));
recordServices.add(rm.newFacetField().setOrder(4).setFieldDataStoreCode("type_s").setTitle("Type"));
recordServices.add(rm.newFacetQuery().setOrder(5).setTitle("Création/Modification")
.withQuery("modifiedOn_dt:[NOW-1MONTH TO NOW]", "Modifiés les 30 derniers jours")
.withQuery("modifiedOn_dt:[NOW-7DAY TO NOW]", "Modifiés les 7 derniers jours")
.withQuery("createdOn_dt:[NOW-1MONTH TO NOW]", "Créés les 30 derniers jours")
.withQuery("createdOn_dt:[NOW-7DAY TO NOW]", "Créés les 7 derniers jours"));
recordServices.add(rm.newFacetField().setOrder(6).setFieldDataStoreCode("administrativeUnitId_s")
.setTitle("Unités administratives"));
List<FacetVO> facets = searchPresenterService.getFacets(allFolders, facetStatus);
assertThat(facets.get(1)).has(label("Règles de conservations")).has(
values(value(records.getRule2()), value(records.getRule4()), value(records.getRule1()),
value(records.getRule3())));
assertThat(facets.get(2)).has(label("Statut d'exemplaire")).has(
values(value(CopyType.PRINCIPAL.getCode(), "Principal"), value(CopyType.SECONDARY.getCode(), "Secondaire")));
assertThat(facets.get(4)).has(label("Unités administratives")).has(
values(value(records.getUnit10a()), value(records.getUnit30c()), value(records.getUnit11b()),
value(records.getUnit12b())));
}
@Test
public void givenFieldAndQueryFacetsConfiguredWhenSearchingEverySchemaTypesThenReturnThoseWithValuesAndSchemas()
throws Exception {
recordServices.add(rm.newFacetQuery().setOrder(0).setTitle("Type")
.withQuery("schema_s:folder*", "Dossiers")
.withQuery("schema_s:document*", "Documents")
.withQuery("schema_s:containerRecord*", "Contenants"));
recordServices.add(rm.newFacetField().setOrder(1).setFieldDataStoreCode("retentionRuleId_s")
.setTitle("Règles de conservations"));
recordServices.add(rm.newFacetField().setOrder(2).setFieldDataStoreCode("copyStatus_s").setTitle("Statut d'exemplaire"));
recordServices.add(rm.newFacetField().setOrder(3).setFieldDataStoreCode("keywords_ss").setTitle("Mots-clés"));
recordServices.add(rm.newFacetField().setOrder(4).setFieldDataStoreCode("type_s").setTitle("Schéma"));
recordServices.add(rm.newFacetQuery().setOrder(5).setTitle("Création/Modification")
.withQuery("modifiedOn_dt:[NOW-1MONTH TO NOW]", "Modifiés les 30 derniers jours")
.withQuery("modifiedOn_dt:[NOW-7DAY TO NOW]", "Modifiés les 7 derniers jours")
.withQuery("createdOn_dt:[NOW-1MONTH TO NOW]", "Créés les 30 derniers jours")
.withQuery("createdOn_dt:[NOW-7DAY TO NOW]", "Créés les 7 derniers jours"));
recordServices.add(rm.newFacetField().setOrder(6).setFieldDataStoreCode("administrativeUnitId_s")
.setTitle("Unités administratives"));
List<FacetVO> facets = searchPresenterService.getFacets(allFoldersAndDocuments, facetStatus);
assertThat(facets.get(0)).has(label("Type")).has(values(
value("schema_s:document*", "Documents"),
value("schema_s:folder*", "Dossiers")));
assertThat(facets.get(1)).has(label("Règles de conservations")).has(
values(value(records.getRule2()), value(records.getRule1()), value(records.getRule4()),
value(records.getRule3())));
assertThat(facets.get(2)).has(label("Statut d'exemplaire")).has(
values(value(CopyType.PRINCIPAL.getCode(), "Principal"), value(CopyType.SECONDARY.getCode(), "Secondaire")));
assertThat(facets.get(4)).has(label("Unités administratives")).has(
values(value(records.getUnit10a()), value(records.getUnit30c()), value(records.getUnit12b()),
value(records.getUnit11b())));
}
@Test
public void givenFacetsWithValuesInAlphabeticalOrdersThenInAlphabeticOrder()
throws Exception {
recordServices.add(rm.newFacetField().setOrder(0).setFieldDataStoreCode("retentionRuleId_s")
.setTitle("Règles de conservations").setOrderResult(FacetOrderType.ALPHABETICAL));
recordServices.add(rm.newFacetField().setOrder(1).setFieldDataStoreCode("copyStatus_s").setTitle("Statut d'exemplaire")
.setOrderResult(FacetOrderType.ALPHABETICAL));
recordServices.add(rm.newFacetField().setOrder(2).setFieldDataStoreCode("administrativeUnitId_s")
.setTitle("Unités administratives").setOrderResult(FacetOrderType.ALPHABETICAL));
List<FacetVO> facets = searchPresenterService.getFacets(allFoldersAndDocuments, facetStatus);
assertThat(facets.get(0)).has(label("Règles de conservations")).has(
values(value(records.getRule1()), value(records.getRule2()), value(records.getRule3()),
value(records.getRule4())));
assertThat(facets.get(1)).has(label("Statut d'exemplaire")).has(
values(value(CopyType.PRINCIPAL.getCode(), "Principal"), value(CopyType.SECONDARY.getCode(), "Secondaire")));
assertThat(facets.get(2)).has(label("Unités administratives")).has(
values(value(records.getUnit10a()), value(records.getUnit11b()), value(records.getUnit12b()),
value(records.getUnit30c())));
}
@Test
public void givenSchemaFacetThenValuesAreObtainedFromSchemaLabels()
throws Exception {
MetadataSchemaTypesBuilder typesBuilder = getModelLayerFactory().getMetadataSchemasManager().modify(zeCollection);
typesBuilder.getSchemaType(Folder.SCHEMA_TYPE).getDefaultSchema().addLabel(Language.French, "Ze folder");
typesBuilder.getSchemaType(Document.SCHEMA_TYPE).getDefaultSchema().addLabel(Language.French, "Ze document");
getModelLayerFactory().getMetadataSchemasManager().saveUpdateSchemaTypes(typesBuilder);
recordServices.add(rm.newFacetField().setOrder(0).setFieldDataStoreCode("schema_s").setTitle("Ze type"));
List<FacetVO> facets = new SearchPresenterService(zeCollection, getModelLayerFactory()).getFacets(allFoldersAndDocuments,
facetStatus);
assertThat(facets.get(0)).has(label("Ze type")).has(
values(value(Document.DEFAULT_SCHEMA, "Ze document"), value(Folder.DEFAULT_SCHEMA, "Ze folder")));
}
@Test
public void givenFacetOpenByDefaultAndNoUserOverrideThenFacetIsOpen()
throws Exception {
recordServices.add(rm.newFacetField().setOrder(0).setFieldDataStoreCode("retentionRuleId_s")
.setTitle("Règles de conservations").setOrderResult(FacetOrderType.RELEVANCE).setOpenByDefault(true));
List<FacetVO> facets = searchPresenterService.getFacets(allFoldersAndDocuments, facetStatus);
assertThat(facets.get(0).isOpen()).isTrue();
}
@Test
public void givenFacetNotOpenByDefaultAndNoUserOverrideThenFacetIsNotOpen()
throws Exception {
recordServices.add(rm.newFacetField().setOrder(0).setFieldDataStoreCode("retentionRuleId_s")
.setTitle("Règles de conservations").setOrderResult(FacetOrderType.RELEVANCE).setOpenByDefault(false));
List<FacetVO> facets = searchPresenterService.getFacets(allFoldersAndDocuments, facetStatus);
assertThat(facets.get(0).isOpen()).isFalse();
}
@Test
public void givenFacetOpenByDefaultAndUserOverrideThenFacetIsClosed()
throws Exception {
Facet facet;
recordServices.add(facet = rm.newFacetField().setOrder(0).setFieldDataStoreCode("retentionRuleId_s")
.setTitle("Règles de conservations").setOrderResult(FacetOrderType.RELEVANCE).setOpenByDefault(true));
facetStatus.put(facet.getId(), false);
List<FacetVO> facets = searchPresenterService.getFacets(allFoldersAndDocuments, facetStatus);
assertThat(facets.get(0).isOpen()).isFalse();
}
@Test
public void givenFacetNotOpenByDefaultAndUserOverrideThenFacetIsOpen()
throws Exception {
Facet facet;
recordServices.add(facet = rm.newFacetField().setOrder(0).setFieldDataStoreCode("retentionRuleId_s")
.setTitle("Règles de conservations").setOrderResult(FacetOrderType.RELEVANCE).setOpenByDefault(false));
facetStatus.put(facet.getId(), true);
List<FacetVO> facets = searchPresenterService.getFacets(allFoldersAndDocuments, facetStatus);
assertThat(facets.get(0).isOpen()).isTrue();
}
// ----------------------------------------------------
// private Condition<? super FacetVO> dataStoreCode(final String expectedDataStoreCode) {
// return new Condition<FacetVO>() {
// @Override
// public boolean matches(FacetVO value) {
// assertThat(value.getDatastoreCode()).describedAs("datastoreCode").isEqualTo(expectedDataStoreCode);
// return true;
// }
// };
// }
private ExpectedFacetValue value(RetentionRule retentionRule) {
int count = (int) searchServices.getResultsCount(from(rm.folderSchemaType())
.where(rm.folder.retentionRule()).isEqualTo(retentionRule));
return new ExpectedFacetValue(retentionRule.getId(), retentionRule.getTitle(), -1);
}
private ExpectedFacetValue value(AdministrativeUnit unit) {
int count = (int) searchServices.getResultsCount(from(rm.folderSchemaType())
.where(rm.folder.administrativeUnit()).isEqualTo(unit));
return new ExpectedFacetValue(unit.getId(), unit.getTitle(), -1);
}
private ExpectedFacetValue value(DocumentType type) {
return new ExpectedFacetValue(type.getId(), type.getTitle(), -1);
}
private ExpectedFacetValue value(String expectedValue, String expectedLabel) {
return new ExpectedFacetValue(expectedValue, expectedLabel, -1);
}
private ExpectedFacetValue value(String expectedValue, String expectedLabel, int count) {
return new ExpectedFacetValue(expectedValue, expectedLabel, count);
}
private static class ExpectedFacetValue {
String value;
String label;
int count;
private ExpectedFacetValue(String value, String label, int count) {
this.value = value;
this.label = label;
this.count = count;
}
}
private Condition<? super FacetVO> values(final ExpectedFacetValue... expectedFacetValues) {
return new Condition<FacetVO>() {
@Override
public boolean matches(FacetVO value) {
List<String> facetValues = new ArrayList<>();
List<String> expectedFacetValuesCodes = new ArrayList<>();
for (FacetValueVO facetValueVO : value.getValues()) {
facetValues.add(facetValueVO.getValue());
}
for (ExpectedFacetValue facetValueVO : expectedFacetValues) {
expectedFacetValuesCodes.add(facetValueVO.value);
}
assertThat(facetValues).isEqualTo(expectedFacetValuesCodes);
for (int i = 0; i < expectedFacetValues.length; i++) {
FacetValueVO facetValue = value.getValues().get(i);
ExpectedFacetValue expectedFacetValue = expectedFacetValues[i];
assertThat(facetValue.getValue()).describedAs("facet value's value").isEqualTo(expectedFacetValue.value);
assertThat(facetValue.getLabel()).describedAs("facet value's label").isEqualTo(expectedFacetValue.label);
if (expectedFacetValue.count == -1) {
assertThat(facetValue.getCount()).describedAs("facet value's count").isGreaterThan(0);
} else {
assertThat(facetValue.getCount()).describedAs("facet value's count").isEqualTo(expectedFacetValue.count);
}
}
return true;
}
};
}
private Condition<? super FacetVO> label(final String expectedLabel) {
return new Condition<FacetVO>() {
@Override
public boolean matches(FacetVO value) {
assertThat(value.getLabel()).describedAs("title").isEqualTo(expectedLabel);
return true;
}
};
}
private void clearExistingFacets() {
for (Record facetRecord : searchServices.search(new LogicalSearchQuery(from(rm.facetSchemaType()).returnAll()))) {
recordServices.logicallyDelete(facetRecord, User.GOD);
recordServices.physicallyDelete(facetRecord, User.GOD);
}
}
}