package com.constellio.app.services.metadata; import static com.constellio.app.modules.rm.model.enums.CopyType.PRINCIPAL; import static com.constellio.app.services.metadata.DeletionProhibitionReason.CALCULATED_METADATA_SOURCE; import static com.constellio.app.services.metadata.DeletionProhibitionReason.COPIED_METADATA_REFERENCE; import static com.constellio.app.services.metadata.DeletionProhibitionReason.COPIED_METADATA_SOURCE; import static com.constellio.app.services.metadata.DeletionProhibitionReason.EXTRACTED_METADATA_SOURCE; import static com.constellio.app.services.metadata.DeletionProhibitionReason.FACET_METADATA; import static com.constellio.app.services.metadata.DeletionProhibitionReason.INHERITED_METADATA; import static com.constellio.app.services.metadata.DeletionProhibitionReason.POPULATED_METADATA; import static com.constellio.model.entities.schemas.MetadataValueType.BOOLEAN; import static com.constellio.model.entities.schemas.MetadataValueType.DATE; import static com.constellio.model.entities.schemas.MetadataValueType.STRING; import static java.util.Arrays.asList; import static org.assertj.core.api.Assertions.assertThat; import static org.junit.Assert.fail; import java.util.List; import org.junit.Before; import org.junit.Test; import com.constellio.app.modules.rm.RMTestRecords; import com.constellio.app.modules.rm.model.enums.CopyType; import com.constellio.app.modules.rm.services.RMSchemasRecordsServices; import com.constellio.app.modules.rm.wrappers.AdministrativeUnit; import com.constellio.app.modules.rm.wrappers.Document; import com.constellio.app.modules.rm.wrappers.Folder; import com.constellio.app.services.metadata.MetadataDeletionException.MetadataDeletionException_CalculatedMetadataSource; import com.constellio.app.services.metadata.MetadataDeletionException.MetadataDeletionException_CopiedMetadataReference; import com.constellio.app.services.metadata.MetadataDeletionException.MetadataDeletionException_CopiedMetadataSource; import com.constellio.app.services.metadata.MetadataDeletionException.MetadataDeletionException_ExtractedMetadataSource; import com.constellio.app.services.metadata.MetadataDeletionException.MetadataDeletionException_FacetMetadata; import com.constellio.app.services.metadata.MetadataDeletionException.MetadataDeletionException_InheritedMetadata; import com.constellio.app.services.metadata.MetadataDeletionException.MetadataDeletionException_PopulatedMetadata; import com.constellio.app.services.metadata.MetadataDeletionException.MetadataDeletionException_SystemMetadata; import com.constellio.data.utils.TimeProvider; import com.constellio.model.entities.calculators.CalculatorParameters; import com.constellio.model.entities.calculators.MetadataValueCalculator; import com.constellio.model.entities.calculators.dependencies.Dependency; import com.constellio.model.entities.calculators.dependencies.LocalDependency; import com.constellio.model.entities.calculators.dependencies.ReferenceDependency; import com.constellio.model.entities.schemas.Metadata; import com.constellio.model.entities.schemas.MetadataSchemaTypes; import com.constellio.model.entities.schemas.MetadataSchemasRuntimeException.NoSuchMetadata; import com.constellio.model.entities.schemas.MetadataValueType; import com.constellio.model.services.records.RecordServices; import com.constellio.model.services.records.RecordServicesException; import com.constellio.model.services.schemas.MetadataSchemasManager; import com.constellio.model.services.schemas.MetadataSchemasManagerException.OptimisticLocking; import com.constellio.model.services.schemas.builders.MetadataBuilder; import com.constellio.model.services.schemas.builders.MetadataPopulateConfigsBuilder; 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.sdk.tests.ConstellioTest; public class MetadataDeletionServiceAcceptanceTest extends ConstellioTest { private RMSchemasRecordsServices rm; RMTestRecords records = new RMTestRecords(zeCollection); MetadataDeletionService metadataDeletionService; Metadata userMetadataInCustomSchema, userMetadataInCustomSchema2, mappedMetadata, systemMetadata, directlyPopulatedMetadata, populatedMetadataInInheritance, inheritedMetadata, copiedMetadataSource, copiedMetadataDestination, copiedMetadataReference, calculatedMetadataLocalDependencySource, calculatedMetadataReferenceDependencySource, calculatedMetadataDestination, extractedMetadataSource, extractedMetadataDestination, facetMetadata; private MetadataSchemasManager schemaManager; private Metadata userEncryptedMetadataWithDefaultValue; private RecordServices recordServices; private MetadataSchemaBuilder folderSchema, customFolderSchema, documentSchema, documentCustomSchema; @Before public void setUp() throws Exception { prepareSystem( withZeCollection().withConstellioRMModule().withAllTestUsers().withRMTest( records).withFoldersAndContainersOfEveryStatus() ); schemaManager = getModelLayerFactory().getMetadataSchemasManager(); metadataDeletionService = new MetadataDeletionService(getAppLayerFactory(), zeCollection); rm = new RMSchemasRecordsServices(zeCollection, getAppLayerFactory()); recordServices = getModelLayerFactory().newRecordServices(); initTestData(); } private void initTestData() throws OptimisticLocking, RecordServicesException { MetadataSchemaTypesBuilder schemaTypesBuilder = schemaManager .modify(zeCollection); MetadataSchemaTypeBuilder folderSchemaType = schemaTypesBuilder.getSchemaType(Folder.SCHEMA_TYPE); folderSchema = schemaTypesBuilder.getSchema(Folder.DEFAULT_SCHEMA); MetadataSchemaBuilder administrativeUnitSchema = schemaTypesBuilder.getSchema(AdministrativeUnit.DEFAULT_SCHEMA); customFolderSchema = folderSchemaType.createCustomSchema("customFolder"); MetadataSchemaBuilder customFolderSchema2 = folderSchemaType.createCustomSchema("customFolder2"); MetadataBuilder mappedMetadataBuilderWithDefaultValue = folderSchema.create("MAPMetadata").setType(STRING) .setDefaultValue("default"); MetadataBuilder userEncryptedMetadataBuilderWithDefaultValue = folderSchema.create("USREncryptMetadata").setType(STRING) .setDefaultValue("encrypted").setEncrypted(true); MetadataBuilder userMetadataBuilder = customFolderSchema.createUndeletable("USRMetadata").setType(BOOLEAN); customFolderSchema2.createUndeletable("USRMetadata").setType(BOOLEAN); MetadataBuilder systemMetadataBuilder = folderSchema.createUndeletable("systemMetadata").setType(STRING); MetadataBuilder populatedMetadataBuilder = folderSchema.createUndeletable("USRPopulatedMetadata").setType(STRING); folderSchema.createUndeletable("populatedMetadataInInheritance").setType(STRING); MetadataBuilder inheritedMetadataBuilder = folderSchema.createUndeletable("USRInheritedMetadata").setType(DATE); MetadataBuilder copiedMetadataSourceBuilder = folderSchema.createUndeletable("USRCopySourceMetadata").setType(DATE); MetadataBuilder copiedMetadataReferenceBuilder = folderSchema.createUndeletable("USRCopiedReferenceMetadata") .defineChildOfRelationshipToType(folderSchemaType); MetadataBuilder copiedMetadataDestinationBuilder = folderSchema.createUndeletable("USRCopyDestinationMetadata") .setType(DATE) .defineDataEntry().asCopied(copiedMetadataReferenceBuilder, copiedMetadataSourceBuilder); MetadataBuilder localDependencyInCalculatorBuilder = folderSchema .createUndeletable("USRCalculatedLocalDependencyMetadata") .setType(BOOLEAN); MetadataBuilder referenceDependencyInCalculatorBuilder = administrativeUnitSchema .createUndeletable("USRCalculatedReferenceDependencyMetadata") .setType(BOOLEAN); MetadataBuilder calculatedMetadataDestinationBuilder = folderSchema.createUndeletable("USRCalculatedDestinationMetadata") .setType(BOOLEAN).defineDataEntry().asCalculated(TestCalculator.class); MetadataBuilder extractedMetadataSourceBuilder = folderSchema.createUndeletable("USRExtractedSourceMetadata") .defineAsEnum(CopyType.class); MetadataPopulateConfigsBuilder metadataPopulateConfigsBuilder = MetadataPopulateConfigsBuilder.create(); metadataPopulateConfigsBuilder.setProperties(asList("USRExtractedSourceMetadata")); MetadataBuilder extractedMetadataDestinationBuilder = folderSchema.createUndeletable("USRExtractedDestinationMetadata") .defineAsEnum(CopyType.class); extractedMetadataDestinationBuilder.definePopulateConfigsBuilder(metadataPopulateConfigsBuilder); MetadataBuilder facetMetadataBuilder = folderSchema.createUndeletable("USRFacetMetadata").setType(STRING) .setDefaultValue("facet default value"); schemaManager.saveUpdateSchemaTypes(schemaTypesBuilder); recordServices.add(records.getFolder_A02() .set(populatedMetadataBuilder.getLocalCode(), "directly populated metadata value") .set(userEncryptedMetadataBuilderWithDefaultValue.getLocalCode(), "encrypted")); recordServices.add(rm.newFacetField().setFieldDataStoreCode(facetMetadataBuilder.getCode()).setTitle("Ze Facet")); MetadataSchemaTypes types = schemaManager.getSchemaTypes(zeCollection); populatedMetadataInInheritance = types .getMetadata(folderSchema.getCode() + "_" + "populatedMetadataInInheritance"); Folder customFolder = new Folder(rm.create(types.getSchema(customFolderSchema.getCode())), types); recordServices.add(customFolder.setTitle("customFolder").setOpenDate(TimeProvider.getLocalDate()) .setAdministrativeUnitEntered(records.getUnit10()) .setCategoryEntered(records.getCategory_X()).setRetentionRuleEntered(records.getRule1()) .setMediumTypes(rm.PA(), rm.DM()).setCopyStatusEntered(PRINCIPAL) .set("populatedMetadataInInheritance", "populated metadata value")); directlyPopulatedMetadata = types.getMetadata(populatedMetadataBuilder.getCode()); mappedMetadata = types.getMetadata(mappedMetadataBuilderWithDefaultValue.getCode()); userEncryptedMetadataWithDefaultValue = types.getMetadata(userEncryptedMetadataBuilderWithDefaultValue.getCode()); userMetadataInCustomSchema = types.getMetadata(userMetadataBuilder.getCode()); userMetadataInCustomSchema2 = types.getMetadata(customFolderSchema2.getCode() + "_" + userMetadataBuilder.getLocalCode()); systemMetadata = types.getMetadata(systemMetadataBuilder.getCode()); inheritedMetadata = types.getMetadata(customFolderSchema.getCode() + "_" + inheritedMetadataBuilder.getLocalCode()); copiedMetadataSource = types.getMetadata(copiedMetadataSourceBuilder.getCode()); copiedMetadataDestination = types.getMetadata(copiedMetadataDestinationBuilder.getCode()); copiedMetadataReference = types.getMetadata(copiedMetadataReferenceBuilder.getCode()); calculatedMetadataLocalDependencySource = types.getMetadata(localDependencyInCalculatorBuilder.getCode()); calculatedMetadataReferenceDependencySource = types.getMetadata(referenceDependencyInCalculatorBuilder.getCode()); calculatedMetadataDestination = types.getMetadata(calculatedMetadataDestinationBuilder.getCode()); extractedMetadataSource = types.getMetadata(extractedMetadataSourceBuilder.getCode()); extractedMetadataDestination = types.getMetadata(extractedMetadataDestinationBuilder.getCode()); facetMetadata = types.getMetadata(facetMetadataBuilder.getCode()); createMetadataWithSameNamesInDocumentSchema(); } private void createMetadataWithSameNamesInDocumentSchema() throws OptimisticLocking { MetadataSchemaTypesBuilder schemaTypesBuilder = schemaManager .modify(zeCollection); MetadataSchemaTypeBuilder documetSchemaType = schemaTypesBuilder.getSchemaType(Document.SCHEMA_TYPE); documentSchema = documetSchemaType.getDefaultSchema(); documentCustomSchema = documetSchemaType.createCustomSchema("customFolder2"); documentSchema.create("MAPMetadata").setType(STRING) .setDefaultValue("default"); documentSchema.create("USREncryptMetadata").setType(STRING) .setDefaultValue("encrypted").setEncrypted(true); documentSchema.createUndeletable("USRMetadata").setType(BOOLEAN); documentSchema.createUndeletable("systemMetadata").setType(STRING); documentSchema.createUndeletable("USRPopulatedMetadata").setType(STRING); documentSchema.createUndeletable("populatedMetadataInInheritance").setType(STRING); documentSchema.createUndeletable("USRInheritedMetadata").setType(DATE); documentSchema.createUndeletable("USRCopySourceMetadata").setType(DATE); documentSchema.createUndeletable("USRCopiedReferenceMetadata").setType(STRING); documentSchema.createUndeletable("USRCopyDestinationMetadata").setType(DATE); documentSchema.createUndeletable("USRCalculatedLocalDependencyMetadata").setType(BOOLEAN); documentSchema.createUndeletable("USRCalculatedDestinationMetadata").setType(BOOLEAN); documentSchema.createUndeletable("USRExtractedSourceMetadata").defineAsEnum(CopyType.class); documentSchema.createUndeletable("USRExtractedDestinationMetadata").defineAsEnum(CopyType.class); documentSchema.createUndeletable("USRFacetMetadata").setType(STRING).setDefaultValue("facet default value"); schemaManager.saveUpdateSchemaTypes(schemaTypesBuilder); } @Test public void whenIsMetadataDeletableThenReturnExpectedValue() { assertThat(metadataDeletionService.isMetadataDeletable(userMetadataInCustomSchema.getCode())).isTrue(); assertThat(metadataDeletionService.isMetadataDeletable(mappedMetadata.getCode())).isTrue(); assertThat(metadataDeletionService.isMetadataDeletable(systemMetadata.getCode())).isFalse(); assertThat(metadataDeletionService.isMetadataDeletable(userMetadataInCustomSchema.getLocalCode())).isTrue(); assertThat(metadataDeletionService.isMetadataDeletable(mappedMetadata.getLocalCode())).isTrue(); assertThat(metadataDeletionService.isMetadataDeletable(systemMetadata.getLocalCode())).isFalse(); } @Test public void whenCanDeleteMetadataThenBehavesAsExpected() { assertThat(metadataDeletionService.canDeleteMetadata(userMetadataInCustomSchema.getCode())).isNull(); assertThat(metadataDeletionService.canDeleteMetadata(mappedMetadata.getCode())).isNull(); assertThat(metadataDeletionService.canDeleteMetadata(copiedMetadataDestination.getCode())).isNull(); assertThat(metadataDeletionService.canDeleteMetadata(calculatedMetadataDestination.getCode())).isNull(); assertThat(metadataDeletionService.canDeleteMetadata(extractedMetadataDestination.getCode())).isNull(); assertThat(metadataDeletionService.canDeleteMetadata(userEncryptedMetadataWithDefaultValue.getCode())).isNull(); assertThat(metadataDeletionService.canDeleteMetadata(inheritedMetadata.getCode())).isEqualTo(INHERITED_METADATA); assertThat(metadataDeletionService.canDeleteMetadata(directlyPopulatedMetadata.getCode())).isEqualTo(POPULATED_METADATA); assertThat(metadataDeletionService.canDeleteMetadata(populatedMetadataInInheritance .getCode())).isEqualTo(POPULATED_METADATA); assertThat(metadataDeletionService.canDeleteMetadata(facetMetadata.getCode())) .isEqualTo(FACET_METADATA); System.out.println(metadataDeletionService.canDeleteMetadata(calculatedMetadataLocalDependencySource.getCode())); assertThat(metadataDeletionService.canDeleteMetadata(calculatedMetadataLocalDependencySource.getCode())) .isEqualTo(CALCULATED_METADATA_SOURCE); assertThat(metadataDeletionService.canDeleteMetadata(extractedMetadataSource.getCode())) .isEqualTo(EXTRACTED_METADATA_SOURCE); assertThat(metadataDeletionService.canDeleteMetadata(calculatedMetadataReferenceDependencySource.getCode())) .isEqualTo(CALCULATED_METADATA_SOURCE); assertThat(metadataDeletionService.canDeleteMetadata(copiedMetadataReference.getCode())) .isEqualTo(COPIED_METADATA_REFERENCE); assertThat(metadataDeletionService.canDeleteMetadata(copiedMetadataSource.getCode())) .isEqualTo(COPIED_METADATA_SOURCE); } @Test public void whenDeleteMetadataThenBehavesAsExpected() throws MetadataDeletionException { metadataDeletionService.deleteMetadata(folderSchema.getCode() + "_" + mappedMetadata.getLocalCode()); assertMetadataDeletedCorrectly(mappedMetadata); metadataDeletionService.deleteMetadata(userEncryptedMetadataWithDefaultValue.getCode()); assertMetadataDeletedCorrectly(userEncryptedMetadataWithDefaultValue); assertMetadataDeletedCorrectly(userEncryptedMetadataWithDefaultValue); metadataDeletionService.deleteMetadata(userMetadataInCustomSchema.getCode()); assertMetadataDeletedCorrectly(userMetadataInCustomSchema); assertThat(schemaManager.getSchemaTypes(zeCollection).getMetadata(userMetadataInCustomSchema2.getCode())).isNotNull(); try { metadataDeletionService.deleteMetadata(systemMetadata.getCode()); fail("non user metadata deletion is forbidden"); } catch (MetadataDeletionException_SystemMetadata e) { //OK assertMetadataNotDeletedAndCanBeDeletedFromDocumentSchema(systemMetadata); } try { metadataDeletionService.deleteMetadata(directlyPopulatedMetadata.getCode()); fail("populated metadata deletion is forbidden"); } catch (MetadataDeletionException_PopulatedMetadata e) { //OK assertMetadataNotDeletedAndCanBeDeletedFromDocumentSchema(directlyPopulatedMetadata); } try { metadataDeletionService.deleteMetadata(extractedMetadataSource.getCode()); fail("extracted metadata source deletion is forbidden"); } catch (MetadataDeletionException_ExtractedMetadataSource e) { //OK assertMetadataNotDeletedAndCanBeDeletedFromDocumentSchema(extractedMetadataSource); } try { metadataDeletionService.deleteMetadata(facetMetadata.getCode()); fail("facet metadata deletion is forbidden"); } catch (MetadataDeletionException_FacetMetadata e) { //OK assertMetadataNotDeletedAndCanBeDeletedFromDocumentSchema(facetMetadata); } try { metadataDeletionService.deleteMetadata(inheritedMetadata.getCode()); fail("inherited metadata deletion is forbidden"); } catch (MetadataDeletionException_InheritedMetadata e) { //OK assertMetadataNotDeletedAndCanBeDeletedFromDocumentSchema(inheritedMetadata); } try { metadataDeletionService.deleteMetadata(calculatedMetadataLocalDependencySource.getCode()); fail("calculated metadata source deletion is forbidden"); } catch (MetadataDeletionException_CalculatedMetadataSource e) { //OK assertMetadataNotDeletedAndCanBeDeletedFromDocumentSchema(calculatedMetadataLocalDependencySource); } try { metadataDeletionService.deleteMetadata(calculatedMetadataReferenceDependencySource.getCode()); fail("calculated metadata source deletion is forbidden"); } catch (MetadataDeletionException_CalculatedMetadataSource e) { //OK assertMetadataNotDeletedAndCanBeDeletedFromDocumentSchema(calculatedMetadataReferenceDependencySource); } try { metadataDeletionService.deleteMetadata(copiedMetadataReference.getCode()); fail("copied metadata reference deletion is forbidden"); } catch (MetadataDeletionException_CopiedMetadataReference e) { //OK assertMetadataNotDeletedAndCanBeDeletedFromDocumentSchema(copiedMetadataReference); } try { metadataDeletionService.deleteMetadata(copiedMetadataSource.getCode()); fail("copied metadata source deletion is forbidden"); } catch (MetadataDeletionException_CopiedMetadataSource e) { //OK assertMetadataNotDeletedAndCanBeDeletedFromDocumentSchema(copiedMetadataSource); } metadataDeletionService.deleteMetadata(copiedMetadataDestination.getCode()); assertMetadataDeletedCorrectly(copiedMetadataDestination); metadataDeletionService.deleteMetadata(calculatedMetadataDestination.getCode()); assertMetadataDeletedCorrectly(calculatedMetadataDestination); metadataDeletionService.deleteMetadata(extractedMetadataDestination.getCode()); assertMetadataDeletedCorrectly(extractedMetadataDestination); } private void assertMetadataNotDeletedAndCanBeDeletedFromDocumentSchema(Metadata metadata) throws MetadataDeletionException { MetadataSchemaTypes types = schemaManager.getSchemaTypes(zeCollection); Metadata metadataFound = types.getMetadata(metadata.getCode()); assertThat(metadataFound).isNotNull(); //FIXME enlever commentaire /*try { String metadataCode = documentCustomSchema .getCode() + "_" + metadata.getLocalCode(); types.getMetadata(metadataCode); fail("Metadata should be deleted " + metadataCode); } catch (NoSuchMetadata e) { //OK }*/ } private void assertMetadataDeletedCorrectly(Metadata metadata) { MetadataSchemaTypes types = schemaManager.getSchemaTypes(zeCollection); assertDeletedFromDefaultFolderSchema(types, metadata.getLocalCode()); assertDeletedFromCustomFolderSchema(types, metadata.getLocalCode()); assertNotDeletedFromDefaultDocumentSchema(types, metadata.getLocalCode()); assertNotDeletedFromCustomDocumentSchema(types, metadata.getLocalCode()); } private void assertNotDeletedFromCustomDocumentSchema(MetadataSchemaTypes types, String localCode) { String metadataCode = documentCustomSchema.getCode() + "_" + localCode; Metadata metadata = types.getMetadata(metadataCode); assertThat(metadata).isNotNull(); } private void assertNotDeletedFromDefaultDocumentSchema(MetadataSchemaTypes types, String localCode) { String metadataCode = documentSchema.getCode() + "_" + localCode; Metadata metadata = types.getMetadata(metadataCode); assertThat(metadata).isNotNull(); } private void assertDeletedFromCustomFolderSchema(MetadataSchemaTypes types, String localCode) { try { String metadataCode = customFolderSchema .getCode() + "_" + localCode; types.getMetadata(metadataCode); fail("Metadata should be deleted " + metadataCode); } catch (NoSuchMetadata e) { //OK } } private void assertDeletedFromDefaultFolderSchema(MetadataSchemaTypes types, String localCode) { try { String metadataCode = folderSchema.getCode() + "_" + localCode; types.getMetadata(metadataCode); fail("Metadata should be deleted " + metadataCode); } catch (NoSuchMetadata e) { //OK } } public static class TestCalculator implements MetadataValueCalculator<Boolean> { ReferenceDependency<Boolean> referenceDependency = ReferenceDependency .toABoolean(Folder.ADMINISTRATIVE_UNIT, "USRCalculatedReferenceDependencyMetadata"); LocalDependency<Boolean> localDependency = LocalDependency.toABoolean("USRCalculatedLocalDependencyMetadata"); @Override public Boolean calculate(CalculatorParameters parameters) { Boolean code = parameters.get(referenceDependency); if (code == null) { return null; } return !code; } @Override public Boolean getDefaultValue() { return null; } @Override public MetadataValueType getReturnType() { return BOOLEAN; } @Override public boolean isMultiValue() { return false; } @Override public List<? extends Dependency> getDependencies() { return asList(referenceDependency, localDependency); } } }