Skip to content

Commit 4311241

Browse files
committed
[2111] Improve stakeholder creation tool using the latest selection dialog changes
Bug: #2111 Signed-off-by: Guillaume Coutable <guillaume.coutable@obeo.fr>
1 parent ec39d4c commit 4311241

7 files changed

Lines changed: 166 additions & 41 deletions

File tree

CHANGELOG.adoc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ As a result, the following GraphQL mutations have been removed `exposeRequiremen
3232

3333
=== Improvements
3434

35+
- https://github.com/eclipse-syson/syson/issues/2111[#2111] [diagrams] Leverage the latest change of the selection dialog to allow creating a `Stakeholder` graphical node without specialization.
3536

3637
=== New features
3738

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

Lines changed: 117 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
package org.eclipse.syson.application.controllers.diagrams.general.view;
1414

1515
import static org.assertj.core.api.Assertions.assertThat;
16+
import static org.assertj.core.api.InstanceOfAssertFactories.type;
1617
import static org.eclipse.sirius.components.diagrams.tests.DiagramEventPayloadConsumer.assertRefreshedDiagramThat;
1718
import static org.junit.jupiter.api.Assertions.assertEquals;
1819

@@ -56,12 +57,14 @@
5657
import org.eclipse.syson.standard.diagrams.view.SDVDescriptionNameGenerator;
5758
import org.eclipse.syson.sysml.Element;
5859
import org.eclipse.syson.sysml.PartUsage;
60+
import org.eclipse.syson.sysml.Specialization;
5961
import org.eclipse.syson.sysml.Subsetting;
6062
import org.eclipse.syson.sysml.SysmlPackage;
6163
import org.eclipse.syson.sysml.helper.EMFUtils;
6264
import org.eclipse.syson.util.IDescriptionNameGenerator;
6365
import org.eclipse.syson.util.SysONRepresentationDescriptionIdentifiers;
6466
import org.junit.jupiter.api.BeforeEach;
67+
import org.junit.jupiter.api.DisplayName;
6568
import org.junit.jupiter.api.Test;
6669
import org.junit.jupiter.params.ParameterizedTest;
6770
import org.junit.jupiter.params.provider.Arguments;
@@ -79,6 +82,7 @@
7982
* @author arichard
8083
*/
8184
@Transactional
85+
@SuppressWarnings("checkstyle:MultipleStringLiterals")
8286
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
8387
public class GVSubNodeRequirementCreationTests extends AbstractIntegrationTests {
8488

@@ -1050,28 +1054,60 @@ public void createRequirementDefinitionChildNodes(EClass childEClass, String com
10501054
.verify(Duration.ofSeconds(10));
10511055
}
10521056

1057+
@DisplayName("GIVEN a ConcernDefinition, WHEN creating a new Stakeholder selecting a Part, THEN the Stakeholder subsetted by the Part is created in the ConcernDefinition")
1058+
@GivenSysONServer({ GeneralViewWithTopNodesTestProjectData.SCRIPT_PATH })
1059+
@Test
1060+
public void createNewStakeholderFromPartInConcernDefinition() {
1061+
this.createNewStakeholderSelectingExistingElementIn(SysmlPackage.eINSTANCE.getConcernDefinition(), GeneralViewWithTopNodesTestProjectData.SemanticIds.CONCERN_DEFINITION_ID, "ConcernDefinition", GeneralViewWithTopNodesTestProjectData.SemanticIds.PART_USAGE_ID);
1062+
}
1063+
1064+
@DisplayName("GIVEN a Concern, WHEN creating a new Stakeholder selecting a Part, THEN the Stakeholder subsetted by the Part is created in the Concern")
1065+
@GivenSysONServer({ GeneralViewWithTopNodesTestProjectData.SCRIPT_PATH })
1066+
@Test
1067+
public void createNewStakeholderFromPartInConcernUsage() {
1068+
this.createNewStakeholderSelectingExistingElementIn(SysmlPackage.eINSTANCE.getConcernUsage(), GeneralViewWithTopNodesTestProjectData.SemanticIds.CONCERN_USAGE_ID, "concern", GeneralViewWithTopNodesTestProjectData.SemanticIds.PART_USAGE_ID);
1069+
}
1070+
1071+
@DisplayName("Given a RequirementDefinition, WHEN creating a new Stakeholder selecting a Part, THEN the Stakeholder subsetted by the Part is created in the RequirementDefinition")
1072+
@GivenSysONServer({ GeneralViewWithTopNodesTestProjectData.SCRIPT_PATH })
1073+
@Test
1074+
public void createNewStakeholderFromPartInRequirementDefinition() {
1075+
this.createNewStakeholderSelectingExistingElementIn(SysmlPackage.eINSTANCE.getRequirementDefinition(), GeneralViewWithTopNodesTestProjectData.SemanticIds.REQUIREMENT_DEFINITION_ID, "RequirementDefinition", GeneralViewWithTopNodesTestProjectData.SemanticIds.PART_USAGE_ID);
1076+
}
1077+
1078+
@DisplayName("Given a Requirement, WHEN creating a new Stakeholder selecting a Part, THEN the Stakeholder subsetted by the Part is created in the Requirement")
1079+
@GivenSysONServer({ GeneralViewWithTopNodesTestProjectData.SCRIPT_PATH })
1080+
@Test
1081+
public void createNewStakeholderFromPartInRequirementUsage() {
1082+
this.createNewStakeholderSelectingExistingElementIn(SysmlPackage.eINSTANCE.getRequirementUsage(), GeneralViewWithTopNodesTestProjectData.SemanticIds.REQUIREMENT_USAGE_ID, "requirement", GeneralViewWithTopNodesTestProjectData.SemanticIds.PART_USAGE_ID);
1083+
}
1084+
1085+
@DisplayName("GIVEN a ConcernDefinition, WHEN creating a new Stakeholder without selection, THEN the Stakeholder without subsetting is created in the ConcernDefinition")
10531086
@GivenSysONServer({ GeneralViewWithTopNodesTestProjectData.SCRIPT_PATH })
10541087
@Test
10551088
public void createNewStakeholderInConcernDefinition() {
1056-
this.createNewStakeholderIn(SysmlPackage.eINSTANCE.getConcernDefinition(), GeneralViewWithTopNodesTestProjectData.SemanticIds.CONCERN_DEFINITION_ID, "ConcernDefinition");
1089+
this.createNewStakeholderWithoutSelectionIn(SysmlPackage.eINSTANCE.getConcernDefinition(), GeneralViewWithTopNodesTestProjectData.SemanticIds.CONCERN_DEFINITION_ID, "ConcernDefinition");
10571090
}
10581091

1092+
@DisplayName("GIVEN a Concern, WHEN creating a new Stakeholder without selection, THEN the Stakeholder without subsetting is created in the Concern")
10591093
@GivenSysONServer({ GeneralViewWithTopNodesTestProjectData.SCRIPT_PATH })
10601094
@Test
10611095
public void createNewStakeholderInConcernUsage() {
1062-
this.createNewStakeholderIn(SysmlPackage.eINSTANCE.getConcernUsage(), GeneralViewWithTopNodesTestProjectData.SemanticIds.CONCERN_USAGE_ID, "concern");
1096+
this.createNewStakeholderWithoutSelectionIn(SysmlPackage.eINSTANCE.getConcernUsage(), GeneralViewWithTopNodesTestProjectData.SemanticIds.CONCERN_USAGE_ID, "concern");
10631097
}
10641098

1099+
@DisplayName("GIVEN a RequirementDefinition, WHEN creating a new Stakeholder without selection, THEN the Stakeholder without specialization is created in the RequirementDefinition")
10651100
@GivenSysONServer({ GeneralViewWithTopNodesTestProjectData.SCRIPT_PATH })
10661101
@Test
10671102
public void createNewStakeholderInRequirementDefinition() {
1068-
this.createNewStakeholderIn(SysmlPackage.eINSTANCE.getRequirementDefinition(), GeneralViewWithTopNodesTestProjectData.SemanticIds.REQUIREMENT_DEFINITION_ID, "RequirementDefinition");
1103+
this.createNewStakeholderWithoutSelectionIn(SysmlPackage.eINSTANCE.getRequirementDefinition(), GeneralViewWithTopNodesTestProjectData.SemanticIds.REQUIREMENT_DEFINITION_ID, "RequirementDefinition");
10691104
}
10701105

1106+
@DisplayName("GIVEN a Requirement, WHEN creating a new Stakeholder without selection, THEN the Stakeholder without specialization is created in the Requirement")
10711107
@GivenSysONServer({ GeneralViewWithTopNodesTestProjectData.SCRIPT_PATH })
10721108
@Test
10731109
public void createNewStakeholderInRequirementUsage() {
1074-
this.createNewStakeholderIn(SysmlPackage.eINSTANCE.getRequirementUsage(), GeneralViewWithTopNodesTestProjectData.SemanticIds.REQUIREMENT_USAGE_ID, "requirement");
1110+
this.createNewStakeholderWithoutSelectionIn(SysmlPackage.eINSTANCE.getRequirementUsage(), GeneralViewWithTopNodesTestProjectData.SemanticIds.REQUIREMENT_USAGE_ID, "requirement");
10751111
}
10761112

10771113
@GivenSysONServer({ GeneralViewWithTopNodesTestProjectData.SCRIPT_PATH })
@@ -1086,7 +1122,7 @@ public void createNewActorInRequirementDefinition() {
10861122
this.createNewActorIn(SysmlPackage.eINSTANCE.getRequirementDefinition(), GeneralViewWithTopNodesTestProjectData.SemanticIds.REQUIREMENT_DEFINITION_ID, "RequirementDefinition");
10871123
}
10881124

1089-
private void createNewStakeholderIn(EClass eClassWithStakeholderParameter, String targetObjectId, String parentNodeLabel) {
1125+
private void createNewStakeholderSelectingExistingElementIn(EClass eClassWithStakeholderParameter, String targetObjectId, String parentNodeLabel, String existingElementId) {
10901126
var flux = this.givenSubscriptionToDiagram();
10911127

10921128
AtomicReference<Diagram> diagram = new AtomicReference<>();
@@ -1101,8 +1137,7 @@ private void createNewStakeholderIn(EClass eClassWithStakeholderParameter, Strin
11011137
.orElseGet(() -> Assertions.fail("No fitting EReference could be found in '%s'.".formatted(eClassWithStakeholderParameter.getName())));
11021138

11031139
final String stakeholderCreationToolName = "New Stakeholder";
1104-
Runnable createNodeRunnable = this.creationTestsService.createNode(diagramDescriptionIdProvider, diagram, eClassWithStakeholderParameter, targetObjectId, stakeholderCreationToolName,
1105-
Stream.of(new ToolVariable("selectedObject", /* PartUsage 'part' */ "2c5fe5a5-18fe-40f4-ab66-a2d91ab7df6a", ToolVariableType.OBJECT_ID)).toList());
1140+
Runnable createNodeRunnable = this.creationTestsService.createNodeWithSelectionDialogWithSingleSelection(diagramDescriptionIdProvider, diagram, eClassWithStakeholderParameter, targetObjectId, stakeholderCreationToolName, existingElementId);
11061141

11071142
Consumer<Object> diagramCheck = assertRefreshedDiagramThat(newDiagram -> {
11081143
var initialDiagram = diagram.get();
@@ -1117,29 +1152,89 @@ private void createNewStakeholderIn(EClass eClassWithStakeholderParameter, Strin
11171152
.check(initialDiagram, newDiagram);
11181153
});
11191154

1120-
final ISemanticChecker semanticChecker = (editingContext) -> {
1121-
final Element semanticRootElement = this.objectSearchService.getObject(editingContext, GeneralViewWithTopNodesTestProjectData.SemanticIds.PACKAGE_1_ID).filter(Element.class::isInstance)
1122-
.map(Element.class::cast).orElseGet(() -> Assertions.fail("Could not find the expected root semantic object."));
1123-
final List<PartUsage> allStakeholderPartUsages = EMFUtils.allContainedObjectOfType(semanticRootElement, PartUsage.class)
1124-
.filter(element -> Objects.equals(element.getName(), "stakeholder1")).toList();
1125-
assertEquals(1, allStakeholderPartUsages.size());
1155+
Consumer<Object> additionalCheck = referencedObject -> {
1156+
assertThat(referencedObject).isInstanceOf(List.class)
1157+
.asInstanceOf(type(List.class))
1158+
.satisfies(stakeHolders -> {
1159+
assertThat(stakeHolders).size().isEqualTo(1);
1160+
assertThat(stakeHolders.getFirst())
1161+
.isInstanceOf(PartUsage.class)
1162+
.asInstanceOf(type(PartUsage.class))
1163+
.satisfies(stakeholderPartUsage -> {
1164+
final EList<Subsetting> subsettings = stakeholderPartUsage.getOwnedSubsetting();
1165+
assertEquals(1, subsettings.size());
1166+
assertThat(subsettings.get(0).getSubsettedFeature().getName()).isEqualTo("part");
1167+
});
1168+
});
1169+
};
11261170

1127-
final PartUsage stakeholderPartUsage = allStakeholderPartUsages.get(0);
1128-
final EList<Subsetting> subsettings = stakeholderPartUsage.getOwnedSubsetting();
1129-
assertEquals(1, subsettings.size());
1130-
assertThat(subsettings.get(0).getSubsettedFeature().getName()).isEqualTo("part");
1171+
Runnable semanticCheck = this.semanticCheckerService.checkEditingContext(
1172+
this.semanticCheckerService.getElementInParentSemanticChecker(parentNodeLabel, stakeholderParameterEReference, SysmlPackage.eINSTANCE.getPartUsage(), additionalCheck));
1173+
1174+
StepVerifier.create(flux)
1175+
.consumeNextWith(initialDiagramContentConsumer)
1176+
.then(createNodeRunnable)
1177+
.consumeNextWith(diagramCheck)
1178+
.then(semanticCheck)
1179+
.thenCancel()
1180+
.verify(Duration.ofSeconds(10));
1181+
}
1182+
1183+
private void createNewStakeholderWithoutSelectionIn(EClass eClassWithStakeholderParameter, String targetObjectId, String parentNodeLabel) {
1184+
var flux = this.givenSubscriptionToDiagram();
1185+
1186+
AtomicReference<Diagram> diagram = new AtomicReference<>();
1187+
Consumer<Object> initialDiagramContentConsumer = assertRefreshedDiagramThat(diagram::set);
1188+
1189+
var diagramDescription = this.givenDiagramDescription.getDiagramDescription(GeneralViewWithTopNodesTestProjectData.EDITING_CONTEXT_ID,
1190+
SysONRepresentationDescriptionIdentifiers.GENERAL_VIEW_DIAGRAM_DESCRIPTION_ID);
1191+
var diagramDescriptionIdProvider = new DiagramDescriptionIdProvider(diagramDescription, this.diagramIdProvider);
1192+
1193+
final EReference stakeholderParameterEReference = eClassWithStakeholderParameter.getEAllReferences().stream()
1194+
.filter(eReference -> eReference.getName().equals("stakeholderParameter") && eReference.getEType() == SysmlPackage.eINSTANCE.getPartUsage()).findFirst()
1195+
.orElseGet(() -> Assertions.fail("No fitting EReference could be found in '%s'.".formatted(eClassWithStakeholderParameter.getName())));
1196+
1197+
final String stakeholderCreationToolName = "New Stakeholder";
1198+
Runnable createNodeRunnable = this.creationTestsService.createNodeWithSelectionDialogWithoutSelectionProvided(diagramDescriptionIdProvider, diagram, eClassWithStakeholderParameter, targetObjectId, stakeholderCreationToolName);
1199+
1200+
Consumer<Object> diagramCheck = assertRefreshedDiagramThat(newDiagram -> {
1201+
var initialDiagram = diagram.get();
1202+
new CheckDiagramElementCount(this.diagramComparator)
1203+
.hasNewNodeCount(1)
1204+
.check(initialDiagram, newDiagram);
1205+
new CheckNodeInCompartment(diagramDescriptionIdProvider, this.diagramComparator)
1206+
.withTargetObjectId(targetObjectId)
1207+
.withCompartmentName("stakeholders")
1208+
.hasNodeDescriptionName(this.descriptionNameGenerator.getCompartmentItemName(eClassWithStakeholderParameter, stakeholderParameterEReference))
1209+
.hasCompartmentCount(0)
1210+
.check(initialDiagram, newDiagram);
1211+
});
1212+
1213+
Consumer<Object> additionalCheck = referencedObject -> {
1214+
assertThat(referencedObject).isInstanceOf(List.class)
1215+
.asInstanceOf(type(List.class))
1216+
.satisfies(stakeHolders -> {
1217+
assertThat(stakeHolders).size().isEqualTo(1);
1218+
assertThat(stakeHolders.getFirst())
1219+
.isInstanceOf(PartUsage.class)
1220+
.asInstanceOf(type(PartUsage.class))
1221+
.satisfies(stakeholderPartUsage -> {
1222+
assertThat(stakeholderPartUsage.getOwnedSpecialization()).allMatch(Specialization::isIsImplied);
1223+
assertThat(stakeholderPartUsage.getType())
1224+
.isNotEmpty()
1225+
.allMatch(Element::isIsLibraryElement);
1226+
});
1227+
});
11311228
};
11321229

1133-
Runnable semanticCheck1 = this.semanticCheckerService.checkEditingContext(
1134-
this.semanticCheckerService.getElementInParentSemanticChecker(parentNodeLabel, stakeholderParameterEReference, SysmlPackage.eINSTANCE.getPartUsage()));
1135-
Runnable semanticCheck2 = this.semanticCheckerService.checkEditingContext(semanticChecker);
1230+
Runnable semanticCheck = this.semanticCheckerService.checkEditingContext(
1231+
this.semanticCheckerService.getElementInParentSemanticChecker(parentNodeLabel, stakeholderParameterEReference, SysmlPackage.eINSTANCE.getPartUsage(), additionalCheck));
11361232

11371233
StepVerifier.create(flux)
11381234
.consumeNextWith(initialDiagramContentConsumer)
11391235
.then(createNodeRunnable)
11401236
.consumeNextWith(diagramCheck)
1141-
.then(semanticCheck1)
1142-
.then(semanticCheck2)
1237+
.then(semanticCheck)
11431238
.thenCancel()
11441239
.verify(Duration.ofSeconds(10));
11451240
}

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ public void createTimesliceNodeOn(EClass parentEClass, String parentTargetObject
150150
var diagramDescriptionIdProvider = new DiagramDescriptionIdProvider(diagramDescription, this.diagramIdProvider);
151151

152152

153-
Runnable createNodeRunnable = creationTestsService.createNodeWithSelectionDialog(diagramDescriptionIdProvider, diagram, parentEClass, parentTargetObjectId, "New Timeslice", selectedObject);
153+
Runnable createNodeRunnable = creationTestsService.createNodeWithSelectionDialogWithSingleSelection(diagramDescriptionIdProvider, diagram, parentEClass, parentTargetObjectId, "New Timeslice", selectedObject);
154154
// The created child EClass depends on the behavior of the selection dialog, here without selection
155155
Consumer<Object> diagramChecker = diagramCheckerService.siblingNodeGraphicalChecker(diagram, diagramDescriptionIdProvider, childEClass, newCompartmentCount, newNodeCount);
156156
Consumer<Object> additionalSemanticCheck = object -> {
@@ -194,7 +194,7 @@ public void createSnapshotNodeOn(EClass parentEClass, String parentTargetObjectI
194194
SysONRepresentationDescriptionIdentifiers.GENERAL_VIEW_DIAGRAM_DESCRIPTION_ID);
195195
var diagramDescriptionIdProvider = new DiagramDescriptionIdProvider(diagramDescription, this.diagramIdProvider);
196196

197-
Runnable createNodeRunnable = creationTestsService.createNodeWithSelectionDialog(diagramDescriptionIdProvider, diagram, parentEClass, parentTargetObjectId, "New Snapshot", selectedObject);
197+
Runnable createNodeRunnable = creationTestsService.createNodeWithSelectionDialogWithSingleSelection(diagramDescriptionIdProvider, diagram, parentEClass, parentTargetObjectId, "New Snapshot", selectedObject);
198198
// The created child EClass depends on the behavior of the selection dialog, here without selection
199199
Consumer<Object> diagramChecker = diagramCheckerService.siblingNodeGraphicalChecker(diagram, diagramDescriptionIdProvider, childEClass, newCompartmentCount, newNodeCount);
200200
Consumer<Object> additionalSemanticCheck = object -> {

0 commit comments

Comments
 (0)