Skip to content
SetNodeControllerTest.java 10.6 KiB
Newer Older
Sonia Zorba's avatar
Sonia Zorba committed
/*
 * This file is part of vospace-rest
 * Copyright (C) 2021 Istituto Nazionale di Astrofisica
 * SPDX-License-Identifier: GPL-3.0-or-later
 */
Sara Bertocco's avatar
Sara Bertocco committed
package it.inaf.oats.vospace;

import it.inaf.oats.vospace.datamodel.NodeProperties;
import it.inaf.oats.vospace.persistence.NodeDAO;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
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.Node;
import net.ivoa.xml.vospace.v2.Property;
Sara Bertocco's avatar
Sara Bertocco committed
import org.junit.jupiter.api.Test;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
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.boot.test.mock.mockito.MockBean;
import org.springframework.http.MediaType;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.TestPropertySource;
import org.springframework.test.web.servlet.MockMvc;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

@SpringBootTest
@AutoConfigureMockMvc
@ContextConfiguration(classes = {TokenFilterConfig.class})
@TestPropertySource(properties = "spring.main.allow-bean-definition-overriding=true")
public class SetNodeControllerTest {

    private static final String URI_PREFIX = "vos://example.com!vospace";

    @MockBean
    private NodeDAO nodeDao;

    @Autowired
    private MockMvc mockMvc;

    protected static String getResourceFileContent(String fileName) throws Exception {
        try ( InputStream in = CreateNodeControllerTest.class.getClassLoader().getResourceAsStream(fileName)) {
            return new String(in.readAllBytes(), StandardCharsets.UTF_8);
        }
    }

    private ContainerNode getContainerParentNode(String path) {
        ContainerNode parentNode = new ContainerNode();
        // Set parent node address at /
        parentNode.setUri("vos://example.com!vospace" + path);
        // Set groupwrite property
        Property groups = new Property();
        groups.setUri("ivo://ivoa.net/vospace/core#groupwrite");
        groups.setValue("group1 group2");
        parentNode.setProperties(List.of(groups));
        return parentNode;
    }

    private Node getWritableDataNode(String path) {
        DataNode node = new DataNode();
        List<Property> nodeProperties = node.getProperties();
Sara Bertocco's avatar
Sara Bertocco committed
        Property groupWriteProp = new Property();
        groupWriteProp.setUri(NodeProperties.GROUP_WRITE_URI);
        groupWriteProp.setValue("group1");
        nodeProperties.add(groupWriteProp);
        node.setUri(URI_PREFIX + path);
        return node;
    }

    private Node getWritableDataNodeWithAcceptsAndProvides(String path) {
        DataNode node = new DataNode();
        List<Property> nodeProperties = node.getProperties();
Sara Bertocco's avatar
Sara Bertocco committed
        Property groupWriteProp = new Property();
        groupWriteProp.setUri(NodeProperties.GROUP_WRITE_URI);
        groupWriteProp.setValue("group1");
        Property groupReadProp = new Property();
        groupReadProp.setUri(NodeProperties.GROUP_READ_URI);
        groupReadProp.setValue("group1 group2");
        Property descriptionProp = new Property();
        descriptionProp.setUri(NodeProperties.DESCRIPTION_URI);
        descriptionProp.setValue("Modified description");
        nodeProperties.add(groupWriteProp);
        nodeProperties.add(groupReadProp);
        nodeProperties.add(descriptionProp);
        List<View> accepts = new ArrayList<>();
        accepts.add(getView("ivo://ivoa.net/vospace/core#defaultview"));
Sara Bertocco's avatar
Sara Bertocco committed
        node.setAccepts(accepts);
        List<View> provides = new ArrayList<>();
        provides.add(getView("ivo://ivoa.net/vospace/core#defaultview"));
        node.setProvides(provides);
Sara Bertocco's avatar
Sara Bertocco committed
        node.setUri(URI_PREFIX + path);
        return node;
    }

    private View getView(String uri) {
        View view = new View();
        view.setUri(uri);
        return view;
    }
Sara Bertocco's avatar
Sara Bertocco committed
    /* Test case:
       try to modify node type.
       Forbidden.
     */
    @Test
    public void testUpdateType() throws Exception {

        String requestBody = getResourceFileContent("modify-data-node-1_type.xml");

        // Create node
        when(nodeDao.listNode(eq("/")))
                .thenReturn(Optional.of(getContainerParentNode("/")));
        when(nodeDao.listNode(eq("/mydata1"))).thenReturn(Optional.of(getWritableDataNode("/mydata1")));

        mockMvc.perform(post("/nodes/mydata1")
                .header("Authorization", "Bearer user2_token")
                .content(requestBody)
                .contentType(MediaType.APPLICATION_XML)
                .accept(MediaType.APPLICATION_XML))
                .andDo(print())
                .andExpect(status().isForbidden());
    }
    
