Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,9 @@ As a consequence, the `syson-table-requirements-view` and `syson-common-view` mo
`GetIntermediateContainerCreationSwitch.java` has been moved from `syson-application-configuration` to `syson-services`.
- https://github.com/eclipse-syson/syson/issues/1245[#1245] [syson] Standardize read-only computation.
The class `SysMLReadOnlyService` and the interface `ISysMLReadOnlyService` have been removed, use `IReadOnlyObjectPredicate` instead.
- https://github.com/eclipse-syson/syson/issues/1546[#1546] [diagrams] Fix drag and drop of a graphical node from the diagram background into a _Package_ graphical node.
As a consequence, the `ViewToolService#expose` method has been moved into `ToolService.java` and `NodeFinder.java` has been moved from `syson-diagram-common-view` to `syson-services`.


=== Dependency update

Expand All @@ -79,6 +82,7 @@ This issue was not visible in SysON but could appear in downstream applications
Now it has been fixed in Sirius Web 2025.8.4, `SysONUpdateLibraryExecutor` has been deleted and `UpdateLibraryExecutor` is used again.
- https://github.com/eclipse-syson/syson/issues/1522[#1522] [diagrams] To avoid edge blinking when refreshing the diagram, we need to set the properties `measured.height` and `measured.width` with the value of the node layout data when converting a custom node accordingly to the xyflow https://reactflow.dev/learn/advanced-use/ssr-ssg-configuration#node-dimensions[documentation].
- https://github.com/eclipse-syson/syson/issues/1545[#1545] [diagrams] Add _interconnection_ compartment to `PartDefinition` nodes in the standard diagrams.
- https://github.com/eclipse-syson/syson/issues/1546[#1546] [diagrams] Fix drag and drop of a graphical node from the diagram background into a _Package_ graphical node.

=== Improvements

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,14 +33,14 @@
import org.eclipse.syson.AbstractIntegrationTests;
import org.eclipse.syson.application.controllers.diagrams.testers.ToolTester;
import org.eclipse.syson.application.data.ActionTransitionUsagesProjectData;
import org.eclipse.syson.diagram.common.view.services.NodeFinder;
import org.eclipse.syson.services.diagrams.DiagramDescriptionIdProvider;
import org.eclipse.syson.services.diagrams.api.IGivenDiagramDescription;
import org.eclipse.syson.services.diagrams.api.IGivenDiagramReference;
import org.eclipse.syson.services.diagrams.api.IGivenDiagramSubscription;
import org.eclipse.syson.standard.diagrams.view.SDVDescriptionNameGenerator;
import org.eclipse.syson.sysml.SysmlPackage;
import org.eclipse.syson.util.IDescriptionNameGenerator;
import org.eclipse.syson.util.NodeFinder;
import org.eclipse.syson.util.SysONRepresentationDescriptionIdentifiers;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
/*******************************************************************************
* Copyright (c) 2025 Obeo.
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Obeo - initial API and implementation
*******************************************************************************/
package org.eclipse.syson.application.controllers.diagrams.general.view;

import static org.assertj.core.api.Assertions.assertThat;
import static org.eclipse.sirius.components.diagrams.tests.DiagramEventPayloadConsumer.assertRefreshedDiagramThat;

import com.jayway.jsonpath.JsonPath;

import java.time.Duration;
import java.util.UUID;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Consumer;

import org.eclipse.sirius.components.collaborative.diagrams.dto.DiagramEventInput;
import org.eclipse.sirius.components.collaborative.diagrams.dto.DiagramRefreshedEventPayload;
import org.eclipse.sirius.components.collaborative.diagrams.dto.DropNodeInput;
import org.eclipse.sirius.components.core.api.SuccessPayload;
import org.eclipse.sirius.components.diagrams.tests.graphql.DropNodeMutationRunner;
import org.eclipse.sirius.components.diagrams.tests.navigation.DiagramNavigator;
import org.eclipse.sirius.web.tests.services.api.IGivenInitialServerState;
import org.eclipse.syson.AbstractIntegrationTests;
import org.eclipse.syson.application.data.GeneralViewWithTopNodesTestProjectData;
import org.eclipse.syson.services.diagrams.api.IGivenDiagramSubscription;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.jdbc.Sql;
import org.springframework.test.context.jdbc.SqlConfig;
import org.springframework.transaction.annotation.Transactional;

import reactor.core.publisher.Flux;
import reactor.test.StepVerifier;

