Skip to content

Commit 1aad707

Browse files
adaussyAxelRICHARD
authored andcommitted
[1602] Unable to DnD a RequirementUsage with no DeclaredName on GV
Bug: #1602 Signed-off-by: Arthur Daussy <arthur.daussy@obeo.fr>
1 parent 0b35687 commit 1aad707

7 files changed

Lines changed: 179 additions & 71 deletions

File tree

CHANGELOG.adoc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@
1212

1313
=== Bug fixes
1414

15-
- https://github.com/eclipse-syson/syson/issues/1604[#1604] Fix an issue where the `Imports` located in the root `Namespace` were not exported in the textual format.
15+
- https://github.com/eclipse-syson/syson/issues/1604[#1604] [export] Fix an issue where the `Imports` located in the root `Namespace` were not exported in the textual format.
16+
- https://github.com/eclipse-syson/syson/issues/1602[#1602] [diagrams] Fix an issue where the drag and drop of a `RequirementUsage` (or any other `Element`) with a declared short name but no declared name from the _Explorer_ view to a diagram was not possible.
1617

1718
=== Improvements
1819

backend/application/syson-application/src/test/java/org/eclipse/syson/application/controllers/diagrams/general/view/GVAddExistingElementsTests.java

Lines changed: 103 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -136,14 +136,16 @@ public void addExistingElementsOnDiagram() {
136136
Consumer<DiagramRefreshedEventPayload> updatedDiagramConsumer = payload -> Optional.of(payload)
137137
.map(DiagramRefreshedEventPayload::diagram)
138138
.ifPresentOrElse(newDiagram -> {
139-
assertThat(newDiagram.getNodes()).as("3 nodes should be visible on the diagram").hasSize(3);
139+
assertThat(newDiagram.getNodes()).as("3 nodes should be visible on the diagram").hasSize(4);
140140
assertThat(newDiagram.getNodes())
141141
.as(MessageFormat.format(NODE_SHOULD_BE_ON_DIAGRAM_MESSAGE, PACKAGE1))
142142
.anyMatch(n -> Objects.equals(n.getTargetObjectLabel(), PACKAGE1))
143143
.as(MessageFormat.format(NODE_SHOULD_BE_ON_DIAGRAM_MESSAGE, ACTION1))
144144
.anyMatch(n -> Objects.equals(n.getTargetObjectLabel(), ACTION1))
145145
.as(MessageFormat.format(NODE_SHOULD_BE_ON_DIAGRAM_MESSAGE, PART1))
146-
.anyMatch(n -> Objects.equals(n.getTargetObjectLabel(), 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"));
147149
}, () -> fail("Missing diagram"));
148150
this.verifier.consumeNextWith(updatedDiagramConsumer);
149151

@@ -161,7 +163,7 @@ public void addExistingElementsRecursiveOnDiagram() {
161163
Consumer<DiagramRefreshedEventPayload> updatedDiagramConsumer = payload -> Optional.of(payload)
162164
.map(DiagramRefreshedEventPayload::diagram)
163165
.ifPresentOrElse(newDiagram -> {
164-
assertThat(newDiagram.getNodes()).as("6 nodes should be visible on the diagram").hasSize(6);
166+
assertThat(newDiagram.getNodes()).as("6 nodes should be visible on the diagram").hasSize(7);
165167
assertThat(newDiagram.getEdges().stream().filter(e -> ViewModifier.Normal.equals(e.getState())).toList())
166168
.as("3 edges should be visible on the diagram")
167169
.hasSize(3)
@@ -179,78 +181,115 @@ public void addExistingElementsRecursiveOnDiagram() {
179181
.as(MessageFormat.format(NODE_SHOULD_BE_ON_DIAGRAM_MESSAGE, PART1))
180182
.anyMatch(n -> Objects.equals(n.getTargetObjectLabel(), PART1))
181183
.as(MessageFormat.format(NODE_SHOULD_BE_ON_DIAGRAM_MESSAGE, PART2))
182-
.anyMatch(n -> Objects.equals(n.getTargetObjectLabel(), PART2));
183-
184-
var optPackageNode = newDiagram.getNodes().stream()
185-
.filter(n -> Objects.equals(n.getTargetObjectLabel(), PACKAGE1))
186-
.findFirst();
187-
assertThat(optPackageNode).isPresent();
188-
assertThat(optPackageNode.get().getChildNodes())
189-
.as("Node " + PACKAGE1 + " should contain 1 child")
190-
.hasSize(1)
191-
.as("Node " + ATTRIBUTE_DEFINITION + " should exist inside " + PACKAGE1)
192-
.anyMatch(n -> Objects.equals(n.getTargetObjectLabel(), ATTRIBUTE_DEFINITION));
193-
194-
var optAction1Node = newDiagram.getNodes().stream()
195-
.filter(n -> Objects.equals(n.getTargetObjectLabel(), ACTION1))
196-
.findFirst();
197-
assertThat(optAction1Node).isPresent();
198-
var action1Node = optAction1Node.get();
199-
var action1ActionsCompartment = this.getCompartment(action1Node, "actions");
200-
assertThat(action1ActionsCompartment)
201-
.as(ACTION1 + " should contain an actions compartment")
202-
.isPresent();
203-
assertThat(action1ActionsCompartment.get().getChildNodes())
204-
.as(ACTION1 + " actions compartment should contain 1 child")
205-
.hasSize(1)
206-
.as(ACTION1 + " actions compartment should contain " + ACTION2)
207-
.anyMatch(n -> Objects.equals(n.getTargetObjectLabel(), ACTION2));
208-
209-
var action1ActionFlowCompartment = this.getCompartment(action1Node, "action flow");
210-
assertThat(action1ActionFlowCompartment)
211-
.as(ACTION1 + " should contain an action flow compartment")
212-
.isPresent();
213-
assertThat(action1ActionFlowCompartment.get().getChildNodes())
214-
.as(ACTION1 + " action flow compartment should contain 2 children")
215-
.hasSize(1) // @technical-debt should be 2 when start node will be synchronized
216-
.as(ACTION1 + " action flow compartment should contain " + ACTION2)
217-
.anyMatch(n -> Objects.equals(n.getTargetObjectLabel(), ACTION2))
218-
;
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+
219191
// @technical-debt enable this part when start node will be synchronized
220192
// .as(ACTION1 + " action flow compartment should contain a start node")
221193
// .anyMatch(n -> n.getStyle() instanceof ImageNodeStyle imageStyle &&
222194
// Objects.equals(imageStyle.getImageURL(), "images/start_action.svg")
223195
// && Objects.equals("start", n.getTargetObjectLabel()));
224196

225-
var optAction2Node = action1ActionFlowCompartment.get().getChildNodes().stream()
226-
.filter(n -> Objects.equals(n.getTargetObjectLabel(), ACTION2))
227-
.findFirst();
228-
assertThat(optAction2Node).isPresent();
229-
var action2Node = optAction2Node.get();
230-
var action2ActionsCompartment = this.getCompartment(action2Node, "actions");
231-
assertThat(action2ActionsCompartment)
232-
.as(ACTION2 + " should contain an actions compartment")
233-
.isPresent();
234-
assertThat(action2ActionsCompartment.get().getChildNodes())
235-
.as(ACTION2 + " actions compartment should contain 1 child")
236-
.hasSize(1)
237-
.as(ACTION2 + " actions compartment should contain " + ACTION3)
238-
.anyMatch(n -> Objects.equals(n.getTargetObjectLabel(), ACTION3));
239-
240-
var action2ActionFlowCompartment = this.getCompartment(action2Node, "action flow");
241-
assertThat(action2ActionFlowCompartment)
242-
.as(ACTION2 + " should contain an action flow compartment")
243-
.isPresent();
244-
assertThat(action2ActionFlowCompartment.get().getChildNodes())
245-
.as(ACTION2 + " action flow compartment should contain 1 child")
246-
.hasSize(1)
247-
.as(ACTION2 + " action flow compartment should contain " + ACTION3)
248-
.anyMatch(n -> Objects.equals(n.getTargetObjectLabel(), ACTION3));
197+
this.checkAction2(newDiagram);
198+
199+
this.checkRequirementUsage(newDiagram);
249200

250201
}, () -> fail("Missing diagram"));
251202
this.verifier.consumeNextWith(updatedDiagramConsumer);
252203
}
253204

205+
private void checkPackageNode(Diagram newDiagram) {
206+
var optPackageNode = newDiagram.getNodes().stream()
207+
.filter(n -> Objects.equals(n.getTargetObjectLabel(), PACKAGE1))
208+
.findFirst();
209+
assertThat(optPackageNode).isPresent();
210+
assertThat(optPackageNode.get().getChildNodes())
211+
.as("Node " + PACKAGE1 + " should contain 1 child")
212+
.hasSize(1)
213+
.as("Node " + ATTRIBUTE_DEFINITION + " should exist inside " + PACKAGE1)
214+
.anyMatch(n -> Objects.equals(n.getTargetObjectLabel(), ATTRIBUTE_DEFINITION));
215+
}
216+
217+
private void checkAction2(Diagram newDiagram) {
218+
219+
var action1ActionFlowCompartment = this.checkAction1(newDiagram);
220+
var optAction2Node = action1ActionFlowCompartment.getChildNodes().stream()
221+
.filter(n -> Objects.equals(n.getTargetObjectLabel(), ACTION2))
222+
.findFirst();
223+
assertThat(optAction2Node).isPresent();
224+
var action2Node = optAction2Node.get();
225+
var action2ActionsCompartment = this.getCompartment(action2Node, "actions");
226+
assertThat(action2ActionsCompartment)
227+
.as(ACTION2 + " should contain an actions compartment")
228+
.isPresent();
229+
assertThat(action2ActionsCompartment.get().getChildNodes())
230+
.as(ACTION2 + " actions compartment should contain 1 child")
231+
.hasSize(1)
232+
.as(ACTION2 + " actions compartment should contain " + ACTION3)
233+
.anyMatch(n -> Objects.equals(n.getTargetObjectLabel(), ACTION3));
234+
235+
var action2ActionFlowCompartment = this.getCompartment(action2Node, "action flow");
236+
assertThat(action2ActionFlowCompartment)
237+
.as(ACTION2 + " should contain an action flow compartment")
238+
.isPresent();
239+
assertThat(action2ActionFlowCompartment.get().getChildNodes())
240+
.as(ACTION2 + " action flow compartment should contain 1 child")
241+
.hasSize(1)
242+
.as(ACTION2 + " action flow compartment should contain " + ACTION3)
243+
.anyMatch(n -> Objects.equals(n.getTargetObjectLabel(), ACTION3));
244+
}
245+
246+
private Node checkAction1(Diagram newDiagram) {
247+
var optAction1Node = newDiagram.getNodes().stream()
248+
.filter(n -> Objects.equals(n.getTargetObjectLabel(), ACTION1))
249+
.findFirst();
250+
assertThat(optAction1Node).isPresent();
251+
var action1Node = optAction1Node.get();
252+
var action1ActionsCompartment = this.getCompartment(action1Node, "actions");
253+
assertThat(action1ActionsCompartment)
254+
.as(ACTION1 + " should contain an actions compartment")
255+
.isPresent();
256+
assertThat(action1ActionsCompartment.get().getChildNodes())
257+
.as(ACTION1 + " actions compartment should contain 1 child")
258+
.hasSize(1)
259+
.as(ACTION1 + " actions compartment should contain " + ACTION2)
260+
.anyMatch(n -> Objects.equals(n.getTargetObjectLabel(), ACTION2));
261+
262+
var action1ActionFlowCompartment = this.getCompartment(action1Node, "action flow");
263+
assertThat(action1ActionFlowCompartment)
264+
.as(ACTION1 + " should contain an action flow compartment")
265+
.isPresent();
266+
assertThat(action1ActionFlowCompartment.get().getChildNodes())
267+
.as(ACTION1 + " action flow compartment should contain 2 children")
268+
.hasSize(1) // @technical-debt should be 2 when start node will be synchronized
269+
.as(ACTION1 + " action flow compartment should contain " + ACTION2)
270+
.anyMatch(n -> Objects.equals(n.getTargetObjectLabel(), ACTION2));
271+
return action1ActionFlowCompartment.get();
272+
}
273+
274+
private void checkRequirementUsage(Diagram newDiagram) {
275+
var optRequirementNode = newDiagram.getNodes().stream()
276+
.filter(n -> Objects.equals(n.getTargetObjectId(), GeneralViewAddExistingElementsTestProjectData.SemanticIds.SN_REQUIREMENT_ELEMENT_ID))
277+
.findFirst();
278+
279+
assertThat(optRequirementNode).isPresent();
280+
assertThat(optRequirementNode.get().getChildNodes())
281+
.as("Node RequirementUsage should contain 6 children")
282+
.hasSize(8);
283+
284+
var requirementDocCompartment = this.getCompartment(optRequirementNode.get(), "doc");
285+
assertThat(requirementDocCompartment).isPresent();
286+
assertThat(requirementDocCompartment.get())
287+
.as("The doc compartment should be visible")
288+
.matches(node -> !node.getModifiers().contains(ViewModifier.Hidden))
289+
.as("The doc compartment should contain a document item")
290+
.matches(node -> node.getChildNodes().size() == 1);
291+
}
292+
254293
private Optional<Node> getCompartment(Node node, String compartmentName) {
255294
return node.getChildNodes().stream()
256295
.filter(n -> Objects.equals(n.getInsideLabel().getText(), compartmentName))

backend/application/syson-application/src/test/java/org/eclipse/syson/application/controllers/diagrams/general/view/GVDropFromExplorerTests.java

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@
5757
import org.eclipse.syson.util.SysONRepresentationDescriptionIdentifiers;
5858
import org.junit.jupiter.api.AfterEach;
5959
import org.junit.jupiter.api.BeforeEach;
60+
import org.junit.jupiter.api.DisplayName;
6061
import org.junit.jupiter.api.Test;
6162
import org.springframework.beans.factory.annotation.Autowired;
6263
import org.springframework.boot.test.context.SpringBootTest;
@@ -194,6 +195,54 @@ public void dropFromExplorerOnEmptyDiagram() {
194195

195196
}
196197

198+
@Sql(scripts = { GeneralViewAddExistingElementsTestProjectData.SCRIPT_PATH }, executionPhase = Sql.ExecutionPhase.BEFORE_TEST_METHOD,
199+
config = @SqlConfig(transactionMode = SqlConfig.TransactionMode.ISOLATED))
200+
@Sql(scripts = { "/scripts/cleanup.sql" }, executionPhase = Sql.ExecutionPhase.AFTER_TEST_METHOD, config = @SqlConfig(transactionMode = SqlConfig.TransactionMode.ISOLATED))
201+
@Test
202+
@DisplayName("GIVEN an Element with no declared name but having a declared short name, WHEN drag and dropping this element on a diagram, THEN graphical node should be created")
203+
public void dropFromExplorerShortNameOnlyOnEmptyDiagram() {
204+
this.verifier.then(() -> {
205+
assertThat(this.diagram.get().getNodes()).hasSize(1);
206+
Node emptyDiagramNode = this.diagram.get().getNodes().get(0);
207+
String emptyDiagramNodeDescriptionId = this.diagramDescriptionIdProvider.getNodeDescriptionId(GeneralViewEmptyDiagramNodeDescriptionProvider.NAME);
208+
// Ensure the existing node is the "empty diagram" one.
209+
assertThat(emptyDiagramNode).hasDescriptionId(emptyDiagramNodeDescriptionId);
210+
this.dropFromExplorerTester.dropFromExplorerOnDiagram(GeneralViewAddExistingElementsTestProjectData.EDITING_CONTEXT_ID, this.diagram,
211+
GeneralViewAddExistingElementsTestProjectData.SemanticIds.SN_REQUIREMENT_ELEMENT_ID);
212+
});
213+
214+
Consumer<DiagramRefreshedEventPayload> updatedDiagramConsumer = payload -> Optional.of(payload)
215+
.map(DiagramRefreshedEventPayload::diagram)
216+
.ifPresentOrElse(newDiagram -> {
217+
new CheckDiagramElementCount(this.diagramComparator)
218+
.hasNewEdgeCount(0)
219+
// 1 node for the Requirement and 8 for its compartments and one for the documentation
220+
.hasNewNodeCount(10)
221+
.check(this.diagram.get(), newDiagram);
222+
new CheckNodeOnDiagram(this.diagramDescriptionIdProvider, this.diagramComparator)
223+
.hasNodeDescriptionName(this.descriptionNameGenerator.getNodeName(SysmlPackage.eINSTANCE.getRequirementUsage()))
224+
.hasTargetObjectLabel("RequirementUsage")
225+
.hasCompartmentCount(8)
226+
.check(this.diagram.get(), newDiagram);
227+
}, () -> fail("Missing diagram"));
228+
229+
this.verifier.consumeNextWith(updatedDiagramConsumer);
230+
231+
Runnable exposedElementsChecker = this.semanticRunnableFactory.createRunnable(GeneralViewAddExistingElementsTestProjectData.EDITING_CONTEXT_ID,
232+
(editingContext, executeEditingContextFunctionInput) -> {
233+
ViewUsage generalViewViewUsage = this.objectSearchService.getObject(editingContext, GeneralViewAddExistingElementsTestProjectData.SemanticIds.GENERAL_VIEW_VIEW_USAGE_ID)
234+
.filter(ViewUsage.class::isInstance)
235+
.map(ViewUsage.class::cast)
236+
.orElse(null);
237+
assertThat(generalViewViewUsage).isNotNull();
238+
assertThat(generalViewViewUsage.getExposedElement()).hasSize(1);
239+
return new ExecuteEditingContextFunctionSuccessPayload(executeEditingContextFunctionInput.id(), true);
240+
});
241+
242+
this.verifier.then(exposedElementsChecker);
243+
244+
}
245+
197246
@Sql(scripts = { GeneralViewAddExistingElementsTestProjectData.SCRIPT_PATH }, executionPhase = Sql.ExecutionPhase.BEFORE_TEST_METHOD,
198247
config = @SqlConfig(transactionMode = SqlConfig.TransactionMode.ISOLATED))
199248
@Sql(scripts = { "/scripts/cleanup.sql" }, executionPhase = Sql.ExecutionPhase.AFTER_TEST_METHOD, config = @SqlConfig(transactionMode = SqlConfig.TransactionMode.ISOLATED))

backend/application/syson-application/src/test/java/org/eclipse/syson/application/data/GeneralViewAddExistingElementsTestProjectData.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ public static final class SemanticIds {
4343

4444
public static final String PART_1_ELEMENT_ID = "67a57df8-2995-41ea-a838-dfb3a9a8ee7f";
4545

46+
public static final String SN_REQUIREMENT_ELEMENT_ID = "10a86ba3-aa07-4f0b-9aef-55ebc0e95347";
47+
4648
public static final String SUCCESSION_START_ACTION_2_IDS = "18d6f2fc-2182-4217-8da2-bf68c36ffa41";
4749
}
4850

0 commit comments

Comments
 (0)