diff --git a/src/main/java/org/gridsuite/study/server/controller/StudyController.java b/src/main/java/org/gridsuite/study/server/controller/StudyController.java index addacb3be..ab935196f 100644 --- a/src/main/java/org/gridsuite/study/server/controller/StudyController.java +++ b/src/main/java/org/gridsuite/study/server/controller/StudyController.java @@ -980,11 +980,12 @@ public ResponseEntity> getAvailableSvgComponentLibraries() { return ResponseEntity.ok().contentType(MediaType.APPLICATION_JSON).body(libraries); } - @GetMapping(value = "/studies/{studyUuid}/network-modifications/references/exists") - @Operation(summary = "Whether the study contains a shared modification, including nested in its composites") - @ApiResponse(responseCode = "200", description = "true if at least one shared modification is found") - public ResponseEntity hasSharedModifications(@PathVariable("studyUuid") UUID studyUuid) { - return ResponseEntity.ok().body(studyService.hasSharedModifications(studyUuid)); + @GetMapping(value = "/studies/{studyUuid}/network-modifications/references/write-access") + @Operation(summary = "Whether the study contains shared modifications, including nested in its composites, and, if so, whether the user can write on all, some or none of them") + @ApiResponse(responseCode = "200", description = "The write access on the shared modifications was returned") + public ResponseEntity getSharedModificationsWriteAccess(@PathVariable("studyUuid") UUID studyUuid, + @RequestHeader(HEADER_USER_ID) String userId) { + return ResponseEntity.ok().body(studyService.getSharedModificationsWriteAccess(studyUuid, userId)); } @GetMapping(value = "/studies/{studyUuid}/nodes/{nodeUuid}/network-modifications", produces = MediaType.TEXT_PLAIN_VALUE) diff --git a/src/main/java/org/gridsuite/study/server/dto/RootNetworkTagsCheckInfos.java b/src/main/java/org/gridsuite/study/server/dto/RootNetworkTagsCheckInfos.java new file mode 100644 index 000000000..3256a94d1 --- /dev/null +++ b/src/main/java/org/gridsuite/study/server/dto/RootNetworkTagsCheckInfos.java @@ -0,0 +1,16 @@ +/** + * Copyright (c) 2026, RTE (http://www.rte-france.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ +package org.gridsuite.study.server.dto; + +import java.util.List; +import java.util.UUID; + +/** + * Modifications to check against root network tags. + */ +public record RootNetworkTagsCheckInfos(List containerUuids, List tags) { +} diff --git a/src/main/java/org/gridsuite/study/server/dto/SharedModificationsWriteAccess.java b/src/main/java/org/gridsuite/study/server/dto/SharedModificationsWriteAccess.java new file mode 100644 index 000000000..2887b1e97 --- /dev/null +++ b/src/main/java/org/gridsuite/study/server/dto/SharedModificationsWriteAccess.java @@ -0,0 +1,19 @@ +/** + * Copyright (c) 2026, RTE (http://www.rte-france.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ +package org.gridsuite.study.server.dto; + +/** + * Whether a user can write on the shared modifications of a study. + * + * @author Florent MILLOT + */ +public enum SharedModificationsWriteAccess { + NO_SHARED_MODIFICATION, + ALL_WRITABLE, + SOME_WRITABLE, + NONE_WRITABLE +} diff --git a/src/main/java/org/gridsuite/study/server/service/StudyService.java b/src/main/java/org/gridsuite/study/server/service/StudyService.java index c2af64fb9..4df8f30c8 100644 --- a/src/main/java/org/gridsuite/study/server/service/StudyService.java +++ b/src/main/java/org/gridsuite/study/server/service/StudyService.java @@ -335,6 +335,9 @@ public void deleteRootNetworks(UUID studyUuid, List rootNetworksUuids, Str @Transactional public RootNetworkRequestInfos createRootNetworkRequest(UUID studyUuid, RootNetworkInfos rootNetworkInfos, String userId) { rootNetworkService.assertCanCreateRootNetwork(studyUuid, rootNetworkInfos.getName(), rootNetworkInfos.getTag()); + if (rootNetworkInfos.getTag() != null) { + assertCanAddRootNetworkTag(studyUuid, rootNetworkInfos.getTag(), userId); + } StudyEntity studyEntity = getStudy(studyUuid); rootNetworkInfos.setId(UUID.randomUUID()); @@ -391,33 +394,35 @@ private void invalidatePreviousRootNetworkNodeTree(StudyEntity studyEntity) { networkModificationTreeService.invalidateNodeTree(studyEntity.getId(), rootNodeUuid, studyEntity.getFirstRootNetwork().getId()); } - private void updateRootNetworkBasicInfos(UUID studyUuid, RootNetworkInfos rootNetworkInfos, boolean updateCase) { + private void updateRootNetworkBasicInfos(UUID studyUuid, RootNetworkInfos rootNetworkInfos, boolean updateCase, String userId) { String previousTag = rootNetworkService.getRootNetworkTag(rootNetworkInfos.getId()); rootNetworkService.updateRootNetwork(rootNetworkInfos, updateCase); // the entity says what the tag really became, unlike the DTO String newTag = rootNetworkService.getRootNetworkTag(rootNetworkInfos.getId()); - renameRootNetworkTagInApplicabilities(studyUuid, previousTag, newTag); + renameRootNetworkTagInApplicabilities(studyUuid, previousTag, newTag, userId); postRootNetworkUpdate(studyUuid, rootNetworkInfos.getId(), updateCase); } - private void renameRootNetworkTagInApplicabilities(UUID studyUuid, String previousTag, String newTag) { + private void renameRootNetworkTagInApplicabilities(UUID studyUuid, String previousTag, String newTag, String userId) { if (previousTag == null || previousTag.equals(newTag)) { return; } - networkModificationRestService.renameRootNetworkTag(getStudyModificationGroupUuids(studyUuid), previousTag, newTag); + networkModificationRestService.renameRootNetworkTag(getStudyModificationGroupUuids(studyUuid), previousTag, newTag, userId); } /** - * Renaming a tag rewrites the applicabilities the shared modifications of the study contain for every study - * referencing them: only a user allowed to write on all of them may do it. + * A root network tag of a study must be associated with all its shared modifications: the ones the user cannot + * write on, which they cannot associate with a new tag, must already be. */ - private void assertCanRenameRootNetworkTag(UUID studyUuid, String userId) { - networkModificationRestService.assertReferencedModificationsAreWritable(getStudyModificationGroupUuids(studyUuid), userId); + private void assertCanAddRootNetworkTag(UUID studyUuid, String newTag, String userId) { + networkModificationRestService.assertRootNetworkTagsAllowed(getStudyModificationGroupUuids(studyUuid), List.of(newTag), userId); } - public boolean hasSharedModifications(UUID studyUuid) { + public SharedModificationsWriteAccess getSharedModificationsWriteAccess(UUID studyUuid, String userId) { List groupUuids = getStudyModificationGroupUuids(studyUuid); - return !groupUuids.isEmpty() && networkModificationRestService.hasModificationReferences(groupUuids); + return groupUuids.isEmpty() + ? SharedModificationsWriteAccess.NO_SHARED_MODIFICATION + : networkModificationRestService.getReferencedModificationsWriteAccess(groupUuids, userId); } private List getStudyModificationGroupUuids(UUID studyUuid) { @@ -431,7 +436,7 @@ public void updateRootNetworkRequest(UUID studyUuid, RootNetworkInfos rootNetwor rootNetworkService.assertCanModifyRootNetwork(studyUuid, rootNetworkInfos.getId(), rootNetworkInfos.getName(), rootNetworkInfos.getTag()); String newTag = rootNetworkInfos.getTag(); if (newTag != null && !newTag.equals(rootNetworkService.getRootNetworkTag(rootNetworkInfos.getId()))) { - assertCanRenameRootNetworkTag(studyUuid, userId); + assertCanAddRootNetworkTag(studyUuid, newTag, userId); } StudyEntity studyEntity = getStudy(studyUuid); @@ -439,7 +444,7 @@ public void updateRootNetworkRequest(UUID studyUuid, RootNetworkInfos rootNetwor RootNetworkRequestEntity requestEntity = rootNetworkService.insertModificationRequest(studyEntity.getId(), rootNetworkInfos, userId); updateRootNetworkCaseInfos(studyEntity.getId(), rootNetworkInfos, userId, requestEntity); } else { - updateRootNetworkBasicInfos(studyEntity.getId(), rootNetworkInfos, false); + updateRootNetworkBasicInfos(studyEntity.getId(), rootNetworkInfos, false, userId); } notificationService.emitElementUpdated(studyUuid, userId); } @@ -458,7 +463,7 @@ private void updateRootNetworkCaseInfos(UUID studyUuid, RootNetworkInfos rootNet @Transactional public void modifyRootNetwork(UUID studyUuid, RootNetworkInfos rootNetworkInfos, String userId) { invalidateStudyRootNetwork(studyUuid, rootNetworkInfos.getId(), userId, true); - updateRootNetworkBasicInfos(studyUuid, rootNetworkInfos, true); + updateRootNetworkBasicInfos(studyUuid, rootNetworkInfos, true, userId); } private void postRootNetworkUpdate(UUID studyUuid, UUID rootNetworkUuid, boolean updateCase) { diff --git a/src/main/java/org/gridsuite/study/server/service/networkmodification/NetworkModificationRestService.java b/src/main/java/org/gridsuite/study/server/service/networkmodification/NetworkModificationRestService.java index 81bf63fab..e8ae6e80a 100644 --- a/src/main/java/org/gridsuite/study/server/service/networkmodification/NetworkModificationRestService.java +++ b/src/main/java/org/gridsuite/study/server/service/networkmodification/NetworkModificationRestService.java @@ -14,6 +14,8 @@ import org.gridsuite.study.server.dto.BuildInfos; import org.gridsuite.study.server.dto.ModificationReference; import org.gridsuite.study.server.dto.NodeReceiver; +import org.gridsuite.study.server.dto.RootNetworkTagsCheckInfos; +import org.gridsuite.study.server.dto.SharedModificationsWriteAccess; import org.gridsuite.study.server.dto.modification.*; import org.gridsuite.study.server.dto.workflow.AbstractWorkflowInfos; import org.gridsuite.study.server.service.RootNetworkService; @@ -415,7 +417,7 @@ public void updateRootNetworkApplicability(List modificationsUuids, String /** * Renames a root network tag in the applicabilities held by the modifications of the given groups. */ - public void renameRootNetworkTag(List groupUuids, String oldTag, String newTag) { + public void renameRootNetworkTag(List groupUuids, String oldTag, String newTag, String userId) { Objects.requireNonNull(oldTag); Objects.requireNonNull(newTag); if (CollectionUtils.isEmpty(groupUuids)) { @@ -431,6 +433,7 @@ public void renameRootNetworkTag(List groupUuids, String oldTag, String ne HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_JSON); + headers.set(HEADER_USER_ID, userId); restTemplate.exchange(path, HttpMethod.PUT, new HttpEntity<>(headers), Void.class); } @@ -774,19 +777,23 @@ public Set getContainersWithModificationReferences(List containerUui return containersWithReferenceModifications == null ? Set.of() : new HashSet<>(containersWithReferenceModifications); } + public SharedModificationsWriteAccess getReferencedModificationsWriteAccess(List containerUuids, String userId) { + String path = UriComponentsBuilder.fromPath(CONTAINERS + DELIMITER + "references/write-access") + .queryParam(UUIDS, containerUuids) + .build().toUriString(); + return restTemplate.exchange(getNetworkModificationServerURI(false) + path, HttpMethod.GET, + userIdEntity(userId), SharedModificationsWriteAccess.class).getBody(); + } + /** - * Asserts that the user may write on every shared modification the given containers point to, directly or through - * other shared modifications. Throws when they cannot. + * Throws forbidden when the unwritable shared modifications involved miss some of the tags. */ - public void assertReferencedModificationsAreWritable(List containerUuids, String userId) { - if (containerUuids.isEmpty()) { + public void assertRootNetworkTagsAllowed(List containerUuids, List rootNetworkTags, String userId) { + if (rootNetworkTags.isEmpty() || containerUuids.isEmpty()) { return; } - String path = UriComponentsBuilder.fromPath(CONTAINERS + DELIMITER + "references/authorized") - .queryParam(UUIDS, containerUuids) - .build().toUriString(); - - restTemplate.exchange(getNetworkModificationServerURI(false) + path, HttpMethod.GET, userIdEntity(userId), Void.class); + restTemplate.exchange(getNetworkModificationServerURI(false) + CONTAINERS + DELIMITER + "root-network-tags/authorized", + HttpMethod.POST, userIdEntity(userId, new RootNetworkTagsCheckInfos(containerUuids, rootNetworkTags)), Void.class); } /** diff --git a/src/test/java/org/gridsuite/study/server/rootnetworks/RootNetworkApplicabilityTest.java b/src/test/java/org/gridsuite/study/server/rootnetworks/RootNetworkApplicabilityTest.java index 913cf3b4e..ef69769be 100644 --- a/src/test/java/org/gridsuite/study/server/rootnetworks/RootNetworkApplicabilityTest.java +++ b/src/test/java/org/gridsuite/study/server/rootnetworks/RootNetworkApplicabilityTest.java @@ -41,6 +41,7 @@ import java.util.*; +import static org.gridsuite.study.server.StudyConstants.HEADER_USER_ID; import static org.gridsuite.study.server.utils.TestUtils.createModificationNodeInfo; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; @@ -281,20 +282,20 @@ void testRenamingARootNetworkTagCarriesTheApplicabilitiesAlong() throws Exceptio updateRootNetwork(studyEntity.getId(), rootNetworkUuid, ROOT_NETWORK_TAG_2); ArgumentCaptor> groupUuidsCaptor = ArgumentCaptor.captor(); - verify(networkModificationRestService, times(1)).renameRootNetworkTag(groupUuidsCaptor.capture(), eq(ROOT_NETWORK_TAG_1), eq(ROOT_NETWORK_TAG_2)); + verify(networkModificationRestService, times(1)).renameRootNetworkTag(groupUuidsCaptor.capture(), eq(ROOT_NETWORK_TAG_1), eq(ROOT_NETWORK_TAG_2), eq(USER_ID)); assertEquals(Set.of(firstNode.getModificationGroupUuid(), secondNode.getModificationGroupUuid()), Set.copyOf(groupUuidsCaptor.getValue())); // an update carrying no tag at all leaves it as it was, so it is not a rename updateRootNetwork(studyEntity.getId(), rootNetworkUuid, null); - verify(networkModificationRestService, times(1)).renameRootNetworkTag(any(), any(), any()); + verify(networkModificationRestService, times(1)).renameRootNetworkTag(any(), any(), any(), any()); // and neither is an update carrying the tag the root network already has updateRootNetwork(studyEntity.getId(), rootNetworkUuid, ROOT_NETWORK_TAG_2); - verify(networkModificationRestService, times(1)).renameRootNetworkTag(any(), any(), any()); + verify(networkModificationRestService, times(1)).renameRootNetworkTag(any(), any(), any(), any()); } @Test - void testRenamingARootNetworkTagNeedsWritePermissionOnTheSharedModifications() throws Exception { + void testRenamingARootNetworkTagNeedsTheSharedModificationsTheUserCannotWriteOnToBeAssociatedWithIt() throws Exception { StudyEntity studyEntity = TestUtils.createDummyStudy(NETWORK_UUID, CASE_UUID, CASE_NAME, CASE_FORMAT, REPORT_UUID); studyRepository.save(studyEntity); UUID rootNetworkUuid = studyService.getExistingBasicRootNetworkInfos(studyEntity.getId()).getFirst().rootNetworkUuid(); @@ -302,9 +303,9 @@ void testRenamingARootNetworkTagNeedsWritePermissionOnTheSharedModifications() t NodeEntity rootNode = networkModificationTreeService.createRoot(studyEntity); NetworkModificationNode firstNode = networkModificationTreeService.createNode(studyEntity, rootNode.getIdNode(), createModificationNodeInfo(NODE_1_NAME), InsertMode.AFTER, null); - // the study points to a shared modification the user is not allowed to write on + // the study points to a shared modification the user is not allowed to write on, and not associated with the new tag doThrow(HttpClientErrorException.create(HttpStatus.FORBIDDEN, "Forbidden", null, null, null)) - .when(networkModificationRestService).assertReferencedModificationsAreWritable(List.of(firstNode.getModificationGroupUuid()), USER_ID); + .when(networkModificationRestService).assertRootNetworkTagsAllowed(List.of(firstNode.getModificationGroupUuid()), List.of(ROOT_NETWORK_TAG_2), USER_ID); UUID studyUuid = studyEntity.getId(); RootNetworkInfos renamingTagInfos = RootNetworkInfos.builder().id(rootNetworkUuid).tag(ROOT_NETWORK_TAG_2).build(); @@ -312,33 +313,35 @@ void testRenamingARootNetworkTagNeedsWritePermissionOnTheSharedModifications() t // neither the tag nor the applicabilities are touched assertEquals(ROOT_NETWORK_TAG_1, rootNetworkService.getRootNetworkTag(rootNetworkUuid)); - verify(networkModificationRestService, never()).renameRootNetworkTag(any(), any(), any()); + verify(networkModificationRestService, never()).renameRootNetworkTag(any(), any(), any(), any()); // an update keeping the tag is no rename, so it needs no permission updateRootNetwork(studyUuid, rootNetworkUuid, ROOT_NETWORK_TAG_1); - verify(networkModificationRestService, times(1)).assertReferencedModificationsAreWritable(any(), any()); + verify(networkModificationRestService, times(1)).assertRootNetworkTagsAllowed(any(), any(), any()); } @Test - void testHasSharedModifications() throws Exception { + void testGetSharedModificationsWriteAccess() throws Exception { StudyEntity studyEntity = TestUtils.createDummyStudy(NETWORK_UUID, CASE_UUID, CASE_NAME, CASE_FORMAT, REPORT_UUID); studyRepository.save(studyEntity); UUID studyUuid = studyEntity.getId(); // a study with no modification node contains no shared modification, and the server is not even asked - assertFalse(hasSharedModifications(studyUuid)); - verify(networkModificationRestService, never()).hasModificationReferences(any()); + assertEquals(SharedModificationsWriteAccess.NO_SHARED_MODIFICATION, getSharedModificationsWriteAccess(studyUuid)); + verify(networkModificationRestService, never()).getReferencedModificationsWriteAccess(any(), any()); NodeEntity rootNode = networkModificationTreeService.createRoot(studyEntity); NetworkModificationNode firstNode = networkModificationTreeService.createNode(studyEntity, rootNode.getIdNode(), createModificationNodeInfo(NODE_1_NAME), InsertMode.AFTER, null); - doReturn(true).when(networkModificationRestService).hasModificationReferences(List.of(firstNode.getModificationGroupUuid())); + doReturn(SharedModificationsWriteAccess.NONE_WRITABLE).when(networkModificationRestService) + .getReferencedModificationsWriteAccess(List.of(firstNode.getModificationGroupUuid()), USER_ID); - assertTrue(hasSharedModifications(studyUuid)); + assertEquals(SharedModificationsWriteAccess.NONE_WRITABLE, getSharedModificationsWriteAccess(studyUuid)); } - private boolean hasSharedModifications(UUID studyUuid) throws Exception { - return Boolean.parseBoolean(mockMvc.perform(get("/v1/studies/{studyUuid}/network-modifications/references/exists", studyUuid)) - .andExpect(status().isOk()).andReturn().getResponse().getContentAsString()); + private SharedModificationsWriteAccess getSharedModificationsWriteAccess(UUID studyUuid) throws Exception { + return objectMapper.readValue(mockMvc.perform(get("/v1/studies/{studyUuid}/network-modifications/references/write-access", studyUuid) + .header(HEADER_USER_ID, USER_ID)) + .andExpect(status().isOk()).andReturn().getResponse().getContentAsString(), SharedModificationsWriteAccess.class); } @Test diff --git a/src/test/java/org/gridsuite/study/server/service/networkmodification/NetworkModificationServiceTest.java b/src/test/java/org/gridsuite/study/server/service/networkmodification/NetworkModificationServiceTest.java index 35a46baf8..29cf68c2d 100644 --- a/src/test/java/org/gridsuite/study/server/service/networkmodification/NetworkModificationServiceTest.java +++ b/src/test/java/org/gridsuite/study/server/service/networkmodification/NetworkModificationServiceTest.java @@ -9,6 +9,8 @@ import com.fasterxml.jackson.databind.ObjectMapper; import org.gridsuite.study.server.RemoteServicesProperties; import org.gridsuite.study.server.dto.ModificationReference; +import org.gridsuite.study.server.dto.RootNetworkTagsCheckInfos; +import org.gridsuite.study.server.dto.SharedModificationsWriteAccess; import org.gridsuite.study.server.service.RootNetworkService; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -218,12 +220,12 @@ void testRenameRootNetworkTag() { String expectedUrl = NETWORK_MODIFICATION_SERVER_URI + "/v1/network-modifications/root-network-tag" + "?groupUuids=" + firstGroupUuid + "&groupUuids=" + secondGroupUuid + "&oldTag=PH1&newTag=PH2"; - networkModificationService.renameRootNetworkTag(List.of(firstGroupUuid, secondGroupUuid), "PH1", "PH2"); + networkModificationService.renameRootNetworkTag(List.of(firstGroupUuid, secondGroupUuid), "PH1", "PH2", USER_ID); verify(restTemplate).exchange(eq(expectedUrl), eq(HttpMethod.PUT), org.mockito.ArgumentMatchers.>any(), eq(Void.class)); // there is nothing to rename without a group - networkModificationService.renameRootNetworkTag(List.of(), "PH1", "PH2"); + networkModificationService.renameRootNetworkTag(List.of(), "PH1", "PH2", USER_ID); verifyNoMoreInteractions(restTemplate); } @@ -261,19 +263,19 @@ void testDuplicateModificationsGroupAssociatesTheRootNetworkTags() { } @Test - void testAssertReferencedModificationsAreWritable() { + void testAssertRootNetworkTagsAllowed() { UUID groupUuid = UUID.randomUUID(); - String expectedUrl = NETWORK_MODIFICATION_SERVER_URI + "/v1/containers/references/authorized?uuids=" + groupUuid; - - networkModificationService.assertReferencedModificationsAreWritable(List.of(groupUuid), USER_ID); - - // the server needs the user to tell whether the shared modifications are writable HttpHeaders headers = new HttpHeaders(); headers.set(HEADER_USER_ID, USER_ID); - verify(restTemplate).exchange(expectedUrl, HttpMethod.GET, new HttpEntity<>(headers), Void.class); + headers.setContentType(MediaType.APPLICATION_JSON); - // there is nothing to check without a container - networkModificationService.assertReferencedModificationsAreWritable(List.of(), USER_ID); + networkModificationService.assertRootNetworkTagsAllowed(List.of(groupUuid), List.of("PH1", "PH2"), USER_ID); + verify(restTemplate).exchange(NETWORK_MODIFICATION_SERVER_URI + "/v1/containers/root-network-tags/authorized", HttpMethod.POST, + new HttpEntity<>(new RootNetworkTagsCheckInfos(List.of(groupUuid), List.of("PH1", "PH2")), headers), Void.class); + + // there is nothing to check without a tag, or without a container to check it on + networkModificationService.assertRootNetworkTagsAllowed(List.of(groupUuid), List.of(), USER_ID); + networkModificationService.assertRootNetworkTagsAllowed(List.of(), List.of("PH1"), USER_ID); verifyNoMoreInteractions(restTemplate); } @@ -287,6 +289,19 @@ void testHasModificationReferences() { verify(restTemplate).getForObject(eq(expectedUrl), eq(Boolean.class)); } + @Test + void testGetReferencedModificationsWriteAccess() { + UUID groupUuid = UUID.randomUUID(); + String expectedUrl = NETWORK_MODIFICATION_SERVER_URI + "/v1/containers/references/write-access?uuids=" + groupUuid; + HttpHeaders headers = new HttpHeaders(); + headers.set(HEADER_USER_ID, USER_ID); + when(restTemplate.exchange(expectedUrl, HttpMethod.GET, new HttpEntity<>(headers), SharedModificationsWriteAccess.class)) + .thenReturn(ResponseEntity.ok(SharedModificationsWriteAccess.NONE_WRITABLE)); + + assertThat(networkModificationService.getReferencedModificationsWriteAccess(List.of(groupUuid), USER_ID)) + .isEqualTo(SharedModificationsWriteAccess.NONE_WRITABLE); + } + @Test void testGetContainersWithModificationReferences() { UUID groupUuid = UUID.randomUUID(); diff --git a/src/test/java/org/gridsuite/study/server/studycontroller/StudyTestBase.java b/src/test/java/org/gridsuite/study/server/studycontroller/StudyTestBase.java index 5a4d44faf..4181113ba 100644 --- a/src/test/java/org/gridsuite/study/server/studycontroller/StudyTestBase.java +++ b/src/test/java/org/gridsuite/study/server/studycontroller/StudyTestBase.java @@ -396,6 +396,7 @@ void setup() { singleLineDiagramService.setSingleLineDiagramServerBaseUri(baseUrl); directoryService.setDirectoryServerServerBaseUri(baseUrl); networkModificationService.setNetworkModificationServerBaseUri(baseUrl); + wireMockStubs.stubRootNetworkTagsAllowed(); } protected UUID getRootNodeUuid(UUID studyUuid) { diff --git a/src/test/java/org/gridsuite/study/server/utils/TestUtils.java b/src/test/java/org/gridsuite/study/server/utils/TestUtils.java index fc0fa8ea6..b3804e872 100644 --- a/src/test/java/org/gridsuite/study/server/utils/TestUtils.java +++ b/src/test/java/org/gridsuite/study/server/utils/TestUtils.java @@ -28,6 +28,7 @@ import org.gridsuite.study.server.service.StudyServerExecutionService; import org.gridsuite.study.server.utils.assertions.Assertions; import org.gridsuite.study.server.utils.wiremock.UserAdminServerStubs; +import org.gridsuite.study.server.utils.wiremock.WireMockStubs; import org.junit.platform.commons.util.StringUtils; import org.mockito.stubbing.Answer; import org.springframework.cloud.stream.binder.test.OutputDestination; @@ -399,6 +400,8 @@ public static void assertWiremockServerRequestsEmptyThenShutdown(WireMockServer // Remove quota operation consume/release requests that are auto-stubbed and do not need explicit verification wireMockServer.removeServeEventsMatching(WireMock.postRequestedFor(WireMock.urlPathMatching(UserAdminServerStubs.QUOTA_CONSUME_URL_PATTERN)).build()); wireMockServer.removeServeEventsMatching(WireMock.postRequestedFor(WireMock.urlPathMatching(UserAdminServerStubs.QUOTA_RELEASE_URL_PATTERN)).build()); + // Remove the root network tags checks on the shared modifications, auto-stubbed as well + wireMockServer.removeServeEventsMatching(WireMock.postRequestedFor(WireMock.urlPathEqualTo(WireMockStubs.ROOT_NETWORK_TAGS_AUTHORIZED_URL)).build()); var requests = wireMockServer.findAll(WireMock.anyRequestedFor(WireMock.anyUrl())); assertEquals(0, requests.size(), "Unverified WireMock requests found:\n" + requests.stream() .map(r -> "URL: " + r.getUrl() + ", Method: " + r.getMethod() + ", Body: " + r.getBodyAsString() + ", Params: " + r.getQueryParams()) @@ -415,6 +418,8 @@ public static void assertWiremockServerRequestsEmptyThenClear(WireMockServer wir // Remove quota operation consume/release requests that are auto-stubbed and do not need explicit verification wireMockServer.removeServeEventsMatching(WireMock.postRequestedFor(WireMock.urlPathMatching(UserAdminServerStubs.QUOTA_CONSUME_URL_PATTERN)).build()); wireMockServer.removeServeEventsMatching(WireMock.postRequestedFor(WireMock.urlPathMatching(UserAdminServerStubs.QUOTA_RELEASE_URL_PATTERN)).build()); + // Remove the root network tags checks on the shared modifications, auto-stubbed as well + wireMockServer.removeServeEventsMatching(WireMock.postRequestedFor(WireMock.urlPathEqualTo(WireMockStubs.ROOT_NETWORK_TAGS_AUTHORIZED_URL)).build()); assertEquals(0, wireMockServer.findAll(WireMock.anyRequestedFor(WireMock.anyUrl())).size()); } finally { wireMockServer.resetAll(); diff --git a/src/test/java/org/gridsuite/study/server/utils/wiremock/WireMockStubs.java b/src/test/java/org/gridsuite/study/server/utils/wiremock/WireMockStubs.java index a6d12c4a3..e9db08d13 100644 --- a/src/test/java/org/gridsuite/study/server/utils/wiremock/WireMockStubs.java +++ b/src/test/java/org/gridsuite/study/server/utils/wiremock/WireMockStubs.java @@ -46,6 +46,7 @@ public class WireMockStubs { private static final String URI_NETWORK_MODIFICATION_GROUPS = "/v1/groups"; private static final String URI_NETWORK_MODIFICATION_CONTAINERS = "/v1/containers"; + public static final String ROOT_NETWORK_TAGS_AUTHORIZED_URL = URI_NETWORK_MODIFICATION_CONTAINERS + "/root-network-tags/authorized"; public static final String FIRST_VARIANT_ID = "first_variant_id"; @@ -172,6 +173,12 @@ public void verifyNetworkElementsIdsPost(UUID stubUuid, String networkUuid, Stri requestBody); } + public UUID stubRootNetworkTagsAllowed() { + return wireMock.stubFor(WireMock.post(WireMock.urlPathEqualTo(ROOT_NETWORK_TAGS_AUTHORIZED_URL)) + .willReturn(WireMock.ok()) + ).getId(); + } + public UUID stubNetworkModificationCountGet(String groupUuid, Integer expectedCount) { return wireMock.stubFor(WireMock.get(WireMock.urlPathMatching(URI_NETWORK_MODIFICATION_CONTAINERS + DELIMITER + groupUuid + "/network-modifications-count")) .withQueryParam(QUERY_PARAM_STASHED, WireMock.equalTo("false"))