Loading src/main/java/it/inaf/oats/vospace/DeleteNodeController.java +9 −27 Original line number Diff line number Diff line Loading @@ -6,14 +6,7 @@ package it.inaf.oats.vospace; import it.inaf.ia2.aa.data.User; import it.inaf.oats.vospace.datamodel.NodeUtils; import it.inaf.oats.vospace.exception.LinkFoundException; import it.inaf.oats.vospace.exception.NodeNotFoundException; import it.inaf.oats.vospace.exception.PermissionDeniedException; import it.inaf.oats.vospace.persistence.NodeDAO; import java.util.List; import javax.servlet.http.HttpServletRequest; import net.ivoa.xml.vospace.v2.Node; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; Loading @@ -23,7 +16,6 @@ import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.RestController; @RestController public class DeleteNodeController extends BaseNodeController { Loading @@ -39,20 +31,10 @@ public class DeleteNodeController extends BaseNodeController { String path = getPath(); LOG.debug("deleteNode called for path {}", path); try { deleteNodeService.doPreliminaryChecks(path); deleteNodeService.deleteNode(path, principal); return ResponseEntity.ok("Node deleted"); } catch(Exception ex) { return new ResponseEntity<>(ex.getMessage(), HttpStatus.BAD_REQUEST); } } } src/main/java/it/inaf/oats/vospace/DeleteNodeService.java +5 −7 Original line number Diff line number Diff line Loading @@ -14,8 +14,6 @@ import java.util.List; import net.ivoa.xml.vospace.v2.Node; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.EnableTransactionManagement; import org.springframework.transaction.annotation.Isolation; Loading Loading @@ -63,7 +61,7 @@ public class DeleteNodeService { } public void doPreliminaryChecks(String path) throws Exception { public void doPreliminaryChecks(String path) { // Check if the node is present, // if the node does not exist the service SHALL throw a HTTP 404 status code // including a NodeNotFound fault in the entity-body Loading @@ -76,13 +74,13 @@ public class DeleteNodeService { // For example, given the URI path /a/b/c, the service must throw a HTTP 400 // status code including a LinkFound fault in the entity-body if either /a // or /a/b are LinkNodes. List<String> pathComponents = NodeUtils.subPathComponents(path); if (pathComponents.isEmpty()) { if (path.equals("/")) { // Manage root node throw PermissionDeniedException.forPath("/"); } else { List<String> pathComponents = NodeUtils.subPathComponents(path); // Manage all precursors in full path for (int i = 0; i < pathComponents.size(); i++) { Loading src/test/java/it/inaf/oats/vospace/DeleteNodeControllerTest.javadeleted 100644 → 0 +0 −201 Original line number Diff line number Diff line /* * This file is part of vospace-rest * Copyright (C) 2021 Istituto Nazionale di Astrofisica * SPDX-License-Identifier: GPL-3.0-or-later */ package it.inaf.oats.vospace; import it.inaf.oats.vospace.datamodel.NodeProperties; import it.inaf.oats.vospace.persistence.NodeDAO; import java.util.List; import java.util.Optional; import net.ivoa.xml.vospace.v2.ContainerNode; import net.ivoa.xml.vospace.v2.DataNode; import net.ivoa.xml.vospace.v2.LinkNode; import net.ivoa.xml.vospace.v2.Node; import net.ivoa.xml.vospace.v2.Property; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.TestPropertySource; import org.springframework.test.web.servlet.MockMvc; import org.junit.jupiter.api.Test; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.when; import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; @SpringBootTest @ContextConfiguration(classes = {TokenFilterConfig.class}) @TestPropertySource(properties = "spring.main.allow-bean-definition-overriding=true") @AutoConfigureMockMvc public class DeleteNodeControllerTest { private static final String URI_PREFIX = "vos://example.com!vospace"; @MockBean private NodeDAO nodeDao; @Autowired private MockMvc mockMvc; @Test public void testDeleteRootNode() throws Exception { when(nodeDao.listNode(eq("/"))).thenReturn(getRootNode()); mockMvc.perform(MockMvcRequestBuilders .delete("/nodes") .header("Authorization", "Bearer user2_token")) .andExpect(status().isForbidden()); } @Test public void testDeleteFirstLevelNode() throws Exception { when(nodeDao.listNode(eq("/mynode"))).thenReturn(Optional.of(getWritableDataNode())); mockMvc.perform(MockMvcRequestBuilders .delete("/nodes/mynode") .header("Authorization", "Bearer user2_token")) .andExpect(status().isOk()); } @Test public void testDeleteMoreLevelNode() throws Exception { when(nodeDao.listNode(eq("/mynode"))).thenReturn(Optional.of(getWritableDataNode("/mynode"))); when(nodeDao.listNode(eq("/mynode/middlenode"))).thenReturn(Optional.of(getWritableDataNode("/mynode/middlenode"))); when(nodeDao.listNode(eq("/mynode/middlenode/myfile.txt"))).thenReturn(Optional.of(getWritableDataNode("/mynode/middlenode/myfile.txt"))); mockMvc.perform(MockMvcRequestBuilders .delete("/nodes/mynode/middlenode/myfile.txt") .header("Authorization", "Bearer user2_token")) .andExpect(status().isOk()); } @Test public void testLeafNodeNotFound() throws Exception { when(nodeDao.listNode(eq("/mynode"))).thenReturn(Optional.of(getWritableDataNode("/mynode"))); mockMvc.perform(MockMvcRequestBuilders .delete("/nodes/mynode/notexisting") .header("Authorization", "Bearer user2_token")) .andExpect(status().isNotFound()); } @Test public void testMiddleLevelNodeNotFound() throws Exception { when(nodeDao.listNode(eq("/mynode"))).thenReturn(Optional.of(getWritableDataNode("/mynode"))); when(nodeDao.listNode(eq("/mynode/middlenode/myfile.txt"))).thenReturn(Optional.of(getWritableDataNode("/mynode/middlenode/myfile.txt"))); mockMvc.perform(MockMvcRequestBuilders .delete("/mynode/middlenode/myfile.txt") .header("Authorization", "Bearer user2_token")) .andExpect(status().isNotFound()); } @Test public void testLinkNodeLeafDelete() throws Exception { when(nodeDao.listNode(eq("/mynode"))).thenReturn(Optional.of(getWritableLinkNode("/mynode"))); mockMvc.perform(MockMvcRequestBuilders .delete("/nodes/mynode") .header("Authorization", "Bearer user2_token")) .andExpect(status().isOk()); } @Test public void testMiddleLevelLinkNodeDelete() throws Exception { when(nodeDao.listNode(eq("/mynode"))).thenReturn(Optional.of(getWritableDataNode("/mynode"))); when(nodeDao.listNode(eq("/mynode/middlenode"))).thenReturn(Optional.of(getWritableLinkNode("/mynode/middlenode"))); when(nodeDao.listNode(eq("/mynode/middlenode/myfile.txt"))).thenReturn(Optional.of(getWritableDataNode("/mynode/middlenode/myfile.txt"))); mockMvc.perform(MockMvcRequestBuilders .delete("/nodes/mynode/middlenode/myfile.txt") .header("Authorization", "Bearer user2_token")) .andExpect(status().isBadRequest()); } @Test public void testDeleteMoreLevelNodeNotAllowed() throws Exception { when(nodeDao.listNode(eq("/mynode"))).thenReturn(Optional.of(getWritableDataNode("/mynode"))); when(nodeDao.listNode(eq("/mynode/middlenode"))).thenReturn(Optional.of(getWritableDataNode("/mynode/middlenode"))); when(nodeDao.listNode(eq("/mynode/middlenode/myfile.txt"))).thenReturn(Optional.of(getWritableDataNode("/mynode/middlenode/myfile.txt"))); mockMvc.perform(MockMvcRequestBuilders .delete("/nodes/mynode/middlenode/myfile.txt")) .andExpect(status().isForbidden()); } private Optional<Node> getRootNode() { ContainerNode root = new ContainerNode(); root.setUri(URI_PREFIX + "/"); root.getNodes().add(getWritableDataNode()); return Optional.of(root); } private Node getWritableDataNode() { DataNode node = new DataNode(); List nodeProperties = node.getProperties(); Property groupWriteProp = new Property(); groupWriteProp.setUri(NodeProperties.GROUP_WRITE_URI); groupWriteProp.setValue("group1"); nodeProperties.add(groupWriteProp); node.setUri(URI_PREFIX + "/mynode"); return node; } private Node getWritableDataNode(String path) { DataNode node = new DataNode(); List nodeProperties = node.getProperties(); Property groupWriteProp = new Property(); groupWriteProp.setUri(NodeProperties.GROUP_WRITE_URI); groupWriteProp.setValue("group1"); nodeProperties.add(groupWriteProp); node.setUri(URI_PREFIX + path); return node; } private LinkNode getWritableLinkNode(String path) { LinkNode myNode = new LinkNode(); // Set parent node address at / myNode.setUri("vos://example.com!vospace" + path); // Set groupwrite property Property groups = new Property(); groups.setUri("ivo://ivoa.net/vospace/core#groupwrite"); groups.setValue("group1"); myNode.setProperties(List.of(groups)); return myNode; } } src/test/java/it/inaf/oats/vospace/DeleteNodeServiceTest.java 0 → 100644 +147 −0 Original line number Diff line number Diff line /* * This file is part of vospace-rest * Copyright (C) 2021 Istituto Nazionale di Astrofisica * SPDX-License-Identifier: GPL-3.0-or-later */ package it.inaf.oats.vospace; import it.inaf.ia2.aa.data.User; import it.inaf.oats.vospace.exception.InternalFaultException; import it.inaf.oats.vospace.exception.NodeBusyException; import it.inaf.oats.vospace.exception.NodeNotFoundException; import it.inaf.oats.vospace.exception.PermissionDeniedException; import it.inaf.oats.vospace.persistence.DataSourceConfigSingleton; import it.inaf.oats.vospace.persistence.NodeDAO; import java.util.Optional; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; import org.junit.jupiter.api.Test; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.TestPropertySource; import org.springframework.test.annotation.DirtiesContext; @SpringBootTest @AutoConfigureMockMvc @ContextConfiguration(classes = DataSourceConfigSingleton.class) @TestPropertySource(locations = "classpath:test.properties", properties = {"vospace-authority=example.com!vospace", "file-service-url=http://file-service"}) @DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD) public class DeleteNodeServiceTest { @Autowired private DeleteNodeService deleteNodeService; @Autowired private NodeDAO nodeDao; @Test public void testPreliminaryCheckOnRoot() { assertThrows(PermissionDeniedException.class, ()->{ deleteNodeService.doPreliminaryChecks("/"); }); } @Test public void testPreliminaryNodeNotFound() { assertThrows(NodeNotFoundException.class, ()->{ deleteNodeService.doPreliminaryChecks("/nonexistent/node"); }); } @Test public void deleteBranchTest() { User user = mock(User.class); when(user.getName()).thenReturn("user3"); Optional<Long> sourceId = nodeDao.getNodeId("/test3/m1"); assertTrue(sourceId.isPresent()); Optional<Long> childId = nodeDao.getNodeId("/test3/m1/m2"); assertTrue(childId.isPresent()); // Delete deleteNodeService.deleteNode("/test3/m1", user); Optional<Long> checkSourceId = nodeDao.getNodeId("/test3/m1"); assertTrue(checkSourceId.isEmpty()); Optional<Long> checkSourceIdChild = nodeDao.getNodeId("/test3/m1/m2"); assertTrue(checkSourceIdChild.isEmpty()); } @Test public void deleteStopOnImmutableTest() { User user = mock(User.class); when(user.getName()).thenReturn("user3"); Optional<Long> sourceId = nodeDao.getNodeId("/test3/m1"); assertTrue(sourceId.isPresent()); Optional<Long> childId = nodeDao.getNodeId("/test3/m1/m2"); assertTrue(childId.isPresent()); nodeDao.setBranchImmutable(childId.get(), true); // Delete assertThrows(InternalFaultException.class, ()->{ deleteNodeService.deleteNode("/test3/m1", user);} ); Optional<Long> checkSourceId = nodeDao.getNodeId("/test3/m1"); assertTrue(checkSourceId.isPresent()); Optional<Long> checkSourceIdChild = nodeDao.getNodeId("/test3/m1/m2"); assertTrue(checkSourceIdChild.isPresent()); } @Test public void deleteStopOnBusyTest() { User user = mock(User.class); when(user.getName()).thenReturn("user3"); Optional<Long> sourceId = nodeDao.getNodeId("/test3/m1"); assertTrue(sourceId.isPresent()); Optional<Long> childId = nodeDao.getNodeId("/test3/m1/m2"); assertTrue(childId.isPresent()); nodeDao.setBranchJobId(childId.get(), "pippo"); // Delete assertThrows(NodeBusyException.class, ()->{ deleteNodeService.deleteNode("/test3/m1", user);} ); Optional<Long> checkSourceId = nodeDao.getNodeId("/test3/m1"); assertTrue(checkSourceId.isPresent()); Optional<Long> checkSourceIdChild = nodeDao.getNodeId("/test3/m1/m2"); assertTrue(checkSourceIdChild.isPresent()); } @Test public void deleteStopOnPermissionDeniedTest() { User user = mock(User.class); when(user.getName()).thenReturn("user-pippo"); Optional<Long> sourceId = nodeDao.getNodeId("/test3/m1"); assertTrue(sourceId.isPresent()); Optional<Long> childId = nodeDao.getNodeId("/test3/m1/m2"); assertTrue(childId.isPresent()); // Delete assertThrows(PermissionDeniedException.class, ()->{ deleteNodeService.deleteNode("/test3/m1", user);} ); Optional<Long> checkSourceId = nodeDao.getNodeId("/test3/m1"); assertTrue(checkSourceId.isPresent()); Optional<Long> checkSourceIdChild = nodeDao.getNodeId("/test3/m1/m2"); assertTrue(checkSourceIdChild.isPresent()); } } Loading
src/main/java/it/inaf/oats/vospace/DeleteNodeController.java +9 −27 Original line number Diff line number Diff line Loading @@ -6,14 +6,7 @@ package it.inaf.oats.vospace; import it.inaf.ia2.aa.data.User; import it.inaf.oats.vospace.datamodel.NodeUtils; import it.inaf.oats.vospace.exception.LinkFoundException; import it.inaf.oats.vospace.exception.NodeNotFoundException; import it.inaf.oats.vospace.exception.PermissionDeniedException; import it.inaf.oats.vospace.persistence.NodeDAO; import java.util.List; import javax.servlet.http.HttpServletRequest; import net.ivoa.xml.vospace.v2.Node; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; Loading @@ -23,7 +16,6 @@ import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.RestController; @RestController public class DeleteNodeController extends BaseNodeController { Loading @@ -39,20 +31,10 @@ public class DeleteNodeController extends BaseNodeController { String path = getPath(); LOG.debug("deleteNode called for path {}", path); try { deleteNodeService.doPreliminaryChecks(path); deleteNodeService.deleteNode(path, principal); return ResponseEntity.ok("Node deleted"); } catch(Exception ex) { return new ResponseEntity<>(ex.getMessage(), HttpStatus.BAD_REQUEST); } } }
src/main/java/it/inaf/oats/vospace/DeleteNodeService.java +5 −7 Original line number Diff line number Diff line Loading @@ -14,8 +14,6 @@ import java.util.List; import net.ivoa.xml.vospace.v2.Node; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.EnableTransactionManagement; import org.springframework.transaction.annotation.Isolation; Loading Loading @@ -63,7 +61,7 @@ public class DeleteNodeService { } public void doPreliminaryChecks(String path) throws Exception { public void doPreliminaryChecks(String path) { // Check if the node is present, // if the node does not exist the service SHALL throw a HTTP 404 status code // including a NodeNotFound fault in the entity-body Loading @@ -76,13 +74,13 @@ public class DeleteNodeService { // For example, given the URI path /a/b/c, the service must throw a HTTP 400 // status code including a LinkFound fault in the entity-body if either /a // or /a/b are LinkNodes. List<String> pathComponents = NodeUtils.subPathComponents(path); if (pathComponents.isEmpty()) { if (path.equals("/")) { // Manage root node throw PermissionDeniedException.forPath("/"); } else { List<String> pathComponents = NodeUtils.subPathComponents(path); // Manage all precursors in full path for (int i = 0; i < pathComponents.size(); i++) { Loading
src/test/java/it/inaf/oats/vospace/DeleteNodeControllerTest.javadeleted 100644 → 0 +0 −201 Original line number Diff line number Diff line /* * This file is part of vospace-rest * Copyright (C) 2021 Istituto Nazionale di Astrofisica * SPDX-License-Identifier: GPL-3.0-or-later */ package it.inaf.oats.vospace; import it.inaf.oats.vospace.datamodel.NodeProperties; import it.inaf.oats.vospace.persistence.NodeDAO; import java.util.List; import java.util.Optional; import net.ivoa.xml.vospace.v2.ContainerNode; import net.ivoa.xml.vospace.v2.DataNode; import net.ivoa.xml.vospace.v2.LinkNode; import net.ivoa.xml.vospace.v2.Node; import net.ivoa.xml.vospace.v2.Property; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.TestPropertySource; import org.springframework.test.web.servlet.MockMvc; import org.junit.jupiter.api.Test; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.when; import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; @SpringBootTest @ContextConfiguration(classes = {TokenFilterConfig.class}) @TestPropertySource(properties = "spring.main.allow-bean-definition-overriding=true") @AutoConfigureMockMvc public class DeleteNodeControllerTest { private static final String URI_PREFIX = "vos://example.com!vospace"; @MockBean private NodeDAO nodeDao; @Autowired private MockMvc mockMvc; @Test public void testDeleteRootNode() throws Exception { when(nodeDao.listNode(eq("/"))).thenReturn(getRootNode()); mockMvc.perform(MockMvcRequestBuilders .delete("/nodes") .header("Authorization", "Bearer user2_token")) .andExpect(status().isForbidden()); } @Test public void testDeleteFirstLevelNode() throws Exception { when(nodeDao.listNode(eq("/mynode"))).thenReturn(Optional.of(getWritableDataNode())); mockMvc.perform(MockMvcRequestBuilders .delete("/nodes/mynode") .header("Authorization", "Bearer user2_token")) .andExpect(status().isOk()); } @Test public void testDeleteMoreLevelNode() throws Exception { when(nodeDao.listNode(eq("/mynode"))).thenReturn(Optional.of(getWritableDataNode("/mynode"))); when(nodeDao.listNode(eq("/mynode/middlenode"))).thenReturn(Optional.of(getWritableDataNode("/mynode/middlenode"))); when(nodeDao.listNode(eq("/mynode/middlenode/myfile.txt"))).thenReturn(Optional.of(getWritableDataNode("/mynode/middlenode/myfile.txt"))); mockMvc.perform(MockMvcRequestBuilders .delete("/nodes/mynode/middlenode/myfile.txt") .header("Authorization", "Bearer user2_token")) .andExpect(status().isOk()); } @Test public void testLeafNodeNotFound() throws Exception { when(nodeDao.listNode(eq("/mynode"))).thenReturn(Optional.of(getWritableDataNode("/mynode"))); mockMvc.perform(MockMvcRequestBuilders .delete("/nodes/mynode/notexisting") .header("Authorization", "Bearer user2_token")) .andExpect(status().isNotFound()); } @Test public void testMiddleLevelNodeNotFound() throws Exception { when(nodeDao.listNode(eq("/mynode"))).thenReturn(Optional.of(getWritableDataNode("/mynode"))); when(nodeDao.listNode(eq("/mynode/middlenode/myfile.txt"))).thenReturn(Optional.of(getWritableDataNode("/mynode/middlenode/myfile.txt"))); mockMvc.perform(MockMvcRequestBuilders .delete("/mynode/middlenode/myfile.txt") .header("Authorization", "Bearer user2_token")) .andExpect(status().isNotFound()); } @Test public void testLinkNodeLeafDelete() throws Exception { when(nodeDao.listNode(eq("/mynode"))).thenReturn(Optional.of(getWritableLinkNode("/mynode"))); mockMvc.perform(MockMvcRequestBuilders .delete("/nodes/mynode") .header("Authorization", "Bearer user2_token")) .andExpect(status().isOk()); } @Test public void testMiddleLevelLinkNodeDelete() throws Exception { when(nodeDao.listNode(eq("/mynode"))).thenReturn(Optional.of(getWritableDataNode("/mynode"))); when(nodeDao.listNode(eq("/mynode/middlenode"))).thenReturn(Optional.of(getWritableLinkNode("/mynode/middlenode"))); when(nodeDao.listNode(eq("/mynode/middlenode/myfile.txt"))).thenReturn(Optional.of(getWritableDataNode("/mynode/middlenode/myfile.txt"))); mockMvc.perform(MockMvcRequestBuilders .delete("/nodes/mynode/middlenode/myfile.txt") .header("Authorization", "Bearer user2_token")) .andExpect(status().isBadRequest()); } @Test public void testDeleteMoreLevelNodeNotAllowed() throws Exception { when(nodeDao.listNode(eq("/mynode"))).thenReturn(Optional.of(getWritableDataNode("/mynode"))); when(nodeDao.listNode(eq("/mynode/middlenode"))).thenReturn(Optional.of(getWritableDataNode("/mynode/middlenode"))); when(nodeDao.listNode(eq("/mynode/middlenode/myfile.txt"))).thenReturn(Optional.of(getWritableDataNode("/mynode/middlenode/myfile.txt"))); mockMvc.perform(MockMvcRequestBuilders .delete("/nodes/mynode/middlenode/myfile.txt")) .andExpect(status().isForbidden()); } private Optional<Node> getRootNode() { ContainerNode root = new ContainerNode(); root.setUri(URI_PREFIX + "/"); root.getNodes().add(getWritableDataNode()); return Optional.of(root); } private Node getWritableDataNode() { DataNode node = new DataNode(); List nodeProperties = node.getProperties(); Property groupWriteProp = new Property(); groupWriteProp.setUri(NodeProperties.GROUP_WRITE_URI); groupWriteProp.setValue("group1"); nodeProperties.add(groupWriteProp); node.setUri(URI_PREFIX + "/mynode"); return node; } private Node getWritableDataNode(String path) { DataNode node = new DataNode(); List nodeProperties = node.getProperties(); Property groupWriteProp = new Property(); groupWriteProp.setUri(NodeProperties.GROUP_WRITE_URI); groupWriteProp.setValue("group1"); nodeProperties.add(groupWriteProp); node.setUri(URI_PREFIX + path); return node; } private LinkNode getWritableLinkNode(String path) { LinkNode myNode = new LinkNode(); // Set parent node address at / myNode.setUri("vos://example.com!vospace" + path); // Set groupwrite property Property groups = new Property(); groups.setUri("ivo://ivoa.net/vospace/core#groupwrite"); groups.setValue("group1"); myNode.setProperties(List.of(groups)); return myNode; } }
src/test/java/it/inaf/oats/vospace/DeleteNodeServiceTest.java 0 → 100644 +147 −0 Original line number Diff line number Diff line /* * This file is part of vospace-rest * Copyright (C) 2021 Istituto Nazionale di Astrofisica * SPDX-License-Identifier: GPL-3.0-or-later */ package it.inaf.oats.vospace; import it.inaf.ia2.aa.data.User; import it.inaf.oats.vospace.exception.InternalFaultException; import it.inaf.oats.vospace.exception.NodeBusyException; import it.inaf.oats.vospace.exception.NodeNotFoundException; import it.inaf.oats.vospace.exception.PermissionDeniedException; import it.inaf.oats.vospace.persistence.DataSourceConfigSingleton; import it.inaf.oats.vospace.persistence.NodeDAO; import java.util.Optional; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; import org.junit.jupiter.api.Test; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.TestPropertySource; import org.springframework.test.annotation.DirtiesContext; @SpringBootTest @AutoConfigureMockMvc @ContextConfiguration(classes = DataSourceConfigSingleton.class) @TestPropertySource(locations = "classpath:test.properties", properties = {"vospace-authority=example.com!vospace", "file-service-url=http://file-service"}) @DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD) public class DeleteNodeServiceTest { @Autowired private DeleteNodeService deleteNodeService; @Autowired private NodeDAO nodeDao; @Test public void testPreliminaryCheckOnRoot() { assertThrows(PermissionDeniedException.class, ()->{ deleteNodeService.doPreliminaryChecks("/"); }); } @Test public void testPreliminaryNodeNotFound() { assertThrows(NodeNotFoundException.class, ()->{ deleteNodeService.doPreliminaryChecks("/nonexistent/node"); }); } @Test public void deleteBranchTest() { User user = mock(User.class); when(user.getName()).thenReturn("user3"); Optional<Long> sourceId = nodeDao.getNodeId("/test3/m1"); assertTrue(sourceId.isPresent()); Optional<Long> childId = nodeDao.getNodeId("/test3/m1/m2"); assertTrue(childId.isPresent()); // Delete deleteNodeService.deleteNode("/test3/m1", user); Optional<Long> checkSourceId = nodeDao.getNodeId("/test3/m1"); assertTrue(checkSourceId.isEmpty()); Optional<Long> checkSourceIdChild = nodeDao.getNodeId("/test3/m1/m2"); assertTrue(checkSourceIdChild.isEmpty()); } @Test public void deleteStopOnImmutableTest() { User user = mock(User.class); when(user.getName()).thenReturn("user3"); Optional<Long> sourceId = nodeDao.getNodeId("/test3/m1"); assertTrue(sourceId.isPresent()); Optional<Long> childId = nodeDao.getNodeId("/test3/m1/m2"); assertTrue(childId.isPresent()); nodeDao.setBranchImmutable(childId.get(), true); // Delete assertThrows(InternalFaultException.class, ()->{ deleteNodeService.deleteNode("/test3/m1", user);} ); Optional<Long> checkSourceId = nodeDao.getNodeId("/test3/m1"); assertTrue(checkSourceId.isPresent()); Optional<Long> checkSourceIdChild = nodeDao.getNodeId("/test3/m1/m2"); assertTrue(checkSourceIdChild.isPresent()); } @Test public void deleteStopOnBusyTest() { User user = mock(User.class); when(user.getName()).thenReturn("user3"); Optional<Long> sourceId = nodeDao.getNodeId("/test3/m1"); assertTrue(sourceId.isPresent()); Optional<Long> childId = nodeDao.getNodeId("/test3/m1/m2"); assertTrue(childId.isPresent()); nodeDao.setBranchJobId(childId.get(), "pippo"); // Delete assertThrows(NodeBusyException.class, ()->{ deleteNodeService.deleteNode("/test3/m1", user);} ); Optional<Long> checkSourceId = nodeDao.getNodeId("/test3/m1"); assertTrue(checkSourceId.isPresent()); Optional<Long> checkSourceIdChild = nodeDao.getNodeId("/test3/m1/m2"); assertTrue(checkSourceIdChild.isPresent()); } @Test public void deleteStopOnPermissionDeniedTest() { User user = mock(User.class); when(user.getName()).thenReturn("user-pippo"); Optional<Long> sourceId = nodeDao.getNodeId("/test3/m1"); assertTrue(sourceId.isPresent()); Optional<Long> childId = nodeDao.getNodeId("/test3/m1/m2"); assertTrue(childId.isPresent()); // Delete assertThrows(PermissionDeniedException.class, ()->{ deleteNodeService.deleteNode("/test3/m1", user);} ); Optional<Long> checkSourceId = nodeDao.getNodeId("/test3/m1"); assertTrue(checkSourceId.isPresent()); Optional<Long> checkSourceIdChild = nodeDao.getNodeId("/test3/m1/m2"); assertTrue(checkSourceIdChild.isPresent()); } }