package com.constellio.model.services.records;
import static com.constellio.model.entities.schemas.Schemas.TITLE;
import static com.constellio.model.entities.security.global.AuthorizationAddRequest.authorizationForUsers;
import static com.constellio.model.entities.security.global.AuthorizationModificationRequest.modifyAuthorizationOnRecord;
import static com.constellio.model.services.records.RecordPhysicalDeleteOptions.PhysicalDeleteTaxonomyRecordsBehavior.PHYSICALLY_DELETE_THEM;
import static com.constellio.model.services.records.RecordPhysicalDeleteOptions.PhysicalDeleteTaxonomyRecordsBehavior.PHYSICALLY_DELETE_THEM_ONLY_IF_PRINCIPAL_TAXONOMY;
import static com.constellio.sdk.tests.TestUtils.assertThatRecord;
import static com.constellio.sdk.tests.TestUtils.idsArray;
import static com.constellio.sdk.tests.TestUtils.recordsIds;
import static java.util.Arrays.asList;
import static junit.framework.Assert.fail;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.spy;
import java.util.List;
import org.assertj.core.api.Condition;
import org.junit.Before;
import org.junit.Test;
import com.carrotsearch.junitbenchmarks.annotation.BenchmarkHistoryChart;
import com.carrotsearch.junitbenchmarks.annotation.LabelType;
import com.constellio.data.frameworks.extensions.ExtensionBooleanResult;
import com.constellio.model.entities.records.Record;
import com.constellio.model.entities.records.Transaction;
import com.constellio.model.entities.records.wrappers.User;
import com.constellio.model.entities.schemas.Metadata;
import com.constellio.model.entities.schemas.MetadataSchema;
import com.constellio.model.entities.schemas.MetadataSchemaType;
import com.constellio.model.entities.schemas.Schemas;
import com.constellio.model.extensions.ModelLayerCollectionExtensions;
import com.constellio.model.extensions.behaviors.RecordExtension;
import com.constellio.model.extensions.events.records.RecordLogicalDeletionValidationEvent;
import com.constellio.model.extensions.events.records.RecordPhysicalDeletionValidationEvent;
import com.constellio.model.services.collections.CollectionsListManager;
import com.constellio.model.services.records.RecordDeleteServicesRuntimeException.RecordDeleteServicesRuntimeException_CannotTotallyDeleteSchemaType;
import com.constellio.model.services.records.RecordDeleteServicesRuntimeException.RecordServicesRuntimeException_CannotPhysicallyDeleteRecord_CannotSetNullOnRecords;
import com.constellio.model.services.records.RecordLogicalDeleteOptions.LogicallyDeleteTaxonomyRecordsBehavior;
import com.constellio.model.services.records.RecordServicesRuntimeException.NoSuchRecordWithId;
import com.constellio.model.services.records.RecordServicesRuntimeException.RecordServicesRuntimeException_CannotLogicallyDeleteRecord;
import com.constellio.model.services.records.RecordServicesRuntimeException.RecordServicesRuntimeException_CannotPhysicallyDeleteRecord;
import com.constellio.model.services.records.RecordServicesRuntimeException.RecordServicesRuntimeException_CannotRestoreRecord;
import com.constellio.model.services.schemas.MetadataSchemaTypesAlteration;
import com.constellio.model.services.schemas.MetadataSchemasManager;
import com.constellio.model.services.schemas.MetadataSchemasManagerException.OptimisticLocking;
import com.constellio.model.services.schemas.builders.MetadataSchemaBuilder;
import com.constellio.model.services.schemas.builders.MetadataSchemaTypeBuilder;
import com.constellio.model.services.schemas.builders.MetadataSchemaTypesBuilder;
import com.constellio.model.services.search.SearchServices;
import com.constellio.model.services.search.StatusFilter;
import com.constellio.model.services.search.query.logical.LogicalSearchQuery;
import com.constellio.model.services.search.query.logical.LogicalSearchQueryOperators;
import com.constellio.model.services.security.AuthorizationsServices;
import com.constellio.model.services.security.SecurityAcceptanceTestSetup;
import com.constellio.model.services.security.SecurityAcceptanceTestSetup.FolderSchema;
import com.constellio.model.services.security.SecurityAcceptanceTestSetup.Records;
import com.constellio.model.services.security.roles.RolesManager;
import com.constellio.model.services.taxonomies.TaxonomiesManager;
import com.constellio.sdk.tests.ConstellioTest;
import com.constellio.sdk.tests.TestRecord;
import com.constellio.sdk.tests.schemas.MetadataSchemaTypesConfigurator;
import com.constellio.sdk.tests.setups.Users;
public class RecordsDeleteAcceptTest extends ConstellioTest {
RecordDeleteServices recordDeleteServices;
SecurityAcceptanceTestSetup schemas = new SecurityAcceptanceTestSetup(zeCollection);
FolderSchema folderSchema = schemas.new FolderSchema();
MetadataSchemasManager schemasManager;
SearchServices searchServices;
RecordServicesImpl recordServices;
TaxonomiesManager taxonomiesManager;
CollectionsListManager collectionsListManager;
AuthorizationsServices authorizationsServices;
RecordPhysicalDeleteOptions withMostReferencesRemoved;
RecordPhysicalDeleteOptions withMostReferencesRemovedPhysicallyDeletingRecords;
RecordPhysicalDeleteOptions withMostReferencesRemovedPhysicallyDeletingRecordsIfPrincipalTaxonomy;
RecordLogicalDeleteOptions logicallyDeletingRecordsIfPrincipalTaxonomy, logicallyDeletingRecords, keepingRecords;
Records records;
Users users = new Users();
RolesManager roleManager;
User bob, userWithDeletePermission;
Record valueListItem1, valueListItem2, valueListItem3, rootUnclassifiedItem, childUnclassifiedItem;
boolean required = true;
boolean notRequired = false;
private ModelLayerCollectionExtensions extensions;
@Before
public void setUp()
throws Exception {
withMostReferencesRemoved = new RecordPhysicalDeleteOptions().setMostReferencesToNull(true);
withMostReferencesRemovedPhysicallyDeletingRecords = new RecordPhysicalDeleteOptions().setMostReferencesToNull(true)
.setBehaviorForRecordsAttachedToTaxonomy(PHYSICALLY_DELETE_THEM);
withMostReferencesRemovedPhysicallyDeletingRecordsIfPrincipalTaxonomy = new RecordPhysicalDeleteOptions()
.setMostReferencesToNull(true)
.setBehaviorForRecordsAttachedToTaxonomy(PHYSICALLY_DELETE_THEM_ONLY_IF_PRINCIPAL_TAXONOMY);
logicallyDeletingRecordsIfPrincipalTaxonomy = new RecordLogicalDeleteOptions().setBehaviorForRecordsAttachedToTaxonomy(
LogicallyDeleteTaxonomyRecordsBehavior.LOGICALLY_DELETE_THEM_ONLY_IF_PRINCIPAL_TAXONOMY);
logicallyDeletingRecords = new RecordLogicalDeleteOptions().setBehaviorForRecordsAttachedToTaxonomy(
LogicallyDeleteTaxonomyRecordsBehavior.LOGICALLY_DELETE_THEM);
keepingRecords = new RecordLogicalDeleteOptions();
customSystemPreparation(new CustomSystemPreparation() {
@Override
public void prepare() {
givenCachedCollection(zeCollection).withAllTestUsers();
givenCachedCollection("anotherCollection").withAllTestUsers();
setupServices();
defineSchemasManager().using(schemas.with(unsecuredAndUnclassifiedValueListSchemaAndUnclassifiedSecuredSchema()));
taxonomiesManager.addTaxonomy(schemas.getTaxonomy1(), schemasManager);
taxonomiesManager.addTaxonomy(schemas.getTaxonomy2(), schemasManager);
taxonomiesManager.setPrincipalTaxonomy(schemas.getTaxonomy1(), schemasManager);
records = schemas.new Records(recordServices);
records.setup();
userWithDeletePermission = users.chuckNorrisIn(zeCollection);
userWithDeletePermission.setCollectionDeleteAccess(true);
try {
recordServices.update(userWithDeletePermission.getWrappedRecord());
} catch (RecordServicesException e) {
throw new RuntimeException(e);
}
}
@Override
public void initializeFromCache() {
setupServices();
schemas.refresh(schemasManager);
records = schemas.new Records(recordServices);
}
private void setupServices() {
users.setUp(getModelLayerFactory().newUserServices());
recordServices = spy(getModelLayerFactory().newCachelessRecordServices());
taxonomiesManager = getModelLayerFactory().getTaxonomiesManager();
searchServices = getModelLayerFactory().newSearchServices();
authorizationsServices = getModelLayerFactory().newAuthorizationsServices();
schemasManager = getModelLayerFactory().getMetadataSchemasManager();
roleManager = getModelLayerFactory().getRolesManager();
collectionsListManager = getModelLayerFactory().getCollectionsListManager();
recordDeleteServices = spy(recordServices.newRecordDeleteServices());
doReturn(recordDeleteServices).when(recordServices).newRecordDeleteServices();
}
});
bob = users.bobIn(zeCollection);
userWithDeletePermission = users.chuckNorrisIn(zeCollection);
extensions = getModelLayerFactory().getExtensions().forCollection(zeCollection);
MetadataSchema valueListItemSchema = schemas.getSchema("valueList_default");
MetadataSchema securedUnclassifiedSchema = schemas.getSchema("securedUnclassified_default");
valueListItem1 = recordServices.newRecordWithSchema(valueListItemSchema, "valuelListItem").set(TITLE, "Ze item");
valueListItem2 = recordServices.newRecordWithSchema(valueListItemSchema, "value2ListItem").set(TITLE, "Ze item 2");
valueListItem3 = recordServices.newRecordWithSchema(valueListItemSchema, "value3ListItem").set(TITLE, "Ze item 3");
rootUnclassifiedItem = recordServices.newRecordWithSchema(securedUnclassifiedSchema, "rootUnclassifiedItem")
.set(TITLE, "rootUnclassifiedItem");
childUnclassifiedItem = recordServices.newRecordWithSchema(securedUnclassifiedSchema, "childUnclassifiedItem")
.set(TITLE, "childUnclassifiedItem").set(securedUnclassifiedSchema.get("parent"), rootUnclassifiedItem);
recordServices.execute(
new Transaction(valueListItem1, valueListItem2, valueListItem3, rootUnclassifiedItem, childUnclassifiedItem));
}
private void givenValueListSchemaHasSecurity() {
MetadataSchema valueListItemSchema = schemas.getSchema("valueList_default");
MetadataSchemaTypesBuilder typesBuilder = getModelLayerFactory().getMetadataSchemasManager().modify(zeCollection);
typesBuilder.getSchemaType("valueList").setSecurity(true);
try {
getModelLayerFactory().getMetadataSchemasManager().saveUpdateSchemaTypes(typesBuilder);
} catch (OptimisticLocking optimistickLocking) {
throw new RuntimeException(optimistickLocking);
}
}
@Test
public void givenRecordReferencedByOtherRecordsIn()
throws Exception {
givenMultiValueLinkToOtherFolderMetadatasIs(required);
given(records.folder2()).hasAReferenceTo(records.folder1(), records.folder4());
given(records.folder3()).hasAReferenceTo(records.folder1());
givenSingleValueLinkToOtherFolderMetadatasIs(required);
given(records.folder2()).hasASingleValueReferenceTo(records.folder1());
given(records.folder3()).hasASingleValueReferenceTo(records.folder4());
given(userWithDeletePermission).logicallyDelete(records.folder1());
try {
when(userWithDeletePermission).physicallyDelete(records.folder1(), withMostReferencesRemoved);
fail("Physically delete should have failed");
} catch (RecordServicesRuntimeException_CannotPhysicallyDeleteRecord_CannotSetNullOnRecords e) {
assertThat(e.getRecordsIdsWithUnremovableReferences()).containsOnly(
records.folder2().getId(), records.folder3().getId());
}
assertThatRecord(records.folder2())
.hasMetadataValue(folderSchema.linkToOtherFolder(), records.folder1().getId())
.hasMetadataValue(folderSchema.linkToOtherFolders(),
asList(records.folder1().getId(), records.folder4().getId()));
assertThatRecord(records.folder3())
.hasMetadataValue(folderSchema.linkToOtherFolders(), asList(records.folder1().getId()));
givenMultiValueLinkToOtherFolderMetadatasIs(notRequired);
try {
when(userWithDeletePermission).physicallyDelete(records.folder1(), withMostReferencesRemoved);
fail("Physically delete should have failed");
} catch (RecordServicesRuntimeException_CannotPhysicallyDeleteRecord_CannotSetNullOnRecords e) {
assertThat(e.getRecordsIdsWithUnremovableReferences()).containsOnly(
records.folder2().getId());
}
assertThatRecord(records.folder2())
.hasMetadataValue(folderSchema.linkToOtherFolder(), records.folder1().getId())
.hasMetadataValue(folderSchema.linkToOtherFolders(),
asList(records.folder1().getId(), records.folder4().getId()));
assertThatRecord(records.folder3())
.hasNoMetadataValue(folderSchema.linkToOtherFolders());
givenSingleValueLinkToOtherFolderMetadatasIs(notRequired);
when(userWithDeletePermission).physicallyDelete(records.folder1(), withMostReferencesRemoved);
assertThatRecord(records.folder2())
.hasNoMetadataValue(folderSchema.linkToOtherFolder())
.hasMetadataValue(folderSchema.linkToOtherFolders(), asList(records.folder4().getId()));
}
@Test
public void givenNotPhysicallyDeletableByExtensionThenNotPhysicallyDeletable()
throws Exception {
extensions.recordExtensions.add(new RecordExtension() {
@Override
public ExtensionBooleanResult isPhysicallyDeletable(RecordPhysicalDeletionValidationEvent params) {
return ExtensionBooleanResult.FALSE;
}
});
given(bob).logicallyDelete(valueListItem1);
assertThat(valueListItem1).isNot(physicallyDeletableBy(bob));
assertThat(valueListItem1).isNot(physicallyDeletableBy(bob, withMostReferencesRemoved));
}
@Test
public void givenPhysicallyDeletableByExtensionThenPhysicallyDeletable()
throws Exception {
extensions.recordExtensions.add(new RecordExtension() {
@Override
public ExtensionBooleanResult isPhysicallyDeletable(RecordPhysicalDeletionValidationEvent params) {
return ExtensionBooleanResult.TRUE;
}
});
given(bob).logicallyDelete(valueListItem1);
assertThat(valueListItem1).is(physicallyDeletableBy(bob));
assertThat(valueListItem1).is(physicallyDeletableBy(bob, withMostReferencesRemoved));
}
@Test
public void givenNotLogicallyDeletableByExtensionThenNotLogicallyDeletable()
throws Exception {
extensions.recordExtensions.add(new RecordExtension() {
@Override
public ExtensionBooleanResult isLogicallyDeletable(RecordLogicalDeletionValidationEvent params) {
return ExtensionBooleanResult.FALSE;
}
});
assertThat(valueListItem1).isNot(logicallyDeletableBy(bob));
}
@Test
public void givenLogicallyDeletableByExtensionThenLogicallyDeletable()
throws Exception {
extensions.recordExtensions.add(new RecordExtension() {
@Override
public ExtensionBooleanResult isLogicallyDeletable(RecordLogicalDeletionValidationEvent params) {
return ExtensionBooleanResult.TRUE;
}
});
assertThat(valueListItem1).is(logicallyDeletableBy(bob));
}
@Test
public void givenNotReferencedValueListItemWithoutSecurityThenLogicallyDeletableByAnybody()
throws Exception {
assertThat(valueListItem1).is(logicallyDeletableBy(bob));
assertThat(valueListItem1).is(logicallyThenPhysicallyDeletableBy(bob));
assertThat(valueListItem1).is(notPhysicallyDeletableBy(bob));
assertThat(valueListItem1).is(notPhysicallyDeletableBy(bob, withMostReferencesRemoved));
when(bob).logicallyDelete(valueListItem1);
assertThat(valueListItem1).is(logicallyDeleted());
}
@Test
public void givenNotReferencedValueListItemWithoutSecurityThenRestorableByAnybody()
throws Exception {
given(bob).logicallyDelete(valueListItem1);
assertThat(valueListItem1).is(restorableBy(bob));
when(bob).restore(valueListItem1);
assertThat(valueListItem1).isNot(logicallyDeleted());
}
@Test
public void givenNotReferencedValueListItemWithoutSecurityThenPhysicallyDeletableByAnybody()
throws Exception {
given(bob).logicallyDelete(valueListItem1);
assertThat(valueListItem1).is(physicallyDeletableBy(bob));
assertThat(valueListItem1).is(physicallyDeletableBy(bob, withMostReferencesRemoved));
when(bob).physicallyDelete(valueListItem1);
assertThat(valueListItem1).is(physicallyDeleted());
}
@Test
public void givenNotReferencedValueListItemWithSecurityThenLogicallyDeletableByGodAndUserWithCollectionDelete()
throws Exception {
givenValueListSchemaHasSecurity();
assertThat(valueListItem1).is(notLogicallyDeletableBy(bob));
assertThat(valueListItem1).is(notLogicallyThenPhysicallyDeletableBy(bob));
assertThat(valueListItem1).is(notLogicallyThenPhysicallyDeletableBy(bob, withMostReferencesRemoved));
assertThat(valueListItem1).is(logicallyDeletableBy(User.GOD));
assertThat(valueListItem1).is(logicallyThenPhysicallyDeletableBy(User.GOD));
assertThat(valueListItem1).is(logicallyThenPhysicallyDeletableBy(User.GOD, withMostReferencesRemoved));
assertThat(valueListItem1).is(logicallyDeletableBy(userWithDeletePermission));
assertThat(valueListItem1).is(logicallyThenPhysicallyDeletableBy(userWithDeletePermission));
assertThat(valueListItem1).is(logicallyThenPhysicallyDeletableBy(userWithDeletePermission, withMostReferencesRemoved));
when(User.GOD).logicallyDelete(valueListItem1);
assertThat(valueListItem1).is(logicallyDeleted());
}
@Test
public void givenNotReferencedValueListItemWithSecurityThenRestorableByGodAndUserWithCollectionDelete()
throws Exception {
givenValueListSchemaHasSecurity();
given(userWithDeletePermission).logicallyDelete(valueListItem1);
assertThat(valueListItem1).is(notRestorableBy(bob));
assertThat(valueListItem1).is(restorableBy(User.GOD));
assertThat(valueListItem1).is(restorableBy(userWithDeletePermission));
when(userWithDeletePermission).restore(valueListItem1);
assertThat(valueListItem1).isNot(logicallyDeleted());
}
@Test
public void givenNotReferencedValueListItemWithSecurityThenPhysicallyDeletableByGodAndUserWithCollectionDelete()
throws Exception {
givenValueListSchemaHasSecurity();
assertThat(valueListItem1).is(notLogicallyThenPhysicallyDeletableBy(bob));
assertThat(valueListItem1).is(logicallyThenPhysicallyDeletableBy(User.GOD));
assertThat(valueListItem1).is(logicallyThenPhysicallyDeletableBy(userWithDeletePermission));
given(User.GOD).logicallyDelete(valueListItem1);
assertThat(valueListItem1).is(notPhysicallyDeletableBy(bob));
assertThat(valueListItem1).is(physicallyDeletableBy(User.GOD));
assertThat(valueListItem1).is(physicallyDeletableBy(userWithDeletePermission));
when(User.GOD).physicallyDelete(valueListItem1);
assertThat(valueListItem1).is(physicallyDeleted());
}
@Test
public void givenReferencedValueListItemThenLogicallyDeletable()
throws Exception {
given(records.folder3()).hasAValueListReferenceTo(valueListItem1);
assertThat(valueListItem1).is(logicallyDeletableBy(bob));
assertThat(valueListItem1).is(notLogicallyThenPhysicallyDeletableBy(bob));
when(bob).logicallyDelete(valueListItem1);
assertThat(valueListItem1).is(logicallyDeleted());
}
@Test
public void givenRecordIsDefaultValueThenNotLogicallyDeletable()
throws Exception {
getModelLayerFactory().getMetadataSchemasManager().modify(zeCollection, new MetadataSchemaTypesAlteration() {
@Override
public void alter(MetadataSchemaTypesBuilder types) {
types.getSchema(records.folder3().getSchemaCode()).get("valueListRef")
.setDefaultValue(asList(valueListItem1.getId()));
}
});
assertThat(valueListItem1).isNot(logicallyDeletableBy(userWithDeletePermission));
assertThat(valueListItem1).is(notLogicallyThenPhysicallyDeletableBy(userWithDeletePermission));
}
@Test
public void givenReferencedValueListItemThenRestorable()
throws Exception {
given(records.folder3()).hasAValueListReferenceTo(valueListItem1);
given(userWithDeletePermission).logicallyDelete(valueListItem1);
assertThat(valueListItem1).is(restorableBy(bob));
when(bob).restore(valueListItem1);
assertThat(valueListItem1).isNot(logicallyDeleted());
}
@Test
public void givenReferencedValueListItemThenNotPhysicallyDeletable()
throws Exception {
given(records.folder3()).hasAValueListReferenceTo(valueListItem1);
given(bob).logicallyDelete(valueListItem1);
assertThat(valueListItem1).is(notPhysicallyDeletableBy(bob));
assertThat(valueListItem1).is(notPhysicallyDeletableBy(User.GOD));
assertThat(valueListItem1).is(notPhysicallyDeletableBy(userWithDeletePermission));
}
@Test
public void givenReferencedValueListItemInMultivalueMetadataThenPhysicallyDeletableWithRefRemovedOption()
throws Exception {
given(records.folder3()).hasAValueListReferenceTo(valueListItem1, valueListItem2, valueListItem3);
given(records.folder4()).hasAValueListReferenceTo(valueListItem2, valueListItem1, valueListItem3);
given(records.folder1()).hasAValueListReferenceTo(valueListItem2, valueListItem3, valueListItem1);
assertThat(valueListItem1).is(logicallyDeletableBy(bob));
assertThat(valueListItem1).is(notLogicallyThenPhysicallyDeletableBy(bob));
assertThat(valueListItem1).is(logicallyThenPhysicallyDeletableBy(bob, withMostReferencesRemoved));
Metadata metadata = folderSchema.instance().getMetadata("valueListRef");
when(bob).logicallyDelete(valueListItem1);
when(bob).physicallyDelete(valueListItem1, withMostReferencesRemoved);
assertThat(valueListItem1).is(physicallyDeleted());
assertThat(records.folder3().getList(metadata)).containsExactly("value2ListItem", "value3ListItem");
assertThat(records.folder4().getList(metadata)).containsExactly("value2ListItem", "value3ListItem");
assertThat(records.folder1().getList(metadata)).containsExactly("value2ListItem", "value3ListItem");
}
@Test
public void givenReferencedValueListItemInSingleValueMetadataThenPhysicallyDeletableWithRefRemovedOption()
throws Exception {
given(records.folder3()).hasASingleValueListReferenceTo(valueListItem1);
given(records.folder4()).hasASingleValueListReferenceTo(valueListItem1);
given(records.folder1()).hasASingleValueListReferenceTo(valueListItem2);
assertThat(valueListItem1).is(logicallyDeletableBy(bob));
assertThat(valueListItem1).is(notLogicallyThenPhysicallyDeletableBy(bob));
assertThat(valueListItem1).is(logicallyThenPhysicallyDeletableBy(bob, withMostReferencesRemoved));
Metadata metadata = folderSchema.instance().getMetadata("valueListSingleRef");
when(bob).logicallyDelete(valueListItem1);
when(bob).physicallyDelete(valueListItem1, withMostReferencesRemoved);
assertThat(valueListItem1).is(physicallyDeleted());
assertThat(records.folder3().get(metadata)).isNull();
assertThat(records.folder4().get(metadata)).isNull();
assertThat(records.folder1().get(metadata)).isEqualTo("value2ListItem");
}
@Test
public void givenUserWithCollectionDeleteAccessWhenDeletingASecuredUnclassifiedRecordThenAllHierarchyDeleted()
throws Exception {
assertThat(rootUnclassifiedItem).is(logicallyDeletableBy(userWithDeletePermission));
assertThat(rootUnclassifiedItem).is(logicallyThenPhysicallyDeletableBy(userWithDeletePermission));
assertThat(rootUnclassifiedItem)
.is(logicallyThenPhysicallyDeletableBy(userWithDeletePermission, withMostReferencesRemoved));
assertThat(rootUnclassifiedItem).is(notPhysicallyDeletableBy(userWithDeletePermission));
assertThat(rootUnclassifiedItem).is(notPhysicallyDeletableBy(userWithDeletePermission, withMostReferencesRemoved));
assertThat(childUnclassifiedItem).is(logicallyDeletableBy(userWithDeletePermission));
assertThat(childUnclassifiedItem).is(logicallyThenPhysicallyDeletableBy(userWithDeletePermission));
assertThat(childUnclassifiedItem).is(logicallyThenPhysicallyDeletableBy(userWithDeletePermission,
withMostReferencesRemoved));
assertThat(childUnclassifiedItem).is(notPhysicallyDeletableBy(userWithDeletePermission));
assertThat(childUnclassifiedItem).is(notPhysicallyDeletableBy(userWithDeletePermission, withMostReferencesRemoved));
when(userWithDeletePermission).logicallyDelete(rootUnclassifiedItem);
when(userWithDeletePermission).physicallyDelete(rootUnclassifiedItem);
assertThat(rootUnclassifiedItem).is(physicallyDeleted());
assertThat(childUnclassifiedItem).is(physicallyDeleted());
}
@Test
public void givenUserDoesntHaveFullDeleteAccessOnASecuredUnclassifiedRecordThenCannotLogicallyDelete()
throws Exception {
assertThat(rootUnclassifiedItem).is(notLogicallyDeletableBy(bob));
assertThat(rootUnclassifiedItem).is(notLogicallyThenPhysicallyDeletableBy(bob));
assertThat(rootUnclassifiedItem).is(notLogicallyThenPhysicallyDeletableBy(bob, withMostReferencesRemoved));
assertThat(rootUnclassifiedItem).is(notPhysicallyDeletableBy(bob));
assertThat(rootUnclassifiedItem).is(notPhysicallyDeletableBy(bob, withMostReferencesRemoved));
assertThat(childUnclassifiedItem).is(notLogicallyDeletableBy(bob));
assertThat(childUnclassifiedItem).is(notLogicallyThenPhysicallyDeletableBy(bob));
assertThat(childUnclassifiedItem).is(notLogicallyThenPhysicallyDeletableBy(bob, withMostReferencesRemoved));
assertThat(childUnclassifiedItem).is(notPhysicallyDeletableBy(bob));
assertThat(childUnclassifiedItem).is(notPhysicallyDeletableBy(bob, withMostReferencesRemoved));
}
@Test
public void givenUserDoesntHaveFullDeleteAccessOnASecuredUnclassifiedLogicallyDeletedRecordThenCannotPhysicallyDeleteOrRestoreIt()
throws Exception {
given(userWithDeletePermission).logicallyDelete(rootUnclassifiedItem);
assertThat(rootUnclassifiedItem).is(notLogicallyDeletableBy(bob));
assertThat(rootUnclassifiedItem).is(notLogicallyThenPhysicallyDeletableBy(bob));
assertThat(rootUnclassifiedItem).is(notLogicallyThenPhysicallyDeletableBy(bob, withMostReferencesRemoved));
assertThat(rootUnclassifiedItem).is(notPhysicallyDeletableBy(bob));
assertThat(rootUnclassifiedItem).is(notPhysicallyDeletableBy(bob, withMostReferencesRemoved));
assertThat(childUnclassifiedItem).is(notLogicallyDeletableBy(bob));
assertThat(childUnclassifiedItem).is(notLogicallyThenPhysicallyDeletableBy(bob));
assertThat(childUnclassifiedItem).is(notLogicallyThenPhysicallyDeletableBy(bob, withMostReferencesRemoved));
assertThat(childUnclassifiedItem).is(notPhysicallyDeletableBy(bob));
assertThat(childUnclassifiedItem).is(notPhysicallyDeletableBy(bob, withMostReferencesRemoved));
}
@Test
public void givenUserHasFullDeleteAccessOnASecuredUnclassifiedRecordWhichAreReferencedThenCanDeleteLogicallyButNotPhysically()
throws Exception {
given(records.folder3()).hasAReferenceToUnclassifiedSecuredRecord(childUnclassifiedItem);
assertThat(rootUnclassifiedItem).is(logicallyDeletableBy(userWithDeletePermission));
assertThat(rootUnclassifiedItem).is(notLogicallyThenPhysicallyDeletableBy(userWithDeletePermission));
assertThat(rootUnclassifiedItem)
.is(logicallyThenPhysicallyDeletableBy(userWithDeletePermission, withMostReferencesRemoved));
assertThat(rootUnclassifiedItem).is(notPhysicallyDeletableBy(userWithDeletePermission));
assertThat(rootUnclassifiedItem).is(notPhysicallyDeletableBy(userWithDeletePermission, withMostReferencesRemoved));
assertThat(childUnclassifiedItem).is(logicallyDeletableBy(userWithDeletePermission));
assertThat(childUnclassifiedItem).is(notLogicallyThenPhysicallyDeletableBy(userWithDeletePermission));
assertThat(childUnclassifiedItem).is(logicallyThenPhysicallyDeletableBy(userWithDeletePermission,
withMostReferencesRemoved));
assertThat(childUnclassifiedItem).is(notPhysicallyDeletableBy(userWithDeletePermission));
assertThat(childUnclassifiedItem).is(notPhysicallyDeletableBy(userWithDeletePermission, withMostReferencesRemoved));
}
@Test
public void givenUserHasDeletePermissionToActiveRecordAndItsHierarchyThenCanDeleteLogicallyButNotPhysically()
throws Exception {
given(bob).hasDeletePermissionOn(records.folder4());
assertThat(records.folder4()).is(logicallyDeletableBy(bob));
assertThat(records.folder4()).is(logicallyThenPhysicallyDeletableBy(bob));
assertThat(records.folder4()).is(notPhysicallyDeletableBy(bob));
}
@Test
public void givenGodUserThenCanDeleteLogicallyButNotPhysically()
throws Exception {
assertThat(records.folder4()).is(logicallyDeletableBy(User.GOD));
assertThat(records.folder4()).is(logicallyThenPhysicallyDeletableBy(User.GOD));
assertThat(records.folder4()).is(notPhysicallyDeletableBy(User.GOD));
}
@Test
public void givenUserHasDeletePermissionToActiveRecordAndItsHierarchyWhenDeletingLogicallyThenAllHierarchyLogicallyDeleted()
throws Exception {
given(bob).hasDeletePermissionOn(records.folder4());
when(bob).logicallyDelete(records.folder4());
assertThat(records.inFolder4Hierarchy()).are(logicallyDeleted());
}
@Test
public void givenGodUserWhenDeletingLogicallyThenAllHierarchyLogicallyDeleted()
throws Exception {
when(User.GOD).logicallyDelete(records.folder4());
assertThat(records.inFolder4Hierarchy()).are(logicallyDeleted());
}
@Test
public void givenUserHasDeletePermissionToActiveRecordButNotToAnElementInItsHierarchyThenCannotDeleteItLogically()
throws Exception {
given(bob).hasDeletePermissionOn(records.folder4());
given(bob).hasRemovedDeletePermissionOn(records.folder4_2_doc1());
assertThat(records.folder4()).is(notLogicallyDeletableBy(bob));
assertThat(records.folder4()).is(notLogicallyThenPhysicallyDeletableBy(bob));
}
@Test
public void givenARecordWithoutPathThenAUserWithCollectionDeleteAccessCanLogicallyDeleteIt()
throws Exception {
Record folder = recordServices.newRecordWithSchema(folderSchema.instance());
recordServices.add(folder.set(TITLE, "title"));
when(userWithDeletePermission).logicallyDelete(folder);
assertThat(folder).is(logicallyDeleted());
}
@Test
public void givenARecordWithoutPathThenATypicalUserCannotLogicallyDeleteIt()
throws Exception {
Record folder = recordServices.newRecordWithSchema(folderSchema.instance());
recordServices.add(folder.set(TITLE, "title"));
assertThat(records.folder4()).is(notLogicallyDeletableBy(bob));
assertThat(records.folder4()).is(notLogicallyThenPhysicallyDeletableBy(bob));
}
@Test
public void givenALogicallyDeletedRecordWithoutPathThenAUserWithCollectionDeleteAccessCanRestoreIt()
throws Exception {
Record folder = recordServices.newRecordWithSchema(folderSchema.instance());
recordServices.add(folder.set(TITLE, "title"));
given(userWithDeletePermission).logicallyDelete(folder);
when(userWithDeletePermission).restore(folder);
assertThat(folder).isNot(logicallyDeleted());
}
@Test
public void givenALogicallyDeletedRecordWithoutPathThenATypicalUserCannotRestoreIt()
throws Exception {
Record folder = recordServices.newRecordWithSchema(folderSchema.instance());
recordServices.add(folder.set(TITLE, "title"));
given(userWithDeletePermission).logicallyDelete(folder);
assertThat(records.folder4()).is(notRestorableBy(bob));
}
@Test
public void givenALogicallyDeletedRecordWithoutPathThenAUserWithCollectionDeleteAccessCanPhysicallyDeleteIt()
throws Exception {
Record folder = recordServices.newRecordWithSchema(folderSchema.instance());
recordServices.add(folder.set(TITLE, "title"));
assertThat(folder).is(logicallyThenPhysicallyDeletableBy(userWithDeletePermission));
given(userWithDeletePermission).logicallyDelete(folder);
when(userWithDeletePermission).physicallyDelete(folder);
assertThat(folder).is(physicallyDeleted());
}
@Test
public void givenALogicallyDeletedRecordWithoutPathThenATypicalUserCannotPhysicallyDeleteIt()
throws Exception {
Record folder = recordServices.newRecordWithSchema(folderSchema.instance());
recordServices.add(folder.set(TITLE, "title"));
given(userWithDeletePermission).logicallyDelete(folder);
assertThat(records.folder4()).is(notPhysicallyDeletableBy(bob));
}
@Test
public void givenARecordIsReferencedInAnotherRecordWhenAUserDeleteTheRecordThenWholeHierarchyLogicallyDeleted()
throws Exception {
given(records.folder2()).hasAReferenceTo(records.folder4());
assertThat(records.folder4()).is(notLogicallyThenPhysicallyDeletableBy(userWithDeletePermission));
assertThat(records.folder4()).is(logicallyThenPhysicallyDeletableBy(userWithDeletePermission, withMostReferencesRemoved));
when(userWithDeletePermission).logicallyDelete(records.folder4());
assertThat(records.inFolder4Hierarchy()).are(logicallyDeleted());
}
@Test
public void givenARecordIsReferencedInAnotherRecordWhenGodUserDeleteTheRecordThenWholeHierarchyLogicallyDeleted()
throws Exception {
given(records.folder2()).hasAReferenceTo(records.folder4());
assertThat(records.folder4()).is(notLogicallyThenPhysicallyDeletableBy(userWithDeletePermission));
when(User.GOD).logicallyDelete(records.folder4());
assertThat(records.inFolder4Hierarchy()).are(logicallyDeleted());
}
@Test
public void givenARecordIsReferencedInAnotherRecordWhenAUserDeleteTheRecordParentThenWholeHierarchyLogicallyDeleted()
throws Exception {
given(records.folder2()).hasAReferenceTo(records.folder4_2());
when(userWithDeletePermission).logicallyDelete(records.folder4());
assertThat(records.inFolder4Hierarchy()).are(logicallyDeleted());
}
@Test
public void givenARecordIsReferencedInAnotherRecordWhenGodUserDeleteTheRecordParentThenWholeHierarchyLogicallyDeleted()
throws Exception {
given(records.folder2()).hasAReferenceTo(records.folder4_2());
when(User.GOD).logicallyDelete(records.folder4());
assertThat(records.inFolder4Hierarchy()).are(logicallyDeleted());
}
@Test
public void givenALogicallyDeletedRecordWhenRestoringItThenAllItsHierarchyRestored()
throws Exception {
given(userWithDeletePermission).logicallyDelete(records.folder4());
when(userWithDeletePermission).restore(records.folder4());
assertThat(records.inFolder4Hierarchy()).areNot(logicallyDeleted());
}
@Test
public void givenALogicallyDeletedRecordWhenRestoringItWithGodUserThenAllItsHierarchyRestored()
throws Exception {
given(userWithDeletePermission).logicallyDelete(records.folder4());
when(User.GOD).restore(records.folder4());
assertThat(records.inFolder4Hierarchy()).areNot(logicallyDeleted());
}
@Test
public void givenALogicallyDeletedRecordThenASubRecordInItsHierarchyIsNotRestorableAlone()
throws Exception {
given(userWithDeletePermission).logicallyDelete(records.folder4());
assertThat(records.folder4_2()).is(notRestorableBy(userWithDeletePermission));
}
@Test
public void givenALogicallyDeletedRecordThenASubRecordInItsHierarchyIsNotRestorableAloneEvenWithGodUser()
throws Exception {
given(userWithDeletePermission).logicallyDelete(records.folder4());
assertThat(records.folder4_2()).is(notRestorableBy(User.GOD));
}
@Test
public void givenARecordIsDeletedLogicallyAndASubRecordRestoredWhenRestoringTheRecordThenAllRestored()
throws Exception {
given(userWithDeletePermission).logicallyDelete(records.folder4());
when(userWithDeletePermission).restore(records.folder4());
assertThat(records.inFolder4Hierarchy()).areNot(logicallyDeleted());
}
@Test
public void givenALogicallyDeletedRecordAndAUserWithoutSufficientDeletePermissionThenCannotRestoreIt()
throws Exception {
given(bob).hasDeletePermissionOn(records.folder4());
given(bob).hasRemovedDeletePermissionOn(records.folder4_2_doc1());
given(userWithDeletePermission).logicallyDelete(records.folder4());
assertThat(records.folder4()).is(restorableBy(userWithDeletePermission));
assertThat(records.folder4()).is(notRestorableBy(bob));
}
@Test
public void givenALogicallyDeletedRecordWhenAUserWithDeletePermissionPhysicallyDeleteItThenAllDeleted()
throws Exception {
List<Record> recordsInFolder4Hierarchy = records.inFolder4Hierarchy();
assertThat(records.folder4()).is(logicallyThenPhysicallyDeletableBy(userWithDeletePermission));
given(userWithDeletePermission).logicallyDelete(records.folder4());
when(userWithDeletePermission).physicallyDelete(records.folder4());
assertThat(recordsInFolder4Hierarchy).are(physicallyDeleted());
}
@Test
public void givenALogicallyDeletedRecordWhenGodUserWithDeletePermissionPhysicallyDeleteItThenAllDeleted()
throws Exception {
List<Record> recordsInFolder4Hierarchy = records.inFolder4Hierarchy();
given(userWithDeletePermission).logicallyDelete(records.folder4());
when(User.GOD).physicallyDelete(records.folder4());
assertThat(recordsInFolder4Hierarchy).are(physicallyDeleted());
}
@Test
public void givenALogicallyDeletedRecordAndAUserWithDeletePermissionToTheRecordButNotToASubRecordThenCannotPhysicallyDeleteIt()
throws Exception {
given(userWithDeletePermission).logicallyDelete(records.folder4());
given(bob).hasDeletePermissionOn(records.folder4());
given(bob).hasRemovedDeletePermissionOn(records.folder4_2());
assertThat(records.folder4()).is(notPhysicallyDeletableBy(bob));
assertThat(records.folder4()).is(notPhysicallyDeletableBy(bob, withMostReferencesRemoved));
assertThat(records.inFolder4Hierarchy()).areNot(physicallyDeleted());
}
@Test
public void givenALogicallyDeletedRecordThenDeletedAndNotReferenceable()
throws Exception {
assertThat(records.folder4()).is(logicallyThenPhysicallyDeletableBy(userWithDeletePermission));
given(userWithDeletePermission).logicallyDelete(records.folder4());
assertThat(records.folder4()).is(logicallyDeleted());
assertThat(records.folder4()).is(physicallyDeletableBy(userWithDeletePermission));
assertThat(records.folder4()).isNot(referencable());
}
@Test
public void givenALogicallyDeletedRecordWhenUpdatingThenStillDeletedAndNotReferenceable()
throws Exception {
given(userWithDeletePermission).logicallyDelete(records.folder4());
given(bob).modify(records.folder4());
assertThat(records.folder4()).is(logicallyDeleted());
assertThat(records.folder4()).is(physicallyDeletableBy(userWithDeletePermission));
assertThat(records.folder4()).isNot(referencable());
}
@Test
public void givenALogicallyDeletedRecordThenAUserWithoutDeletePermissionCannotPhysicallyDeleteIt()
throws Exception {
given(userWithDeletePermission).logicallyDelete(records.folder4());
assertThat(records.folder4()).is(logicallyDeleted());
assertThat(records.folder4()).is(notPhysicallyDeletableBy(bob));
assertThat(records.inFolder4Hierarchy()).areNot(physicallyDeleted());
}
@Test
public void givenALogicallyDeletedRecordAndAUserWithoutDeletePermissionThenCannotPhysicallyDeleteIt()
throws Exception {
given(userWithDeletePermission).logicallyDelete(records.folder4());
assertThat(records.folder4()).is(notPhysicallyDeletableBy(bob));
assertThat(records.inFolder4Hierarchy()).areNot(physicallyDeleted());
}
@Test
public void givenALogicallyDeletedRecordOfSchemaWithoutSecurityAndAUserWithoutDeletePermissionThenCanPhysicallyDeleteIt()
throws Exception {
List<Record> recordsInFolder4Hierarchy = records.inFolder4Hierarchy();
givenSecurityDisabledInFolderSchemaType();
assertThat(records.folder4()).is(logicallyThenPhysicallyDeletableBy(userWithDeletePermission));
given(userWithDeletePermission).logicallyDelete(records.folder4());
assertThat(records.folder4()).is(physicallyDeletableBy(bob));
when(bob).physicallyDelete(records.folder4());
assertThat(recordsInFolder4Hierarchy).are(physicallyDeleted());
}
@Test
public void givenRecordOfSchemaWithoutSecurityAndAUserWithoutDeletePermissionThenCanPhysicallyDeleteIt()
throws Exception {
givenSecurityDisabledInFolderSchemaType();
assertThat(records.folder4()).is(logicallyDeletableBy(bob));
when(bob).logicallyDelete(records.folder4());
assertThat(records.inFolder4Hierarchy()).are(logicallyDeleted());
}
@Test
public void givenALogicallyDeletedRecordIsReferencedByAnotherRecordThenCannotPhysicallyDeleteIt()
throws Exception {
given(records.folder2()).hasAReferenceTo(records.folder4_2());
assertThat(records.folder4_2()).is(notLogicallyThenPhysicallyDeletableBy(userWithDeletePermission));
given(userWithDeletePermission).logicallyDelete(records.folder4());
assertThat(records.folder4_2()).is(notPhysicallyDeletableBy(userWithDeletePermission));
}
@Test
public void givenALogicallyDeletedRecordInHierarchyIsReferencedByMultivalueMetadataAnotherRecordThenCannotPhysicallyDeleteIt()
throws Exception {
given(records.folder2()).hasAReferenceTo(records.folder4_2());
assertThat(records.folder4()).is(notLogicallyThenPhysicallyDeletableBy(userWithDeletePermission));
given(userWithDeletePermission).logicallyDelete(records.folder4());
assertThat(records.folder4()).is(notPhysicallyDeletableBy(userWithDeletePermission));
}
@Test
public void givenALogicallyDeletedRecordInHierarchyIsReferencedBySingleValueMetadataAnotherRecordThenCannotPhysicallyDeleteIt()
throws Exception {
given(records.folder2()).hasASingleValueReferenceTo(records.folder4_2());
assertThat(records.folder4()).is(notLogicallyThenPhysicallyDeletableBy(userWithDeletePermission));
given(userWithDeletePermission).logicallyDelete(records.folder4());
assertThat(records.folder4()).is(notPhysicallyDeletableBy(userWithDeletePermission));
}
@Test
public void givenALogicallyDeletedRecordIsReferencedByMultivalueMetadataInAnotherRecordAndTheReferenceIsRemovedThenCanPhysicallyDeleteIt()
throws Exception {
given(records.folder2()).hasAReferenceTo(records.folder4_2());
given(userWithDeletePermission).logicallyDelete(records.folder4());
when(records.folder2()).hasAReferenceTo();
assertThat(records.folder4()).is(physicallyDeletableBy(userWithDeletePermission));
assertThat(records.folder4_2()).is(physicallyDeletableBy(userWithDeletePermission));
}
@Test
public void givenALogicallyDeletedRecordIsReferencedBySinglevalueMetadataInAnotherRecordAndTheReferenceIsRemovedThenCanPhysicallyDeleteIt()
throws Exception {
given(records.folder2()).hasASingleValueReferenceTo(records.folder4_2());
given(userWithDeletePermission).logicallyDelete(records.folder4());
when(records.folder2()).hasASingleValueReferenceTo(null);
assertThat(records.folder4()).is(physicallyDeletableBy(userWithDeletePermission));
assertThat(records.folder4_2()).is(physicallyDeletableBy(userWithDeletePermission));
}
@Test
public void givenALogicallyDeletedRecordIsReferencedByMultivalueMetadataInAnotherRecordAndTheReferenceIsRemovedAndRecordRestoredThenCanLogicallyThenPhysicallyDeleteIt()
throws Exception {
given(records.folder2()).hasAReferenceTo(records.folder4_2());
assertThat(records.folder4()).is(notLogicallyThenPhysicallyDeletableBy(userWithDeletePermission));
assertThat(records.folder4_2()).is(notLogicallyThenPhysicallyDeletableBy(userWithDeletePermission));
given(userWithDeletePermission).logicallyDelete(records.folder4());
when(records.folder2()).hasAReferenceTo();
given(userWithDeletePermission).restore(records.folder4());
assertThat(records.folder4()).is(logicallyThenPhysicallyDeletableBy(userWithDeletePermission));
assertThat(records.folder4_2()).is(logicallyThenPhysicallyDeletableBy(userWithDeletePermission));
}
@Test
public void givenALogicallyDeletedRecordIsReferencedBySinglevalueMetadataInAnotherRecordAndTheReferenceIsRemovedAndRecordRestoredThenCanLogicallyThenPhysicallyDeleteIt()
throws Exception {
given(records.folder2()).hasASingleValueReferenceTo(records.folder4_2());
assertThat(records.folder4()).is(notLogicallyThenPhysicallyDeletableBy(userWithDeletePermission));
assertThat(records.folder4_2()).is(notLogicallyThenPhysicallyDeletableBy(userWithDeletePermission));
given(userWithDeletePermission).logicallyDelete(records.folder4());
when(records.folder2()).hasASingleValueReferenceTo(null);
given(userWithDeletePermission).restore(records.folder4());
assertThat(records.folder4()).is(logicallyThenPhysicallyDeletableBy(userWithDeletePermission));
assertThat(records.folder4_2()).is(logicallyThenPhysicallyDeletableBy(userWithDeletePermission));
}
@Test
public void givenALogicallyDeletedRecordIsReferencedByAnotherRecordAndTheReferenceIsReplacedThenCanPhysicallyDeleteIt()
throws Exception {
given(records.folder2()).hasAReferenceTo(records.folder4_2());
given(userWithDeletePermission).logicallyDelete(records.folder4());
when(records.folder2()).hasAReferenceTo(records.folder3());
assertThat(records.folder4()).is(physicallyDeletableBy(userWithDeletePermission));
assertThat(records.folder4_2()).is(physicallyDeletableBy(userWithDeletePermission));
}
@Test
public void givenALogicallyDeletedRecordIsReferencedByAnotherRecordAndTheReferenceIsReplacedAndRecordRestoredThenCanLogicallyThenPhysicallyDeleteIt()
throws Exception {
given(records.folder2()).hasAReferenceTo(records.folder4_2());
assertThat(records.folder4()).is(notLogicallyThenPhysicallyDeletableBy(userWithDeletePermission));
assertThat(records.folder4_2()).is(notLogicallyThenPhysicallyDeletableBy(userWithDeletePermission));
given(userWithDeletePermission).logicallyDelete(records.folder4());
when(records.folder2()).hasAReferenceTo(records.folder3());
given(userWithDeletePermission).restore(records.folder4());
assertThat(records.folder4()).is(logicallyThenPhysicallyDeletableBy(userWithDeletePermission));
assertThat(records.folder4_2()).is(logicallyThenPhysicallyDeletableBy(userWithDeletePermission));
}
@Test
public void givenALogicallyDeletedRecordIsReferencedByAnotherRecordAndANewReferenceIsAddedKeepingThePreviousThenCannotPhysicallyDeleteIt()
throws Exception {
given(records.folder2()).hasAReferenceTo(records.folder4_2());
given(userWithDeletePermission).logicallyDelete(records.folder4());
when(records.folder2()).hasAReferenceTo(records.folder4_2(), records.folder3());
assertThat(records.folder4()).is(notPhysicallyDeletableBy(userWithDeletePermission));
assertThat(records.folder4_2()).is(notPhysicallyDeletableBy(userWithDeletePermission));
given(userWithDeletePermission).restore(records.folder4());
assertThat(records.folder4()).is(notLogicallyThenPhysicallyDeletableBy(userWithDeletePermission));
assertThat(records.folder4_2()).is(notLogicallyThenPhysicallyDeletableBy(userWithDeletePermission));
}
@Test
public void givenALogicallyDeletedRecordIsReferencedByMultivalueMetadataInAnotherRecordAndIsMovedInAnOtherFolderThenPreviousParentFolderIsNowPhysicallyDeletable()
throws Exception {
given(records.folder2()).hasAReferenceTo(records.folder4_2());
given(userWithDeletePermission).logicallyDelete(records.folder4());
when(records.folder4_2()).hasNewParent(records.folder3());
assertThat(records.folder4()).is(physicallyDeletableBy(userWithDeletePermission));
assertThat(records.folder4_2()).is(notPhysicallyDeletableBy(userWithDeletePermission));
when(userWithDeletePermission).logicallyDelete(records.folder3());
assertThat(records.folder3()).is(notPhysicallyDeletableBy(userWithDeletePermission));
}
@Test
public void givenALogicallyDeletedRecordIsReferencedBySingleValueMetadataInAnotherRecordAndIsMovedInAnOtherFolderThenPreviousParentFolderIsNowPhysicallyDeletable()
throws Exception {
given(records.folder2()).hasASingleValueReferenceTo(records.folder4_2());
given(userWithDeletePermission).logicallyDelete(records.folder4());
when(records.folder4_2()).hasNewParent(records.folder3());
assertThat(records.folder4()).is(physicallyDeletableBy(userWithDeletePermission));
assertThat(records.folder4_2()).is(notPhysicallyDeletableBy(userWithDeletePermission));
when(userWithDeletePermission).logicallyDelete(records.folder3());
assertThat(records.folder3()).is(notPhysicallyDeletableBy(userWithDeletePermission));
}
@Test
public void givenALogicallyDeletedRecordIsReferencedByThreeRecordsWhenAllReferencingRecordsDeletedThenRecordIsPhysicallyDeletable()
throws Exception {
given(records.folder1()).hasAReferenceTo(records.folder4());
given(records.folder2()).hasAReferenceTo(records.folder4());
assertThat(records.folder4()).is(notLogicallyThenPhysicallyDeletableBy(userWithDeletePermission));
given(userWithDeletePermission).logicallyDelete(records.folder4());
assertThat(records.folder4()).is(notPhysicallyDeletableBy(userWithDeletePermission));
when(userWithDeletePermission).logicallyDelete(records.folder1());
when(userWithDeletePermission).physicallyDelete(records.folder1());
assertThat(records.folder4()).is(notPhysicallyDeletableBy(userWithDeletePermission));
when(userWithDeletePermission).logicallyDelete(records.folder2());
when(userWithDeletePermission).physicallyDelete(records.folder2());
assertThat(records.folder4()).is(physicallyDeletableBy(userWithDeletePermission));
given(userWithDeletePermission).restore(records.folder4());
assertThat(records.folder4()).is(logicallyThenPhysicallyDeletableBy(userWithDeletePermission));
}
@Test
public void givenALogicallyDeletedRecordIsReferencedByThreeRecordsWhenPhysicallyDeletingWithRefRemovedThenRefRemoved()
throws Exception {
given(records.folder1()).hasAReferenceTo(records.folder4());
given(records.folder2()).hasAReferenceTo(records.folder4());
Record folder4 = records.folder4();
assertThat(records.folder4()).is(notLogicallyThenPhysicallyDeletableBy(userWithDeletePermission));
assertThat(records.folder4()).is(logicallyThenPhysicallyDeletableBy(userWithDeletePermission, withMostReferencesRemoved));
given(userWithDeletePermission).logicallyDelete(records.folder4());
when(userWithDeletePermission).physicallyDelete(records.folder4(), withMostReferencesRemoved);
assertThat(folder4).is(physicallyDeleted());
assertThat(records.folder1().getList(folderSchema.linkToOtherFolders())).isEmpty();
assertThat(records.folder2().getList(folderSchema.linkToOtherFolders())).isEmpty();
}
@Test
public void givenRecordIsReferencedBySiblingRecordThenParentRecordIsPhysicallyDeletable()
throws Exception {
given(records.folder4_1()).hasAReferenceTo(records.folder4_2());
assertThat(records.folder4()).is(logicallyThenPhysicallyDeletableBy(userWithDeletePermission));
given(userWithDeletePermission).logicallyDelete(records.folder4());
assertThat(records.folder4()).is(physicallyDeletableBy(userWithDeletePermission));
}
@Test
public void givenRecordIsReferencedBySiblingAndCousinRecordsThenParentRecordIsPhysicallyDeletable()
throws Exception {
given(records.folder4_1()).hasAReferenceTo(records.folder4_2());
given(records.folder3()).hasAReferenceTo(records.folder4());
assertThat(records.taxo1_category2()).is(logicallyThenPhysicallyDeletableBy(userWithDeletePermission));
assertThat(records.taxo1_category2_1()).is(logicallyThenPhysicallyDeletableBy(userWithDeletePermission));
given(userWithDeletePermission).logicallyDelete(records.taxo1_category2(), logicallyDeletingRecordsIfPrincipalTaxonomy);
assertThat(records.taxo1_category2()).is(physicallyDeletableBy(userWithDeletePermission));
}
@Test
public void whenAPrincipalConceptIsLogicallyDeletedIncludingRecordsThenAllConceptsSubConceptsAndRecordsLogicallyDeleted()
throws Exception {
assertThat(records.taxo1_category2()).is(logicallyThenPhysicallyDeletableBy(userWithDeletePermission));
assertThat(records.taxo1_category2_1()).is(logicallyThenPhysicallyDeletableBy(userWithDeletePermission));
when(userWithDeletePermission).logicallyDelete(records.taxo1_category2(), logicallyDeletingRecordsIfPrincipalTaxonomy);
assertThat(records.taxo1_category2()).is(logicallyDeleted());
assertThat(records.taxo1_category2_1()).is(logicallyDeleted());
assertThat(records.folder3()).is(logicallyDeleted());
assertThat(records.inFolder4Hierarchy()).are(logicallyDeleted());
}
@Test
public void whenAPrincipalConceptIsLogicallyDeletedIncludingRecordsIfPrincipalTaxonomyByGodThenAllConceptsSubConceptsAndRecordsLogicallyDeleted()
throws Exception {
when(User.GOD).logicallyDelete(records.taxo1_category2(), logicallyDeletingRecordsIfPrincipalTaxonomy);
assertThat(records.taxo1_category2()).is(logicallyDeleted());
assertThat(records.taxo1_category2_1()).is(logicallyDeleted());
assertThat(records.folder3()).is(logicallyDeleted());
assertThat(records.inFolder4Hierarchy()).are(logicallyDeleted());
}
@Test
public void whenAPrincipalConceptIsLogicallyDeletedIncludingRecordsByGodThenAllConceptsSubConceptsAndRecordsLogicallyDeleted()
throws Exception {
when(User.GOD).logicallyDelete(records.taxo1_category2(), logicallyDeletingRecords);
assertThat(records.taxo1_category2()).is(logicallyDeleted());
assertThat(records.taxo1_category2_1()).is(logicallyDeleted());
assertThat(records.folder3()).is(logicallyDeleted());
assertThat(records.inFolder4Hierarchy()).are(logicallyDeleted());
}
@Test
public void givenAUserHasNoDeleteAccessOnCategoriesThenCannotLogicallyDeleteIt()
throws Exception {
assertThat(records.taxo1_category2()).is(notLogicallyThenPhysicallyDeletableBy(bob));
assertThat(records.taxo1_category2_1()).is(notLogicallyThenPhysicallyDeletableBy(bob));
assertThat(records.taxo1_category2()).is(notLogicallyDeletableIncludingRecordsBy(bob));
assertThat(records.taxo1_category2_1()).is(notLogicallyDeletableIncludingRecordsBy(bob));
assertThat(records.taxo1_category2()).is(notLogicallyDeletableExcludingRecordsBy(bob));
assertThat(records.taxo1_category2_1()).is(notLogicallyDeletableExcludingRecordsBy(bob));
}
@Test
public void givenAUserHasDeleteAccessOnCategoriesAndSubCategoriesButNotOnRecordsThenCanOnlyDeletePrincipalConceptExcludingRecords()
throws Exception {
given(bob).hasDeletePermissionOn(records.taxo1_category2());
given(bob).hasRemovedDeletePermissionOn(records.folder3());
assertThat(records.taxo1_category2()).is(notLogicallyThenPhysicallyDeletableBy(bob));
assertThat(records.taxo1_category2_1()).is(notLogicallyThenPhysicallyDeletableBy(bob));
assertThat(records.taxo1_category2()).is(notLogicallyDeletableIncludingRecordsBy(bob));
assertThat(records.taxo1_category2_1()).is(notLogicallyDeletableIncludingRecordsBy(bob));
assertThat(records.taxo1_category2()).is(logicallyDeletableExcludingRecordsBy(bob));
assertThat(records.taxo1_category2_1()).is(logicallyDeletableExcludingRecordsBy(bob));
}
@Test
public void givenLogicallyDeletedPrincipalConceptExcludingRecordsThenEvenGodUserCannotPhysicallyDeleteThePrincipalConcept()
throws Exception {
given(User.GOD).logicallyDelete(records.taxo1_category2());
assertThat(records.taxo1_category2()).is(notPhysicallyDeletableBy(User.GOD));
assertThat(records.taxo1_category2_1()).is(notPhysicallyDeletableBy(User.GOD));
}
@Test
public void givenAUserHasDeleteAccessOnCategoriesSubCategoriesAndRecordsThenCanDeletePrincipalConceptIncludingAndExcludingRecords()
throws Exception {
given(bob).hasDeletePermissionOn(records.taxo1_category2());
assertThat(records.taxo1_category2()).is(logicallyThenPhysicallyDeletableBy(bob));
assertThat(records.taxo1_category2_1()).is(logicallyThenPhysicallyDeletableBy(bob));
assertThat(records.taxo1_category2()).is(logicallyDeletableIncludingRecordsBy(bob));
assertThat(records.taxo1_category2_1()).is(logicallyDeletableIncludingRecordsBy(bob));
assertThat(records.taxo1_category2()).is(logicallyDeletableExcludingRecordsBy(bob));
assertThat(records.taxo1_category2_1()).is(logicallyDeletableExcludingRecordsBy(bob));
}
@Test
public void givenAUserHasDeleteAccessOnACategoryButNotOnASubCategoryThenCannotLogicallyDeleteIt()
throws Exception {
given(bob).hasDeletePermissionOn(records.taxo1_category2());
given(bob).hasRemovedDeletePermissionOn(records.taxo1_category2_1());
assertThat(records.taxo1_category2()).is(notLogicallyThenPhysicallyDeletableBy(bob));
assertThat(records.taxo1_category2_1()).is(notLogicallyThenPhysicallyDeletableBy(bob));
assertThat(records.taxo1_category2()).is(notLogicallyDeletableIncludingRecordsBy(bob));
assertThat(records.taxo1_category2_1()).is(notLogicallyDeletableIncludingRecordsBy(bob));
assertThat(records.taxo1_category2()).is(notLogicallyDeletableExcludingRecordsBy(bob));
assertThat(records.taxo1_category2_1()).is(notLogicallyDeletableExcludingRecordsBy(bob));
}
@Test
public void givenLogicallyDeletedPrincipalConceptAndAllItsHierarchyWhenRestoringThePrincipalConceptThenAllHierarchyRestored()
throws Exception {
given(userWithDeletePermission).logicallyDelete(records.taxo1_category2(), logicallyDeletingRecordsIfPrincipalTaxonomy);
when(userWithDeletePermission).restore(records.taxo1_category2());
assertThat(records.taxo1_category2()).isNot(logicallyDeleted());
assertThat(records.taxo1_category2_1()).isNot(logicallyDeleted());
assertThat(records.folder3()).isNot(logicallyDeleted());
assertThat(records.inFolder4Hierarchy()).areNot(logicallyDeleted());
}
@Test
public void givenLogicallyDeletedPrincipalConceptAndAllItsHierarchyThenAPrincipalSubConceptInALogicallyDeleteConceptIsNotRestorable()
throws Exception {
given(userWithDeletePermission).logicallyDelete(records.taxo1_category2(), logicallyDeletingRecordsIfPrincipalTaxonomy);
assertThat(records.taxo1_category2_1()).is(notRestorableBy(userWithDeletePermission));
}
@Test
public void givenLogicallyDeletedPrincipalConceptAndAllItsHierarchyWhenDeletingThePrincipalConceptThenAllHierarchyIsPhysicallyDeleted()
throws Exception {
Record taxo1_category2 = records.taxo1_category2();
Record taxo1_category2_1 = records.taxo1_category2_1();
Record folder3 = records.folder3();
List<Record> recordsInFolder4Hierarchy = records.inFolder4Hierarchy();
assertThat(records.taxo1_category2()).is(logicallyThenPhysicallyDeletableBy(userWithDeletePermission));
assertThat(records.taxo1_category2_1()).is(logicallyThenPhysicallyDeletableBy(userWithDeletePermission));
given(userWithDeletePermission).logicallyDelete(records.taxo1_category2(), logicallyDeletingRecordsIfPrincipalTaxonomy);
when(userWithDeletePermission)
.physicallyDelete(records.taxo1_category2(), withMostReferencesRemovedPhysicallyDeletingRecords);
assertThat(taxo1_category2).is(physicallyDeleted());
assertThat(taxo1_category2_1).is(physicallyDeleted());
assertThat(folder3).is(physicallyDeleted());
assertThat(recordsInFolder4Hierarchy).are(physicallyDeleted());
}
@Test
public void givenLogicallyDeletedPrincipalConceptAndAllItsHierarchyWhenDeletingAPrincipalSubConceptThenAllHierarchyIsPhysicallyDeletedExceptPrincipalRootConcept()
throws Exception {
Record taxo1_category2 = records.taxo1_category2();
Record taxo1_category2_1 = records.taxo1_category2_1();
Record folder3 = records.folder3();
List<Record> recordsInFolder4Hierarchy = records.inFolder4Hierarchy();
given(userWithDeletePermission).logicallyDelete(records.taxo1_category2(), logicallyDeletingRecordsIfPrincipalTaxonomy);
when(userWithDeletePermission).physicallyDelete(records.taxo1_category2_1(),
withMostReferencesRemovedPhysicallyDeletingRecords);
assertThat(taxo1_category2).isNot(physicallyDeleted());
assertThat(taxo1_category2_1).is(physicallyDeleted());
assertThat(folder3).is(physicallyDeleted());
assertThat(recordsInFolder4Hierarchy).areNot(physicallyDeleted());
}
@Test
public void whenAPrincipalConceptIsLogicallyDeletedExcludingRecordsThenOnlyConceptsSubConceptsDeleted()
throws Exception {
when(userWithDeletePermission).logicallyDelete(records.taxo1_category2(), keepingRecords);
assertThat(records.taxo1_category2()).is(logicallyDeleted());
assertThat(records.taxo1_category2_1()).is(logicallyDeleted());
assertThat(records.folder3()).isNot(logicallyDeleted());
assertThat(records.inFolder4Hierarchy()).areNot(logicallyDeleted());
}
@Test
public void whenLogicallyDeletingANonPrincipalConceptIncludingRecordsIfPrincipalThenOnlyLogicallyDeleteConceptsInHierarchy()
throws Exception {
when(userWithDeletePermission).logicallyDelete(records.taxo2_unit1(), logicallyDeletingRecordsIfPrincipalTaxonomy);
assertThat(records.taxo2_unit1()).is(logicallyDeleted());
assertThat(records.taxo2_unit1_1()).is(logicallyDeleted());
assertThat(records.folder1()).isNot(logicallyDeleted());
assertThat(records.folder1_doc1()).isNot(logicallyDeleted());
assertThat(records.folder2()).isNot(logicallyDeleted());
}
@Test
public void whenLogicallyDeletingANonPrincipalConceptIncludingRecordsThenAllLogicallyDeleted()
throws Exception {
when(userWithDeletePermission).logicallyDelete(records.taxo2_unit1(), logicallyDeletingRecords);
assertThat(records.taxo2_unit1()).is(logicallyDeleted());
assertThat(records.taxo2_unit1_1()).is(logicallyDeleted());
assertThat(records.folder1()).is(logicallyDeleted());
assertThat(records.folder1_doc1()).is(logicallyDeleted());
assertThat(records.folder2()).is(logicallyDeleted());
}
@Test
public void givenANonPrincipalConceptAndAllHisRecordsAreLogicallyDeletingWhenPhysicallyDeleteRecordsThenOnlyDeleteConceptsInHierarchy()
throws Exception {
Record taxo2_unit1 = records.taxo2_unit1();
Record taxo2_unit1_1 = records.taxo2_unit1_1();
Record folder1 = records.folder1();
Record folder1_doc1 = records.folder1_doc1();
Record folder2 = records.folder2();
when(userWithDeletePermission).logicallyDelete(records.taxo2_unit1());
when(userWithDeletePermission).logicallyDelete(records.folder1());
when(userWithDeletePermission).logicallyDelete(records.folder2());
when(userWithDeletePermission).logicallyDelete(records.folder3());
when(userWithDeletePermission).logicallyDelete(records.folder4());
when(userWithDeletePermission).logicallyDelete(records.folder5());
when(userWithDeletePermission)
.physicallyDelete(records.taxo2_unit1(), withMostReferencesRemovedPhysicallyDeletingRecords);
assertThat(taxo2_unit1).is(physicallyDeleted());
assertThat(taxo2_unit1_1).is(physicallyDeleted());
assertThat(folder1).is(physicallyDeleted());
assertThat(folder1_doc1).is(physicallyDeleted());
assertThat(folder2).is(physicallyDeleted());
}
@Test
public void givenANonPrincipalConceptAndAllHisRecordsAreLogicallyDeletingWhenPhysicallyDeleteRecordsIfPrincipalTaxonomyThenOnlyDeleteConceptsInHierarchy()
throws Exception {
Record taxo2_unit1 = records.taxo2_unit1();
Record taxo2_unit1_1 = records.taxo2_unit1_1();
when(userWithDeletePermission).logicallyDelete(records.taxo2_unit1());
when(userWithDeletePermission).logicallyDelete(records.folder1());
when(userWithDeletePermission).logicallyDelete(records.folder2());
when(userWithDeletePermission).logicallyDelete(records.folder3());
when(userWithDeletePermission).logicallyDelete(records.folder4());
when(userWithDeletePermission).logicallyDelete(records.folder5());
when(userWithDeletePermission)
.physicallyDelete(records.taxo2_unit1(), withMostReferencesRemovedPhysicallyDeletingRecordsIfPrincipalTaxonomy);
assertThat(taxo2_unit1).is(physicallyDeleted());
assertThat(taxo2_unit1_1).is(physicallyDeleted());
assertThat(records.folder1()).isNot(physicallyDeleted());
assertThat(records.folder1_doc1()).isNot(physicallyDeleted());
assertThat(records.folder2()).isNot(physicallyDeleted());
}
@Test
public void givenANonPrincipalConceptIsLogicallyDeletingWhenPhysicallyDeleteThenOnlyDeleteConceptsInHierarchy()
throws Exception {
Record taxo2_unit1 = records.taxo2_unit1();
Record taxo2_unit1_1 = records.taxo2_unit1_1();
given(userWithDeletePermission).logicallyDelete(records.taxo2_unit1());
when(userWithDeletePermission).physicallyDelete(records.taxo2_unit1(), withMostReferencesRemoved);
assertThat(taxo2_unit1).is(physicallyDeleted());
assertThat(taxo2_unit1_1).is(physicallyDeleted());
assertThat(records.folder1()).isNot(logicallyDeleted());
assertThat(records.folder1()).isNot(physicallyDeleted());
assertThat(records.folder1_doc1()).isNot(logicallyDeleted());
assertThat(records.folder1_doc1()).isNot(physicallyDeleted());
assertThat(records.folder2()).isNot(logicallyDeleted());
assertThat(records.folder2()).isNot(physicallyDeleted());
}
@Test
public void givenARecordReferencingALogicallyDeletedRecordWhenAddingASecondReferenceThenSecondReferenceAdded()
throws Exception {
given(records.folder2()).hasAReferenceTo(records.folder4_2());
given(userWithDeletePermission).logicallyDelete(records.folder4());
when(records.folder2()).hasAReferenceTo(records.folder4_2(), records.folder3());
recordServices.refresh(records.folder2());
assertThat((List) records.folder2().get(folderSchema.linkToOtherFolders())).hasSize(2);
}
@Test(expected = RecordServicesRuntimeException.NewReferenceToOtherLogicallyDeletedRecord.class)
public void givenARecordWhenAddingAReferenceToALogicallyDeletedRecordThenException()
throws Exception {
given(userWithDeletePermission).logicallyDelete(records.folder4());
when(records.folder2()).hasAReferenceTo(records.folder4());
}
@Test(expected = RecordServicesRuntimeException.NewReferenceToOtherLogicallyDeletedRecord.class)
public void givenARecordWhenAddingAReferenceToALogicallyDeletedSubRecordThenException()
throws Exception {
given(userWithDeletePermission).logicallyDelete(records.folder4());
when(records.folder2()).hasAReferenceTo(records.folder4_2());
}
@Test
public void givenARecordWhenAddingAReferenceToARestoredLogicallyDeletedRecordThenOK()
throws Exception {
given(userWithDeletePermission).logicallyDelete(records.folder4());
given(userWithDeletePermission).restore(records.folder4());
when(records.folder2()).hasAReferenceTo(records.folder4());
}
@Test
public void givenARecordWhenAddingAReferenceToARestoredLogicallyDeletedSubRecordThenOK()
throws Exception {
given(userWithDeletePermission).logicallyDelete(records.folder4());
given(userWithDeletePermission).restore(records.folder4());
when(records.folder2()).hasAReferenceTo(records.folder4_2());
}
@Test
public void givenARecordWithoutReferencesWhenGetListOfReferencesThenEmpty()
throws Exception {
assertThat(records.folder4()).is(notReferenced());
assertThat(records.folder4()).is(seenByUserToBeReferencedByNoRecords(userWithDeletePermission));
}
@Test
public void whenLogicallyDeletingANonPrincipalConceptThenOnlyLogicallyDeleteConceptsInHierarchy()
throws Exception {
when(userWithDeletePermission).logicallyDelete(records.taxo2_unit1());
assertThat(records.taxo2_unit1()).is(logicallyDeleted());
assertThat(records.taxo2_unit1_1()).is(logicallyDeleted());
assertThat(records.folder1()).isNot(logicallyDeleted());
assertThat(records.folder2()).isNot(logicallyDeleted());
}
@Test
public void givenARecordWith2ReferencesWhenGetListOfReferencesThen2Records()
throws Exception {
given(records.folder3()).hasAReferenceTo(records.folder4());
given(records.folder3()).hasAReferenceTo(records.folder4_2());
given(records.folder2()).hasAReferenceTo(records.folder4_2());
assertThat(records.folder4()).is(referenced());
assertThat(records.folder4())
.is(seenByUserToBeReferencedByRecords(userWithDeletePermission, records.folder2(), records.folder3()));
}
@Test
public void givenARecordWith2ReferencesWhenGetListOfReferencesWithUserOnlySeeing1RecordThen1Record()
throws Exception {
given(records.folder3()).hasAReferenceTo(records.folder4());
given(records.folder3()).hasAReferenceTo(records.folder4_2());
given(records.folder2()).hasAReferenceTo(records.folder4_2());
given(bob).hasReadPermissionOn(records.folder3());
assertThat(records.folder4()).is(referenced());
assertThat(records.folder4()).is(seenByUserToBeReferencedByRecords(bob, records.folder3()));
}
@Test
public void givenARecordWith2ReferencesWhenGetListOfReferencesWithUserSeeingNoRecordThen0RecordButStillConsideredAsReferenced()
throws Exception {
given(records.folder3()).hasAReferenceTo(records.folder4());
given(records.folder3()).hasAReferenceTo(records.folder4_2());
given(records.folder2()).hasAReferenceTo(records.folder4_2());
assertThat(records.folder4()).is(referenced());
assertThat(records.folder4()).is(seenByUserToBeReferencedByNoRecords(bob));
}
@Test
public void givenALogicallyDeletedRecordWithoutReferencesWhenGetListOfReferencesThenEmpty()
throws Exception {
given(userWithDeletePermission).logicallyDelete(records.folder4());
assertThat(records.folder4()).is(notReferenced());
assertThat(records.folder4()).is(seenByUserToBeReferencedByNoRecords(userWithDeletePermission));
}
@Test
public void givenALogicallyDeletedRecordWith2ReferencesWhenGetListOfReferencesThen2Records()
throws Exception {
given(records.folder3()).hasAReferenceTo(records.folder4());
given(records.folder3()).hasAReferenceTo(records.folder4_2());
given(records.folder2()).hasAReferenceTo(records.folder4_2());
given(userWithDeletePermission).logicallyDelete(records.folder4());
recordServices.refresh(records.folder4());
recordServices.isReferencedByOtherRecords(records.folder4());
assertThat(records.folder4()).is(referenced());
assertThat(records.folder4())
.is(seenByUserToBeReferencedByRecords(userWithDeletePermission, records.folder2(), records.folder3()));
}
@Test
public void givenALogicallyDeletedRecordWith2ReferencesWhenGetListOfReferencesWithUserOnlySeeing1RecordThen1Record()
throws Exception {
given(records.folder3()).hasAReferenceTo(records.folder4());
given(records.folder3()).hasAReferenceTo(records.folder4_2());
given(records.folder2()).hasAReferenceTo(records.folder4_2());
given(bob).hasReadPermissionOn(records.folder3());
given(userWithDeletePermission).logicallyDelete(records.folder4());
assertThat(records.folder4()).is(referenced());
assertThat(records.folder4()).is(seenByUserToBeReferencedByRecords(bob, records.folder3()));
}
@BenchmarkHistoryChart(maxRuns = 20, labelWith = LabelType.RUN_ID)
@Test
public void givenALogicallyDeletedRecordWith2ReferencesWhenGetListOfReferencesWithUserSeeingNoRecordThen0RecordButStillConsideredAsReferenced()
throws Exception {
given(records.folder3()).hasAReferenceTo(records.folder4());
given(records.folder3()).hasAReferenceTo(records.folder4_2());
given(records.folder2()).hasAReferenceTo(records.folder4_2());
given(userWithDeletePermission).logicallyDelete(records.folder4());
assertThat(records.folder4()).is(referenced());
assertThat(records.folder4()).is(seenByUserToBeReferencedByRecords(bob));
}
@Test
public void givenActiveRestoredAndLogicallyDeletedRecordsWhenSearchingRecordsUsingTheStatusFilterThenObtainCorrectResults()
throws Exception {
given(userWithDeletePermission).logicallyDelete(records.folder2());
given(userWithDeletePermission).restore(records.folder2());
given(userWithDeletePermission).logicallyDelete(records.folder4());
// Search only root folders (Folder1, 2, 3 and 4)
LogicalSearchQuery query = new LogicalSearchQuery(LogicalSearchQueryOperators.from(folderSchema.instance())
.where(folderSchema.taxonomy1()).isNotNull());
assertThat(searchServices.searchRecordIds(query))
.containsOnly(idsArray(records.folder1(), records.folder2(), records.folder3(), records.folder4()));
assertThat(searchServices.searchRecordIds(query.filteredByStatus(StatusFilter.ALL))).containsOnly(
idsArray(records.folder1(), records.folder2(), records.folder3(), records.folder4()));
assertThat(searchServices.searchRecordIds(query.filteredByStatus(StatusFilter.DELETED)))
.containsOnly(idsArray(records.folder4()));
assertThat(searchServices.searchRecordIds(query.filteredByStatus(StatusFilter.ACTIVES))).containsOnly(
idsArray(records.folder1(), records.folder2(), records.folder3()));
}
@Test(expected = RecordDeleteServicesRuntimeException_CannotTotallyDeleteSchemaType.class)
public void givenTypeNotSupportingTotalDeleteWhenTotallyDeletingRecordsThenExceptionThrown()
throws Exception {
MetadataSchemaType typeNotTotallyDeletable = schemas.get("valueList");
recordDeleteServices.totallyDeleteSchemaTypeRecords(typeNotTotallyDeletable);
}
@Test
public void givenTypeSupportingTotalDeleteWhenTotallyDeletingRecordsThenAllDeleted()
throws Exception {
MetadataSchemaType typeTotallyDeletable = schemas.get("typeSupportingRawDelete");
Record record1 = new TestRecord(typeTotallyDeletable.getDefaultSchema(), "totalRecord1").set(TITLE, "1");
Record record2 = new TestRecord(typeTotallyDeletable.getDefaultSchema(), "totalRecord2").set(TITLE, "2");
recordServices.execute(new Transaction(record1, record2));
assertThatRecord(record1).isNot(physicallyDeleted());
assertThatRecord(record2).isNot(physicallyDeleted());
assertThatRecord(records.folder2()).isNot(physicallyDeleted());
recordDeleteServices.totallyDeleteSchemaTypeRecords(typeTotallyDeletable);
assertThatRecord(record1).is(physicallyDeleted());
assertThatRecord(record2).is(physicallyDeleted());
assertThatRecord(records.folder2()).isNot(physicallyDeleted());
}
// -------------------------------------------------------------
private Condition<? super Record> logicallyDeletableBy(final User user) {
return new Condition<Record>() {
@Override
public boolean matches(Record record) {
return recordServices.isLogicallyDeletable(record, user);
}
}.describedAs("logically deletable by " + user);
}
private Condition<? super Record> logicallyThenPhysicallyDeletableBy(final User user) {
return logicallyThenPhysicallyDeletableBy(user, new RecordPhysicalDeleteOptions());
}
private Condition<? super Record> logicallyThenPhysicallyDeletableBy(final User user,
final RecordPhysicalDeleteOptions options) {
return new Condition<Record>() {
@Override
public boolean matches(Record record) {
return recordServices.isLogicallyThenPhysicallyDeletable(record, user, options);
}
}.describedAs("logically then physically deletable by " + user);
}
private Condition<? super Record> notLogicallyThenPhysicallyDeletableBy(final User user) {
return notLogicallyThenPhysicallyDeletableBy(user, new RecordPhysicalDeleteOptions());
}
private Condition<? super Record> notLogicallyThenPhysicallyDeletableBy(final User user,
final RecordPhysicalDeleteOptions options) {
return new Condition<Record>() {
@Override
public boolean matches(Record record) {
boolean deletable = recordServices.isLogicallyThenPhysicallyDeletable(record, user);
assertThat(deletable).describedAs("isLogicallyThenPhysicallyDeletable").isFalse();
boolean logicallyDeleted = false;
try {
recordServices.logicallyDelete(record, user);
logicallyDeleted = true;
recordServices.physicallyDelete(record, user, options);
return false;
} catch (Exception e) {
//OK
if (logicallyDeleted) {
recordServices.restore(record, user);
}
return true;
}
}
}.describedAs("not logically then physically deletable by " + user);
}
private Condition<? super Record> notLogicallyDeletableBy(final User user) {
return new Condition<Record>() {
@Override
public boolean matches(Record record) {
if (recordServices.isLogicallyDeletable(record, user)) {
return false;
} else {
try {
// It's not logically deletable... Fine. But let's try to deleteLogically it anyway
recordServices.logicallyDelete(record, user);
// An exception should be thrown, the condition fail
return false;
} catch (RecordServicesRuntimeException_CannotLogicallyDeleteRecord e) {
return true;
}
}
}
}.describedAs("not logically deletable by " + user);
}
private Condition<? super Record> logicallyDeletableExcludingRecordsBy(final User user) {
return new Condition<Record>() {
@Override
public boolean matches(Record record) {
return recordServices.isPrincipalConceptLogicallyDeletableExcludingContent(record, user);
}
}.describedAs("principal concept excluding records logically deletable by " + user);
}
private Condition<? super Record> notLogicallyDeletableExcludingRecordsBy(final User user) {
return new Condition<Record>() {
@Override
public boolean matches(Record record) {
if (recordServices.isPrincipalConceptLogicallyDeletableExcludingContent(record, user)) {
return false;
} else {
try {
// It's not logically deletable... Fine. But let's try to deleteLogically it anyway
recordServices.logicallyDelete(record, user);
// An exception should be thrown, the condition fail
return false;
} catch (RecordServicesRuntimeException_CannotLogicallyDeleteRecord e) {
return true;
}
}
}
}.describedAs("principal concept excluding records not logically deletable by " + user);
}
private Condition<? super Record> logicallyDeletableIncludingRecordsBy(final User user) {
return new Condition<Record>() {
@Override
public boolean matches(Record record) {
return recordServices.isPrincipalConceptLogicallyDeletableIncludingContent(record, user);
}
}.describedAs("principal concept including records logically deletable by " + user);
}
private Condition<? super Record> notLogicallyDeletableIncludingRecordsBy(final User user) {
return new Condition<Record>() {
@Override
public boolean matches(Record record) {
if (recordServices.isPrincipalConceptLogicallyDeletableIncludingContent(record, user)) {
return false;
} else {
try {
RecordLogicalDeleteOptions options = new RecordLogicalDeleteOptions()
.setBehaviorForRecordsAttachedToTaxonomy(
LogicallyDeleteTaxonomyRecordsBehavior.LOGICALLY_DELETE_THEM_ONLY_IF_PRINCIPAL_TAXONOMY);
// It's not logically deletable... Fine. But let's try to deleteLogically it anyway
recordServices.logicallyDelete(record, user, options);
// An exception should be thrown, the condition fail
return false;
} catch (RecordServicesRuntimeException_CannotLogicallyDeleteRecord e) {
return true;
}
}
}
}.describedAs("principal concept including records not logically deletable by " + user);
}
private Condition<? super Record> referencable() {
return new Condition<Record>() {
@Override
public boolean matches(Record value) {
Record record = new TestRecord(folderSchema);
record.set(folderSchema.linkToOtherFolders(), asList(value));
try {
recordServices.add(record);
return true;
} catch (Exception e) {
return false;
}
}
};
}
private Condition<? super Record> physicallyDeletableBy(final User user) {
return physicallyDeletableBy(user, new RecordPhysicalDeleteOptions());
}
private Condition<? super Record> physicallyDeletableBy(final User user, final RecordPhysicalDeleteOptions options) {
return new Condition<Record>() {
@Override
public boolean matches(Record record) {
return recordServices.isPhysicallyDeletable(record, user, options);
}
}.describedAs("physically deletable by " + user);
}
private Condition<? super Record> notPhysicallyDeletableBy(final User user) {
return notPhysicallyDeletableBy(user, new RecordPhysicalDeleteOptions());
}
private Condition<? super Record> notPhysicallyDeletableBy(final User user, final RecordPhysicalDeleteOptions options) {
return new Condition<Record>() {
@Override
public boolean matches(Record record) {
if (recordServices.isPhysicallyDeletable(record, user, options)) {
return false;
} else {
try {
// It's not physically deletable... Fine. But let's try to deleteLogically it anyway
recordServices.physicallyDelete(record, user);
// An exception should be thrown, the condition fail
return false;
} catch (RecordServicesRuntimeException_CannotPhysicallyDeleteRecord e) {
return true;
}
}
}
}.describedAs("not physically deletable by " + user);
}
private Condition<? super Record> restorableBy(final User user) {
return new Condition<Record>() {
@Override
public boolean matches(Record record) {
return recordServices.isRestorable(record, user);
}
}.describedAs("restorable by " + user);
}
private Condition<? super Record> notRestorableBy(final User user) {
return new Condition<Record>() {
@Override
public boolean matches(Record record) {
if (recordServices.isRestorable(record, user)) {
return false;
} else {
try {
// It's not restorable... Fine. But let's try to restore it anyway
recordServices.restore(record, user);
// An exception should be thrown, the condition fail
return false;
} catch (RecordServicesRuntimeException_CannotRestoreRecord e) {
return true;
}
}
}
}.describedAs("not restorable by " + user);
}
private Condition<? super Record> logicallyDeleted() {
return new Condition<Record>() {
@Override
public boolean matches(Record record) {
try {
Record refreshedRecord = recordServices.getDocumentById(record.getId());
return Boolean.TRUE == refreshedRecord.get(Schemas.LOGICALLY_DELETED_STATUS);
} catch (NoSuchRecordWithId e) {
return false;
}
}
}.describedAs("logicallyDeleted");
}
private Condition<? super Record> physicallyDeleted() {
return new Condition<Record>() {
@Override
public boolean matches(Record record) {
try {
recordServices.getDocumentById(record.getId());
return false;
} catch (NoSuchRecordWithId e) {
return true;
}
}
}.describedAs("physicallyDeleted");
}
private UserPreparation given(User user) {
return new UserPreparation(user);
}
private RecordPreparation given(Record record) {
return new RecordPreparation(record);
}
private UserPreparation when(User user) {
return new UserPreparation(user);
}
private RecordPreparation when(Record record) {
return new RecordPreparation(record);
}
private Condition<? super Record> notReferenced() {
return new Condition<Record>() {
@Override
public boolean matches(Record record) {
recordServices.refresh(record);
return !recordServices.isReferencedByOtherRecords(record);
}
}.describedAs("not referenced");
}
private Condition<? super Record> referenced() {
return new Condition<Record>() {
@Override
public boolean matches(Record record) {
recordServices.refresh(record);
return recordServices.isReferencedByOtherRecords(record);
}
}.describedAs("referenced");
}
private Condition<? super Record> seenByUserToBeReferencedByNoRecords(User user) {
return seenByUserToBeReferencedByRecords(user);
}
private Condition<? super Record> seenByUserToBeReferencedByRecords(final User user, final Record... records) {
return new Condition<Record>() {
@Override
public boolean matches(Record record) {
recordServices.refresh(record);
List<String> foundReferences = recordsIds(recordServices.getVisibleRecordsWithReferenceTo(record, user));
assertThat(foundReferences).containsOnly(idsArray(records));
return true;
}
}.describedAs("seen by user to be referenced by records");
}
private void givenSecurityDisabledInFolderSchemaType() {
MetadataSchemaTypesBuilder typesBuilder = getModelLayerFactory().getMetadataSchemasManager().modify(zeCollection);
typesBuilder.getSchemaType(folderSchema.type().getCode()).setSecurity(false);
try {
getModelLayerFactory().getMetadataSchemasManager().saveUpdateSchemaTypes(typesBuilder);
} catch (OptimisticLocking optimistickLocking) {
throw new RuntimeException(optimistickLocking);
}
}
private class UserPreparation {
private User user;
private UserPreparation(User user) {
this.user = user;
}
public void physicallyDelete(Record record) {
recordServices.physicallyDelete(record, user);
}
public void physicallyDelete(Record record, RecordPhysicalDeleteOptions options) {
recordServices.physicallyDelete(record, user, options);
}
public void logicallyDelete(Record record) {
recordServices.logicallyDelete(record, user);
}
public void logicallyDelete(Record record, RecordLogicalDeleteOptions options) {
recordServices.logicallyDelete(record, user, options);
}
// public void logicallyDeletePrincipalConceptIncludingRecords(Record record) {
// recordServices.logicallyDeletePrincipalConceptIncludingRecords(record, user);
// }
//
// public void logicallyDeletePrincipalConceptExcludingRecords(Record record) {
// recordServices.logicallyDeletePrincipalConceptExcludingRecords(record, user);
// }
public void restore(Record record) {
recordServices.restore(record, user);
}
public void hasDeletePermissionOn(Record record)
throws InterruptedException {
recordServices.refresh(record);
authorizationsServices.add(authorizationForUsers(user).on(record).givingReadDeleteAccess());
waitForBatchProcess();
}
public void hasReadPermissionOn(Record record)
throws InterruptedException {
recordServices.refresh(record);
authorizationsServices.add(authorizationForUsers(user).on(record).givingReadAccess());
waitForBatchProcess();
}
public void hasRemovedDeletePermissionOn(Record record)
throws InterruptedException {
recordServices.refresh(record);
String authorizationDetailId = authorizationsServices.getRecordAuthorizations(record).get(0).getDetail().getId();
authorizationsServices.execute(modifyAuthorizationOnRecord(authorizationDetailId, record).removingItOnRecord());
waitForBatchProcess();
}
public void modify(Record record) {
recordServices.refresh(record);
record.set(TITLE, record.get(TITLE) + " modified");
try {
recordServices.update(record);
} catch (RecordServicesException e) {
throw new RuntimeException(e);
}
}
}
private class RecordPreparation {
private Record record;
private RecordPreparation(Record record) {
this.record = record;
}
public void hasASingleValueListReferenceTo(Record anotherRecord) {
record.set(folderSchema.instance().getMetadata("valueListSingleRef"), anotherRecord);
try {
recordServices.update(record);
} catch (RecordServicesException e) {
throw new RuntimeException(e);
}
}
public void hasAValueListReferenceTo(Record... anotherRecords) {
record.set(folderSchema.instance().getMetadata("valueListRef"), asList(anotherRecords));
try {
recordServices.update(record);
} catch (RecordServicesException e) {
throw new RuntimeException(e);
}
}
public void hasAReferenceTo(Record... anotherRecords) {
record.set(folderSchema.linkToOtherFolders(), asList(anotherRecords));
try {
recordServices.update(record);
} catch (RecordServicesException e) {
throw new RuntimeException(e);
}
}
public void hasASingleValueReferenceTo(Record anotherRecord) {
record.set(folderSchema.linkToOtherFolder(), anotherRecord);
try {
recordServices.update(record);
} catch (RecordServicesException e) {
throw new RuntimeException(e);
}
}
public void hasNewParent(Record record)
throws InterruptedException {
recordServices.refresh(this.record);
this.record.set(folderSchema.parent(), record);
try {
recordServices.update(this.record);
} catch (RecordServicesException e) {
throw new RuntimeException(e);
}
waitForBatchProcess();
}
public void hasAReferenceToUnclassifiedSecuredRecord(Record referencedRecord)
throws InterruptedException {
this.record.set(folderSchema.instance().get("securedUnclassified"), referencedRecord);
try {
recordServices.update(this.record);
} catch (RecordServicesException e) {
throw new RuntimeException(e);
}
waitForBatchProcess();
}
}
private MetadataSchemaTypesConfigurator unsecuredAndUnclassifiedValueListSchemaAndUnclassifiedSecuredSchema() {
return new MetadataSchemaTypesConfigurator() {
@Override
public void configure(MetadataSchemaTypesBuilder schemaTypes) {
MetadataSchemaTypeBuilder aValueListType = schemaTypes.createNewSchemaType("valueList");
aValueListType.setSecurity(false);
MetadataSchemaTypeBuilder securedUnclassifiedSchemaType = schemaTypes.createNewSchemaType("securedUnclassified");
securedUnclassifiedSchemaType.setSecurity(true);
securedUnclassifiedSchemaType.getDefaultSchema().create("parent")
.defineChildOfRelationshipToType(securedUnclassifiedSchemaType);
MetadataSchemaBuilder folderSchema = schemaTypes.getSchemaType("folder").getDefaultSchema();
folderSchema.create("valueListRef").defineReferencesTo(aValueListType).setMultivalue(true);
folderSchema.create("valueListSingleRef").defineReferencesTo(aValueListType).setMultivalue(false);
folderSchema.create("securedUnclassified").defineReferencesTo(securedUnclassifiedSchemaType);
MetadataSchemaTypeBuilder typeSupportingRawDelete = schemaTypes.createNewSchemaType("typeSupportingRawDelete")
.setInTransactionLog(false);
}
};
}
private void givenMultiValueLinkToOtherFolderMetadatasIs(final boolean value) {
schemas.modify(new MetadataSchemaTypesAlteration() {
@Override
public void alter(MetadataSchemaTypesBuilder types) {
types.getMetadata(schemas.folderSchema.linkToOtherFolders().getCode()).setDefaultRequirement(value);
}
});
}
private void givenSingleValueLinkToOtherFolderMetadatasIs(final boolean value) {
schemas.modify(new MetadataSchemaTypesAlteration() {
@Override
public void alter(MetadataSchemaTypesBuilder types) {
types.getMetadata(schemas.folderSchema.linkToOtherFolder().getCode()).setDefaultRequirement(value);
}
});
}
}