11/*******************************************************************************
2- * Copyright (c) 2024, 2025 Obeo.
2+ * Copyright (c) 2024, 2026 Obeo.
33 * This program and the accompanying materials
44 * are made available under the terms of the Eclipse Public License v2.0
55 * which accompanies this distribution, and is available at
1313package org .eclipse .syson .application .controllers .diagrams .general .view ;
1414
1515import static org .assertj .core .api .Assertions .assertThat ;
16- import static org .junit . jupiter . api . Assertions . fail ;
16+ import static org .eclipse . sirius . components . diagrams . tests . DiagramEventPayloadConsumer . assertRefreshedDiagramThat ;
1717
1818import java .text .MessageFormat ;
1919import java .time .Duration ;
2828import org .eclipse .sirius .components .diagrams .Diagram ;
2929import org .eclipse .sirius .components .diagrams .Node ;
3030import org .eclipse .sirius .components .diagrams .ViewModifier ;
31- import org .eclipse .sirius .components .view .diagram .DiagramDescription ;
3231import org .eclipse .sirius .components .view .emf .diagram .IDiagramIdProvider ;
3332import org .eclipse .sirius .web .tests .services .api .IGivenInitialServerState ;
3433import org .eclipse .syson .AbstractIntegrationTests ;
3534import org .eclipse .syson .application .controllers .diagrams .testers .ToolTester ;
3635import org .eclipse .syson .application .data .GeneralViewAddExistingElementsTestProjectData ;
3736import org .eclipse .syson .services .diagrams .DiagramDescriptionIdProvider ;
3837import org .eclipse .syson .services .diagrams .api .IGivenDiagramDescription ;
39- import org .eclipse .syson .services .diagrams .api .IGivenDiagramReference ;
4038import org .eclipse .syson .services .diagrams .api .IGivenDiagramSubscription ;
4139import org .eclipse .syson .util .SysONRepresentationDescriptionIdentifiers ;
42- import org .junit .jupiter .api .AfterEach ;
4340import org .junit .jupiter .api .BeforeEach ;
4441import org .junit .jupiter .api .Test ;
4542import org .springframework .beans .factory .annotation .Autowired ;
4845import org .springframework .test .context .jdbc .SqlConfig ;
4946import org .springframework .transaction .annotation .Transactional ;
5047
48+ import reactor .core .publisher .Flux ;
5149import reactor .test .StepVerifier ;
52- import reactor .test .StepVerifier .Step ;
5350
5451/**
5552 * Tests the invocation of the "addExistingElements" tool in the General View diagram.
@@ -79,9 +76,6 @@ public class GVAddExistingElementsTests extends AbstractIntegrationTests {
7976 @ Autowired
8077 private IGivenInitialServerState givenInitialServerState ;
8178
82- @ Autowired
83- private IGivenDiagramReference givenDiagram ;
84-
8579 @ Autowired
8680 private IGivenDiagramDescription givenDiagramDescription ;
8781
@@ -94,60 +88,58 @@ public class GVAddExistingElementsTests extends AbstractIntegrationTests {
9488 @ Autowired
9589 private ToolTester nodeCreationTester ;
9690
97- private DiagramDescriptionIdProvider diagramDescriptionIdProvider ;
98-
99- private Step <DiagramRefreshedEventPayload > verifier ;
100-
101- private AtomicReference <Diagram > diagram ;
102-
103- private DiagramDescription diagramDescription ;
104-
105- @ BeforeEach
106- public void setUp () {
107- this .givenInitialServerState .initialize ();
91+ private Flux <DiagramRefreshedEventPayload > givenSubscriptionToDiagram () {
10892 var diagramEventInput = new DiagramEventInput (UUID .randomUUID (),
10993 GeneralViewAddExistingElementsTestProjectData .EDITING_CONTEXT_ID ,
11094 GeneralViewAddExistingElementsTestProjectData .GraphicalIds .DIAGRAM_ID );
111- var flux = this .givenDiagramSubscription .subscribe (diagramEventInput );
112- this .verifier = StepVerifier .create (flux );
113- this .diagram = this .givenDiagram .getDiagram (this .verifier );
114- this .diagramDescription = this .givenDiagramDescription .getDiagramDescription (GeneralViewAddExistingElementsTestProjectData .EDITING_CONTEXT_ID ,
115- SysONRepresentationDescriptionIdentifiers .GENERAL_VIEW_DIAGRAM_DESCRIPTION_ID );
116- this .diagramDescriptionIdProvider = new DiagramDescriptionIdProvider (this .diagramDescription , this .diagramIdProvider );
95+ return this .givenDiagramSubscription .subscribe (diagramEventInput );
11796 }
11897
119- @ AfterEach
120- public void tearDown () {
121- if (this .verifier != null ) {
122- this .verifier .thenCancel ()
123- .verify (Duration .ofSeconds (10 ));
124- }
98+
99+ @ BeforeEach
100+ public void setUp () {
101+ this .givenInitialServerState .initialize ();
125102 }
126103
127104 @ Sql (scripts = { GeneralViewAddExistingElementsTestProjectData .SCRIPT_PATH }, executionPhase = Sql .ExecutionPhase .BEFORE_TEST_METHOD ,
128105 config = @ SqlConfig (transactionMode = SqlConfig .TransactionMode .ISOLATED ))
129106 @ Sql (scripts = { "/scripts/cleanup.sql" }, executionPhase = Sql .ExecutionPhase .AFTER_TEST_METHOD , config = @ SqlConfig (transactionMode = SqlConfig .TransactionMode .ISOLATED ))
130107 @ Test
131108 public void addExistingElementsOnDiagram () {
132- String creationToolId = this .diagramDescriptionIdProvider .getDiagramCreationToolId ("Add existing elements" );
109+ var flux = this .givenSubscriptionToDiagram ();
110+
111+ var diagramDescription = this .givenDiagramDescription .getDiagramDescription (GeneralViewAddExistingElementsTestProjectData .EDITING_CONTEXT_ID ,
112+ SysONRepresentationDescriptionIdentifiers .GENERAL_VIEW_DIAGRAM_DESCRIPTION_ID );
113+ var diagramDescriptionIdProvider = new DiagramDescriptionIdProvider (diagramDescription , this .diagramIdProvider );
114+
115+ AtomicReference <Diagram > diagram = new AtomicReference <>();
116+
117+ Consumer <Object > initialDiagramContentConsumer = assertRefreshedDiagramThat (diagram ::set );
118+
119+ String creationToolId = diagramDescriptionIdProvider .getDiagramCreationToolId ("Add existing elements" );
133120 assertThat (creationToolId ).as ("The tool 'Add existing elements' should exist on the diagram" ).isNotNull ();
134- this .verifier .then (() -> this .nodeCreationTester .invokeTool (GeneralViewAddExistingElementsTestProjectData .EDITING_CONTEXT_ID , this .diagram , creationToolId ));
135-
136- Consumer <DiagramRefreshedEventPayload > updatedDiagramConsumer = payload -> Optional .of (payload )
137- .map (DiagramRefreshedEventPayload ::diagram )
138- .ifPresentOrElse (newDiagram -> {
139- assertThat (newDiagram .getNodes ()).as ("3 nodes should be visible on the diagram" ).hasSize (4 );
140- assertThat (newDiagram .getNodes ())
141- .as (MessageFormat .format (NODE_SHOULD_BE_ON_DIAGRAM_MESSAGE , PACKAGE1 ))
142- .anyMatch (n -> Objects .equals (n .getTargetObjectLabel (), PACKAGE1 ))
143- .as (MessageFormat .format (NODE_SHOULD_BE_ON_DIAGRAM_MESSAGE , ACTION1 ))
144- .anyMatch (n -> Objects .equals (n .getTargetObjectLabel (), ACTION1 ))
145- .as (MessageFormat .format (NODE_SHOULD_BE_ON_DIAGRAM_MESSAGE , PART1 ))
146- .anyMatch (n -> Objects .equals (n .getTargetObjectLabel (), PART1 ))
147- .as (MessageFormat .format (NODE_SHOULD_BE_ON_DIAGRAM_MESSAGE , "RequirementUsage" ))
148- .anyMatch (n -> Objects .equals (n .getTargetObjectLabel (), "RequirementUsage" ));
149- }, () -> fail ("Missing diagram" ));
150- this .verifier .consumeNextWith (updatedDiagramConsumer );
121+
122+ Runnable nodeCreationRunner = () -> this .nodeCreationTester .invokeTool (GeneralViewAddExistingElementsTestProjectData .EDITING_CONTEXT_ID , diagram , creationToolId );
123+
124+ Consumer <Object > updatedDiagramConsumer = assertRefreshedDiagramThat (newDiagram -> {
125+ assertThat (newDiagram .getNodes ()).as ("3 nodes should be visible on the diagram" ).hasSize (4 );
126+ assertThat (newDiagram .getNodes ())
127+ .as (MessageFormat .format (NODE_SHOULD_BE_ON_DIAGRAM_MESSAGE , PACKAGE1 ))
128+ .anyMatch (n -> Objects .equals (n .getTargetObjectLabel (), PACKAGE1 ))
129+ .as (MessageFormat .format (NODE_SHOULD_BE_ON_DIAGRAM_MESSAGE , ACTION1 ))
130+ .anyMatch (n -> Objects .equals (n .getTargetObjectLabel (), ACTION1 ))
131+ .as (MessageFormat .format (NODE_SHOULD_BE_ON_DIAGRAM_MESSAGE , PART1 ))
132+ .anyMatch (n -> Objects .equals (n .getTargetObjectLabel (), PART1 ))
133+ .as (MessageFormat .format (NODE_SHOULD_BE_ON_DIAGRAM_MESSAGE , "RequirementUsage" ))
134+ .anyMatch (n -> Objects .equals (n .getTargetObjectLabel (), "RequirementUsage" ));
135+ });
136+
137+ StepVerifier .create (flux )
138+ .consumeNextWith (initialDiagramContentConsumer )
139+ .then (nodeCreationRunner )
140+ .consumeNextWith (updatedDiagramConsumer )
141+ .thenCancel ()
142+ .verify (Duration .ofSeconds (10 ));
151143
152144 }
153145
@@ -156,50 +148,63 @@ public void addExistingElementsOnDiagram() {
156148 @ Sql (scripts = { "/scripts/cleanup.sql" }, executionPhase = Sql .ExecutionPhase .AFTER_TEST_METHOD , config = @ SqlConfig (transactionMode = SqlConfig .TransactionMode .ISOLATED ))
157149 @ Test
158150 public void addExistingElementsRecursiveOnDiagram () {
159- String creationToolId = this .diagramDescriptionIdProvider .getDiagramCreationToolId ("Add existing elements (recursive)" );
151+ var flux = this .givenSubscriptionToDiagram ();
152+
153+ var diagramDescription = this .givenDiagramDescription .getDiagramDescription (GeneralViewAddExistingElementsTestProjectData .EDITING_CONTEXT_ID ,
154+ SysONRepresentationDescriptionIdentifiers .GENERAL_VIEW_DIAGRAM_DESCRIPTION_ID );
155+ var diagramDescriptionIdProvider = new DiagramDescriptionIdProvider (diagramDescription , this .diagramIdProvider );
156+
157+ AtomicReference <Diagram > diagram = new AtomicReference <>();
158+
159+ Consumer <Object > initialDiagramContentConsumer = assertRefreshedDiagramThat (diagram ::set );
160+
161+ String creationToolId = diagramDescriptionIdProvider .getDiagramCreationToolId ("Add existing elements (recursive)" );
160162 assertThat (creationToolId ).as ("The tool 'Add existing elements (recursive)' should exist on the diagram" ).isNotNull ();
161- this .verifier .then (() -> this .nodeCreationTester .invokeTool (GeneralViewAddExistingElementsTestProjectData .EDITING_CONTEXT_ID , this .diagram , creationToolId ));
162-
163- Consumer <DiagramRefreshedEventPayload > updatedDiagramConsumer = payload -> Optional .of (payload )
164- .map (DiagramRefreshedEventPayload ::diagram )
165- .ifPresentOrElse (newDiagram -> {
166- assertThat (newDiagram .getNodes ()).as ("6 nodes should be visible on the diagram" ).hasSize (7 );
167- assertThat (newDiagram .getEdges ().stream ().filter (e -> ViewModifier .Normal .equals (e .getState ())).toList ())
168- .as ("3 edges should be visible on the diagram" )
169- .hasSize (3 )
170- .as ("The diagram should contain a composite edge between part2 and part1" )
171- .anyMatch (edge -> edge .getTargetObjectLabel ().equals (PART1 ))
172- .as ("The diagram should contain a composite edge between action1 and action2" )
173- .anyMatch (edge -> edge .getTargetObjectLabel ().equals (ACTION1 ))
174- .as ("The diagram should contain a composite edge between action2 and action3" )
175- .anyMatch (edge -> edge .getTargetObjectLabel ().equals (ACTION2 ));
176- assertThat (newDiagram .getNodes ())
177- .as (MessageFormat .format (NODE_SHOULD_BE_ON_DIAGRAM_MESSAGE , PACKAGE1 ))
178- .anyMatch (n -> Objects .equals (n .getTargetObjectLabel (), PACKAGE1 ))
179- .as (MessageFormat .format (NODE_SHOULD_BE_ON_DIAGRAM_MESSAGE , ACTION1 ))
180- .anyMatch (n -> Objects .equals (n .getTargetObjectLabel (), ACTION1 ))
181- .as (MessageFormat .format (NODE_SHOULD_BE_ON_DIAGRAM_MESSAGE , PART1 ))
182- .anyMatch (n -> Objects .equals (n .getTargetObjectLabel (), PART1 ))
183- .as (MessageFormat .format (NODE_SHOULD_BE_ON_DIAGRAM_MESSAGE , PART2 ))
184- .anyMatch (n -> Objects .equals (n .getTargetObjectLabel (), PART2 ))
185- .as (MessageFormat .format (NODE_SHOULD_BE_ON_DIAGRAM_MESSAGE , "RequirementUsage" ))
186- .anyMatch (n -> Objects .equals (n .getTargetObjectLabel (), "RequirementUsage" ));
187-
188- this .checkPackageNode (newDiagram );
189-
190-
191- // @technical-debt enable this part when start node will be synchronized
192- // .as(ACTION1 + " action flow compartment should contain a start node")
193- // .anyMatch(n -> n.getStyle() instanceof ImageNodeStyle imageStyle &&
194- // Objects.equals(imageStyle.getImageURL(), "images/start_action.svg")
195- // && Objects.equals("start", n.getTargetObjectLabel()));
196-
197- this .checkAction2 (newDiagram );
198-
199- this .checkRequirementUsage (newDiagram );
200-
201- }, () -> fail ("Missing diagram" ));
202- this .verifier .consumeNextWith (updatedDiagramConsumer );
163+
164+ Runnable nodeCreationRunner = () -> this .nodeCreationTester .invokeTool (GeneralViewAddExistingElementsTestProjectData .EDITING_CONTEXT_ID , diagram , creationToolId );
165+
166+ Consumer <Object > updatedDiagramConsumer = assertRefreshedDiagramThat (newDiagram -> {
167+ assertThat (newDiagram .getNodes ()).as ("6 nodes should be visible on the diagram" ).hasSize (7 );
168+ assertThat (newDiagram .getEdges ().stream ().filter (e -> ViewModifier .Normal .equals (e .getState ())).toList ())
169+ .as ("3 edges should be visible on the diagram" )
170+ .hasSize (3 )
171+ .as ("The diagram should contain a composite edge between part2 and part1" )
172+ .anyMatch (edge -> edge .getTargetObjectLabel ().equals (PART1 ))
173+ .as ("The diagram should contain a composite edge between action1 and action2" )
174+ .anyMatch (edge -> edge .getTargetObjectLabel ().equals (ACTION1 ))
175+ .as ("The diagram should contain a composite edge between action2 and action3" )
176+ .anyMatch (edge -> edge .getTargetObjectLabel ().equals (ACTION2 ));
177+ assertThat (newDiagram .getNodes ())
178+ .as (MessageFormat .format (NODE_SHOULD_BE_ON_DIAGRAM_MESSAGE , PACKAGE1 ))
179+ .anyMatch (n -> Objects .equals (n .getTargetObjectLabel (), PACKAGE1 ))
180+ .as (MessageFormat .format (NODE_SHOULD_BE_ON_DIAGRAM_MESSAGE , ACTION1 ))
181+ .anyMatch (n -> Objects .equals (n .getTargetObjectLabel (), ACTION1 ))
182+ .as (MessageFormat .format (NODE_SHOULD_BE_ON_DIAGRAM_MESSAGE , PART1 ))
183+ .anyMatch (n -> Objects .equals (n .getTargetObjectLabel (), PART1 ))
184+ .as (MessageFormat .format (NODE_SHOULD_BE_ON_DIAGRAM_MESSAGE , PART2 ))
185+ .anyMatch (n -> Objects .equals (n .getTargetObjectLabel (), PART2 ))
186+ .as (MessageFormat .format (NODE_SHOULD_BE_ON_DIAGRAM_MESSAGE , "RequirementUsage" ))
187+ .anyMatch (n -> Objects .equals (n .getTargetObjectLabel (), "RequirementUsage" ));
188+
189+ this .checkPackageNode (newDiagram );
190+
191+ // @technical-debt enable this part when start node will be synchronized
192+ // .as(ACTION1 + " action flow compartment should contain a start node")
193+ // .anyMatch(n -> n.getStyle() instanceof ImageNodeStyle imageStyle &&
194+ // Objects.equals(imageStyle.getImageURL(), "images/start_action.svg")
195+ // && Objects.equals("start", n.getTargetObjectLabel()));
196+
197+ this .checkAction2 (newDiagram );
198+
199+ this .checkRequirementUsage (newDiagram );
200+ });
201+
202+ StepVerifier .create (flux )
203+ .consumeNextWith (initialDiagramContentConsumer )
204+ .then (nodeCreationRunner )
205+ .consumeNextWith (updatedDiagramConsumer )
206+ .thenCancel ()
207+ .verify (Duration .ofSeconds (10 ));
203208 }
204209
205210 private void checkPackageNode (Diagram newDiagram ) {
@@ -215,7 +220,6 @@ private void checkPackageNode(Diagram newDiagram) {
215220 }
216221
217222 private void checkAction2 (Diagram newDiagram ) {
218-
219223 var action1ActionFlowCompartment = this .checkAction1 (newDiagram );
220224 var optAction2Node = action1ActionFlowCompartment .getChildNodes ().stream ()
221225 .filter (n -> Objects .equals (n .getTargetObjectLabel (), ACTION2 ))
0 commit comments