Skip to content
This repository was archived by the owner on Dec 23, 2023. It is now read-only.

Commit d1c04e7

Browse files
Fixes a bug that allows relationships to be created between parents and children.
1 parent 08bd5de commit d1c04e7

File tree

3 files changed

+115
-35
lines changed

3 files changed

+115
-35
lines changed

Structurizr.Core.Tests/Model/ModelTests.cs

+82
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,88 @@ public void Test_AddRelationship_AllowsMultipleRelationshipsBetweenElements()
155155
Assert.Equal(2, element1.Relationships.Count);
156156
}
157157

158+
[Fact]
159+
public void Test_AddRelationship_ThrowsAnException_WhenTheDestinationIsAChildOfTheSource()
160+
{
161+
SoftwareSystem softwareSystem = Model.AddSoftwareSystem("Software System", "");
162+
Container container = softwareSystem.AddContainer("Container", "", "");
163+
Component component = container.AddComponent("Component", "", "");
164+
165+
try
166+
{
167+
softwareSystem.Uses(container, "Uses");
168+
throw new TestFailedException();
169+
}
170+
catch (ArgumentException ae)
171+
{
172+
Assert.Equal("Relationships cannot be added between parents and children.", ae.Message);
173+
Assert.Equal(0, softwareSystem.Relationships.Count);
174+
}
175+
176+
try
177+
{
178+
container.Uses(component, "Uses");
179+
throw new TestFailedException();
180+
}
181+
catch (ArgumentException ae)
182+
{
183+
Assert.Equal("Relationships cannot be added between parents and children.", ae.Message);
184+
Assert.Equal(0, softwareSystem.Relationships.Count);
185+
}
186+
187+
try
188+
{
189+
softwareSystem.Uses(component, "Uses");
190+
throw new TestFailedException();
191+
}
192+
catch (ArgumentException ae)
193+
{
194+
Assert.Equal("Relationships cannot be added between parents and children.", ae.Message);
195+
Assert.Equal(0, softwareSystem.Relationships.Count);
196+
}
197+
}
198+
199+
[Fact]
200+
public void Test_AddRelationship_ThrowsAnException_WhenTheSourceIsAChildOfTheDestination()
201+
{
202+
SoftwareSystem softwareSystem = Model.AddSoftwareSystem("Software System", "");
203+
Container container = softwareSystem.AddContainer("Container", "", "");
204+
Component component = container.AddComponent("Component", "", "");
205+
206+
try
207+
{
208+
container.Uses(softwareSystem, "Uses");
209+
throw new TestFailedException();
210+
}
211+
catch (ArgumentException ae)
212+
{
213+
Assert.Equal("Relationships cannot be added between parents and children.", ae.Message);
214+
Assert.Equal(0, softwareSystem.Relationships.Count);
215+
}
216+
217+
try
218+
{
219+
component.Uses(container, "Uses");
220+
throw new TestFailedException();
221+
}
222+
catch (ArgumentException ae)
223+
{
224+
Assert.Equal("Relationships cannot be added between parents and children.", ae.Message);
225+
Assert.Equal(0, softwareSystem.Relationships.Count);
226+
}
227+
228+
try
229+
{
230+
component.Uses(softwareSystem, "Uses");
231+
throw new TestFailedException();
232+
}
233+
catch (ArgumentException ae)
234+
{
235+
Assert.Equal("Relationships cannot be added between parents and children.", ae.Message);
236+
Assert.Equal(0, softwareSystem.Relationships.Count);
237+
}
238+
}
239+
158240
[Fact]
159241
public void Test_ModifyRelationship_ThrowsAnException_WhenARelationshipIsNotSpecified()
160242
{

Structurizr.Core/Model/Model.cs

+29-35
Original file line numberDiff line numberDiff line change
@@ -339,7 +339,12 @@ internal Relationship AddRelationship(Element source, Element destination, strin
339339
{
340340
throw new ArgumentException("The destination must be specified.");
341341
}
342-
342+
343+
if (IsChildOf(source, destination) || IsChildOf(destination, source))
344+
{
345+
throw new ArgumentException("Relationships cannot be added between parents and children.");
346+
}
347+
343348
Relationship relationship = new Relationship(source, destination, description, technology, interactionStyle);
344349
if (AddRelationship(relationship)) {
345350
return relationship;
@@ -348,6 +353,26 @@ internal Relationship AddRelationship(Element source, Element destination, strin
348353
return null;
349354
}
350355

356+
private bool IsChildOf(Element e1, Element e2)
357+
{
358+
if (e1 is Person || e2 is Person) {
359+
return false;
360+
}
361+
362+
Element parent = e2.Parent;
363+
while (parent != null)
364+
{
365+
if (parent.Id.Equals(e1.Id))
366+
{
367+
return true;
368+
}
369+
370+
parent = parent.Parent;
371+
}
372+
373+
return false;
374+
}
375+
351376
private bool AddRelationship(Relationship relationship)
352377
{
353378
if (!relationship.Source.Has(relationship))
@@ -667,41 +692,10 @@ private bool propagatedRelationshipIsAllowed(Element source, Element destination
667692
{
668693
return false;
669694
}
670-
671-
if (source.Parent != null) {
672-
if (destination.Equals(source.Parent))
673-
{
674-
return false;
675-
}
676-
677-
if (source.Parent.Parent != null)
678-
{
679-
if (destination.Equals(source.Parent.Parent))
680-
{
681-
return false;
682-
}
683-
}
684-
}
685-
686-
if (destination.Parent != null)
687-
{
688-
if (source.Equals(destination.Parent))
689-
{
690-
return false;
691-
}
692-
693-
if (destination.Parent.Parent != null)
694-
{
695-
if (source.Equals(destination.Parent.Parent))
696-
{
697-
return false;
698-
}
699-
}
700-
}
701-
702-
return true;
695+
696+
return !(IsChildOf(source, destination) || IsChildOf(destination, source));
703697
}
704698

705699
}
706700

707-
}
701+
}

docs/changelog.md

+4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
# Changelog
22

3+
## 0.9.3 (unreleased)
4+
5+
- Fixes a bug that allows relationships to be created between parents and children.
6+
37
## 0.9.2 (16th September 2019)
48

59
- Fixes a bug where element and relationship positioning is lost when workspaces are merged.

0 commit comments

Comments
 (0)