package com.constellio.model.services.taxonomies;
import static com.constellio.app.modules.rm.constants.RMTaxonomies.ADMINISTRATIVE_UNITS;
import static com.constellio.app.modules.rm.constants.RMTaxonomies.CLASSIFICATION_PLAN;
import static com.constellio.model.entities.security.global.AuthorizationAddRequest.authorizationForUsers;
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.Collections;
import java.util.Comparator;
import java.util.List;
import org.assertj.core.api.Condition;
import org.assertj.core.api.ObjectAssert;
import org.joda.time.LocalDate;
import org.junit.Before;
import org.junit.Test;
import com.constellio.app.modules.rm.RMTestRecords;
import com.constellio.app.modules.rm.constants.RMTaxonomies;
import com.constellio.app.modules.rm.services.RMSchemasRecordsServices;
import com.constellio.app.modules.rm.services.decommissioning.DecommissioningService;
import com.constellio.app.modules.rm.wrappers.AdministrativeUnit;
import com.constellio.app.modules.rm.wrappers.Category;
import com.constellio.app.modules.rm.wrappers.ContainerRecord;
import com.constellio.app.modules.rm.wrappers.Document;
import com.constellio.app.modules.rm.wrappers.Folder;
import com.constellio.model.entities.records.Record;
import com.constellio.model.entities.records.Transaction;
import com.constellio.model.entities.records.wrappers.RecordWrapper;
import com.constellio.model.entities.records.wrappers.User;
import com.constellio.model.entities.schemas.Schemas;
import com.constellio.model.entities.security.Authorization;
import com.constellio.model.entities.security.global.AuthorizationDetails;
import com.constellio.model.entities.security.CustomizedAuthorizationsBehavior;
import com.constellio.model.entities.security.Role;
import com.constellio.model.entities.security.global.UserCredential;
import com.constellio.model.services.records.RecordServices;
import com.constellio.model.services.records.RecordServicesException;
import com.constellio.model.services.records.RecordUtils;
import com.constellio.model.services.schemas.MetadataSchemasManager;
import com.constellio.model.services.schemas.SchemaUtils;
import com.constellio.model.services.search.query.logical.LogicalSearchQuery;
import com.constellio.model.services.search.query.logical.condition.ConditionTemplate;
import com.constellio.model.services.security.AuthorizationsServices;
import com.constellio.model.services.users.UserServices;
import com.constellio.sdk.tests.ConstellioTest;
import com.constellio.sdk.tests.setups.Users;
public class TaxonomiesSearchServices_VisibleTreesWithoutChildrenDetectionAcceptTest extends ConstellioTest {
String subFolderId;
Users users = new Users();
User alice;
DecommissioningService decommissioningService;
TaxonomiesSearchServices service;
RMSchemasRecordsServices rm;
RMTestRecords records = new RMTestRecords(zeCollection);
MetadataSchemasManager manager;
RecordServices recordServices;
String document1InA16, document2InA16, document3InA16;
AuthorizationsServices authServices;
@Before
public void setUp()
throws Exception {
prepareSystem(
withZeCollection().withAllTest(users).withConstellioRMModule().withRMTest(records)
.withFoldersAndContainersOfEveryStatus()
);
inCollection(zeCollection).giveReadAccessTo(admin);
rm = new RMSchemasRecordsServices(zeCollection, getAppLayerFactory());
service = getModelLayerFactory().newTaxonomiesSearchService();
decommissioningService = new DecommissioningService(zeCollection, getAppLayerFactory());
recordServices = getModelLayerFactory().newRecordServices();
UserServices userServices = getModelLayerFactory().newUserServices();
UserCredential userCredential = userServices.getUserCredential(aliceWonderland);
userServices.addUserToCollection(userCredential, zeCollection);
alice = userServices.getUserInCollection(aliceWonderland, zeCollection);
manager = getModelLayerFactory().getMetadataSchemasManager();
DecommissioningService service = new DecommissioningService(zeCollection, getAppLayerFactory());
Folder subfolder = service.newSubFolderIn(records.getFolder_A16());
subfolder.setTitle("Sous-dossier");
recordServices.add(subfolder);
subFolderId = subfolder.getId();
List<String> documentsInA16 = getFolderDocuments(records.folder_A16);
document1InA16 = documentsInA16.get(0);
document2InA16 = documentsInA16.get(1);
document3InA16 = documentsInA16.get(2);
for (String documentId : getFolderDocuments(records.folder_A17)) {
Record document = recordServices.getDocumentById(documentId);
recordServices.logicallyDelete(document, User.GOD);
}
for (String documentId : getFolderDocuments(records.folder_A18)) {
Record document = recordServices.getDocumentById(documentId);
recordServices.logicallyDelete(document, User.GOD);
}
authServices = getModelLayerFactory().newAuthorizationsServices();
getDataLayerFactory().getDataLayerLogger().setPrintAllQueriesLongerThanMS(0);
}
private List<String> getFolderDocuments(String id) {
return getModelLayerFactory().newSearchServices().searchRecordIds(new LogicalSearchQuery()
.sortAsc(Schemas.TITLE).setCondition(from(rm.documentSchemaType()).where(rm.documentFolder()).isEqualTo(id)));
}
// @Test
// public void givenUserCreateNewTaxonomyAndAssignRecordsToItThenRecordsVisibleInTheTaxonomyTree()
// throws Exception {
//
// getModelLayerFactory().newRecordServices().update(alice.setCollectionReadAccess(true));
//
// ValueListServices services = new ValueListServices(getModelLayerFactory(), zeCollection);
// String type = services.createTaxonomy("ZE").getSchemaTypes().get(0);
//
// MetadataSchemaTypesBuilder types = manager.modifyTo(zeCollection);
// types.getSchema(Folder.SCHEMA_TYPE).create("ZeMetadata").defineTaxonomyRelationshipToType(types.getSchemaType(type));
// manager.saveUpdateSchemaTypes(types);
//
// HierarchicalValueListItem item = rm.newHierarchicalValueListItem(type + "_default");
//
// }
@Test
public void whenDakotaIsNavigatingATaxonomyWithVisibleRecordsThenSeesRecords()
throws Exception {
assertThatRootWhenUserNavigateUsingPlanTaxonomy(records.getDakota_managerInA_userInB())
.has(recordsInOrder(records.categoryId_X, records.categoryId_Z))
.has(recordsWithChildren(records.categoryId_X, records.categoryId_Z))
.has(numFoundAndListSize(2));
assertThatChildWhenUserNavigateUsingPlanTaxonomy(records.getDakota_managerInA_userInB(), records.categoryId_X)
.has(recordsInOrder(records.categoryId_X100))
.has(recordsWithChildren(records.categoryId_X100))
.has(numFoundAndListSize(1));
assertThatChildWhenUserNavigateUsingPlanTaxonomy(records.getDakota_managerInA_userInB(), records.categoryId_X100)
.has(recordsInOrder(records.categoryId_X110, records.categoryId_X120, records.folder_A16, records.folder_A17,
records.folder_A18, records.folder_B06, records.folder_B32))
.has(recordsWithChildren(records.categoryId_X110, records.categoryId_X120, records.folder_A16, records.folder_A17,
records.folder_A18, records.folder_B06, records.folder_B32))
.has(numFoundAndListSize(7));
assertThatChildWhenUserNavigateUsingPlanTaxonomy(records.getDakota_managerInA_userInB(), records.folder_A16)
.has(recordsInOrder(document1InA16, document2InA16, document3InA16, subFolderId))
.has(recordsWithChildren(subFolderId))
.has(numFoundAndListSize(4));
}
@Test
public void whenAdminIsNavigatingATaxonomyWithVisibleRecordsThenSeesRecords()
throws Exception {
assertThatRootWhenUserNavigateUsingPlanTaxonomy(records.getAdmin())
.has(recordsInOrder(records.categoryId_X, records.categoryId_Z))
.has(recordsWithChildren(records.categoryId_X, records.categoryId_Z))
.has(numFoundAndListSize(2));
assertThatChildWhenUserNavigateUsingPlanTaxonomy(records.getAdmin(), records.categoryId_X)
.has(recordsInOrder(records.categoryId_X100))
.has(recordsWithChildren(records.categoryId_X100))
.has(numFoundAndListSize(1));
assertThatChildWhenUserNavigateUsingPlanTaxonomy(records.getAdmin(), records.categoryId_X100)
.has(recordsInOrder("categoryId_X110", "categoryId_X120", "A16", "A17", "A18", "C06", "B06", "C32", "B32"))
.has(recordsWithChildren("categoryId_X110", "categoryId_X120", "A16", "A17", "A18", "C06", "B06", "C32", "B32"))
.has(numFoundAndListSize(9));
assertThatChildWhenUserNavigateUsingPlanTaxonomy(records.getAdmin(), records.categoryId_Z)
.has(recordsInOrder(records.categoryId_Z100))
.has(recordsWithChildren(records.categoryId_Z100))
.has(numFoundAndListSize(1));
assertThatChildWhenUserNavigateUsingPlanTaxonomy(records.getAdmin(), records.categoryId_Z100)
.has(recordsInOrder(records.categoryId_Z110, records.categoryId_Z120))
.has(recordsWithChildren(records.categoryId_Z110, records.categoryId_Z120))
.has(numFoundAndListSize(2));
assertThatChildWhenUserNavigateUsingPlanTaxonomy(records.getAdmin(), records.categoryId_Z110)
.has(recordsInOrder(records.categoryId_Z112))
.has(recordsWithChildren(records.categoryId_Z112))
.has(numFoundAndListSize(1));
}
@Test
public void whenAdminIsNavigatingATaxonomyWithVisibleRecordsAlwaysDisplayingConceptsWithReadAccessThenSeesRecordsAndAllConcepts()
throws Exception {
recordServices.add(rm.newCategoryWithId("category_Y_id").setCode("Y").setTitle("Ze category Y"));
TaxonomiesSearchOptions options = new TaxonomiesSearchOptions().setAlwaysReturnTaxonomyConceptsWithReadAccess(true);
assertThatRootWhenUserNavigateUsingPlanTaxonomy(records.getAdmin(), options)
.has(recordsInOrder(records.categoryId_X, "category_Y_id", records.categoryId_Z))
.has(recordsWithChildren(records.categoryId_X, records.categoryId_Z))
.has(numFoundAndListSize(3));
assertThatChildWhenUserNavigateUsingPlanTaxonomy(records.getAdmin(), records.categoryId_X, options)
.has(recordsInOrder(records.categoryId_X13, records.categoryId_X100))
.has(recordsWithChildren(records.categoryId_X100))
.has(numFoundAndListSize(2));
assertThatChildWhenUserNavigateUsingPlanTaxonomy(records.getAdmin(), records.categoryId_X100, options)
.has(recordsInOrder("categoryId_X110", "categoryId_X120", "A16", "A17", "A18", "C06", "B06", "C32", "B32"))
.has(recordsWithChildren("categoryId_X110", "categoryId_X120", "A16", "A17", "A18", "C06", "B06", "C32", "B32"))
.has(numFoundAndListSize(9));
assertThatChildWhenUserNavigateUsingPlanTaxonomy(records.getAdmin(), records.categoryId_Z, options)
.has(recordsInOrder(records.categoryId_Z100, records.categoryId_Z200, records.categoryId_Z999,
records.categoryId_ZE42))
.has(recordsWithChildren(records.categoryId_Z100))
.has(numFoundAndListSize(4));
assertThatChildWhenUserNavigateUsingPlanTaxonomy(records.getAdmin(), records.categoryId_Z100, options)
.has(recordsInOrder(records.categoryId_Z110, records.categoryId_Z120))
.has(recordsWithChildren(records.categoryId_Z110, records.categoryId_Z120))
.has(numFoundAndListSize(2));
assertThatChildWhenUserNavigateUsingPlanTaxonomy(records.getAdmin(), records.categoryId_Z110, options)
.has(recordsInOrder(records.categoryId_Z111, records.categoryId_Z112))
.has(recordsWithChildren(records.categoryId_Z112))
.has(numFoundAndListSize(2));
}
@Test
public void whenAdminIsNavigatingAdminUnitTaxonomyWithVisibleRecordsThenSeesRecords()
throws Exception {
TaxonomiesSearchOptions options = new TaxonomiesSearchOptions();
assertThatRootWhenUserNavigateUsingAdministrativeUnitsTaxonomy(records.getAdmin(), options)
.has(recordsInOrder(records.unitId_10, records.unitId_30))
.has(recordsWithChildren(records.unitId_10, records.unitId_30))
.has(numFoundAndListSize(2));
assertThatChildWhenUserNavigateUsingAdminUnitsTaxonomy(records.getAdmin(), records.unitId_12, options)
.has(recordsInOrder(records.unitId_12b))
.has(recordsWithChildren(records.unitId_12b))
.has(numFoundAndListSize(1));
assertThatChildWhenUserNavigateUsingAdminUnitsTaxonomy(records.getAdmin(), records.unitId_12b, options)
.has(recordsInOrder("B02", "B04", "B06", "B08", "B32"))
.has(recordsWithChildren("B02", "B04", "B06", "B08", "B32"))
.has(numFoundAndListSize(5));
}
@Test
public void whenUserIsNavigatingAdminUnitTaxonomyThenOnlySeeConceptsContainingAccessibleRecords()
throws Exception {
TaxonomiesSearchOptions options = new TaxonomiesSearchOptions();
User sasquatch = users.sasquatchIn(zeCollection);
User robin = users.robinIn(zeCollection);
User admin = users.adminIn(zeCollection);
authServices.add(authorizationForUsers(sasquatch).on("B06").givingReadAccess(), admin);
authServices.add(authorizationForUsers(sasquatch).on(records.unitId_20d).givingReadAccess(), admin);
authServices.add(authorizationForUsers(robin).on("B06").givingReadAccess(), admin);
authServices.add(authorizationForUsers(robin).on(records.unitId_12c).givingReadAccess(), admin);
authServices.add(authorizationForUsers(robin).on(records.unitId_30).givingReadAccess(), admin);
recordServices.refresh(robin);
recordServices.refresh(sasquatch);
waitForBatchProcess();
assertThat(robin.hasReadAccess().on(recordServices.getDocumentById("B06"))).isTrue();
assertThat(sasquatch.hasReadAccess().on(recordServices.getDocumentById("B06"))).isTrue();
//Sasquatch
assertThatRootWhenUserNavigateUsingAdministrativeUnitsTaxonomy(sasquatch, options)
.has(recordsInOrder(records.unitId_10))
.has(recordsWithChildren(records.unitId_10))
.has(numFoundAndListSize(1));
assertThatChildWhenUserNavigateUsingAdminUnitsTaxonomy(sasquatch, records.unitId_10, options)
.has(recordsInOrder(records.unitId_12))
.has(recordsWithChildren(records.unitId_12))
.has(numFoundAndListSize(1));
assertThatChildWhenUserNavigateUsingAdminUnitsTaxonomy(sasquatch, records.unitId_12, options)
.has(recordsInOrder(records.unitId_12b))
.has(recordsWithChildren(records.unitId_12b))
.has(numFoundAndListSize(1));
assertThatChildWhenUserNavigateUsingAdminUnitsTaxonomy(sasquatch, records.unitId_12b, options)
.has(recordsInOrder("B06"))
.has(recordsWithChildren("B06"))
.has(numFoundAndListSize(1));
//Robin
assertThatRootWhenUserNavigateUsingAdministrativeUnitsTaxonomy(robin, options)
.has(recordsInOrder(records.unitId_10, records.unitId_30))
.has(recordsWithChildren(records.unitId_10, records.unitId_30))
.has(numFoundAndListSize(2));
assertThatChildWhenUserNavigateUsingAdminUnitsTaxonomy(robin, records.unitId_10, options)
.has(recordsInOrder(records.unitId_12))
.has(recordsWithChildren(records.unitId_12))
.has(numFoundAndListSize(1));
assertThatChildWhenUserNavigateUsingAdminUnitsTaxonomy(robin, records.unitId_12, options)
.has(recordsInOrder(records.unitId_12b))
.has(recordsWithChildren(records.unitId_12b))
.has(numFoundAndListSize(1));
assertThatChildWhenUserNavigateUsingAdminUnitsTaxonomy(robin, records.unitId_12b, options)
.has(recordsInOrder("B06"))
.has(recordsWithChildren("B06"))
.has(numFoundAndListSize(1));
}
@Test
public void whenUserIsNavigatingAdminUnitTaxonomyAlwaysDisplayingConceptsWithReadAccessThenOnlySeeConceptsContainingAccessibleRecordsAndThoseWithReadAccess()
throws Exception {
getDataLayerFactory().getDataLayerLogger().setPrintAllQueriesLongerThanMS(0);
TaxonomiesSearchOptions options = new TaxonomiesSearchOptions().setAlwaysReturnTaxonomyConceptsWithReadAccess(true);
User sasquatch = users.sasquatchIn(zeCollection);
User robin = users.robinIn(zeCollection);
User admin = users.adminIn(zeCollection);
authServices.add(authorizationForUsers(sasquatch).on("B06").givingReadAccess(), admin);
authServices.add(authorizationForUsers(sasquatch).on(records.unitId_20d).givingReadAccess(), admin);
authServices.add(authorizationForUsers(robin).on("B06").givingReadAccess(), admin);
authServices.add(authorizationForUsers(robin).on(records.unitId_12c).givingReadAccess(), admin);
authServices.add(authorizationForUsers(robin).on(records.unitId_30).givingReadAccess(), admin);
recordServices.refresh(sasquatch);
recordServices.refresh(robin);
waitForBatchProcess();
//Sasquatch
assertThatRootWhenUserNavigateUsingAdministrativeUnitsTaxonomy(sasquatch, options)
.has(recordsInOrder(records.unitId_10, records.unitId_20))
.has(recordsWithChildren(records.unitId_10, records.unitId_20))
.has(numFoundAndListSize(2));
assertThatChildWhenUserNavigateUsingAdminUnitsTaxonomy(sasquatch, records.unitId_10, options)
.has(recordsInOrder(records.unitId_12))
.has(recordsWithChildren(records.unitId_12))
.has(numFoundAndListSize(1));
assertThatChildWhenUserNavigateUsingAdminUnitsTaxonomy(sasquatch, records.unitId_12, options)
.has(recordsInOrder(records.unitId_12b))
.has(recordsWithChildren(records.unitId_12b))
.has(numFoundAndListSize(1));
assertThatChildWhenUserNavigateUsingAdminUnitsTaxonomy(sasquatch, records.unitId_12b, options)
.has(recordsInOrder("B06"))
.has(recordsWithChildren("B06"))
.has(numFoundAndListSize(1));
assertThatChildWhenUserNavigateUsingAdminUnitsTaxonomy(sasquatch, records.unitId_12c, options)
.has(numFoundAndListSize(0));
//Robin
assertThatRootWhenUserNavigateUsingAdministrativeUnitsTaxonomy(robin, options)
.has(recordsInOrder(records.unitId_10, records.unitId_30))
.has(recordsWithChildren(records.unitId_10, records.unitId_30))
.has(numFoundAndListSize(2));
assertThatChildWhenUserNavigateUsingAdminUnitsTaxonomy(robin, records.unitId_10, options)
.has(recordsInOrder(records.unitId_12))
.has(recordsWithChildren(records.unitId_12))
.has(numFoundAndListSize(1));
assertThatChildWhenUserNavigateUsingAdminUnitsTaxonomy(robin, records.unitId_12, options)
.has(recordsInOrder(records.unitId_12b, records.unitId_12c))
.has(recordsWithChildren(records.unitId_12b))
.has(numFoundAndListSize(2));
assertThatChildWhenUserNavigateUsingAdminUnitsTaxonomy(robin, records.unitId_30, options)
.has(recordsInOrder(records.unitId_30c))
.has(recordsWithChildren(records.unitId_30c))
.has(numFoundAndListSize(1));
assertThatChildWhenUserNavigateUsingAdminUnitsTaxonomy(robin, records.unitId_12b, options)
.has(recordsInOrder("B06"))
.has(recordsWithChildren("B06"))
.has(numFoundAndListSize(1));
}
@Test
public void whenAdminIsNavigatingAdminUnityWithVisibleRecordsAlwaysDisplayingConceptsWithReadAccessThenSeesRecordsAndAllConcepts()
throws Exception {
TaxonomiesSearchOptions options = new TaxonomiesSearchOptions().setAlwaysReturnTaxonomyConceptsWithReadAccess(true);
assertThatRootWhenUserNavigateUsingAdministrativeUnitsTaxonomy(records.getAdmin(), options)
.has(recordsInOrder(records.unitId_10, records.unitId_20, records.unitId_30))
.has(recordsWithChildren(records.unitId_10, records.unitId_20, records.unitId_30))
.has(numFoundAndListSize(3));
assertThatChildWhenUserNavigateUsingAdminUnitsTaxonomy(records.getAdmin(), records.unitId_12, options)
.has(recordsInOrder(records.unitId_12b, records.unitId_12c))
.has(recordsWithChildren(records.unitId_12b))
.has(numFoundAndListSize(2));
assertThatChildWhenUserNavigateUsingAdminUnitsTaxonomy(records.getAdmin(), records.unitId_12b, options)
.has(recordsInOrder("B02", "B04", "B06", "B08", "B32"))
.has(recordsWithChildren("B02", "B04", "B06", "B08", "B32"))
.has(numFoundAndListSize(5));
}
@Test
public void whenNavigatingByIntervalThenGetGoodResults()
throws Exception {
assertThatRootWhenUserNavigateUsingPlanTaxonomy(records.getAdmin())
.has(recordsInOrder(records.categoryId_X, records.categoryId_Z))
.has(recordsWithChildren(records.categoryId_X, records.categoryId_Z))
.has(numFoundAndListSize(2));
assertThatRootWhenUserNavigateUsingPlanTaxonomy(records.getAdmin(), 0, 2)
.has(recordsInOrder(records.categoryId_X, records.categoryId_Z))
.has(recordsWithChildren(records.categoryId_X, records.categoryId_Z))
.has(numFoundAndListSize(2));
assertThatRootWhenUserNavigateUsingPlanTaxonomy(records.getAdmin(), 0, 1)
.has(recordsInOrder(records.categoryId_X))
.has(recordsWithChildren(records.categoryId_X))
.has(listSize(1)).has(numFound(2));
assertThatRootWhenUserNavigateUsingPlanTaxonomy(records.getAdmin(), 1, 1)
.has(recordsInOrder(records.categoryId_Z))
.has(recordsWithChildren(records.categoryId_Z))
.has(listSize(1)).has(numFound(2));
assertThatChildWhenUserNavigateUsingPlanTaxonomy(records.getAdmin(), records.categoryId_X100)
.has(recordsInOrder("categoryId_X110", "categoryId_X120", "A16", "A17", "A18", "C06", "B06", "C32", "B32"))
.has(recordsWithChildren("categoryId_X110", "categoryId_X120", "A16", "A17", "A18", "C06", "B06", "C32", "B32"))
.has(listSize(9)).has(numFound(9));
assertThatChildWhenUserNavigateUsingPlanTaxonomy(records.getAdmin(), records.categoryId_X100, 0, 10)
.has(recordsInOrder("categoryId_X110", "categoryId_X120", "A16", "A17", "A18", "C06", "B06", "C32", "B32"))
.has(recordsWithChildren("categoryId_X110", "categoryId_X120", "A16", "A17", "A18", "C06", "B06", "C32", "B32"))
.has(listSize(9)).has(numFound(9));
assertThatChildWhenUserNavigateUsingPlanTaxonomy(records.getAdmin(), records.categoryId_X100, 0, 7)
.has(recordsInOrder("categoryId_X110", "categoryId_X120", "A16", "A17", "A18", "C06", "B06"))
.has(recordsWithChildren("categoryId_X110", "categoryId_X120", "A16", "A17", "A18", "C06", "B06"))
.has(listSize(7)).has(numFound(9));
assertThatChildWhenUserNavigateUsingPlanTaxonomy(records.getAdmin(), records.categoryId_X100, 0, 3)
.has(recordsInOrder("categoryId_X110", "categoryId_X120", "A16"))
.has(recordsWithChildren("categoryId_X110", "categoryId_X120", "A16"))
.has(listSize(3)).has(numFound(9));
assertThatChildWhenUserNavigateUsingPlanTaxonomy(records.getAdmin(), records.categoryId_X100, 1, 4)
.has(recordsInOrder("categoryId_X120", "A16", "A17", "A18"))
.has(recordsWithChildren("categoryId_X120", "A16", "A17", "A18"))
.has(listSize(4)).has(numFound(9));
assertThatChildWhenUserNavigateUsingPlanTaxonomy(records.getAdmin(), records.folder_A16, 0, 5)
.has(recordsInOrder(document1InA16, document2InA16, document3InA16, subFolderId))
.has(recordsWithChildren(subFolderId))
.has(listSize(4)).has(numFound(4));
assertThatChildWhenUserNavigateUsingPlanTaxonomy(records.getAdmin(), records.folder_A16, 0, 1)
.has(recordsInOrder(document1InA16))
.has(noRecordsWithChildren())
.has(listSize(1)).has(numFound(4));
}
@Test
public void givenHugeClassificationPlanContainingMultipleFoldersThenValidSearchResponses()
throws Exception {
User admin = users.adminIn(zeCollection);
admin.setCollectionReadAccess(true);
List<Category> rootCategories = new ArrayList<>();
for (int i = 1; i <= 100; i++) {
String code = toTitle(i);
rootCategories.add(rm.newCategoryWithId(code).setCode(code).setTitle("Title " + toTitle((20000 - i)))
.setRetentionRules(asList(records.ruleId_1)));
}
Category category42 = rootCategories.get(41);
addRecordsInRandomOrder(rootCategories);
List<Category> childCategories = new ArrayList<>();
for (int i = 1; i <= 100; i++) {
String code = "42_" + toTitle(i);
childCategories.add(rm.newCategoryWithId(code).setRetentionRules(asList(records.ruleId_1))
.setParent(category42).setCode(code).setTitle("Title " + toTitle((20000 - i))));
}
Category category42_42 = childCategories.get(41);
addRecordsInRandomOrder(childCategories);
List<Folder> category42_42_folders = new ArrayList<>();
for (int i = 1; i <= 100; i++) {
category42_42_folders.add(newFolderInCategory(category42_42, "Folder " + toTitle(i)));
}
addRecordsInRandomOrder(category42_42_folders);
List<Folder> otherCategoriesFolder = new ArrayList<>();
for (Category category : rootCategories) {
if (!category.getId().equals(category42.getId())) {
otherCategoriesFolder.add(newFolderInCategory(category, "A folder"));
}
}
for (Category category : childCategories) {
if (!category.getId().equals(category42_42.getId())) {
otherCategoriesFolder.add(newFolderInCategory(category, "A folder"));
}
}
addRecordsInRandomOrder(otherCategoriesFolder);
for (int i = 0; i < rootCategories.size() - 25; i += 25) {
LinkableTaxonomySearchResponse response = service.getVisibleRootConceptResponse(
admin, zeCollection, CLASSIFICATION_PLAN, new TaxonomiesSearchOptions().setStartRow(i).setRows(25), null);
List<String> expectedIds = new RecordUtils().toWrappedRecordIdsList(rootCategories.subList(i, i + 25));
assertThat(response.getRecords()).extracting("id").isEqualTo(expectedIds);
}
for (int i = 0; i < childCategories.size() - 25; i += 25) {
LinkableTaxonomySearchResponse response = service.getVisibleChildConceptResponse(admin, CLASSIFICATION_PLAN,
category42.getWrappedRecord(), new TaxonomiesSearchOptions().setStartRow(i).setRows(25));
List<String> expectedIds = new RecordUtils().toWrappedRecordIdsList(childCategories.subList(i, i + 25));
assertThat(response.getRecords()).extracting("id").isEqualTo(expectedIds);
}
for (int i = 0; i < category42_42_folders.size() - 25; i += 25) {
LinkableTaxonomySearchResponse response = service.getVisibleChildConceptResponse(admin, CLASSIFICATION_PLAN,
category42_42.getWrappedRecord(), new TaxonomiesSearchOptions().setStartRow(i).setRows(25));
List<String> expectedIds = new RecordUtils().toWrappedRecordIdsList(category42_42_folders.subList(i, i + 25));
assertThat(response.getNumFound()).isEqualTo(category42_42_folders.size());
assertThat(response.getRecords()).extracting("id").isEqualTo(expectedIds);
}
}
@Test
public void givenHugeAdministrativeUnitsContainingMultipleFoldersThenValidSearchResponses()
throws Exception {
User admin = users.adminIn(zeCollection);
admin.setCollectionReadAccess(true);
List<AdministrativeUnit> rootAdministrativeUnits = new ArrayList<>();
for (int i = 1; i <= 100; i++) {
String code = toTitle(1000 + i);
rootAdministrativeUnits.add(rm.newAdministrativeUnitWithId(code).setCode(code)
.setTitle("Title " + toTitle(20000 - i)));
}
AdministrativeUnit unit42 = rootAdministrativeUnits.get(41);
addRecordsInRandomOrder(rootAdministrativeUnits);
List<AdministrativeUnit> childAdministrativeUnits = new ArrayList<>();
for (int i = 1; i <= 100; i++) {
String code = "42_" + toTitle(i);
childAdministrativeUnits.add(rm.newAdministrativeUnitWithId(code)
.setParent(unit42).setCode(code).setTitle("Title " + toTitle((20000 - i))));
}
AdministrativeUnit unit42_666 = childAdministrativeUnits.get(41);
addRecordsInRandomOrder(childAdministrativeUnits);
List<Folder> unit42_666_folders = new ArrayList<>();
for (int i = 1; i <= 100; i++) {
unit42_666_folders.add(newFolderInUnit(unit42_666, "Folder " + toTitle(i)));
}
addRecordsInRandomOrder(unit42_666_folders);
List<Folder> otherUnitsFolder = new ArrayList<>();
for (AdministrativeUnit unit : rootAdministrativeUnits) {
if (!unit.getId().equals(unit42.getId())) {
otherUnitsFolder.add(newFolderInUnit(unit, "A folder"));
}
}
for (AdministrativeUnit unit : childAdministrativeUnits) {
if (!unit.getId().equals(unit42_666.getId())) {
otherUnitsFolder.add(newFolderInUnit(unit, "A folder"));
}
}
addRecordsInRandomOrder(otherUnitsFolder);
for (int i = 0; i < rootAdministrativeUnits.size() - 25; i += 25) {
LinkableTaxonomySearchResponse response = service.getVisibleRootConceptResponse(
admin, zeCollection, ADMINISTRATIVE_UNITS, new TaxonomiesSearchOptions().setStartRow(2 + i).setRows(25),
null);
List<String> expectedIds = new RecordUtils().toWrappedRecordIdsList(rootAdministrativeUnits.subList(i, i + 25));
assertThat(response.getRecords()).extracting("id").isEqualTo(expectedIds);
}
for (int i = 0; i < childAdministrativeUnits.size() - 25; i += 25) {
LinkableTaxonomySearchResponse response = service.getVisibleChildConceptResponse(admin, ADMINISTRATIVE_UNITS,
unit42.getWrappedRecord(), new TaxonomiesSearchOptions().setStartRow(i).setRows(25));
List<String> expectedIds = new RecordUtils().toWrappedRecordIdsList(childAdministrativeUnits.subList(i, i + 25));
assertThat(response.getRecords()).extracting("id").isEqualTo(expectedIds);
}
for (int i = 0; i < unit42_666_folders.size() - 25; i += 25) {
LinkableTaxonomySearchResponse response = service.getVisibleChildConceptResponse(admin, ADMINISTRATIVE_UNITS,
unit42_666.getWrappedRecord(), new TaxonomiesSearchOptions().setStartRow(i).setRows(25));
List<String> expectedIds = new RecordUtils().toWrappedRecordIdsList(unit42_666_folders.subList(i, i + 25));
assertThat(response.getNumFound()).isEqualTo(unit42_666_folders.size());
assertThat(response.getRecords()).extracting("id").isEqualTo(expectedIds);
}
}
private Folder newFolderInCategory(Category category, String title) {
return rm.newFolder().setCategoryEntered(category).setTitle(title).setOpenDate(new LocalDate())
.setRetentionRuleEntered(records.ruleId_1).setAdministrativeUnitEntered(records.unitId_10a);
}
private Folder newFolderInUnit(AdministrativeUnit unit, String title) {
return rm.newFolder().setCategoryEntered(records.categoryId_X100).setTitle(title).setOpenDate(new LocalDate())
.setRetentionRuleEntered(records.ruleId_1).setAdministrativeUnitEntered(unit);
}
private String toTitle(int i) {
String value = "0000" + i;
return value.substring(value.length() - 5, value.length());
}
// -------
private void addRecordsInRandomOrder(List<? extends RecordWrapper> records) {
List<RecordWrapper> copy = new ArrayList<>(records);
RecordWrapper addedBefore = copy.remove(23);
RecordWrapper addedAfter = copy.remove(24);
try {
recordServices.add(addedBefore);
Transaction transaction = new Transaction();
transaction.addUpdate(new RecordUtils().unwrap(copy));
recordServices.execute(transaction);
recordServices.add(addedAfter);
} catch (RecordServicesException e) {
throw new RuntimeException(e);
}
}
private Condition<? super LinkableTaxonomySearchResponse> numFoundAndListSize(final int expectedCount) {
return new Condition<LinkableTaxonomySearchResponse>() {
@Override
public boolean matches(LinkableTaxonomySearchResponse value) {
assertThat(value.getNumFound()).describedAs(description().toString() + " NumFound").isEqualTo(expectedCount);
assertThat(value.getRecords().size()).describedAs(description().toString() + " records list size")
.isEqualTo(expectedCount);
return true;
}
};
}
private Condition<? super LinkableTaxonomySearchResponse> numFound(final int expectedCount) {
return new Condition<LinkableTaxonomySearchResponse>() {
@Override
public boolean matches(LinkableTaxonomySearchResponse value) {
assertThat(value.getNumFound()).describedAs("NumFound").isEqualTo(expectedCount);
return true;
}
};
}
private Condition<? super LinkableTaxonomySearchResponse> listSize(final int expectedCount) {
return new Condition<LinkableTaxonomySearchResponse>() {
@Override
public boolean matches(LinkableTaxonomySearchResponse value) {
assertThat(value.getRecords().size()).describedAs("records list size").isEqualTo(expectedCount);
return true;
}
};
}
private Condition<? super LinkableTaxonomySearchResponse> recordsInOrder(String... ids) {
final List<String> idsList = asList(ids);
return new Condition<LinkableTaxonomySearchResponse>() {
@Override
public boolean matches(LinkableTaxonomySearchResponse response) {
List<String> valueIds = new ArrayList<>();
for (TaxonomySearchRecord value : response.getRecords()) {
valueIds.add(value.getRecord().getId());
}
assertThat(valueIds).describedAs(description().toString()).isEqualTo(idsList);
return true;
}
};
}
private Condition<? super LinkableTaxonomySearchResponse> noRecordsWithChildren() {
return recordsWithChildren();
}
private Condition<? super LinkableTaxonomySearchResponse> recordsWithChildren(String... ids) {
final List<String> idsList = asList(ids);
return new Condition<LinkableTaxonomySearchResponse>() {
@Override
public boolean matches(LinkableTaxonomySearchResponse response) {
List<String> valueIds = new ArrayList<>();
for (TaxonomySearchRecord value : response.getRecords()) {
if (value.hasChildren()) {
valueIds.add(value.getRecord().getId());
}
}
assertThat(valueIds).describedAs(description().toString()).isEqualTo(idsList);
return true;
}
};
}
private Condition<? super List<TaxonomySearchRecord>> validOrder() {
return new Condition<List<TaxonomySearchRecord>>() {
@Override
public boolean matches(List<TaxonomySearchRecord> values) {
List<Record> actualRecords = new ArrayList<>();
List<Record> recordsInExpectedOrder = new ArrayList<>();
for (TaxonomySearchRecord value : values) {
actualRecords.add(value.getRecord());
recordsInExpectedOrder.add(value.getRecord());
}
final List<String> typesOrder = asList(Category.SCHEMA_TYPE, AdministrativeUnit.SCHEMA_TYPE,
ContainerRecord.SCHEMA_TYPE, Folder.SCHEMA_TYPE, Document.SCHEMA_TYPE);
Collections.sort(recordsInExpectedOrder, new Comparator<Record>() {
@Override
public int compare(Record r1, Record r2) {
int r1TypeIndex = typesOrder.indexOf(new SchemaUtils().getSchemaTypeCode(r1.getSchemaCode()));
int r2TypeIndex = typesOrder.indexOf(new SchemaUtils().getSchemaTypeCode(r2.getSchemaCode()));
if (r1TypeIndex != r2TypeIndex) {
return new Integer(r1TypeIndex).compareTo(r2TypeIndex);
} else {
String code1 = r1.get(Schemas.CODE);
String code2 = r2.get(Schemas.CODE);
if (code1 != null && code2 != null) {
return code1.compareTo(code2);
} else if (code1 != null && code2 == null) {
return 1;
} else if (code1 == null && code2 != null) {
return -1;
} else {
String title1 = r1.get(Schemas.TITLE);
String title2 = r2.get(Schemas.TITLE);
if (title1 == null) {
return -1;
} else {
return title1.compareTo(title2);
}
}
}
}
});
assertThat(actualRecords).isEqualTo(recordsInExpectedOrder);
return true;
}
};
}
private Condition<? super List<TaxonomySearchRecord>> unlinkable(final String... ids) {
return new Condition<List<TaxonomySearchRecord>>() {
@Override
public boolean matches(List<TaxonomySearchRecord> records) {
for (String id : ids) {
TaxonomySearchRecord foundRecord = null;
for (TaxonomySearchRecord record : records) {
if (id.equals(record.getRecord().getId())) {
if (foundRecord != null) {
throw new RuntimeException("Same record found twice");
}
foundRecord = record;
}
}
if (foundRecord == null) {
throw new RuntimeException("Record not found : " + id);
} else {
assertThat(foundRecord.isLinkable()).isFalse();
}
}
return true;
}
};
}
private Condition<? super List<TaxonomySearchRecord>> linkable(final String... ids) {
return new Condition<List<TaxonomySearchRecord>>() {
@Override
public boolean matches(List<TaxonomySearchRecord> records) {
for (String id : ids) {
TaxonomySearchRecord foundRecord = null;
for (TaxonomySearchRecord record : records) {
if (id.equals(record.getRecord().getId())) {
if (foundRecord != null) {
throw new RuntimeException("Same record found twice");
}
foundRecord = record;
}
}
if (foundRecord == null) {
throw new RuntimeException("Record not found : " + id);
} else {
assertThat(foundRecord.isLinkable()).isTrue();
}
}
return true;
}
};
}
private void givenUserHasReadAccessTo(String... ids) {
for (String id : ids) {
getModelLayerFactory().newAuthorizationsServices().add(authorizationForUsers(alice).on(id).givingReadAccess());
}
getModelLayerFactory().getBatchProcessesManager().waitUntilAllFinished();
alice = getModelLayerFactory().newUserServices().getUserInCollection(aliceWonderland, zeCollection);
}
private ConditionTemplate withoutFilters = null;
private ObjectAssert<LinkableTaxonomySearchResponse> assertThatRootWhenUserNavigateUsingPlanTaxonomy(User user) {
return assertThatRootWhenUserNavigateUsingPlanTaxonomy(user, 0, 10000);
}
private ObjectAssert<LinkableTaxonomySearchResponse> assertThatRootWhenUserNavigateUsingPlanTaxonomy(User user, int start,
int rows) {
LinkableTaxonomySearchResponse response = service.getVisibleRootConceptResponse(
user, zeCollection, CLASSIFICATION_PLAN,
new TaxonomiesSearchOptions().setStartRow(start).setRows(rows).setHasChildrenFlagCalculated(false), null);
if (rows == 10000) {
assertThat(response.getNumFound()).isEqualTo(response.getRecords().size());
}
return assertThat(response);
}
private ObjectAssert<LinkableTaxonomySearchResponse> assertThatRootWhenUserNavigateUsingPlanTaxonomy(User user,
TaxonomiesSearchOptions options) {
LinkableTaxonomySearchResponse response = service.getVisibleRootConceptResponse(
user, zeCollection, CLASSIFICATION_PLAN, options, null);
options.setHasChildrenFlagCalculated(false);
if (options.getRows() == 10000) {
assertThat(response.getNumFound()).isEqualTo(response.getRecords().size());
}
return assertThat(response);
}
private ObjectAssert<LinkableTaxonomySearchResponse> assertThatRootWhenUserNavigateUsingAdministrativeUnitsTaxonomy(User user,
TaxonomiesSearchOptions options) {
LinkableTaxonomySearchResponse response = service.getVisibleRootConceptResponse(
user, zeCollection, RMTaxonomies.ADMINISTRATIVE_UNITS, options, null);
options.setHasChildrenFlagCalculated(false);
if (options.getRows() == 10000) {
assertThat(response.getNumFound()).isEqualTo(response.getRecords().size());
}
return assertThat(response);
}
private ObjectAssert<LinkableTaxonomySearchResponse> assertThatChildWhenUserNavigateUsingPlanTaxonomy(User user,
String category) {
return assertThatChildWhenUserNavigateUsingPlanTaxonomy(user, category, 0, 10000);
}
private ObjectAssert<LinkableTaxonomySearchResponse> assertThatChildWhenUserNavigateUsingPlanTaxonomy(User user,
String category,
int start, int rows) {
Record inRecord = getModelLayerFactory().newRecordServices().getDocumentById(category);
LinkableTaxonomySearchResponse response = service.getVisibleChildConceptResponse(user, CLASSIFICATION_PLAN, inRecord,
new TaxonomiesSearchOptions().setStartRow(start).setRows(rows).setHasChildrenFlagCalculated(false));
if (rows == 10000) {
assertThat(response.getNumFound()).isEqualTo(response.getRecords().size());
}
return assertThat(response);
}
private ObjectAssert<LinkableTaxonomySearchResponse> assertThatChildWhenUserNavigateUsingPlanTaxonomy(User user,
String category, TaxonomiesSearchOptions options) {
options.setHasChildrenFlagCalculated(false);
Record inRecord = getModelLayerFactory().newRecordServices().getDocumentById(category);
LinkableTaxonomySearchResponse response = service
.getVisibleChildConceptResponse(user, CLASSIFICATION_PLAN, inRecord, options);
if (options.getRows() == 10000) {
assertThat(response.getNumFound()).isEqualTo(response.getRecords().size());
}
return assertThat(response);
}
private ObjectAssert<LinkableTaxonomySearchResponse> assertThatChildWhenUserNavigateUsingAdminUnitsTaxonomy(User user,
String category, TaxonomiesSearchOptions options) {
options.setHasChildrenFlagCalculated(false);
Record inRecord = getModelLayerFactory().newRecordServices().getDocumentById(category);
LinkableTaxonomySearchResponse response = service
.getVisibleChildConceptResponse(user, RMTaxonomies.ADMINISTRATIVE_UNITS, inRecord, options);
if (options.getRows() == 10000) {
assertThat(response.getNumFound()).isEqualTo(response.getRecords().size());
}
return assertThat(response);
}
}