1212 *******************************************************************************/
1313package org .eclipse .syson .application .controllers .diagrams .general .view ;
1414
15+ import static org .assertj .core .api .Assertions .assertThat ;
16+ import static org .junit .jupiter .api .Assertions .fail ;
17+
1518import java .time .Duration ;
19+ import java .util .List ;
20+ import java .util .Optional ;
1621import java .util .UUID ;
1722import java .util .concurrent .atomic .AtomicReference ;
23+ import java .util .function .Consumer ;
1824
1925import org .eclipse .sirius .components .collaborative .diagrams .dto .DiagramEventInput ;
2026import org .eclipse .sirius .components .collaborative .diagrams .dto .DiagramRefreshedEventPayload ;
2127import org .eclipse .sirius .components .diagrams .Diagram ;
28+ import org .eclipse .sirius .components .diagrams .Edge ;
29+ import org .eclipse .sirius .components .diagrams .InsideLabel ;
2230import org .eclipse .sirius .components .diagrams .tests .graphql .EditLabelMutationRunner ;
2331import org .eclipse .sirius .components .diagrams .tests .graphql .InitialDirectEditElementLabelQueryRunner ;
32+ import org .eclipse .sirius .components .diagrams .tests .navigation .DiagramNavigator ;
2433import org .eclipse .sirius .web .tests .services .api .IGivenInitialServerState ;
2534import org .eclipse .syson .AbstractIntegrationTests ;
35+ import org .eclipse .syson .application .controllers .diagrams .testers .DeleteFromDiagramRunner ;
36+ import org .eclipse .syson .application .controllers .diagrams .testers .DeleteFromDiagramTester ;
2637import org .eclipse .syson .application .controllers .diagrams .testers .DirectEditInitialLabelTester ;
2738import org .eclipse .syson .application .controllers .diagrams .testers .DirectEditTester ;
2839import org .eclipse .syson .application .data .GeneralViewItemAndAttributeProjectData ;
40+ import org .eclipse .syson .services .diagrams .DiagramComparator ;
2941import org .eclipse .syson .services .diagrams .api .IGivenDiagramReference ;
3042import org .eclipse .syson .services .diagrams .api .IGivenDiagramSubscription ;
3143import org .junit .jupiter .api .AfterEach ;
@@ -65,6 +77,12 @@ public class GVItemAndAttributeExpressionTests extends AbstractIntegrationTests
6577 @ Autowired
6678 private EditLabelMutationRunner editLabelMutationRunner ;
6779
80+ @ Autowired
81+ private DiagramComparator diagramComparator ;
82+
83+ @ Autowired
84+ private DeleteFromDiagramRunner deleteFromDiagramRunner ;
85+
6886 private Step <DiagramRefreshedEventPayload > verifier ;
6987
7088 private AtomicReference <Diagram > diagram ;
@@ -73,6 +91,8 @@ public class GVItemAndAttributeExpressionTests extends AbstractIntegrationTests
7391
7492 private DirectEditTester directEditTester ;
7593
94+ private DeleteFromDiagramTester deleteFromDiagramTester ;
95+
7696 @ BeforeEach
7797 public void setUp () {
7898 this .givenInitialServerState .initialize ();
@@ -84,6 +104,8 @@ public void setUp() {
84104 this .diagram = this .givenDiagram .getDiagram (this .verifier );
85105 this .directEditInitialLabelTester = new DirectEditInitialLabelTester (this .initialDirectEditElementLabelQueryRunner , GeneralViewItemAndAttributeProjectData .EDITING_CONTEXT_ID );
86106 this .directEditTester = new DirectEditTester (this .editLabelMutationRunner , GeneralViewItemAndAttributeProjectData .EDITING_CONTEXT_ID );
107+ this .deleteFromDiagramTester = new DeleteFromDiagramTester (this .deleteFromDiagramRunner , GeneralViewItemAndAttributeProjectData .EDITING_CONTEXT_ID ,
108+ GeneralViewItemAndAttributeProjectData .GraphicalIds .DIAGRAM_ID );
87109 }
88110
89111 @ AfterEach
@@ -215,4 +237,92 @@ public void attributeWithBranketExpression() {
215237 GeneralViewItemAndAttributeProjectData .GraphicalIds .P1_1_X1_ID ,
216238 "a2_1 = 45 [kilogram]" );
217239 }
240+
241+ @ DisplayName ("GIVEN an ItemUsage, WHEN with a value referencing another ItemUsage, THEN an edge should connect the ItemUsage" )
242+ @ Test
243+ @ Sql (scripts = { GeneralViewItemAndAttributeProjectData .SCRIPT_PATH }, executionPhase = Sql .ExecutionPhase .BEFORE_TEST_METHOD )
244+ @ Sql (scripts = { "/scripts/cleanup.sql" }, executionPhase = Sql .ExecutionPhase .AFTER_TEST_METHOD , config = @ SqlConfig (transactionMode = SqlConfig .TransactionMode .ISOLATED ))
245+ public void itemFeatureChainBindingEdge () {
246+
247+ // Create an edge using direct edit
248+ this .directEditTester .checkDirectEditInsideLabel (this .verifier , this .diagram ,
249+ GeneralViewItemAndAttributeProjectData .GraphicalIds .A2_1_ICON_AND_LABEL_ID ,
250+ "in a2_1 = a1.a1_1" ,
251+ this .buildEdgeChecker (GeneralViewItemAndAttributeProjectData .GraphicalIds .A2_1_ICON_AND_LABEL_ID , "in a2_1 = a1.a1_1" ,
252+ GeneralViewItemAndAttributeProjectData .GraphicalIds .A2_1_BORDERED_NODE_ID , GeneralViewItemAndAttributeProjectData .GraphicalIds .A1_1_BORDERED_NODE_ID ));
253+
254+ // Change the edge to a new target
255+ this .directEditTester .checkDirectEditInsideLabel (this .verifier , this .diagram ,
256+ GeneralViewItemAndAttributeProjectData .GraphicalIds .A2_1_ICON_AND_LABEL_ID ,
257+ "in a2_1 = a1.a1_2" ,
258+ this .buildEdgeChecker (GeneralViewItemAndAttributeProjectData .GraphicalIds .A2_1_ICON_AND_LABEL_ID , "in a2_1 = a1.a1_2" ,
259+ GeneralViewItemAndAttributeProjectData .GraphicalIds .A2_1_BORDERED_NODE_ID , GeneralViewItemAndAttributeProjectData .GraphicalIds .A1_2_BORDERED_NODE_ID ));
260+
261+ // Remove edge
262+ this .directEditTester .checkDirectEditInsideLabel (this .verifier , this .diagram ,
263+ GeneralViewItemAndAttributeProjectData .GraphicalIds .A2_1_ICON_AND_LABEL_ID ,
264+ "in a2_1 =" ,
265+ this .buildNoEdgeStartingFromChecker (GeneralViewItemAndAttributeProjectData .GraphicalIds .A2_1_ICON_AND_LABEL_ID , "in a2_1" ,
266+ GeneralViewItemAndAttributeProjectData .GraphicalIds .A2_1_BORDERED_NODE_ID ));
267+
268+ }
269+
270+ @ DisplayName ("GIVEN an ItemUsage, WHEN deleting an edge representing a FeatureValue, THEN the FeatureValue should be deleted and the label of the ItemUsage should be updated updated" )
271+ @ Test
272+ @ Sql (scripts = { GeneralViewItemAndAttributeProjectData .SCRIPT_PATH }, executionPhase = Sql .ExecutionPhase .BEFORE_TEST_METHOD )
273+ @ Sql (scripts = { "/scripts/cleanup.sql" }, executionPhase = Sql .ExecutionPhase .AFTER_TEST_METHOD , config = @ SqlConfig (transactionMode = SqlConfig .TransactionMode .ISOLATED ))
274+ public void deleteFeatureValueEdge () {
275+
276+ this .deleteFromDiagramTester .checkRemoveFromDiagram (this .verifier , List .of (), List .of (GeneralViewItemAndAttributeProjectData .GraphicalIds .FEATURE_VALUE_A2_2_TO_A1_4_EDGE ),
277+ payload -> Optional .of (payload )
278+ .map (DiagramRefreshedEventPayload ::diagram )
279+ .ifPresentOrElse (newDiagram -> {
280+ // Check label no more FeatureValue (the = part is gone)
281+ DiagramNavigator diagramNavigator = new DiagramNavigator (newDiagram );
282+ InsideLabel newLabel = diagramNavigator .nodeWithId (GeneralViewItemAndAttributeProjectData .GraphicalIds .A2_2_ICON_AND_LABEL_ID ).getNode ().getInsideLabel ();
283+ assertThat (newLabel .getText ()).isEqualTo ("out a2_2" );
284+
285+ // No more edge starting from a2_2
286+ assertThat (newDiagram .getEdges ()).noneMatch (s -> GeneralViewItemAndAttributeProjectData .GraphicalIds .A2_2_BORDERED_NODE_ID .equals (s .getSourceId ()));
287+ }, () -> fail ("Missing diagram" )));
288+
289+ }
290+
291+ private Consumer <DiagramRefreshedEventPayload > buildEdgeChecker (String nodeToCheckForLabel , String expectedLabel , String sourceNodeId , String targetNodeId ) {
292+ return payload -> Optional .of (payload )
293+ .map (DiagramRefreshedEventPayload ::diagram )
294+ .ifPresentOrElse (newDiagram -> {
295+ // Check label
296+ DiagramNavigator diagramNavigator = new DiagramNavigator (newDiagram );
297+ InsideLabel newLabel = diagramNavigator .nodeWithId (nodeToCheckForLabel ).getNode ().getInsideLabel ();
298+ assertThat (newLabel .getText ()).isEqualTo (expectedLabel );
299+
300+ // Check new edge
301+ List <Edge > newEdges = this .diagramComparator .newEdges (this .diagram .get (), newDiagram );
302+ assertThat (newEdges ).hasSize (1 )
303+ .first ()
304+ .satisfies (edge -> {
305+ assertThat (edge .getSourceId ()).as ("Should start from A2_1" ).isEqualTo (sourceNodeId );
306+ }, edge -> {
307+ assertThat (edge .getTargetId ()).as ("Should end to A1_1" ).isEqualTo (targetNodeId );
308+ });
309+ }, () -> fail ("Missing diagram" ));
310+ }
311+
312+ private Consumer <DiagramRefreshedEventPayload > buildNoEdgeStartingFromChecker (String nodeToCheckForLabel , String expectedLabel , String sourceNodeId ) {
313+ return payload -> Optional .of (payload )
314+ .map (DiagramRefreshedEventPayload ::diagram )
315+ .ifPresentOrElse (newDiagram -> {
316+ // Check label
317+ DiagramNavigator diagramNavigator = new DiagramNavigator (newDiagram );
318+ InsideLabel newLabel = diagramNavigator .nodeWithId (nodeToCheckForLabel ).getNode ().getInsideLabel ();
319+ assertThat (newLabel .getText ()).isEqualTo (expectedLabel );
320+
321+ // Check there is starting from the given source
322+ List <Edge > newEdges = this .diagramComparator .newEdges (this .diagram .get (), newDiagram );
323+
324+ assertThat (newDiagram .getEdges ()).noneMatch (s -> sourceNodeId .equals (s .getSourceId ()));
325+ assertThat (newEdges ).hasSize (0 );
326+ }, () -> fail ("Missing diagram" ));
327+ }
218328}
0 commit comments