public (string, string) ComputeUniqueName(ParentChildRelationHierarchy hierarchy, ParentChildRelation relation) { var mapping = _mappingsMap[relation.Child.GetType()]; var sourceName = mapping.GetKeyForInstance(relation.Child); var sourceTypeName = mapping.ArdoqComponentTypeName; var localName = sourceName + " " + sourceTypeName; if (relation.Parent == null) { return(null, localName); } var parentRelations = hierarchy.GetAllParentChildRelations().Where(rel => rel.Child == relation.Parent); if (parentRelations.Count() > 1) { var parentMapping = _mappingsMap[relation.Parent?.GetType()]; var parentType = parentMapping.ArdoqComponentTypeName; var parentName = parentMapping.GetKeyForInstance(relation.Parent); throw new Exception($"Multiple elements found matching type={parentType} with key={parentName}"); } ParentChildRelation parentRelation = hierarchy.GetAllParentChildRelations().SingleOrDefault(rel => rel.Child == relation.Parent); var parentUniqueName = parentRelation.ChildUniqueName ?? ComputeUniqueName(hierarchy, parentRelation).Item2; return(parentUniqueName, parentUniqueName + " -> " + localName); }
public (int, int) Link(IEnumerable <ParentChildRelation> relations, ParentChildRelation relation) { var sourceObject = relation.Child; var existingReferences = _session.GetAllSourceReferencesFromChild(relation) .Where(r => r.TargetWorkspace == _workspace.Id) .ToList(); var expectedReferencesRelations = GetExpectedReferencesRelations(relations, sourceObject).ToList(); var missingReferences = new List <(ParentChildRelation, int)>(); foreach (var expectedReferencesRelation in expectedReferencesRelations) { var targetComponent = _session.GetChildComponent(expectedReferencesRelation.Item1); var existing = existingReferences.SingleOrDefault(r => r.Target == targetComponent.Id); if (existing != null) { existingReferences.Remove(existing); } else { missingReferences.Add(expectedReferencesRelation); } } AddMissingReferences(relation, missingReferences); RemoveStaleReferences(existingReferences); return(missingReferences.Count, existingReferences.Count); }
private bool AddComponent(ParentChildRelation relation) { if (ComponentExists(relation)) { return(false); } var mapping = _mappings[relation.Child.GetType()]; var key = mapping.GetKeyForInstance(relation.Child); if (relation.Parent == null) { _session.AddComponent( key, mapping.GetComponentInfo(relation.Child).Item2, mapping.ArdoqComponentTypeName, relation.PreexistingHierarchyReference); } else { var parentMapping = _mappings[relation.Parent.GetType()]; var parentKey = parentMapping.GetKeyForInstance(relation.Parent); var existingParentComponent = GetParent(relation); _session.AddComponentWithParent( key, mapping.GetComponentInfo(relation.Child).Item2, mapping.ArdoqComponentTypeName, existingParentComponent); } return(true); }
public void BuildRelationHierarchies_SingleLinearRelations_ReturnsExpectedHierarchies() { // Arrange var subscription = new Subscription { Name = "NETT-PLAYGROUND" }; var subscriptionRelation = new ParentChildRelation(null, subscription); var resourceGroup = new ResourceGroup { Name = "PLAYGROUND-RGprod" }; var resourceGroupRelation = new ParentChildRelation(subscription, resourceGroup); var relations = new List <ParentChildRelation> { subscriptionRelation, resourceGroupRelation }; var builder = new ParentChildRelationHierarchyBuilder(Helper.GetModel(ModelType.Subscription_ResourceGroup_EventHubNamespace_EventHub)); // Act var hiers = builder.BuildRelationHierarchies(relations); // Assert Assert.Single(hiers); var h = hiers.First(); Assert.Equal(2, h.LevelCount); var level = h.GetLevel(0); Assert.Single(level); Assert.Contains(subscriptionRelation, level); level = h.GetLevel(1); Assert.Contains(resourceGroupRelation, level); }
private void SearchAndLink(ParentChildRelation relation, SearchSpec searchSpec) { var sourceComponent = _sourceWorkspaceSession.GetChildComponent(relation); var components = _searcher.Search(searchSpec).Result; if (components == null || !components.Any()) { return; } var refType = _sourceWorkspaceSession.GetReferenceTypeForName(_ardoqReferenceName); var existingReferences = _sourceWorkspaceSession.GetAllSourceReferencesFromChild(relation) .Where(r => r.Type == refType) .ToList(); foreach (var targetComponent in components) { if (existingReferences.Any(r => r.Target == targetComponent.Id)) { continue; } _sourceWorkspaceSession.AddReference(refType, sourceComponent, targetComponent); } }
private void Link(IExternalReferenceSpecification referenceSpecification, ParentChildRelation rel, IArdoqSession sourceWorkspaceSession, IMaintainenceSession maintainenceSession) { var targetWorkspace = GetWorkspace(referenceSpecification.WorkspaceName); var sourceComponent = sourceWorkspaceSession.GetChildComponent(rel); var targetComponentType = referenceSpecification.TargetComponentType; var targetComponentKey = referenceSpecification.GetTargetComponentKey(rel.Child); if (targetComponentKey == null) { return; } var targetSession = GetSession(targetWorkspace, referenceSpecification); var targetComponent = targetSession.GetComponentsOfType(targetComponentType) .Single(c => c.Name == targetComponentKey); var refType = sourceWorkspaceSession.GetReferenceTypeForName(referenceSpecification.ReferenceName); var existingReferences = sourceWorkspaceSession.GetAllSourceReferencesFromChild(rel) .Where(r => r.TargetWorkspace == targetWorkspace.Id && r.Target == targetComponent.Id && r.Type == refType); if (existingReferences.Any()) { return; } targetSession.AddReference(refType, sourceComponent, targetComponent); }
public Component GetParentComponent(ParentChildRelation relation) { InitIfNecessary(); var parentComponent = _components.SingleOrDefault(c => UniqueName(c) == relation.ParentUniqueName); return(parentComponent); }
public IEnumerable <Reference> GetAllSourceReferencesFromChild(ParentChildRelation relation) { InitIfNecessary(); var sourceComponent = GetChildComponent(relation); return(_references.Where(r => r.Source == sourceComponent.Id)); }
public void LinkBySearch_FindsSeveralObjectsAlreadyHasRefs_CreatedExpectedReferences() { // Arrange var refName = "uses"; var refType = 99; var employeeNumber = "A221133"; var countryComponentId = "country-1"; var mapping = new ComponentMapping <Employee>("Employee").WithKey(emp => emp.EmployeeNumber); var service = GetService(mapping, refName); var searchBuilder = GetSearchBuilder(); var employee = new Employee { Name = "Magnus Carlsen", Age = 28, EmployeeNumber = employeeNumber }; var employeeComponent = new Component(employeeNumber, null, null) { Type = "Employee" }; var countryComponent1 = new Component("Norway", null, null) { Id = countryComponentId }; var countryComponent2 = new Component("Sweden", null, null) { Id = "swe" }; var countryComponent3 = new Component("Denmark", null, null) { Id = "dk" }; IEnumerable <Component> searchResComponents = new List <Component> { countryComponent1, countryComponent2, countryComponent3 }; _searcherMock.Setup(s => s.Search(It.IsAny <SearchSpec>())) .Returns(Task.FromResult(searchResComponents)); ParentChildRelation parentChildRelation = new ParentChildRelation(null, employee); _sessionMock.Setup(s => s.GetChildComponent(parentChildRelation)) .Returns(employeeComponent); _sessionMock.Setup(s => s.GetReferenceTypeForName(refName)) .Returns(refType); _sessionMock.Setup(s => s.GetAllSourceReferencesFromChild(parentChildRelation)) .Returns(new List <Reference>()); // Act service.LinkBySearch(searchBuilder, new List <ParentChildRelation> { parentChildRelation }); // Assert _sessionMock.Verify(s => s.AddReference(refType, employeeComponent, It.IsAny <Component>()), Times.Exactly(3)); }
private Component GetParent(ParentChildRelation relation) { if (relation.Parent == null) { return(null); } var parent = _session.GetParentComponent(relation); return(parent); }
public Component GetChildComponent(ParentChildRelation relation) { InitIfNecessary(); var list = _components.Where(c => UniqueName(c) == relation.ChildUniqueName); if (list.Count() > 1) { throw new Exception($"Found multiple Components with same UniqueName: {relation.ChildUniqueName}"); } return(list.SingleOrDefault()); }
public void LinkBySearch_FindsObjectsNoPriorRefs_CreatesNewReference() { // Arrange var refName = "uses"; var refType = 99; var countryComponentId = "country-1"; var employeeNumber = "A221133"; const string workspaceId = "workspaceId"; var mapping = new ComponentMapping <Employee>("Employee").WithKey(emp => emp.EmployeeNumber); var service = GetService(mapping, refName); var searchBuilder = GetSearchBuilder(); var employee = new Employee { Name = "Magnus Carlsen", Age = 28, EmployeeNumber = employeeNumber }; var employeeComponent = new Component(employeeNumber, workspaceId, null) { Type = "Employee" }; var countryComponent = new Component("Norway", workspaceId, null) { Id = countryComponentId }; IEnumerable <Component> searchResComponents = new List <Component> { countryComponent }; _searcherMock.Setup(s => s.Search(It.IsAny <SearchSpec>())) .Returns(Task.FromResult(searchResComponents)); ParentChildRelation parentChildRelation = new ParentChildRelation(null, employee); _sessionMock.Setup(s => s.GetChildComponent(parentChildRelation)) .Returns(employeeComponent); _sessionMock.Setup(s => s.GetReferenceTypeForName(refName)) .Returns(refType); _sessionMock.Setup(s => s.GetAllSourceReferencesFromChild(parentChildRelation)) .Returns(new List <Reference>()); // Act service.LinkBySearch(searchBuilder, new List <ParentChildRelation> { parentChildRelation }); // Assert _sessionMock.Verify(s => s.AddReference(refType, employeeComponent, countryComponent), Times.Once); }
public void AddReference( int refType, ParentChildRelation source, ParentChildRelation target) { InitIfNecessary(); var sourceComponent = GetChildComponent(source); var targetComponent = GetChildComponent(target); //var sourceComponent = _components.Single(c => c.Type == sourceType && c.Name == sourceName); // TODO: I think this could fail if the source does not have a unique type and name //var targetComponent = _components.Single(c => c.Type == targetType && c.Name == targetName); // TODO: I think this could fail if the target does not have a unique type and name AddReference(refType, sourceComponent, targetComponent); }
private List <ParentChildRelation> FindRelationsCore(object obj) { if (!_mappings.ContainsKey(obj.GetType())) { throw new InvalidOperationException($"Type {obj.GetType().FullName} not registered."); } var result = _mappings[obj.GetType()].ModelledHierarchyAccessSpecifications .Aggregate( new List <ParentChildRelation>(), (list, accessor) => { var relatedObjects = accessor.GetRelatedObjects(obj); if (relatedObjects == null) { list.Add(new ParentChildRelation(null, obj)); } else { foreach (var tuple in relatedObjects) { var r = tuple.Item2 == ModelledReferenceDirection.Child ? new ParentChildRelation(tuple.Item1, obj) : new ParentChildRelation(obj, tuple.Item1); list.Add(r); } } return(list); }); if (result.All(r => r.Child != obj)) { var r = new ParentChildRelation(null, obj); if (_mappings[obj.GetType()].NamedHierarchyParentAccessSpecifications.Any()) { var np = _mappings[obj.GetType()].NamedHierarchyParentAccessSpecifications.Single(); r.PreexistingHierarchyReference = np.GetName(); } result.Add(r); } return(result); }
public void Link( ParentChildRelation relation, IEnumerable <string> tags, IBuiltComponentMapping mapping, string ardoqReferenceName, string searchFolder = null) { var component = _session.GetChildComponent(relation); List <global::Ardoq.Models.Tag> allTags = _reader.GetAllTagsInFolder(searchFolder).Result; var componentDict = new Dictionary <string, List <global::Ardoq.Models.Tag> >(); foreach (var tag in allTags) { foreach (var compId in tag.Components) { if (!componentDict.ContainsKey(compId)) { componentDict[compId] = new List <global::Ardoq.Models.Tag>(); } componentDict[compId].Add(tag); } } var componentIds = componentDict.Select(pair => pair.Key); foreach (var tag in tags) { var compsMatchingTag = componentDict .Where(pair => pair.Value.Select(t => t.Name).Contains(tag)) .Select(pair => pair.Key); componentIds = componentIds.Intersect(compsMatchingTag); } var refType = _session.GetReferenceTypeForName(ardoqReferenceName); foreach (var targetComponentId in componentIds) { var refs = _session.GetAllSourceReferencesFromChild(relation); if (!refs.Any(r => r.Target == targetComponentId && r.Type == refType)) { _session.AddReference(refType, component.Id, targetComponentId); } } }
public void BuildRelationHierarchies_SingleRelation_ReturnsExpectedHierarchy() { // Arrange var relation = new ParentChildRelation(null, new Subscription { Name = "sub1" }); var relations = new List <ParentChildRelation> { relation }; var builder = new ParentChildRelationHierarchyBuilder(Helper.GetModel(ModelType.Subscription_ResourceGroup_EventHubNamespace)); // Act var hiers = builder.BuildRelationHierarchies(relations); // Assert Assert.Single(hiers); Assert.Equal(1, hiers.First().LevelCount); }
public ParentChildRelationDTO ParentChildRelationToDTO(ParentChildRelation a) { int childID = -1; if (a.Child != null) { childID = a.Child.SubprocessID; } int parentID = -1; if (a.Parent != null) { parentID = a.Parent.SubprocessID; } return(new ParentChildRelationDTO { ChildID = childID, ParentChildRelationID = a.ParentChildRelationID, ParentID = parentID }); }
public void GetAllChildren_ForBuiltHierarchy_GetsExpectedChildren() { // Arrange var subscription = new Subscription { Name = "NETT-PLAYGROUND" }; var subscriptionRelation = new ParentChildRelation(null, subscription); var resourceGroup = new ResourceGroup { Name = "PLAYGROUND-RGprod" }; var resourceGroupRelation = new ParentChildRelation(subscription, resourceGroup); var ehNamespace = new EventHubNamespace { Name = "my-namespace" }; var ehNamespaceReleation = new ParentChildRelation(resourceGroup, ehNamespace); var eventHub = new EventHub { Name = "my-events" }; var eventHubRelation = new ParentChildRelation(ehNamespace, eventHub); var relations = new List <ParentChildRelation> { subscriptionRelation, resourceGroupRelation, ehNamespaceReleation, eventHubRelation }; var builder = new ParentChildRelationHierarchyBuilder(Helper.GetModel(ModelType.Subscription_ResourceGroup_EventHubNamespace_EventHub)); var hierarchy = builder.BuildRelationHierarchies(relations).First(); // Act var children = hierarchy.GetAllChildren().ToList(); // Assert Assert.Equal(4, children.Count()); Assert.Contains(subscription, children); Assert.Contains(resourceGroup, children); Assert.Contains(ehNamespace, children); Assert.Contains(eventHub, children); }
public void LinkBySearch_NoObjectsFound_NoReferencesCreated() { // Arrange var refName = "uses"; var refType = 99; var employeeNumber = "A221133"; var mapping = new ComponentMapping <Employee>("Employee").WithKey(emp => emp.EmployeeNumber); var service = GetService(mapping, refName); var searchBuilder = GetSearchBuilder(); var employee = new Employee { Name = "Magnus Carlsen", Age = 28, EmployeeNumber = employeeNumber }; var employeeComponent = new Component(employeeNumber, null, null) { Type = "Employee" }; _searcherMock.Setup(s => s.Search(It.IsAny <SearchSpec>())) .Returns(Task.FromResult((IEnumerable <Component>) new List <Component>())); ParentChildRelation parentChildRelation = new ParentChildRelation(null, employee); _sessionMock.Setup(s => s.GetChildComponent(parentChildRelation)) .Returns(employeeComponent); _sessionMock.Setup(s => s.GetReferenceTypeForName(refName)) .Returns(refType); _sessionMock.Setup(s => s.GetAllSourceReferencesFromChild(parentChildRelation)) .Returns(new List <Reference>()); // Act service.LinkBySearch(searchBuilder, new List <ParentChildRelation> { parentChildRelation }); // Assert _sessionMock.Verify(s => s.AddReference(It.IsAny <int>(), It.IsAny <Component>(), It.IsAny <Component>()), Times.Never); }
private void ExpandFrom(ParentChildRelation current, int level, List <ParentChildRelation> relations) { List <ParentChildRelation> levelList; if (_levels.ContainsKey(level)) { levelList = _levels[level]; } else { levelList = new List <ParentChildRelation>(); _levels[level] = levelList; } levelList.Add(current); var nextLevel = level + 1; foreach (var childRelation in relations.Where(r => r.Parent == current.Child)) { ExpandFrom(childRelation, nextLevel, relations); } }
private void AddMissingReferences(ParentChildRelation relation, List <(ParentChildRelation, int)> missingReferences)
public void Link_ReferenceAlreadyExists_WritesNothing() { // Arrange var ardoqReferenceName = "ref-1"; var refType = 99; var rootWorkspaceId = "root-workspace-1"; var sourceComponentId = "source-1"; var sourceComponent = new Component("MDM-RGtest", rootWorkspaceId, null) { Id = sourceComponentId }; var targetComponentId = "target-1"; var m = new ComponentMapping <ResourceGroup>("ResourceGroup") .WithKey(rg => rg.Name) .WithPreexistingHierarchyReference("ResourceGroups"); var relation = new ParentChildRelation(null, new ResourceGroup { Name = "MDM-RGtest" }); var tags = new List <string> { "environment-test", "mdm-storage-internal" }; _sessionMock.Setup(s => s.GetChildComponent(relation)) .Returns(sourceComponent); _sessionMock.Setup(s => s.GetReferenceTypeForName(ardoqReferenceName)) .Returns(refType); _readerMock.Setup(r => r.GetAllTagsInFolder(null)) .Returns(Task.FromResult(new List <Tag> { new Tag("environment-test", null, null) { Components = new List <string> { targetComponentId } }, new Tag("mdm-storage-internal", null, null) { Components = new List <string> { targetComponentId } } })); var existingReference = new Reference(null, null, sourceComponentId, targetComponentId, refType); _sessionMock.Setup(s => s.GetAllSourceReferencesFromChild(relation)) .Returns(new List <Reference> { existingReference }); var service = new TagLinkageService(_sessionMock.Object, _readerMock.Object, _writerMock.Object); // Act service.Link(relation, tags, m, ardoqReferenceName); // Assert _sessionMock.Verify(s => s.AddReference(refType, sourceComponentId, targetComponentId), Times.Never); }
private bool ComponentExists(ParentChildRelation relation) { return(_session.GetChildComponent(relation) != null); }
public HRESULT OnVisualTreeChange(ParentChildRelation relation, VisualElement element, VisualMutationType mutationType) { return(((delegate * unmanaged <IVisualTreeServiceCallback *, ParentChildRelation, VisualElement, VisualMutationType, int>)(lpVtbl[3]))((IVisualTreeServiceCallback *)Unsafe.AsPointer(ref this), relation, element, mutationType)); }
public void BuildRelationHierarchies_BroadAndParalellHierachies_ReturnsExpectedHierarchies() { // Arrange var subscription = new Subscription { Name = "NETT-PLAYGROUND" }; var subscriptionRelation = new ParentChildRelation(null, subscription); var resourceGroup = new ResourceGroup { Name = "PLAYGROUND-RGprod" }; var resourceGroupRelation = new ParentChildRelation(subscription, resourceGroup); var ehNamespace = new EventHubNamespace { Name = "my-namespace" }; var ehNamespaceReleation = new ParentChildRelation(resourceGroup, ehNamespace); var eventHub = new EventHub { Name = "my-events" }; var eventHubRelation = new ParentChildRelation(ehNamespace, eventHub); var sub2 = new Subscription { Name = "NETT-MDM" }; var sub2R = new ParentChildRelation(null, sub2); var rg2 = new ResourceGroup { Name = "MDM-RGtest" }; var rg2R = new ParentChildRelation(sub2, rg2); var ehn1 = new EventHubNamespace { Name = "mdm-1" }; var ehn1R = new ParentChildRelation(rg2, ehn1); var ehn2 = new EventHubNamespace { Name = "mdm-2" }; var ehn2R = new ParentChildRelation(rg2, ehn2); var eh1 = new EventHub { Name = "eh1" }; var eh1R = new ParentChildRelation(ehn1, eh1); var eh2 = new EventHub { Name = "eh2" }; var eh2R = new ParentChildRelation(ehn2, eh2); var relations = new List <ParentChildRelation> { subscriptionRelation, resourceGroupRelation, ehNamespaceReleation, eventHubRelation, sub2R, rg2R, ehn1R, ehn2R, eh1R, eh2R }; var builder = new ParentChildRelationHierarchyBuilder(Helper.GetModel(ModelType.Subscription_ResourceGroup_EventHubNamespace_EventHub)); // Act var hiers = builder.BuildRelationHierarchies(relations).ToList(); // Assert Assert.Equal(2, hiers.Count()); var hier = hiers.Single(h => ((Subscription)h.GetLevel(0).First().Child).Name == "NETT-PLAYGROUND"); Assert.Equal(4, hier.LevelCount); var level = hier.GetLevel(0); Assert.Single(level); Assert.Contains(subscriptionRelation, level); level = hier.GetLevel(1); Assert.Contains(resourceGroupRelation, level); level = hier.GetLevel(2); Assert.Contains(ehNamespaceReleation, level); level = hier.GetLevel(3); Assert.Contains(eventHubRelation, level); hier = hiers.Single(h => ((Subscription)h.GetLevel(0).First().Child).Name == "NETT-MDM"); level = hier.GetLevel(0); Assert.Single(level); Assert.Contains(sub2R, level); level = hier.GetLevel(1); Assert.Contains(rg2R, level); level = hier.GetLevel(2); Assert.Equal(2, level.Count); Assert.Contains(ehn1R, level); Assert.Contains(ehn2R, level); level = hier.GetLevel(3); Assert.Equal(2, level.Count); Assert.Contains(eh1R, level); Assert.Contains(eh2R, level); }
public ParentChildRelationHierarchy(ParentChildRelation relation) { _levels[0] = new List <ParentChildRelation> { relation }; }
public void LinkAll_NoReferencesPreexist_ReferenceCreatedInArdoq() { // Arrange var sourceWorkspaceId = "my-workspace-id"; var sourceWorkspaceName = "RoleWorkspace"; var refName = "typical_role_in"; var refId = 707; var targetCompModel = "TargetComponentModel"; var sourceCompModel = "SourceComponentModel"; var targetWorkspaceId = "industry-workspace"; var targetWorkspaceName = "IndustryWorkspace"; var session = new ArdoqSession(sourceWorkspaceId, _readerMock.Object, _writerMock.Object); var sourceObj = new Role() { Name = "Sales" }; var relation = new ParentChildRelation(null, sourceObj) { ChildUniqueName = "Sales Role" }; var relations = new List <ParentChildRelation> { relation }; var internalmodel = new global::Ardoq.Models.Model( "model-id", "MyModel", null, null, new Dictionary <string, int> { [refName] = refId }); IArdoqModel model = new ArdoqModel(internalmodel); var referenceSpec = new ExternalReferenceSpecification <Role>( "Industry", r => r.GetNameOfIndustry(), refName, targetWorkspaceName); var sourceWorkspace = new Workspace(sourceWorkspaceName, null) { Id = sourceWorkspaceId, ComponentModel = sourceCompModel }; var targetWorkspace = new Workspace(targetWorkspaceName, null) { Id = targetWorkspaceId, ComponentModel = targetCompModel }; _readerMock.Setup(r => r.GetWorkspaceNamed(sourceWorkspaceName, null)) .Returns(Task.FromResult(sourceWorkspace)); _readerMock.Setup(r => r.GetWorkspaceById(sourceWorkspaceId)) .Returns(Task.FromResult(sourceWorkspace)); _readerMock.Setup(r => r.GetWorkspaceNamed(targetWorkspaceName, null)) .Returns(Task.FromResult(targetWorkspace)); _readerMock.Setup(r => r.GetWorkspaceById(targetWorkspaceId)) .Returns(Task.FromResult(targetWorkspace)); _readerMock.Setup(r => r.GetModelById(targetCompModel)) .Returns(Task.FromResult(model)); _readerMock.Setup(r => r.GetModelById(sourceCompModel)) .Returns(Task.FromResult(model)); _readerMock.Setup(r => r.GetReferencesById(sourceWorkspaceId)) .Returns(Task.FromResult(new List <Reference>())); _readerMock.Setup(r => r.GetReferencesById(targetWorkspaceId)) .Returns(Task.FromResult(new List <Reference>())); IEnumerable <Component> sourceComps = new List <Component> { new Component("Sales", sourceWorkspaceId, null) { Type = "Role", Id = "role-comp-1" } }; IEnumerable <Component> targetComps = new List <Component> { new Component("Sales and marketing", targetWorkspaceId, null) { Type = "Industry", Id = "industry-comp-2" } }; _readerMock.Setup(r => r.GetAllComponents(sourceWorkspaceId)) .Returns(Task.FromResult(sourceComps)); _readerMock.Setup(r => r.GetAllComponents(targetWorkspaceId)) .Returns(Task.FromResult(targetComps)); _maintenanceSessionMock.Setup(m => m.GetComponentType(typeof(Role))).Returns("Role"); _maintenanceSessionMock.Setup(m => m.GetKeyForInstance(sourceObj)).Returns("Sales"); var linkageService = new ExternalLinkageService(_readerMock.Object, _writerMock.Object); // Act linkageService.LinkAll(referenceSpec, relations, session, _maintenanceSessionMock.Object); // Assert _writerMock.Verify(w => w.CreateReference(targetWorkspaceId, "role-comp-1", "industry-comp-2", refId), Times.Once); }