Newer
Older
/*
* This file is part of vospace-file-service
* Copyright (C) 2021 Istituto Nazionale di Astrofisica
* SPDX-License-Identifier: GPL-3.0-or-later
*/
package it.inaf.ia2.transfer.controller;
import it.inaf.ia2.transfer.persistence.FileDAO;
import it.inaf.ia2.transfer.persistence.JobDAO;
import it.inaf.ia2.transfer.persistence.ListOfFilesDAO;
import java.io.File;
import java.nio.charset.StandardCharsets;
import java.nio.file.Path;
import java.util.Collections;
import java.util.Optional;
import java.util.UUID;
import net.ivoa.xml.uws.v1.ExecutionPhase;
import org.junit.jupiter.api.AfterAll;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.ArgumentMatchers.argThat;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
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.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.request.MockMultipartHttpServletRequestBuilder;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.request.RequestPostProcessor;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import org.springframework.util.FileSystemUtils;
@SpringBootTest
@AutoConfigureMockMvc
public class PutFileControllerTest {
@MockBean
private FileDAO fileDao;
@MockBean
private JobDAO jobDAO;
@MockBean
private ListOfFilesDAO listOfFilesDAO;
@Autowired
private static File temporaryDirectory;
@BeforeAll
public static void setUp() {
temporaryDirectory = Files.newTemporaryFolder();
}
@AfterAll
public static void tearDown() {
FileSystemUtils.deleteRecursively(temporaryDirectory);
}
@Test
public void putGenericFile() throws Exception {
String randomFileName = UUID.randomUUID().toString();
createBaseFileInfo(randomFileName);
MockMultipartFile fakeFile = new MockMultipartFile("file", "test.txt", "text/plain", "content".getBytes());
mockMvc.perform(putMultipart("/path/to/test.txt")
.file(fakeFile))
.andDo(print())
.andExpect(status().isOk());
File file = Path.of(getTestFilePath(randomFileName)).toFile();
assertTrue(file.exists());
assertEquals("content", Files.contentOf(file, StandardCharsets.UTF_8));
public void putGenericFileWithNameConflictExtension() throws Exception {
putGenericFileWithNameConflict("test.txt", "test-1.txt", "test-2.txt");
}
@Test
public void putGenericFileWithNameConflictNoExtension() throws Exception {
putGenericFileWithNameConflict("test", "test-1", "test-2");
}
public void putGenericFileWithNameConflict(String name1, String name2, String name3) throws Exception {
createBaseFileInfo(name1);
MockMultipartFile fakeFile = new MockMultipartFile("file", "test.txt", "text/plain", "content".getBytes());
mockMvc.perform(putMultipart("/path/to/test.txt")
.file(fakeFile))
.andDo(print())
.andExpect(status().isOk());
File file = Path.of(getTestFilePath(name1)).toFile();
assertTrue(file.exists());
assertEquals("content", Files.contentOf(file, StandardCharsets.UTF_8));
MockMultipartFile fakeFile2 = new MockMultipartFile("file", "test.txt", "text/plain", "content2".getBytes());
mockMvc.perform(putMultipart("/path/to/test.txt")
.file(fakeFile2))
.andDo(print())
.andExpect(status().isOk());
File file2 = Path.of(getTestFilePath(name2)).toFile();
assertTrue(file2.exists());
assertEquals("content2", Files.contentOf(file2, StandardCharsets.UTF_8));
MockMultipartFile fakeFile3 = new MockMultipartFile("file", "test.txt", "text/plain", "content3".getBytes());
mockMvc.perform(putMultipart("/path/to/test.txt")
.file(fakeFile3))
.andDo(print())
.andExpect(status().isOk());
File file3 = Path.of(getTestFilePath(name3)).toFile();
assertTrue(file3.exists());
assertEquals("content3", Files.contentOf(file3, StandardCharsets.UTF_8));
assertTrue(file.delete());
assertTrue(file2.delete());
}
@Test
public void putGenericFileWithJobId() throws Exception {
when(jobDAO.isJobExisting("pippo10")).thenReturn(false);
when(jobDAO.isJobExisting("pippo5")).thenReturn(true);
String randomFileName = UUID.randomUUID().toString();
createBaseFileInfo(randomFileName);
MockMultipartFile fakeFile = new MockMultipartFile("file", "test.txt", "text/plain", "content".getBytes());
// Try with invalid jobid
mockMvc.perform(putMultipart("/path/to/test.txt")
.file(fakeFile).param("jobid", "pippo10"))
.andDo(print())
.andExpect(status().is4xxClientError());
verify(jobDAO, times(1)).isJobExisting(eq("pippo10"));
// Retry with valid jobid
mockMvc.perform(putMultipart("/path/to/test.txt")
.file(fakeFile).param("jobid", "pippo5"))
.andDo(print())
.andExpect(status().is2xxSuccessful());
verify(jobDAO, times(1)).isJobExisting(eq("pippo5"));
verify(jobDAO, times(1)).updateJobPhase(eq(ExecutionPhase.COMPLETED), any());
File file = Path.of(getTestFilePath(randomFileName)).toFile();
assertTrue(file.exists());
assertEquals("content", Files.contentOf(file, StandardCharsets.UTF_8));
assertTrue(file.delete());
}
@Test
public void putListOfFiles() throws Exception {
String randomFileName = UUID.randomUUID().toString();
FileInfo fileInfo = createBaseFileInfo(randomFileName);
fileInfo.setAcceptViews(Collections.singletonList("urn:list-of-files"));
String content = "/path/to/file1\n/path/to/file2";
MockMultipartFile fakeFile = new MockMultipartFile("file", "test.txt", "text/plain", content.getBytes());
mockMvc.perform(putMultipart("/path/to/test.txt")
.file(fakeFile))
.andDo(print())
.andExpect(status().isOk());
verify(listOfFilesDAO, times(1)).createList(any(), argThat(list -> list.size() == 2));
}
private FileInfo createBaseFileInfo(String fileName) {
FileInfo fileInfo = new FileInfo();
fileInfo.setOsPath(getTestFilePath(fileName));
fileInfo.setIsPublic(false);
when(fileDao.getFileInfo(any())).thenReturn(Optional.of(fileInfo));
return fileInfo;
}
private String getTestFilePath(String fileName) {
return temporaryDirectory.toPath().resolve(fileName).toFile().getAbsolutePath();
}
private MockMultipartHttpServletRequestBuilder putMultipart(String uri) {
MockMultipartHttpServletRequestBuilder builder = MockMvcRequestBuilders.multipart(uri);
builder.with(new RequestPostProcessor() {
@Override
public MockHttpServletRequest postProcessRequest(MockHttpServletRequest request) {
request.setMethod("PUT");
return request;
}
});
return builder;
}
}