2020
2121import java .time .Duration ;
2222import java .util .List ;
23+ import java .util .Map ;
2324import java .util .Objects ;
2425import java .util .Optional ;
2526import java .util .UUID ;
2829
2930import org .eclipse .sirius .components .collaborative .diagrams .dto .DiagramEventInput ;
3031import org .eclipse .sirius .components .collaborative .diagrams .dto .DiagramRefreshedEventPayload ;
32+ import org .eclipse .sirius .components .collaborative .diagrams .dto .InvokeSingleClickOnDiagramElementToolInput ;
33+ import org .eclipse .sirius .components .collaborative .diagrams .dto .InvokeSingleClickOnDiagramElementToolSuccessPayload ;
3134import org .eclipse .sirius .components .collaborative .dto .CreateChildInput ;
3235import org .eclipse .sirius .components .collaborative .dto .CreateChildSuccessPayload ;
3336import org .eclipse .sirius .components .core .api .IEditingContext ;
37+ import org .eclipse .sirius .components .core .api .IFeedbackMessageService ;
3438import org .eclipse .sirius .components .core .api .IIdentityService ;
3539import org .eclipse .sirius .components .core .api .IObjectSearchService ;
3640import org .eclipse .sirius .components .diagrams .Diagram ;
3741import org .eclipse .sirius .components .diagrams .Node ;
42+ import org .eclipse .sirius .components .diagrams .ViewModifier ;
43+ import org .eclipse .sirius .components .diagrams .tests .graphql .InvokeSingleClickOnDiagramElementToolMutationRunner ;
44+ import org .eclipse .sirius .components .diagrams .tests .graphql .PaletteQueryRunner ;
45+ import org .eclipse .sirius .components .diagrams .tests .navigation .DiagramNavigator ;
3846import org .eclipse .sirius .components .graphql .tests .ExecuteEditingContextFunctionSuccessPayload ;
3947import org .eclipse .sirius .components .representations .MessageLevel ;
4048import org .eclipse .sirius .components .view .emf .diagram .IDiagramIdProvider ;
4149import org .eclipse .sirius .web .tests .graphql .CreateChildMutationRunner ;
4250import org .eclipse .sirius .web .tests .services .api .IGivenInitialServerState ;
4351import org .eclipse .syson .AbstractIntegrationTests ;
4452import org .eclipse .syson .GivenSysONServer ;
45- import org .eclipse .syson .SysONTestsProperties ;
4653import org .eclipse .syson .application .controllers .diagrams .checkers .CheckDiagramElementCount ;
4754import org .eclipse .syson .application .controllers .diagrams .checkers .CheckNodeOnDiagram ;
4855import org .eclipse .syson .application .controllers .diagrams .testers .DropFromExplorerTester ;
7986 * @author gdaniel
8087 */
8188@ Transactional
82- @ SpringBootTest (webEnvironment = SpringBootTest .WebEnvironment .RANDOM_PORT , properties = { SysONTestsProperties . NO_DEFAULT_LIBRARIES_PROPERTY } )
89+ @ SpringBootTest (webEnvironment = SpringBootTest .WebEnvironment .RANDOM_PORT )
8390public class GVDropFromExplorerTests extends AbstractIntegrationTests {
8491
8592 @ Autowired
@@ -112,8 +119,18 @@ public class GVDropFromExplorerTests extends AbstractIntegrationTests {
112119 @ Autowired
113120 private CreateChildMutationRunner createChildMutationRunner ;
114121
122+ @ Autowired
123+ private PaletteQueryRunner paletteQueryRunner ;
124+
125+ @ Autowired
126+ private InvokeSingleClickOnDiagramElementToolMutationRunner invokeSingleClickOnDiagramElementToolMutationRunner ;
127+
128+ @ Autowired
129+ private IFeedbackMessageService feedbackMessageService ;
130+
115131 private final IDescriptionNameGenerator descriptionNameGenerator = new SDVDescriptionNameGenerator ();
116132
133+
117134 private Flux <DiagramRefreshedEventPayload > givenSubscriptionToDiagram () {
118135 var diagramEventInput = new DiagramEventInput (UUID .randomUUID (),
119136 GeneralViewAddExistingElementsTestProjectData .EDITING_CONTEXT_ID ,
@@ -198,9 +215,9 @@ public void dropFromExplorerOnEmptyDiagram() {
198215 .verify (Duration .ofSeconds (10 ));
199216 }
200217
218+ @ 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" )
201219 @ GivenSysONServer ({ GeneralViewAddExistingElementsTestProjectData .SCRIPT_PATH })
202220 @ Test
203- @ 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" )
204221 public void dropFromExplorerShortNameOnlyOnEmptyDiagram () {
205222 var flux = this .givenSubscriptionToDiagram ();
206223
@@ -358,7 +375,7 @@ public void dropFromExplorerTwiceShouldNotExposeElementTwice() {
358375 List <Object > messages = JsonPath .read (result .data (), "$.data.dropOnDiagram.messages[*]" );
359376 assertThat (messages ).as ("We should receive at least one message when dropping an already visible element" ).hasSizeGreaterThanOrEqualTo (1 );
360377 String messageBody = JsonPath .read (result .data (), "$.data.dropOnDiagram.messages[0].body" );
361- assertThat (messageBody ).isEqualTo ("The element part1 is already visible in its parent General View " );
378+ assertThat (messageBody ).isEqualTo ("The element part1 is already visible in its parent Package 1 " );
362379 String messageLevel = JsonPath .read (result .data (), "$.data.dropOnDiagram.messages[0].level" );
363380 assertThat (messageLevel ).isEqualTo (MessageLevel .WARNING .toString ());
364381 };
@@ -376,6 +393,128 @@ public void dropFromExplorerTwiceShouldNotExposeElementTwice() {
376393 .verify (Duration .ofSeconds (10 ));
377394 }
378395
396+ @ DisplayName ("GIVEN a diagram WHEN dropping a semantic element from the explorer on various targets THEN the user gets the appropriate feedback message" )
397+ @ GivenSysONServer ({ GeneralViewAddExistingElementsTestProjectData .SCRIPT_PATH })
398+ @ Test
399+ public void dropFromExplorerFeedback () {
400+ AtomicReference <Diagram > diagram = new AtomicReference <>();
401+ AtomicReference <String > packageNodeId = new AtomicReference <>();
402+ AtomicReference <String > attributeNodeId = new AtomicReference <>();
403+ AtomicReference <String > hideToolId = new AtomicReference <>();
404+
405+ String package1Id = GeneralViewAddExistingElementsTestProjectData .SemanticIds .PACKAGE1_ID ;
406+ String attributeDefinition1Id = GeneralViewAddExistingElementsTestProjectData .SemanticIds .ATTRIBUTE_DEFINITION_1_ID ;
407+
408+ var flux = this .givenSubscriptionToDiagram ();
409+
410+ Consumer <Object > initialDiagramContentConsumer = assertRefreshedDiagramThat (diagram ::set );
411+
412+ Runnable dropPackageOnDiagramBackground = () -> this .dropFromExplorer (diagram , null , package1Id , Optional .empty ());
413+
414+ Consumer <Object > diagramWithPackageNodeConsumer = assertRefreshedDiagramThat (newDiagram -> {
415+ new CheckDiagramElementCount (this .diagramComparator ).hasNewNodeCount (1 ).check (diagram .get (), newDiagram );
416+ var packageNode = new DiagramNavigator (newDiagram ).nodeWithTargetObjectId (package1Id ).getNode ();
417+ assertThat (packageNode ).isNotNull ();
418+ packageNodeId .set (packageNode .getId ());
419+ diagram .set (newDiagram );
420+ });
421+
422+ Runnable dropAttributeOnPackage = () -> this .dropFromExplorer (diagram , packageNodeId .get (), attributeDefinition1Id , Optional .empty ());
423+
424+ Consumer <Object > diagramWithAttributeNodeConsumer = assertRefreshedDiagramThat (newDiagram -> {
425+ // 3 new nodes: AttributeDefinition container and its 2 compartments
426+ new CheckDiagramElementCount (this .diagramComparator ).hasNewNodeCount (3 ).check (diagram .get (), newDiagram );
427+ var attributeNode = new DiagramNavigator (newDiagram ).nodeWithTargetObjectId (attributeDefinition1Id ).getNode ();
428+ assertThat (attributeNode ).isNotNull ().extracting (Node ::getState ).isEqualTo (ViewModifier .Normal );
429+ attributeNodeId .set (attributeNode .getId ());
430+ diagram .set (newDiagram );
431+ });
432+
433+ Runnable getHideTool = () -> hideToolId .set (this .getQuickToolIdByLabel (diagram .get ().getId (), attributeNodeId .get (), "Hide" ));
434+
435+ Runnable dropAttributeOnDiagram = () -> this .dropFromExplorer (diagram ,
436+ null , attributeDefinition1Id ,
437+ Optional .of ("The element AttributeDefinition1 is already visible in its parent Package1" ));
438+
439+ Consumer <Object > diagramNotChangeConsumer = assertRefreshedDiagramThat (newDiagram -> {
440+ new CheckDiagramElementCount (this .diagramComparator ).check (diagram .get (), newDiagram );
441+ diagram .set (newDiagram );
442+ });
443+
444+ Runnable hideAttributeNode = () -> {
445+ var input = new InvokeSingleClickOnDiagramElementToolInput (UUID .randomUUID (), GeneralViewAddExistingElementsTestProjectData .EDITING_CONTEXT_ID , diagram .get ().getId (),
446+ List .of (attributeNodeId .get ()), hideToolId .get (), 0 , 0 , List .of ());
447+ var result = this .invokeSingleClickOnDiagramElementToolMutationRunner .run (input );
448+ String typename = JsonPath .read (result .data (), "$.data.invokeSingleClickOnDiagramElementTool.__typename" );
449+ assertThat (typename ).isEqualTo (InvokeSingleClickOnDiagramElementToolSuccessPayload .class .getSimpleName ());
450+ };
451+
452+ Consumer <Object > atributeNodeHiddenConsumer = assertRefreshedDiagramThat (newDiagram -> {
453+ new CheckDiagramElementCount (this .diagramComparator ).check (diagram .get (), newDiagram );
454+ var attributeNode = new DiagramNavigator (newDiagram ).nodeWithTargetObjectId (attributeDefinition1Id ).getNode ();
455+ assertThat (attributeNode ).isNotNull ().extracting (Node ::getState ).isEqualTo (ViewModifier .Hidden );
456+ diagram .set (newDiagram );
457+ });
458+
459+ Runnable dropAttributeOnDiagramNoMessage = () -> this .dropFromExplorer (diagram , null , attributeDefinition1Id , Optional .empty ());
460+
461+ Runnable dropAttributeOnPackageAgain = () -> this .dropFromExplorer (diagram , packageNodeId .get (), attributeDefinition1Id , Optional .empty ());
462+
463+ Consumer <Object > diagramWithAttributeNodeRevealedConsumer = assertRefreshedDiagramThat (newDiagram -> {
464+ new CheckDiagramElementCount (this .diagramComparator ).check (diagram .get (), newDiagram );
465+ var attributeNode = new DiagramNavigator (newDiagram ).nodeWithTargetObjectId (GeneralViewAddExistingElementsTestProjectData .SemanticIds .ATTRIBUTE_DEFINITION_1_ID ).getNode ();
466+ assertThat (attributeNode ).isNotNull ().extracting (Node ::getState ).isEqualTo (ViewModifier .Normal );
467+ });
468+
469+ StepVerifier .create (flux )
470+ .consumeNextWith (initialDiagramContentConsumer )
471+ .then (dropPackageOnDiagramBackground )
472+ .consumeNextWith (diagramWithPackageNodeConsumer )
473+ .then (dropAttributeOnPackage )
474+ .consumeNextWith (diagramWithAttributeNodeConsumer )
475+ .then (getHideTool )
476+ .then (dropAttributeOnDiagram )
477+ .consumeNextWith (diagramNotChangeConsumer )
478+ .then (hideAttributeNode )
479+ .consumeNextWith (atributeNodeHiddenConsumer )
480+ .then (dropAttributeOnDiagramNoMessage )
481+ .consumeNextWith (diagramNotChangeConsumer )
482+ .then (dropAttributeOnPackageAgain )
483+ .consumeNextWith (diagramWithAttributeNodeRevealedConsumer )
484+ .thenCancel ()
485+ .verify (Duration .ofSeconds (10 ));
486+ }
487+
488+ private void dropFromExplorer (AtomicReference <Diagram > diagram , String targetId , String elementId , Optional <String > expectedWarning ) {
489+ // Workaround: clear the messages left by the previous tool's execution
490+ this .feedbackMessageService .getFeedbackMessages ().clear ();
491+ var result = this .dropFromExplorerTester .dropFromExplorer (GeneralViewAddExistingElementsTestProjectData .EDITING_CONTEXT_ID , diagram ,
492+ targetId , elementId );
493+ List <Object > messages = JsonPath .read (result .data (), "$.data.dropOnDiagram.messages[*]" );
494+ if (expectedWarning .isPresent ()) {
495+ assertThat (messages ).hasSize (1 );
496+ String messageBody = JsonPath .read (result .data (), "$.data.dropOnDiagram.messages[0].body" );
497+ assertThat (messageBody ).isEqualTo (expectedWarning .get ());
498+ String messageLevel = JsonPath .read (result .data (), "$.data.dropOnDiagram.messages[0].level" );
499+ assertThat (messageLevel ).isEqualTo (MessageLevel .WARNING .toString ());
500+ } else {
501+ assertThat (messages ).isEmpty ();
502+ }
503+ }
504+
505+ private String getQuickToolIdByLabel (String diagramId , String nodeId , String toolName ) {
506+ Map <String , Object > variables = Map .of (
507+ "editingContextId" , GeneralViewAddExistingElementsTestProjectData .EDITING_CONTEXT_ID ,
508+ "representationId" , diagramId ,
509+ "diagramElementIds" , List .of (nodeId ));
510+ var result = this .paletteQueryRunner .run (variables );
511+ List <String > labels = JsonPath .read (result .data (), "$.data.viewer.editingContext.representation.description.palette.quickAccessTools[*].label" );
512+ assertThat (labels ).contains (toolName );
513+ int toolIndex = labels .indexOf (toolName );
514+ List <String > ids = JsonPath .read (result .data (), "$.data.viewer.editingContext.representation.description.palette.quickAccessTools[*].id" );
515+ return ids .get (toolIndex );
516+ }
517+
379518 @ GivenSysONServer ({ GeneralViewEmptyTestProjectData .SCRIPT_PATH })
380519 @ Test
381520 public void dropLibraryPackageFromExplorerOnDiagram () {
0 commit comments