    /* Test case:
       request and payload URIs don't match
       Forbidden.
     */
    @Test
    public void testRequestPayloadURIMismatch() throws Exception {
Sara Bertocco's avatar
Sara Bertocco committed

        String requestBody = getResourceFileContent("modify-data-node-1_type.xml");

        // Create node
        when(nodeDao.listNode(eq("/")))
                .thenReturn(Optional.of(getContainerParentNode("/")));
        when(nodeDao.listNode(eq("/mydata1"))).thenReturn(Optional.of(getWritableDataNode("/mydata1")));

        mockMvc.perform(post("/nodes/mydataPippo1")
                .header("Authorization", "Bearer user2_token")
                .content(requestBody)
                .contentType(MediaType.APPLICATION_XML)
                .accept(MediaType.APPLICATION_XML))
                .andDo(print())
                .andExpect(status().isBadRequest());
    }
    
Sara Bertocco's avatar
Sara Bertocco committed
    /* Test case:
       try to add accepted views to a node without views. 
       Forbidden
     */
    @Test
    public void testModifyAccepts() throws Exception {

        String requestBody = getResourceFileContent("modify-data-node-1-views.xml");

        // Create node
        when(nodeDao.listNode(eq("/")))
                .thenReturn(Optional.of(getContainerParentNode("/")));
        when(nodeDao.listNode(eq("/mydata1"))).thenReturn(Optional.of(getWritableDataNode("/mydata1")));

        mockMvc.perform(post("/nodes/mydata1")
                .header("Authorization", "Bearer user2_token")
                .content(requestBody)
                .contentType(MediaType.APPLICATION_XML)
                .accept(MediaType.APPLICATION_XML))
                .andDo(print())
                .andExpect(status().isForbidden());
    }

    /* Test case:
       try to modify accepted and provides views and protocols of a node already having. 
       Forbidden
     */
    @Test
    public void testModifyAcceptsAndProvides() throws Exception {

        String requestBody = getResourceFileContent("modify-data-node-having-views.xml");
Sara Bertocco's avatar
Sara Bertocco committed

        // Create node
        when(nodeDao.listNode(eq("/")))
                .thenReturn(Optional.of(getContainerParentNode("/")));
        when(nodeDao.listNode(eq("/mydata1"))).thenReturn(Optional.of(getWritableDataNodeWithAcceptsAndProvides("/mydata1")));

        mockMvc.perform(post("/nodes/mydata1")
                .header("Authorization", "Bearer user2_token")
                .content(requestBody)
                .contentType(MediaType.APPLICATION_XML)
                .accept(MediaType.APPLICATION_XML))
                .andDo(print())
                .andExpect(status().isForbidden());
    }

    /* Test case:
       try to modify node having accepted and provides views and protocols  
       Forbidden
     */
    @Test
    public void testModifyNodeHavingAcceptsAndProvides() throws Exception {

        String requestBody = getResourceFileContent("modify-data-node-having-views.xml");
Sara Bertocco's avatar
Sara Bertocco committed

        // Create node
        when(nodeDao.listNode(eq("/")))
                .thenReturn(Optional.of(getContainerParentNode("/")));
        when(nodeDao.listNode(eq("/mydata1"))).thenReturn(Optional.of(getWritableDataNodeWithAcceptsAndProvides("/mydata1")));

        mockMvc.perform(post("/nodes/mydata1")
                .header("Authorization", "Bearer user2_token")
                .content(requestBody)
                .contentType(MediaType.APPLICATION_XML)
                .accept(MediaType.APPLICATION_XML))
                .andDo(print())
                .andExpect(status().isForbidden());
    }

    /* Test case:
       try to modify node not modifying accepted and provides views and protocols  
       Expect OK
     */
    @Test
    public void testModifyNodeLeavingAcceptsAndProvides() throws Exception {
        String requestBody = getResourceFileContent("modify-data-node-description-leaving-views.xml");
Sara Bertocco's avatar
Sara Bertocco committed

        Node node = getWritableDataNodeWithAcceptsAndProvides("/mydata1");
Sara Bertocco's avatar
Sara Bertocco committed
        // Create node
        when(nodeDao.listNode(eq("/")))
                .thenReturn(Optional.of(getContainerParentNode("/")));
        when(nodeDao.listNode(eq("/mydata1"))).thenReturn(Optional.of(node));
        when(nodeDao.setNode(any(), eq(false))).thenReturn(node);
Sara Bertocco's avatar
Sara Bertocco committed

        mockMvc.perform(post("/nodes/mydata1")
                .header("Authorization", "Bearer user2_token")
                .content(requestBody)
                .contentType(MediaType.APPLICATION_XML)
                .accept(MediaType.APPLICATION_XML))
                .andDo(print())
                .andExpect(status().isOk());
    }

    @Test
    public void testSetNodeRecursive() throws Exception {
        String requestBody = getResourceFileContent("modify-container-node.xml");

        ContainerNode node = new ContainerNode();
        node.setUri(URI_PREFIX + "/myfolder1");

        Property groupWriteProp = new Property();
        groupWriteProp.setUri(NodeProperties.GROUP_WRITE_URI);
        groupWriteProp.setValue("group1");
        node.getProperties().add(groupWriteProp);

        when(nodeDao.listNode(eq("/"))).thenReturn(Optional.of(getContainerParentNode("/")));
        when(nodeDao.listNode(eq("/myfolder1"))).thenReturn(Optional.of(node));
        when(nodeDao.setNode(any(), eq(true))).thenReturn(node);

        mockMvc.perform(post("/nodes/myfolder1")
                .param("recursive", "true")
                .header("Authorization", "Bearer user2_token")
                .content(requestBody)
                .contentType(MediaType.APPLICATION_XML)
                .accept(MediaType.APPLICATION_XML))
                .andDo(print())
                .andExpect(status().isOk());
    }
Sara Bertocco's avatar
Sara Bertocco committed
}