diff --git a/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/model/rma/type/RecordFolderType.java b/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/model/rma/type/RecordFolderType.java index d9b8ffe6b4..9fb22a875c 100644 --- a/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/model/rma/type/RecordFolderType.java +++ b/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/model/rma/type/RecordFolderType.java @@ -32,6 +32,7 @@ import java.util.Map; import org.alfresco.error.AlfrescoRuntimeException; import org.alfresco.model.ContentModel; +import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel; import org.alfresco.module.org_alfresco_module_rm.model.behaviour.AbstractDisposableItem; import org.alfresco.module.org_alfresco_module_rm.record.RecordService; import org.alfresco.module.org_alfresco_module_rm.recordfolder.RecordFolderService; @@ -40,6 +41,7 @@ import org.alfresco.repo.copy.CopyBehaviourCallback; import org.alfresco.repo.copy.CopyDetails; import org.alfresco.repo.copy.DefaultCopyBehaviourCallback; import org.alfresco.repo.node.NodeServicePolicies; +import org.alfresco.repo.node.integrity.IntegrityException; import org.alfresco.repo.policy.Behaviour.NotificationFrequency; import org.alfresco.repo.policy.annotation.Behaviour; import org.alfresco.repo.policy.annotation.BehaviourBean; @@ -219,6 +221,15 @@ public class RecordFolderType extends AbstractDisposableItem if (nodeService.exists(nodeRef)) { + boolean notFolderOrRmFolderSubType = !instanceOf(nodeRef, ContentModel.TYPE_FOLDER) || + instanceOf(nodeRef, RecordsManagementModel.TYPE_RECORDS_MANAGEMENT_CONTAINER) || + instanceOf(nodeRef, RecordsManagementModel.TYPE_RECORD_FOLDER) || + instanceOf(nodeRef, RecordsManagementModel.TYPE_TRANSFER); + + if (!instanceOf(nodeRef, ContentModel.TYPE_CONTENT) && notFolderOrRmFolderSubType) + { + throw new IntegrityException(I18NUtil.getMessage(MSG_CANNOT_CREATE_RECORD_FOLDER), null); + } // ensure nothing is being added to a closed record folder NodeRef recordFolder = childAssocRef.getParentRef(); Boolean isClosed = (Boolean) nodeService.getProperty(recordFolder, PROP_IS_CLOSED); @@ -245,9 +256,9 @@ public class RecordFolderType extends AbstractDisposableItem final NodeRef recordFolder = childAssocRef.getChildRef(); // only records can be added in a record folder or hidden folders(is the case of e-mail attachments) - if (!instanceOf(recordFolder, ContentModel.TYPE_CONTENT) && !nodeService.hasAspect(recordFolder, ContentModel.ASPECT_HIDDEN)) + if (instanceOf(recordFolder, ContentModel.TYPE_FOLDER) && !nodeService.hasAspect(recordFolder, ContentModel.ASPECT_HIDDEN)) { - throw new AlfrescoRuntimeException(I18NUtil.getMessage(MSG_CANNOT_CREATE_RECORD_FOLDER)); + throw new IntegrityException(I18NUtil.getMessage(MSG_CANNOT_CREATE_RECORD_FOLDER), null); } behaviourFilter.disableBehaviour(); diff --git a/rm-community/rm-community-repo/unit-test/java/org/alfresco/module/org_alfresco_module_rm/model/rma/type/RecordFolderTypeUnitTest.java b/rm-community/rm-community-repo/unit-test/java/org/alfresco/module/org_alfresco_module_rm/model/rma/type/RecordFolderTypeUnitTest.java new file mode 100644 index 0000000000..c058675604 --- /dev/null +++ b/rm-community/rm-community-repo/unit-test/java/org/alfresco/module/org_alfresco_module_rm/model/rma/type/RecordFolderTypeUnitTest.java @@ -0,0 +1,226 @@ +/* + * #%L + * Alfresco Records Management Module + * %% + * Copyright (C) 2005 - 2016 Alfresco Software Limited + * %% + * This file is part of the Alfresco software. + * - + * If the software was purchased under a paid Alfresco license, the terms of + * the paid license agreement will prevail. Otherwise, the software is + * provided under the following open source license terms: + * - + * Alfresco is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * - + * Alfresco is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * - + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + * #L% + */ + +package org.alfresco.module.org_alfresco_module_rm.model.rma.type; + +import static org.mockito.Mockito.when; + +import org.alfresco.module.org_alfresco_module_rm.test.util.AlfMock; +import org.alfresco.module.org_alfresco_module_rm.test.util.BaseUnitTest; +import org.alfresco.module.org_alfresco_module_rm.test.util.MockAuthenticationUtilHelper; +import org.alfresco.module.org_alfresco_module_rm.util.AuthenticationUtil; +import org.alfresco.module.org_alfresco_module_rm.vital.VitalRecordService; +import org.alfresco.repo.node.integrity.IntegrityException; +import org.alfresco.service.cmr.repository.ChildAssociationRef; +import org.alfresco.service.cmr.repository.NodeRef; +import org.alfresco.service.namespace.QName; +import org.junit.Before; +import org.junit.Test; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + +/** + * Unit test class for RecordFolderType + * + * @author Silviu Dinuta + * @since 2.6 + * + */ +public class RecordFolderTypeUnitTest extends BaseUnitTest +{ + @Mock + private AuthenticationUtil mockAuthenticationUtil; + + @Mock + private VitalRecordService mockedVitalRecordService; + + private @InjectMocks RecordFolderType recordFolderType; + + @Before + public void setup() + { + MockitoAnnotations.initMocks(this); + MockAuthenticationUtilHelper.setup(mockAuthenticationUtil); + when(mockedApplicationContext.getBean("dbNodeService")).thenReturn(mockedNodeService); + } + + /** + * Given that we try to add one rma:transfer to a record folder, + * Then IntegrityException is thrown. + */ + @Test(expected = IntegrityException.class) + public void testCreateTransferFolder() throws Exception + { + NodeRef recordFolderNodeRef = AlfMock.generateNodeRef(mockedNodeService, TYPE_RECORD_FOLDER); + QName type = AlfMock.generateQName(); + when(mockedDictionaryService.isSubClass(type, TYPE_TRANSFER)).thenReturn(true); + NodeRef nodeRef = AlfMock.generateNodeRef(mockedNodeService, type, true); + ChildAssociationRef childAssocRef = generateChildAssociationRef(recordFolderNodeRef, nodeRef); + recordFolderType.onCreateChildAssociation(childAssocRef, true); + } + + /** + * Given that we try to add one record folder to a record folder, + * Then IntegrityException is thrown. + */ + @Test(expected = IntegrityException.class) + public void testCreateRecordFolder() throws Exception + { + NodeRef recordFolderNodeRef = AlfMock.generateNodeRef(mockedNodeService, TYPE_RECORD_FOLDER); + QName type = AlfMock.generateQName(); + when(mockedDictionaryService.isSubClass(type, TYPE_RECORD_FOLDER)).thenReturn(true); + NodeRef nodeRef = AlfMock.generateNodeRef(mockedNodeService, type, true); + ChildAssociationRef childAssocRef = generateChildAssociationRef(recordFolderNodeRef, nodeRef); + recordFolderType.onCreateChildAssociation(childAssocRef, true); + } + + /** + * Given that we try to add sub-type of rma:recordsManagementContainer to a record folder, + * Then IntegrityException is thrown. + */ + @Test(expected = IntegrityException.class) + public void testCreateSubTypesOfRecordManagementContainer() throws Exception + { + NodeRef recordFolderNodeRef = AlfMock.generateNodeRef(mockedNodeService, TYPE_RECORD_FOLDER); + QName type = AlfMock.generateQName(); + when(mockedDictionaryService.isSubClass(type, TYPE_RECORDS_MANAGEMENT_CONTAINER)).thenReturn(true); + NodeRef nodeRef = AlfMock.generateNodeRef(mockedNodeService, type, true); + ChildAssociationRef childAssocRef = generateChildAssociationRef(recordFolderNodeRef, nodeRef); + recordFolderType.onCreateChildAssociation(childAssocRef, true); + } + + /** + * Given that we try to add cm:folder sub-type to a record folder, + * Then the operation is successful. + */ + @Test + public void testCreateFolderSubType() throws Exception + { + NodeRef recordFolderNodeRef = AlfMock.generateNodeRef(mockedNodeService, TYPE_RECORD_FOLDER); + QName type = AlfMock.generateQName(); + when(mockedDictionaryService.isSubClass(type, TYPE_FOLDER)).thenReturn(true); + NodeRef nodeRef = AlfMock.generateNodeRef(mockedNodeService, type, true); + ChildAssociationRef childAssocRef = generateChildAssociationRef(recordFolderNodeRef, nodeRef); + recordFolderType.onCreateChildAssociation(childAssocRef, true); + } + + /** + * Given that we try to add non cm:folder sub-type to a record folder, + * Then IntegrityException is thrown. + */ + @Test(expected = IntegrityException.class) + public void testCreateNonFolderSubType() throws Exception + { + NodeRef recordFolderNodeRef = AlfMock.generateNodeRef(mockedNodeService, TYPE_RECORD_FOLDER); + QName type = AlfMock.generateQName(); + when(mockedDictionaryService.isSubClass(type, TYPE_FOLDER)).thenReturn(false); + NodeRef nodeRef = AlfMock.generateNodeRef(mockedNodeService, type, true); + ChildAssociationRef childAssocRef = generateChildAssociationRef(recordFolderNodeRef, nodeRef); + recordFolderType.onCreateChildAssociation(childAssocRef, true); + } + + /** + * Given that we try to add cm:content sub-type to a record folder, + * Then the operation is successful. + */ + public void testCreateContent() throws Exception + { + NodeRef recordFolderNodeRef = AlfMock.generateNodeRef(mockedNodeService, TYPE_RECORD_FOLDER); + QName type = AlfMock.generateQName(); + when(mockedDictionaryService.isSubClass(type, TYPE_CONTENT)).thenReturn(true); + NodeRef nodeRef = AlfMock.generateNodeRef(mockedNodeService, type, true); + ChildAssociationRef childAssocRef = generateChildAssociationRef(recordFolderNodeRef, nodeRef); + recordFolderType.onCreateChildAssociation(childAssocRef, true); + } + + /** + * Given that we try to add non cm:content or non cm:folder sub-type to a record folder, + * Then IntegrityException is thrown. + */ + @Test(expected = IntegrityException.class) + public void testCreateNonContent() throws Exception + { + NodeRef recordFolderNodeRef = AlfMock.generateNodeRef(mockedNodeService, TYPE_RECORD_FOLDER); + QName type = AlfMock.generateQName(); + when(mockedDictionaryService.isSubClass(type, TYPE_CONTENT)).thenReturn(false); + when(mockedDictionaryService.isSubClass(type, TYPE_FOLDER)).thenReturn(false); + NodeRef nodeRef = AlfMock.generateNodeRef(mockedNodeService, type, true); + ChildAssociationRef childAssocRef = generateChildAssociationRef(recordFolderNodeRef, nodeRef); + recordFolderType.onCreateChildAssociation(childAssocRef, true); + } + + /** + * Given that we try to add not hidden cm:folder sub-type to a record folder, + * Then IntegrityException is thrown on commit. + */ + @Test(expected = IntegrityException.class) + public void testCreateNotHiddenFolderSubTypeOnCommit() throws Exception + { + NodeRef recordFolderNodeRef = AlfMock.generateNodeRef(mockedNodeService, TYPE_RECORD_FOLDER); + QName type = AlfMock.generateQName(); + when(mockedDictionaryService.isSubClass(type, TYPE_FOLDER)).thenReturn(true); + NodeRef nodeRef = AlfMock.generateNodeRef(mockedNodeService, type, true); + ChildAssociationRef childAssocRef = generateChildAssociationRef(recordFolderNodeRef, nodeRef); + recordFolderType.onCreateChildAssociationOnCommit(childAssocRef, true); + } + + /** + * Given that we try to add hidden cm:folder sub-type to a record folder, + * Then the operation is successful. + */ + @Test + public void testCreateHiddenFolderSubTypeOnCommit() throws Exception + { + NodeRef recordFolderNodeRef = AlfMock.generateNodeRef(mockedNodeService, TYPE_RECORD_FOLDER); + QName type = AlfMock.generateQName(); + NodeRef nodeRef = AlfMock.generateNodeRef(mockedNodeService, type, true); + + when(mockedDictionaryService.isSubClass(type, TYPE_FOLDER)).thenReturn(true); + when(mockedNodeService.hasAspect(nodeRef, ASPECT_HIDDEN)).thenReturn(true); + + ChildAssociationRef childAssocRef = generateChildAssociationRef(recordFolderNodeRef, nodeRef); + recordFolderType.onCreateChildAssociationOnCommit(childAssocRef, true); + } + + /** + * Given that we try to add non cm:folder sub-type to a record folder, + * Then the operation is successful. + */ + @Test + public void testCreateNonFolderSubTypeOnCommit() throws Exception + { + NodeRef recordFolderNodeRef = AlfMock.generateNodeRef(mockedNodeService, TYPE_RECORD_FOLDER); + QName type = AlfMock.generateQName(); + NodeRef nodeRef = AlfMock.generateNodeRef(mockedNodeService, type, true); + + when(mockedDictionaryService.isSubClass(type, TYPE_FOLDER)).thenReturn(false); + + ChildAssociationRef childAssocRef = generateChildAssociationRef(recordFolderNodeRef, nodeRef); + recordFolderType.onCreateChildAssociationOnCommit(childAssocRef, true); + } +}