package com.constellio.app.services.trash;
import static com.constellio.model.entities.security.global.AuthorizationAddRequest.authorizationForUsers;
import static com.constellio.sdk.tests.TestUtils.assertThatRecord;
import static java.util.Arrays.asList;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.Assert.fail;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
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.services.RMSchemasRecordsServices;
import com.constellio.app.modules.rm.wrappers.Cart;
import com.constellio.app.modules.rm.wrappers.Category;
import com.constellio.app.modules.rm.wrappers.Document;
import com.constellio.app.modules.rm.wrappers.Folder;
import com.constellio.app.modules.tasks.model.wrappers.Task;
import com.constellio.app.modules.tasks.services.TasksSchemasRecordsServices;
import com.constellio.data.utils.TimeProvider;
import com.constellio.model.entities.records.Record;
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.global.AuthorizationAddRequest;
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.RecordServicesRuntimeException.NoSuchRecordWithId;
import com.constellio.model.services.search.SearchServices;
import com.constellio.model.services.search.query.logical.LogicalSearchQuery;
import com.constellio.model.services.security.AuthorizationsServices;
import com.constellio.model.services.trash.TrashServices;
import com.constellio.model.services.users.UserCredentialsManager;
import com.constellio.model.services.users.UserServices;
import com.constellio.sdk.tests.ConstellioTest;
import com.constellio.sdk.tests.setups.Users;
public class TrashServicesAcceptanceTest extends ConstellioTest {
TrashServices trashServices;
Users users = new Users();
RMTestRecords records = new RMTestRecords(zeCollection);
private RecordServices recordServices;
private String folderDeletedLogicallyId, documentDeletedLogicallyId, categoryDeletedLogicallyId,
documentInADeletedFolder, documentInADeletedFolderTitle;
User admin;
private SearchServices searchServices;
private Task task;
private RMSchemasRecordsServices rm;
@Before
public void setUp()
throws Exception {
prepareSystem(
withZeCollection().withConstellioRMModule().withAllTestUsers().withRMTest(records)
.withFoldersAndContainersOfEveryStatus().withDocumentsHavingContent(),
withCollection(businessCollection).withTasksModule().withAllTestUsers()
);
recordServices = getModelLayerFactory().newRecordServices();
users.setUp(getModelLayerFactory().newUserServices());
trashServices = new TrashServices(getAppLayerFactory().getModelLayerFactory(), zeCollection);
admin = users.adminIn(zeCollection);
searchServices = getModelLayerFactory().newSearchServices();
rm = new RMSchemasRecordsServices(zeCollection, getAppLayerFactory());
initTests();
}
private void initTests()
throws RecordServicesException {
deleteLogicallyAFolderADocumentAndACategory();
deleteTaskFromBusinessCollection();
deleteUserChuck();
deleteCartLogically();
}
private void deleteCartLogically()
throws RecordServicesException {
Cart cart = rm.newCart();
User adminInZCollection = users.adminIn(zeCollection);
recordServices.add(cart.setOwner(adminInZCollection).setTitle("zCart"));
recordServices.logicallyDelete(cart.getWrappedRecord(), adminInZCollection);
}
private void deleteUserChuck() {
UserServices userServices = getModelLayerFactory()
.newUserServices();
UserCredential chuck = users.chuckNorris();
userServices.removeUserCredentialAndUser(chuck);
}
private void deleteTaskFromBusinessCollection()
throws RecordServicesException {
TasksSchemasRecordsServices taskSchemas = new TasksSchemasRecordsServices(businessCollection, getAppLayerFactory());
task = taskSchemas.newTask().setTitle("title");
recordServices.add(task);
User adminInBusiness = users.adminIn(businessCollection);
AuthorizationsServices authorizationService = getModelLayerFactory().newAuthorizationsServices();
authorizationService.add(authorizationForUsers(adminInBusiness).on(task).giving("d"));
recordServices.logicallyDelete(task.getWrappedRecord(), null);
}
private void deleteLogicallyAFolderADocumentAndACategory()
throws RecordServicesException {
LocalDateTime now;
givenTimeIs(now = TimeProvider.getLocalDateTime());
User adminUser = users.adminIn(zeCollection);
Folder folderA1 = records.getFolder_A01();
folderDeletedLogicallyId = folderA1.getId();
Document doc = rm.newDocument().setFolder(folderA1).setTitle("zDoc");
recordServices.add(doc);
documentInADeletedFolder = doc.getId();
documentInADeletedFolderTitle = doc.getTitle();
recordServices.logicallyDelete(folderA1.getWrappedRecord(), adminUser);
Category category = records.getCategory_X13();
categoryDeletedLogicallyId = category.getId();
recordServices.logicallyDelete(category.getWrappedRecord(), adminUser);
givenTimeIs(now.plusDays(1));
Document document = records.getDocumentWithContent_A49();
documentDeletedLogicallyId = document.getId();
recordServices.logicallyDelete(document.getWrappedRecord(), adminUser);
recordServices.add(folderA1.set(Schemas.ERROR_ON_PHYSICAL_DELETION.getLocalCode(), true));
}
@Test
public void whenGetTrashRecordsQueryForTypeThenOk()
throws Exception {
whenGetTrashRecordsQueryForFoldersTypeThenOk();
whenGetTrashRecordsQueryForDocumentsTypeThenOk();
whenGetTrashRecordsQueryForCategoryTypeThenOk();
}
private void whenGetTrashRecordsQueryForCategoryTypeThenOk() {
LogicalSearchQuery query = trashServices
.getTrashRecordsQueryForType(Folder.SCHEMA_TYPE, admin);
List<String> recordIds = getQueryResultsIds(query);
assertThat(recordIds).contains(folderDeletedLogicallyId);
assertThat(recordIds).doesNotContain(documentDeletedLogicallyId, categoryDeletedLogicallyId);
}
private List<String> getQueryResultsIds(LogicalSearchQuery query) {
List<Record> result = searchServices.search(query);
List<String> returnList = new ArrayList<>();
for (Record record : result) {
returnList.add(record.getId());
}
return returnList;
}
private void whenGetTrashRecordsQueryForDocumentsTypeThenOk() {
LogicalSearchQuery query = trashServices
.getTrashRecordsQueryForType(Document.SCHEMA_TYPE, admin);
List<String> recordIds = getQueryResultsIds(query);
assertThat(recordIds).contains(documentDeletedLogicallyId);
assertThat(recordIds).doesNotContain(folderDeletedLogicallyId, categoryDeletedLogicallyId);
}
private void whenGetTrashRecordsQueryForFoldersTypeThenOk() {
LogicalSearchQuery query = trashServices
.getTrashRecordsQueryForType(Category.SCHEMA_TYPE, admin);
List<String> recordIds = getQueryResultsIds(query);
assertThat(recordIds).contains(categoryDeletedLogicallyId);
assertThat(recordIds).doesNotContain(documentDeletedLogicallyId, folderDeletedLogicallyId);
}
@Test
public void whenGetTrashRecordsQueryForCollectionThenOk()
throws Exception {
LogicalSearchQuery query = trashServices
.getTrashRecordsQueryForCollection(zeCollection, admin);
List<String> recordIds = getQueryResultsIds(query);
assertThat(recordIds).contains(categoryDeletedLogicallyId, documentDeletedLogicallyId, folderDeletedLogicallyId);
assertThat(recordIds).doesNotContain(task.getId());
}
@Test
public void whenGetTypesWithLogicallyDeletedRecordsThenOk()
throws Exception {
Set<String> types = trashServices.getTypesWithLogicallyDeletedRecords(zeCollection, admin);
assertThat(types).containsOnly(Folder.SCHEMA_TYPE, Document.SCHEMA_TYPE, Category.SCHEMA_TYPE);
}
@Test
public void whenGetLogicallyDeletedRecordsCountThenOk()
throws Exception {
long count = trashServices.getLogicallyDeletedRecordsCount(zeCollection, admin);
assertThat(count).isEqualTo(8);
}
@Test
public void givenRestorableRecordWhenRestoreSelectionThenOk()
throws Exception {
List<String> notRestored = trashServices.restoreSelection(new HashSet<>(asList(folderDeletedLogicallyId)), admin);
assertThat(notRestored).isEmpty();
Record folder = recordServices.getDocumentById(folderDeletedLogicallyId);
assertThatRecord(folder).hasMetadataValue(Schemas.LOGICALLY_DELETED_STATUS, false);
assertThatRecord(folder).hasMetadataValue(Schemas.LOGICALLY_DELETED_ON, null);
}
@Test
public void givenNonRestorableRecordWhenRestoreSelectionThenRecordNotRestored()
throws Exception {
List<String> notRestored = trashServices.restoreSelection(new HashSet<>(asList(documentInADeletedFolder)), admin);
assertThat(notRestored).containsOnly(documentInADeletedFolderTitle);
Record doc = recordServices.getDocumentById(documentInADeletedFolder);
assertThatRecord(doc).hasMetadataValue(Schemas.LOGICALLY_DELETED_STATUS, true);
}
@Test
public void givenDeletableRecordWhenDeleteSelectionThenOk()
throws Exception {
trashServices.deleteSelection(new HashSet<>(asList(documentInADeletedFolder)), admin);
try {
recordServices.getDocumentById(documentInADeletedFolder);
fail("was not deleted physically");
} catch (NoSuchRecordWithId e) {
//OK
}
}
@Test
public void givenNonDeletableRecordWhenDeleteSelectionThenNotDeleted()
throws Exception {
//TODO and add another test with problematic delete
trashServices.deleteSelection(new HashSet<>(asList(folderDeletedLogicallyId)), admin);
try {
recordServices.getDocumentById(folderDeletedLogicallyId);
fail("was not deleted physically");
} catch (NoSuchRecordWithId e) {
//OK
}
}
}