/**
* Tests the drag and drop of nodes inside the General View diagram.
*
* @author arichard
*/
@Transactional
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class GVDropFromDiagramTests extends AbstractIntegrationTests {

@Autowired
private IGivenInitialServerState givenInitialServerState;

@Autowired
private IGivenDiagramSubscription givenDiagramSubscription;

@Autowired
private DropNodeMutationRunner dropNodeMutationRunner;

private Flux<DiagramRefreshedEventPayload> givenSubscriptionToDiagram() {
var diagramEventInput = new DiagramEventInput(UUID.randomUUID(),
GeneralViewWithTopNodesTestProjectData.EDITING_CONTEXT_ID,
GeneralViewWithTopNodesTestProjectData.GraphicalIds.DIAGRAM_ID);
var flux = this.givenDiagramSubscription.subscribe(diagramEventInput);
return flux;
}

@BeforeEach
public void beforeEach() {
this.givenInitialServerState.initialize();
}

@DisplayName("Given a diagram with some nodes, when a node is dropped in another one, then the diagram is updated")
@Sql(scripts = { GeneralViewWithTopNodesTestProjectData.SCRIPT_PATH }, executionPhase = Sql.ExecutionPhase.BEFORE_TEST_METHOD,
config = @SqlConfig(transactionMode = SqlConfig.TransactionMode.ISOLATED))
@Sql(scripts = { "/scripts/cleanup.sql" }, executionPhase = Sql.ExecutionPhase.AFTER_TEST_METHOD, config = @SqlConfig(transactionMode = SqlConfig.TransactionMode.ISOLATED))
@Test
public void dropPartFromDiagramToPackageThenFromPackageToPart() {
var flux = this.givenSubscriptionToDiagram();

var diagramId = new AtomicReference<String>();
var packageNodeId = new AtomicReference<String>();
var partNodeId = new AtomicReference<String>();

Consumer<Object> initialDiagramContentConsumer = assertRefreshedDiagramThat(diagram -> {
diagramId.set(diagram.getId());

var packageNode = new DiagramNavigator(diagram).nodeWithLabel("Package").getNode();
packageNodeId.set(packageNode.getId());

var partNode = new DiagramNavigator(diagram).nodeWithLabel("\u00ABref part\u00BB\npart").getNode();
partNodeId.set(partNode.getId());

assertThat(packageNode.getChildNodes()).hasSize(0);
});

Runnable dropPartNodeFromDiagramToPackage = () -> {
var input = new DropNodeInput(
UUID.randomUUID(),
GeneralViewWithTopNodesTestProjectData.EDITING_CONTEXT_ID.toString(),
diagramId.get(),
partNodeId.get(),
packageNodeId.get(),
0,
0);
var result = this.dropNodeMutationRunner.run(input);
String typename = JsonPath.read(result, "$.data.dropNode.__typename");
assertThat(typename).isEqualTo(SuccessPayload.class.getSimpleName());
};

Consumer<Object> updatedDiagramContentConsumerAfterFirstDrop = assertRefreshedDiagramThat(diagram -> {
var packageNode = new DiagramNavigator(diagram).nodeWithLabel("Package").getNode();

var partNode = new DiagramNavigator(diagram).nodeWithLabel("\u00ABref part\u00BB\npart").getNode();
partNodeId.set(partNode.getId());

assertThat(packageNode.getChildNodes()).hasSize(1);
assertThat(packageNode.getChildNodes().get(0)).isEqualTo(partNode);
});

Runnable dropPartNodeFromPackageToDiagram = () -> {
var input = new DropNodeInput(
UUID.randomUUID(),
GeneralViewWithTopNodesTestProjectData.EDITING_CONTEXT_ID.toString(),
diagramId.get(),
partNodeId.get(),
diagramId.get(),
0,
0);
var result = this.dropNodeMutationRunner.run(input);
String typename = JsonPath.read(result, "$.data.dropNode.__typename");
assertThat(typename).isEqualTo(SuccessPayload.class.getSimpleName());
};

Consumer<Object> updatedDiagramContentConsumerAfterSecondDrop = assertRefreshedDiagramThat(diagram -> {
var packageNode = new DiagramNavigator(diagram).nodeWithLabel("Package").getNode();

var partNode = new DiagramNavigator(diagram).nodeWithLabel("\u00ABref part\u00BB\npart").getNode();

assertThat(packageNode.getChildNodes()).hasSize(0);
assertThat(partNode).isNotNull();
});

StepVerifier.create(flux)
.consumeNextWith(initialDiagramContentConsumer)
.then(dropPartNodeFromDiagramToPackage)
.consumeNextWith(updatedDiagramContentConsumerAfterFirstDrop)
.then(dropPartNodeFromPackageToDiagram)
.consumeNextWith(updatedDiagramContentConsumerAfterSecondDrop)
.thenCancel()
.verify(Duration.ofSeconds(10));
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2024 Obeo.
* Copyright (c) 2024, 2025 Obeo.
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v2.0
* which accompanies this distribution, and is available at
Expand All @@ -17,7 +17,7 @@
import org.eclipse.sirius.components.diagrams.Diagram;
import org.eclipse.sirius.components.diagrams.Edge;
import org.eclipse.sirius.components.diagrams.Node;
import org.eclipse.syson.diagram.common.view.services.NodeFinder;
import org.eclipse.syson.util.NodeFinder;
import org.springframework.stereotype.Service;

/**
Expand Down
Loading
Loading