()
+ {
+ public Void doWork()
+ {
+ final NodeRef sourceNode = renditionService.getSourceNode(renditionNodeRef).getParentRef();
+ if (contentClassificationService.isClassified(sourceNode))
+ {
+ // All renditions should be given the same classification as their source node
+ servicesExtras.copyAspect(sourceNode, renditionNodeRef, ASPECT_CLASSIFIED);
+ }
+ return null;
+ }
+ }, authenticationUtil.getSystemUserName());
+ }
+}
diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/model/clf/aspect/ClassifiedAspect.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/model/clf/aspect/ClassifiedAspect.java
index 402beb0181..97f71efddd 100644
--- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/model/clf/aspect/ClassifiedAspect.java
+++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/model/clf/aspect/ClassifiedAspect.java
@@ -30,6 +30,7 @@ import org.alfresco.module.org_alfresco_module_rm.classification.ClassificationS
import org.alfresco.module.org_alfresco_module_rm.classification.ClassificationSchemeService.Reclassification;
import org.alfresco.module.org_alfresco_module_rm.classification.model.ClassifiedContentModel;
import org.alfresco.module.org_alfresco_module_rm.model.BaseBehaviourBean;
+import org.alfresco.module.org_alfresco_module_rm.util.CoreServicesExtras;
import org.alfresco.module.org_alfresco_module_rm.util.RMCollectionUtils.Difference;
import org.alfresco.repo.node.NodeServicePolicies;
import org.alfresco.repo.policy.Behaviour.NotificationFrequency;
@@ -38,6 +39,8 @@ import org.alfresco.repo.policy.annotation.BehaviourBean;
import org.alfresco.repo.policy.annotation.BehaviourKind;
import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork;
+import org.alfresco.service.cmr.rendition.RenditionService;
+import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.namespace.QName;
@@ -51,15 +54,28 @@ import org.alfresco.service.namespace.QName;
defaultType = "clf:classified"
)
public class ClassifiedAspect extends BaseBehaviourBean implements NodeServicePolicies.OnUpdatePropertiesPolicy,
- NodeServicePolicies.OnAddAspectPolicy, ClassifiedContentModel
+ NodeServicePolicies.OnAddAspectPolicy,
+ ClassifiedContentModel
{
private ClassificationSchemeService classificationSchemeService;
+ private RenditionService renditionService;
+ private CoreServicesExtras servicesExtras;
public void setClassificationSchemeService(ClassificationSchemeService service)
{
this.classificationSchemeService = service;
}
+ public void setRenditionService(RenditionService service)
+ {
+ this.renditionService = service;
+ }
+
+ public void setCoreServicesExtras(CoreServicesExtras extras)
+ {
+ this.servicesExtras = extras;
+ }
+
/**
* Behaviour associated with updating the classified aspect properties.
*
@@ -104,6 +120,8 @@ public class ClassifiedAspect extends BaseBehaviourBean implements NodeServicePo
checkConsistencyOfProperties(nodeRef);
+ copyClassifiedPropertiesToRenditions(nodeRef);
+
return null;
}
}, AuthenticationUtil.getSystemUserName());
@@ -127,11 +145,24 @@ public class ClassifiedAspect extends BaseBehaviourBean implements NodeServicePo
public Void doWork()
{
checkConsistencyOfProperties(nodeRef);
+
+ copyClassifiedPropertiesToRenditions(nodeRef);
+
return null;
}
}, AuthenticationUtil.getSystemUserName());
}
+ private void copyClassifiedPropertiesToRenditions(NodeRef nodeRef)
+ {
+ // All renditions should be given the same classification as their source node
+ for (final ChildAssociationRef chAssRef : renditionService.getRenditions(nodeRef))
+ {
+ final NodeRef renditionNode = chAssRef.getChildRef();
+ servicesExtras.copyAspect(nodeRef, renditionNode, ASPECT_CLASSIFIED);
+ }
+ }
+
/**
* Check the consistency of the classification properties and throw an exception if they are invalid.
*
diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/util/CoreServicesExtras.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/util/CoreServicesExtras.java
new file mode 100644
index 0000000000..bba48d78eb
--- /dev/null
+++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/util/CoreServicesExtras.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2005-2015 Alfresco Software Limited.
+ *
+ * This file is part of Alfresco
+ *
+ * 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 .
+ */
+package org.alfresco.module.org_alfresco_module_rm.util;
+
+import static org.alfresco.util.collections.CollectionUtils.filterKeys;
+
+import org.alfresco.service.cmr.dictionary.AspectDefinition;
+import org.alfresco.service.cmr.dictionary.DictionaryException;
+import org.alfresco.service.cmr.dictionary.DictionaryService;
+import org.alfresco.service.cmr.repository.NodeRef;
+import org.alfresco.service.cmr.repository.NodeService;
+import org.alfresco.service.namespace.QName;
+import org.alfresco.util.collections.Function;
+
+import java.io.Serializable;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Provides additional methods of general use that could (in principle) be moved to the core services.
+ *
+ * @author Neil Mc Erlean
+ * @since 3.0.a
+ */
+public class CoreServicesExtras
+{
+ private DictionaryService dictionaryService;
+ private NodeService nodeService;
+
+ public void setDictionaryService(DictionaryService service)
+ {
+ this.dictionaryService = service;
+ }
+
+ public void setNodeService(NodeService service)
+ {
+ this.nodeService = service;
+ }
+
+ /**
+ * This method copies the property values for the specified aspect from one node to another.
+ * All associations are ignored.
+ *
+ * @param from the node whose property values are to be read.
+ * @param to the node to which the property values are to be written.
+ * @return a Map of the property values which were copied.
+ */
+ public Map copyAspect(NodeRef from, NodeRef to, QName aspectQName)
+ {
+ final AspectDefinition aspectDefn = dictionaryService.getAspect(aspectQName);
+
+ if (aspectDefn == null) { throw new DictionaryException("Unknown aspect: " + aspectQName); }
+
+ final Set aspectProperties = aspectDefn.getProperties().keySet();
+
+ final Map nodeProperties = nodeService.getProperties(from);
+ final Map relevantPropVals = filterKeys(nodeProperties, new Function()
+ {
+ @Override public Boolean apply(QName value)
+ {
+ return aspectProperties.contains(value);
+ }
+ });
+ nodeService.setProperties(to, relevantPropVals);
+ return relevantPropVals;
+ }
+}
diff --git a/rm-server/unit-test/java/org/alfresco/module/org_alfresco_module_rm/model/clf/ClassifiedRenditionsUnitTest.java b/rm-server/unit-test/java/org/alfresco/module/org_alfresco_module_rm/model/clf/ClassifiedRenditionsUnitTest.java
new file mode 100644
index 0000000000..b0ad04bef7
--- /dev/null
+++ b/rm-server/unit-test/java/org/alfresco/module/org_alfresco_module_rm/model/clf/ClassifiedRenditionsUnitTest.java
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2005-2015 Alfresco Software Limited.
+ *
+ * This file is part of Alfresco
+ *
+ * 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 .
+ */
+package org.alfresco.module.org_alfresco_module_rm.model.clf;
+
+import static java.util.Arrays.asList;
+
+import static org.mockito.Mockito.eq;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+import static org.mockito.MockitoAnnotations.initMocks;
+
+import org.alfresco.model.RenditionModel;
+import org.alfresco.module.org_alfresco_module_rm.classification.ContentClassificationService;
+import org.alfresco.module.org_alfresco_module_rm.classification.model.ClassifiedContentModel;
+import org.alfresco.module.org_alfresco_module_rm.model.clf.aspect.ClassifiedAspect;
+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.util.CoreServicesExtras;
+import org.alfresco.service.cmr.rendition.RenditionService;
+import org.alfresco.service.cmr.repository.ChildAssociationRef;
+import org.alfresco.service.cmr.repository.NodeRef;
+import org.alfresco.service.cmr.repository.NodeService;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+
+/**
+ * Unit tests for {@link ClassifiedRenditions}.
+ *
+ * @since 3.0.a
+ */
+public class ClassifiedRenditionsUnitTest implements ClassifiedContentModel
+{
+ private static final NodeRef SOURCE_NODE = new NodeRef("node://ref/");
+ private static final NodeRef RENDITION_1 = new NodeRef("node://rendition1/");
+ private static final NodeRef RENDITION_2 = new NodeRef("node://rendition2/");
+
+ @InjectMocks ClassifiedAspect classifiedAspect;
+
+ @Mock AuthenticationUtil mockAuthenticationUtil;
+ @Mock ContentClassificationService mockContentClassificationService;
+ @Mock CoreServicesExtras mockCoreServicesExtras;
+ @Mock NodeService mockNodeService;
+ @Mock RenditionService mockRenditionService;
+
+ @Before
+ public void setUp()
+ {
+ initMocks(this);
+
+ MockAuthenticationUtilHelper.setup(mockAuthenticationUtil);
+ }
+
+ @Test public void newRenditionOfClassifiedNodeShouldItselfBeClassified()
+ {
+ when(mockRenditionService.getRenditions(eq(SOURCE_NODE)))
+ .thenReturn(asList(rendition(SOURCE_NODE, RENDITION_1), rendition(SOURCE_NODE, RENDITION_2)));
+ when(mockRenditionService.getSourceNode(eq(RENDITION_1))).thenReturn(rendition(SOURCE_NODE, RENDITION_1));
+ when(mockRenditionService.getSourceNode(eq(RENDITION_2))).thenReturn(rendition(SOURCE_NODE, RENDITION_2));
+ when(mockContentClassificationService.isClassified(eq(SOURCE_NODE))).thenReturn(true);
+
+ final ClassifiedRenditions behaviour = new ClassifiedRenditions();
+ behaviour.setAuthenticationUtil(mockAuthenticationUtil);
+ behaviour.setContentClassificationService(mockContentClassificationService);
+ behaviour.setCoreServicesExtras(mockCoreServicesExtras);
+ behaviour.setNodeService(mockNodeService);
+ behaviour.setRenditionService(mockRenditionService);
+
+ behaviour.onAddAspect(RENDITION_2, RenditionModel.ASPECT_RENDITION);
+
+ verify(mockCoreServicesExtras).copyAspect(eq(SOURCE_NODE), eq(RENDITION_2), eq(ClassifiedContentModel.ASPECT_CLASSIFIED));
+ }
+
+ /** Creates a mock Rendition ChildAssociationRef. */
+ private ChildAssociationRef rendition(NodeRef source, NodeRef rendition)
+ {
+ return new ChildAssociationRef(RenditionModel.ASSOC_RENDITION, source, RenditionModel.ASSOC_RENDITION, rendition);
+ }
+}
diff --git a/rm-server/unit-test/java/org/alfresco/module/org_alfresco_module_rm/model/clf/aspect/ClassifiedAspectUnitTest.java b/rm-server/unit-test/java/org/alfresco/module/org_alfresco_module_rm/model/clf/aspect/ClassifiedAspectUnitTest.java
index 86ab1bd54c..e27de66301 100644
--- a/rm-server/unit-test/java/org/alfresco/module/org_alfresco_module_rm/model/clf/aspect/ClassifiedAspectUnitTest.java
+++ b/rm-server/unit-test/java/org/alfresco/module/org_alfresco_module_rm/model/clf/aspect/ClassifiedAspectUnitTest.java
@@ -18,15 +18,29 @@
*/
package org.alfresco.module.org_alfresco_module_rm.model.clf.aspect;
+import static java.util.Arrays.asList;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.mockito.MockitoAnnotations.initMocks;
+import java.io.Serializable;
import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+import org.alfresco.model.RenditionModel;
import org.alfresco.module.org_alfresco_module_rm.classification.ClassificationException.MissingDowngradeInstructions;
+import org.alfresco.module.org_alfresco_module_rm.classification.ClassificationLevel;
+import org.alfresco.module.org_alfresco_module_rm.classification.ClassificationSchemeService;
import org.alfresco.module.org_alfresco_module_rm.classification.model.ClassifiedContentModel;
+import org.alfresco.module.org_alfresco_module_rm.util.CoreServicesExtras;
+import org.alfresco.service.cmr.rendition.RenditionService;
+import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
+import org.alfresco.service.namespace.QName;
import org.junit.Before;
import org.junit.Test;
import org.mockito.InjectMocks;
@@ -40,10 +54,17 @@ import org.mockito.Mock;
*/
public class ClassifiedAspectUnitTest implements ClassifiedContentModel
{
- private static final NodeRef NODE_REF = new NodeRef("node://Ref/");
+ private static final NodeRef NODE_REF = new NodeRef("node://Ref/");
+ private static final NodeRef RENDITION_1 = new NodeRef("node://rendition1/");
+ private static final NodeRef RENDITION_2 = new NodeRef("node://rendition2/");
+ private static final ClassificationLevel TOP_SECRET = new ClassificationLevel("Top Secret", "Top Secret");
+ private static final ClassificationLevel SECRET = new ClassificationLevel("Secret", "Secret");
@InjectMocks ClassifiedAspect classifiedAspect;
- @Mock NodeService mockNodeService;
+ @Mock ClassificationSchemeService mockClassificationSchemeService;
+ @Mock CoreServicesExtras mockCoreServicesExtras;
+ @Mock NodeService mockNodeService;
+ @Mock RenditionService mockRenditionService;
@Before
public void setUp()
@@ -103,11 +124,67 @@ public class ClassifiedAspectUnitTest implements ClassifiedContentModel
@Test(expected = MissingDowngradeInstructions.class)
public void testCheckConsistencyOfProperties_emptyStringsSupplied()
{
- when(mockNodeService.hasAspect(NODE_REF, ASPECT_CLASSIFIED)).thenReturn(true);
+ for (NodeRef n : asList(NODE_REF, RENDITION_1, RENDITION_2))
+ {
+ when(mockNodeService.hasAspect(n, ASPECT_CLASSIFIED)).thenReturn(true);
+ }
when(mockNodeService.getProperty(NODE_REF, PROP_DOWNGRADE_DATE)).thenReturn("");
when(mockNodeService.getProperty(NODE_REF, PROP_DOWNGRADE_EVENT)).thenReturn("Event");
when(mockNodeService.getProperty(NODE_REF, PROP_DOWNGRADE_INSTRUCTIONS)).thenReturn("");
classifiedAspect.checkConsistencyOfProperties(NODE_REF);
}
+
+ /** Check that when a node is classified, its renditions are also classified. */
+ @Test public void classificationOfNodeShouldClassifyRenditions()
+ {
+ for (NodeRef n : asList(NODE_REF, RENDITION_1, RENDITION_2))
+ {
+ when(mockNodeService.hasAspect(n, ASPECT_CLASSIFIED)).thenReturn(true);
+ }
+ when(mockClassificationSchemeService.getClassificationLevelById(eq("Top Secret"))).thenReturn(TOP_SECRET);
+ when(mockClassificationSchemeService.getClassificationLevelById(eq("Secret"))).thenReturn(SECRET);
+ when(mockClassificationSchemeService.getReclassification(any(), any())).thenReturn(ClassificationSchemeService.Reclassification.DOWNGRADE);
+ when(mockRenditionService.getRenditions(eq(NODE_REF)))
+ .thenReturn(asList(rendition(NODE_REF, RENDITION_1), rendition(NODE_REF, RENDITION_2)));
+
+ classifiedAspect.onAddAspect(NODE_REF, ASPECT_CLASSIFIED);
+
+ for (NodeRef rendition : asList(RENDITION_1, RENDITION_2))
+ {
+ verify(mockCoreServicesExtras).copyAspect(eq(NODE_REF), eq(rendition), eq(ClassifiedContentModel.ASPECT_CLASSIFIED));
+ }
+ }
+
+ @Test public void reclassificationOfNodeShouldReclassifyRenditions()
+ {
+ for (NodeRef n : asList(NODE_REF, RENDITION_1, RENDITION_2))
+ {
+ when(mockNodeService.hasAspect(n, ASPECT_CLASSIFIED)).thenReturn(true);
+ }
+ when(mockClassificationSchemeService.getClassificationLevelById(eq("Top Secret"))).thenReturn(TOP_SECRET);
+ when(mockClassificationSchemeService.getClassificationLevelById(eq("Secret"))).thenReturn(SECRET);
+ when(mockClassificationSchemeService.getReclassification(any(), any())).thenReturn(ClassificationSchemeService.Reclassification.DOWNGRADE);
+ when(mockRenditionService.getRenditions(eq(NODE_REF)))
+ .thenReturn(asList(rendition(NODE_REF, RENDITION_1), rendition(NODE_REF, RENDITION_2)));
+
+ Map oldProps = new HashMap<>();
+ oldProps.put(PROP_CLASSIFIED_BY, "userone");
+ oldProps.put(PROP_CURRENT_CLASSIFICATION, "Top Secret");
+ Map newProps = new HashMap<>(oldProps);
+ newProps.put(PROP_CURRENT_CLASSIFICATION, "Secret");
+
+ classifiedAspect.onUpdateProperties(NODE_REF, oldProps, newProps);
+
+ for (NodeRef rendition : asList(RENDITION_1, RENDITION_2))
+ {
+ verify(mockCoreServicesExtras).copyAspect(eq(NODE_REF), eq(rendition), eq(ClassifiedContentModel.ASPECT_CLASSIFIED));
+ }
+ }
+
+ /** Creates a mock Rendition ChildAssociationRef. */
+ private ChildAssociationRef rendition(NodeRef source, NodeRef rendition)
+ {
+ return new ChildAssociationRef(RenditionModel.ASSOC_RENDITION, source, RenditionModel.ASSOC_RENDITION, rendition);
+ }
}
diff --git a/rm-server/unit-test/java/org/alfresco/module/org_alfresco_module_rm/util/CoreServicesExtrasUnitTest.java b/rm-server/unit-test/java/org/alfresco/module/org_alfresco_module_rm/util/CoreServicesExtrasUnitTest.java
new file mode 100644
index 0000000000..d8551a3494
--- /dev/null
+++ b/rm-server/unit-test/java/org/alfresco/module/org_alfresco_module_rm/util/CoreServicesExtrasUnitTest.java
@@ -0,0 +1,122 @@
+/*
+ * Copyright (C) 2005-2015 Alfresco Software Limited.
+ *
+ * This file is part of Alfresco
+ *
+ * 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 .
+ */
+
+package org.alfresco.module.org_alfresco_module_rm.util;
+
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.when;
+import static org.mockito.Mockito.mock;
+
+import static org.alfresco.module.org_alfresco_module_rm.test.util.ExceptionUtils.expectedException;
+import static org.junit.Assert.assertEquals;
+
+import org.alfresco.service.cmr.dictionary.AspectDefinition;
+import org.alfresco.service.cmr.dictionary.DictionaryException;
+import org.alfresco.service.cmr.dictionary.DictionaryService;
+import org.alfresco.service.cmr.dictionary.PropertyDefinition;
+import org.alfresco.service.cmr.repository.NodeRef;
+import org.alfresco.service.cmr.repository.NodeService;
+import org.alfresco.service.cmr.repository.StoreRef;
+import org.alfresco.service.namespace.QName;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.io.Serializable;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Unit tests for {@link CoreServicesExtras}.
+ *
+ * @author Neil Mc Erlean
+ * @since 3.0.a
+ */
+public class CoreServicesExtrasUnitTest
+{
+ private CoreServicesExtras serviceExtras;
+
+ private final QName testAspect = QName.createQName("test", "aspect");
+ private final QName testProp1 = QName.createQName("test", "prop1");
+ private final QName testProp2 = QName.createQName("test", "prop2");
+ private final QName testProp3 = QName.createQName("test", "prop3");
+ private final NodeRef testNode1 = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, "1");
+ private final NodeRef testNode2 = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, "2");
+
+ @Before public void setUp()
+ {
+ serviceExtras = new CoreServicesExtras();
+ }
+
+ @Test public void copyingAnUnknownAspectShouldResultInAnException()
+ {
+ final DictionaryService mockDS = mock(DictionaryService.class);
+
+ when(mockDS.getAspect(any(QName.class))).thenReturn(null);
+ serviceExtras.setDictionaryService(mockDS);
+
+ expectedException(DictionaryException.class, () -> serviceExtras.copyAspect(testNode1, testNode2, testAspect));
+ }
+
+ @Test public void copyingAnAspectWithNoProperties()
+ {
+ final DictionaryService mockDS = mock(DictionaryService.class);
+ final NodeService mockNS = mock(NodeService.class);
+
+ final AspectDefinition mockAspect = mock(AspectDefinition.class);
+ when(mockAspect.getProperties()).thenReturn(Collections.emptyMap());
+
+ when(mockDS.getAspect(eq(testAspect))).thenReturn(mockAspect);
+ when(mockNS.getProperties(eq(testNode1))).thenReturn(Collections.emptyMap());
+ serviceExtras.setDictionaryService(mockDS);
+ serviceExtras.setNodeService(mockNS);
+
+ assertEquals(Collections.emptyMap(), serviceExtras.copyAspect(testNode1, testNode2, testAspect));
+ }
+
+ @Test public void copyingAnAspectWithProperties()
+ {
+ final DictionaryService mockDS = mock(DictionaryService.class);
+ final NodeService mockNS = mock(NodeService.class);
+
+ final AspectDefinition mockAspect = mock(AspectDefinition.class);
+ final Map props = new HashMap<>();
+ final PropertyDefinition mockProp1 = mock(PropertyDefinition.class);
+ final PropertyDefinition mockProp2 = mock(PropertyDefinition.class);
+ props.put(testProp1, mockProp1);
+ props.put(testProp2, mockProp2);
+ when(mockAspect.getProperties()).thenReturn(props);
+
+ final Map propVals = new HashMap<>();
+ propVals.put(testProp1, "one");
+ propVals.put(testProp2, "two");
+ propVals.put(testProp3, "three"); // Not defined on the aspect above.
+ when(mockDS.getAspect(eq(testAspect))).thenReturn(mockAspect);
+ when(mockNS.getProperties(eq(testNode1))).thenReturn(propVals);
+
+ serviceExtras.setDictionaryService(mockDS);
+ serviceExtras.setNodeService(mockNS);
+
+ Map expected = new HashMap<>();
+ expected.put(testProp1, "one");
+ expected.put(testProp2, "two");
+ assertEquals(expected, serviceExtras.copyAspect(testNode1, testNode2, testAspect));
+ }
+}