|
17 | 17 | import static org.eclipse.sirius.components.diagrams.tests.assertions.DiagramAssertions.assertThat; |
18 | 18 | import static org.eclipse.sirius.components.diagrams.tests.assertions.DiagramInstanceOfAssertFactories.EDGE_STYLE; |
19 | 19 |
|
| 20 | +import com.jayway.jsonpath.JsonPath; |
| 21 | + |
20 | 22 | import java.time.Duration; |
| 23 | +import java.util.List; |
| 24 | +import java.util.Map; |
21 | 25 | import java.util.UUID; |
22 | 26 | import java.util.concurrent.atomic.AtomicReference; |
23 | 27 | import java.util.function.Consumer; |
24 | 28 |
|
25 | 29 | import org.eclipse.sirius.components.collaborative.diagrams.dto.DiagramEventInput; |
26 | 30 | import org.eclipse.sirius.components.collaborative.diagrams.dto.DiagramRefreshedEventPayload; |
| 31 | +import org.eclipse.sirius.components.collaborative.diagrams.dto.EditLabelInput; |
| 32 | +import org.eclipse.sirius.components.collaborative.diagrams.dto.EditLabelSuccessPayload; |
| 33 | +import org.eclipse.sirius.components.collaborative.diagrams.dto.InvokeSingleClickOnDiagramElementToolInput; |
| 34 | +import org.eclipse.sirius.components.collaborative.diagrams.dto.InvokeSingleClickOnDiagramElementToolSuccessPayload; |
| 35 | +import org.eclipse.sirius.components.collaborative.diagrams.dto.ToolVariable; |
| 36 | +import org.eclipse.sirius.components.collaborative.diagrams.dto.ToolVariableType; |
| 37 | +import org.eclipse.sirius.components.core.api.IEditingContext; |
27 | 38 | import org.eclipse.sirius.components.core.api.IIdentityService; |
28 | 39 | import org.eclipse.sirius.components.core.api.IObjectSearchService; |
29 | 40 | import org.eclipse.sirius.components.diagrams.ArrowStyle; |
30 | 41 | import org.eclipse.sirius.components.diagrams.Diagram; |
31 | 42 | import org.eclipse.sirius.components.diagrams.Edge; |
32 | 43 | import org.eclipse.sirius.components.diagrams.events.ReconnectEdgeKind; |
33 | 44 | import org.eclipse.sirius.components.diagrams.tests.assertions.DiagramAssertions; |
| 45 | +import org.eclipse.sirius.components.diagrams.tests.graphql.EditLabelMutationRunner; |
| 46 | +import org.eclipse.sirius.components.diagrams.tests.graphql.InvokeSingleClickOnDiagramElementToolMutationRunner; |
| 47 | +import org.eclipse.sirius.components.diagrams.tests.graphql.PaletteQueryRunner; |
| 48 | +import org.eclipse.sirius.components.diagrams.tests.navigation.DiagramNavigator; |
| 49 | +import org.eclipse.sirius.components.graphql.tests.ExecuteEditingContextFunctionSuccessPayload; |
34 | 50 | import org.eclipse.sirius.components.view.emf.diagram.IDiagramIdProvider; |
35 | 51 | import org.eclipse.sirius.web.tests.services.api.IGivenInitialServerState; |
36 | 52 | import org.eclipse.syson.AbstractIntegrationTests; |
|
40 | 56 | import org.eclipse.syson.application.controllers.diagrams.testers.EdgeCreationTester; |
41 | 57 | import org.eclipse.syson.application.controllers.diagrams.testers.EdgeReconnectionTester; |
42 | 58 | import org.eclipse.syson.application.data.GeneralViewFlowConnectionItemUsagesProjectData; |
| 59 | +import org.eclipse.syson.application.data.GeneralViewFlowUsageProjectData; |
43 | 60 | import org.eclipse.syson.services.SemanticRunnableFactory; |
44 | 61 | import org.eclipse.syson.services.diagrams.DiagramComparator; |
45 | 62 | import org.eclipse.syson.services.diagrams.DiagramDescriptionIdProvider; |
46 | 63 | import org.eclipse.syson.services.diagrams.api.IGivenDiagramDescription; |
47 | 64 | import org.eclipse.syson.services.diagrams.api.IGivenDiagramSubscription; |
48 | 65 | import org.eclipse.syson.standard.diagrams.view.SDVDescriptionNameGenerator; |
| 66 | +import org.eclipse.syson.sysml.ConnectionUsage; |
| 67 | +import org.eclipse.syson.sysml.FeatureTyping; |
| 68 | +import org.eclipse.syson.sysml.FlowEnd; |
49 | 69 | import org.eclipse.syson.sysml.FlowUsage; |
| 70 | +import org.eclipse.syson.sysml.PayloadFeature; |
50 | 71 | import org.eclipse.syson.sysml.SysmlPackage; |
51 | 72 | import org.eclipse.syson.util.IDescriptionNameGenerator; |
52 | 73 | import org.eclipse.syson.util.SysONRepresentationDescriptionIdentifiers; |
@@ -86,6 +107,15 @@ public class GVFlowUsageTests extends AbstractIntegrationTests { |
86 | 107 | @Autowired |
87 | 108 | private EdgeCreationTester edgeCreationTester; |
88 | 109 |
|
| 110 | + @Autowired |
| 111 | + private EditLabelMutationRunner editLabelMutationRunner; |
| 112 | + |
| 113 | + @Autowired |
| 114 | + private InvokeSingleClickOnDiagramElementToolMutationRunner invokeSingleClickOnDiagramElementToolMutationRunner; |
| 115 | + |
| 116 | + @Autowired |
| 117 | + private PaletteQueryRunner paletteQueryRunner; |
| 118 | + |
89 | 119 | @Autowired |
90 | 120 | private DiagramComparator diagramComparator; |
91 | 121 |
|
@@ -297,4 +327,163 @@ public void reconnectFlowUsageSource() { |
297 | 327 | .verify(Duration.ofSeconds(10)); |
298 | 328 | } |
299 | 329 |
|
| 330 | + @Test |
| 331 | + @DisplayName("GIVEN a connection WHEN we create a flow usage in it THEN the flow is correctly setup") |
| 332 | + @GivenSysONServer({ GeneralViewFlowUsageProjectData.SCRIPT_PATH }) |
| 333 | + public void createFlowUsageInConnection() { |
| 334 | + var diagramEventInput = new DiagramEventInput(UUID.randomUUID(), |
| 335 | + GeneralViewFlowUsageProjectData.EDITING_CONTEXT_ID, |
| 336 | + GeneralViewFlowUsageProjectData.GraphicalIds.DIAGRAM_ID); |
| 337 | + |
| 338 | + var flux = this.givenDiagramSubscription.subscribe(diagramEventInput); |
| 339 | + |
| 340 | + var diagramId = new AtomicReference<String>(); |
| 341 | + var connectionEdgeId = new AtomicReference<String>(); |
| 342 | + var connectionEdgeLabelId = new AtomicReference<String>(); |
| 343 | + |
| 344 | + var diagramDescription = this.givenDiagramDescription.getDiagramDescription(GeneralViewFlowUsageProjectData.EDITING_CONTEXT_ID, |
| 345 | + SysONRepresentationDescriptionIdentifiers.GENERAL_VIEW_DIAGRAM_DESCRIPTION_ID); |
| 346 | + var diagramDescriptionIdProvider = new DiagramDescriptionIdProvider(diagramDescription, this.diagramIdProvider); |
| 347 | + String flowCreationToolId = diagramDescriptionIdProvider.getNodeCreationToolIdOnEdge(this.descriptionNameGenerator.getEdgeName(SysmlPackage.eINSTANCE.getConnectionUsage()), "New Flow"); |
| 348 | + |
| 349 | + Consumer<Object> initialDiagramContentConsumer = assertRefreshedDiagramThat(diagram -> { |
| 350 | + diagramId.set(diagram.getId()); |
| 351 | + var connectionEdge = new DiagramNavigator(diagram).edgeWithId(GeneralViewFlowUsageProjectData.GraphicalIds.CONNECTION_EDGE_ID).getEdge(); |
| 352 | + connectionEdgeId.set(connectionEdge.getId()); |
| 353 | + connectionEdgeLabelId.set(connectionEdge.getCenterLabel().id()); |
| 354 | + }); |
| 355 | + |
| 356 | + Runnable renameAndTypeTheConnection = () -> this.editLabel(diagramId.get(), connectionEdgeLabelId.get(), "cable : HDMICable"); |
| 357 | + |
| 358 | + Consumer<Object> validateLabelEditResult = assertRefreshedDiagramThat(diagram -> this.assertEdgeLabelText(connectionEdgeId.get(), diagram, "cable : HDMICable")); |
| 359 | + |
| 360 | + Runnable validateSemanticEffectOfLabelEdit = this.semanticRunnableFactory.createRunnable(GeneralViewFlowUsageProjectData.EDITING_CONTEXT_ID, |
| 361 | + (editingContext, executeEditingContextFunctionInput) -> { |
| 362 | + this.assertConnectionType(editingContext, GeneralViewFlowUsageProjectData.SemanticIds.CONNECT_ID, GeneralViewFlowUsageProjectData.SemanticIds.HDMI_CABLE_ID); |
| 363 | + return new ExecuteEditingContextFunctionSuccessPayload(executeEditingContextFunctionInput.id(), true); |
| 364 | + }); |
| 365 | + |
| 366 | + Runnable createFlowUsageOnConnection = () -> { |
| 367 | + var selectedObjectVariable = new ToolVariable("selectedObject", GeneralViewFlowUsageProjectData.SemanticIds.VIDEO_SIGNAL_ID, ToolVariableType.OBJECT_ID); |
| 368 | + var input = new InvokeSingleClickOnDiagramElementToolInput(UUID.randomUUID(), GeneralViewFlowUsageProjectData.EDITING_CONTEXT_ID, diagramId.get(), List.of(connectionEdgeId.get()), |
| 369 | + flowCreationToolId, 0, 0, |
| 370 | + List.of(selectedObjectVariable)); |
| 371 | + var result = this.invokeSingleClickOnDiagramElementToolMutationRunner.run(input); |
| 372 | + String typename = JsonPath.read(result.data(), "$.data.invokeSingleClickOnDiagramElementTool.__typename"); |
| 373 | + assertThat(typename).isEqualTo(InvokeSingleClickOnDiagramElementToolSuccessPayload.class.getSimpleName()); |
| 374 | + List<String> messages = JsonPath.read(result.data(), "$.data.invokeSingleClickOnDiagramElementTool.messages[*].body"); |
| 375 | + assertThat(messages).hasSize(0); |
| 376 | + }; |
| 377 | + |
| 378 | + Consumer<Object> validateEffectOnLabel = assertRefreshedDiagramThat(diagram -> this.assertEdgeLabelText(connectionEdgeId.get(), diagram, "cable : HDMICable \u25b6 Flow")); |
| 379 | + |
| 380 | + Runnable validateSemanticEffectOfFlowCreation = this.semanticRunnableFactory.createRunnable(GeneralViewFlowUsageProjectData.EDITING_CONTEXT_ID, |
| 381 | + (editingContext, executeEditingContextFunctionInput) -> { |
| 382 | + var optionalConnection = this.objectSearchService.getObject(editingContext, GeneralViewFlowUsageProjectData.SemanticIds.CONNECT_ID); |
| 383 | + assertThat(optionalConnection).containsInstanceOf(ConnectionUsage.class); |
| 384 | + ConnectionUsage connection = (ConnectionUsage) optionalConnection.get(); |
| 385 | + // The flow usage has been created |
| 386 | + var optionalFlowUsage = connection.getOwnedFeature().stream().filter(FlowUsage.class::isInstance).map(FlowUsage.class::cast).findFirst(); |
| 387 | + assertThat(optionalFlowUsage).isPresent(); |
| 388 | + var flowUsage = optionalFlowUsage.get(); |
| 389 | + |
| 390 | + // The flow has a FeatureMembership with a PayloadFeature typed by "Video Signal" (the passed |
| 391 | + // payload) |
| 392 | + var optionalPayloadFeature = flowUsage.getOwnedFeature().stream().filter(PayloadFeature.class::isInstance).map(PayloadFeature.class::cast).findFirst(); |
| 393 | + assertThat(optionalPayloadFeature).isPresent(); |
| 394 | + var payloadFeature = optionalPayloadFeature.get(); |
| 395 | + var payloadType = ((FeatureTyping) payloadFeature.getOwnedRelationship().get(0)).getType(); |
| 396 | + assertThat(this.identityService.getId(payloadType)).isEqualTo(GeneralViewFlowUsageProjectData.SemanticIds.VIDEO_SIGNAL_ID); |
| 397 | + |
| 398 | + // The flow has two FlowEnds: one redefining HDMICable::inputSide, the other HDMICable::outputSide |
| 399 | + var flowEnds = flowUsage.getOwnedFeature().stream().filter(FlowEnd.class::isInstance).map(FlowEnd.class::cast).toList(); |
| 400 | + assertThat(flowEnds).hasSize(2); |
| 401 | + var sourceEnd = flowEnds.get(0); |
| 402 | + assertThat(sourceEnd.getOwnedFeature().get(0).getOwnedRedefinition().get(0).getRedefinedFeature().getQualifiedName()).isEqualTo("Package1::HDMICable::inputSide"); |
| 403 | + var targetEnd = flowEnds.get(1); |
| 404 | + assertThat(targetEnd.getOwnedFeature().get(0).getOwnedRedefinition().get(0).getRedefinedFeature().getQualifiedName()).isEqualTo("Package1::HDMICable::outputSide"); |
| 405 | + return new ExecuteEditingContextFunctionSuccessPayload(executeEditingContextFunctionInput.id(), true); |
| 406 | + }); |
| 407 | + |
| 408 | + StepVerifier.create(flux) |
| 409 | + .consumeNextWith(initialDiagramContentConsumer) |
| 410 | + .then(renameAndTypeTheConnection) |
| 411 | + .consumeNextWith(validateLabelEditResult) |
| 412 | + .then(validateSemanticEffectOfLabelEdit) |
| 413 | + .then(createFlowUsageOnConnection) |
| 414 | + .consumeNextWith(validateEffectOnLabel) |
| 415 | + .then(validateSemanticEffectOfFlowCreation) |
| 416 | + .thenCancel() |
| 417 | + .verify(Duration.ofSeconds(10)); |
| 418 | + } |
| 419 | + |
| 420 | + @Test |
| 421 | + @DisplayName("GIVEN an untype connection WHEN we opening its palette THEN the flow tool is not proposed") |
| 422 | + @GivenSysONServer({ GeneralViewFlowUsageProjectData.SCRIPT_PATH }) |
| 423 | + public void createFlowUsageInUntypedConnectionConnection() { |
| 424 | + var diagramEventInput = new DiagramEventInput(UUID.randomUUID(), |
| 425 | + GeneralViewFlowUsageProjectData.EDITING_CONTEXT_ID, |
| 426 | + GeneralViewFlowUsageProjectData.GraphicalIds.DIAGRAM_ID); |
| 427 | + |
| 428 | + var flux = this.givenDiagramSubscription.subscribe(diagramEventInput); |
| 429 | + |
| 430 | + var diagramId = new AtomicReference<String>(); |
| 431 | + var connectionEdgeId = new AtomicReference<String>(); |
| 432 | + |
| 433 | + var diagramDescription = this.givenDiagramDescription.getDiagramDescription(GeneralViewFlowUsageProjectData.EDITING_CONTEXT_ID, |
| 434 | + SysONRepresentationDescriptionIdentifiers.GENERAL_VIEW_DIAGRAM_DESCRIPTION_ID); |
| 435 | + var diagramDescriptionIdProvider = new DiagramDescriptionIdProvider(diagramDescription, this.diagramIdProvider); |
| 436 | + String flowCreationToolId = diagramDescriptionIdProvider.getNodeCreationToolIdOnEdge(this.descriptionNameGenerator.getEdgeName(SysmlPackage.eINSTANCE.getConnectionUsage()), "New Flow"); |
| 437 | + |
| 438 | + Consumer<Object> initialDiagramContentConsumer = assertRefreshedDiagramThat(diagram -> { |
| 439 | + diagramId.set(diagram.getId()); |
| 440 | + var connectionEdge = new DiagramNavigator(diagram).edgeWithId(GeneralViewFlowUsageProjectData.GraphicalIds.CONNECTION_EDGE_ID).getEdge(); |
| 441 | + connectionEdgeId.set(connectionEdge.getId()); |
| 442 | + }); |
| 443 | + |
| 444 | + Runnable getEdgePalette = () -> { |
| 445 | + Map<String, Object> variables = Map.of( |
| 446 | + "editingContextId", GeneralViewFlowUsageProjectData.EDITING_CONTEXT_ID, |
| 447 | + "representationId", diagramId.get(), |
| 448 | + "diagramElementIds", List.of(connectionEdgeId.get())); |
| 449 | + var result = this.paletteQueryRunner.run(variables); |
| 450 | + Map<String, Object> behaviorSection = JsonPath.read(result.data(), "$.data.viewer.editingContext.representation.description.palette.paletteEntries[1]"); |
| 451 | + assertThat(behaviorSection.get("label")).isEqualTo("Behavior"); |
| 452 | + List<Object> behaviorTools = JsonPath.read(result.data(), "$.data.viewer.editingContext.representation.description.palette.paletteEntries[1].tools"); |
| 453 | + assertThat(behaviorTools).isEmpty(); |
| 454 | + List<String> allTools = JsonPath.read(result.data(), "$.data.viewer.editingContext.representation.description.palette.paletteEntries[*].tools[*].id"); |
| 455 | + assertThat(allTools).doesNotContain(flowCreationToolId); |
| 456 | + }; |
| 457 | + |
| 458 | + |
| 459 | + StepVerifier.create(flux) |
| 460 | + .consumeNextWith(initialDiagramContentConsumer) |
| 461 | + .then(getEdgePalette) |
| 462 | + .thenCancel() |
| 463 | + .verify(Duration.ofSeconds(10)); |
| 464 | + } |
| 465 | + |
| 466 | + private void editLabel(String diagramId, String labelId, String newText) { |
| 467 | + var input = new EditLabelInput(UUID.randomUUID(), GeneralViewFlowUsageProjectData.EDITING_CONTEXT_ID, diagramId, labelId, newText); |
| 468 | + var result = this.editLabelMutationRunner.run(input); |
| 469 | + String typename = JsonPath.read(result.data(), "$.data.editLabel.__typename"); |
| 470 | + assertThat(typename).isEqualTo(EditLabelSuccessPayload.class.getSimpleName()); |
| 471 | + List<String> messages = JsonPath.read(result.data(), "$.data.editLabel.messages[*].body"); |
| 472 | + assertThat(messages).hasSize(0); |
| 473 | + } |
| 474 | + |
| 475 | + private void assertEdgeLabelText(String connectionEdgeId, Diagram diagram, String expectedLabelText) { |
| 476 | + var edge = new DiagramNavigator(diagram).edgeWithId(connectionEdgeId).getEdge(); |
| 477 | + DiagramAssertions.assertThat(edge.getCenterLabel()).hasText(expectedLabelText); |
| 478 | + } |
| 479 | + |
| 480 | + private void assertConnectionType(IEditingContext editingContext, String connectionElementId, String expectedTypeElementId) { |
| 481 | + var optionalConnection = this.objectSearchService.getObject(editingContext, connectionElementId); |
| 482 | + assertThat(optionalConnection).containsInstanceOf(ConnectionUsage.class); |
| 483 | + ConnectionUsage connection = (ConnectionUsage) optionalConnection.get(); |
| 484 | + assertThat(connection.getType()).hasSize(1); |
| 485 | + var connectionType = connection.getType().get(0); |
| 486 | + var connectionTypeId = this.identityService.getId(connectionType); |
| 487 | + assertThat(connectionTypeId).isEqualTo(expectedTypeElementId); |
| 488 | + } |
300 | 489 | } |
0 commit comments