Loading src/main/java/it/inaf/ia2/transfer/auth/GmsClient.java +2 −2 Original line number Diff line number Diff line Loading @@ -31,8 +31,8 @@ public class GmsClient { private final RestTemplate restTemplate; @Autowired public GmsClient() { restTemplate = new RestTemplate(); public GmsClient(RestTemplate restTemplate) { this.restTemplate = restTemplate; } @Cacheable("gms_cache") Loading src/test/java/it/inaf/ia2/transfer/auth/GmsClientTest.java 0 → 100644 +52 −0 Original line number Diff line number Diff line /* * 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.auth; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; import org.mockito.InjectMocks; import org.mockito.Mock; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; import org.mockito.junit.jupiter.MockitoExtension; import org.springframework.http.HttpEntity; import org.springframework.http.HttpMethod; import org.springframework.http.ResponseEntity; import org.springframework.web.client.RestTemplate; @ExtendWith(MockitoExtension.class) public class GmsClientTest { @Mock private RestTemplate restTemplate; @InjectMocks private GmsClient gmsClient; @Test public void testIsMemberOf() { mockGmsResponse("group1\n"); assertTrue(gmsClient.isMemberOf("<token>", "group1")); } @Test public void testIsNotMemberOf() { mockGmsResponse(""); assertFalse(gmsClient.isMemberOf("<token>", "group1")); } private void mockGmsResponse(String body) { ResponseEntity<String> mockedResponse = mock(ResponseEntity.class); when(mockedResponse.getBody()).thenReturn(body); when(restTemplate.exchange(any(String.class), eq(HttpMethod.GET), any(HttpEntity.class), eq(String.class))).thenReturn(mockedResponse); } } src/test/java/it/inaf/ia2/transfer/controller/GetFileControllerTest.java +84 −17 Original line number Diff line number Diff line Loading @@ -8,18 +8,23 @@ package it.inaf.ia2.transfer.controller; import it.inaf.ia2.transfer.persistence.model.FileInfo; import it.inaf.ia2.aa.jwt.TokenParser; import it.inaf.ia2.transfer.auth.GmsClient; import it.inaf.ia2.transfer.exception.JobException; import it.inaf.ia2.transfer.persistence.FileDAO; import it.inaf.ia2.transfer.persistence.JobDAO; import java.io.File; import java.util.Collections; import java.util.HashMap; import java.util.Map; import java.util.Optional; import net.ivoa.xml.uws.v1.ExecutionPhase; import org.assertj.core.util.Files; import org.junit.jupiter.api.AfterEach; import static org.junit.jupiter.api.Assertions.assertTrue; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; 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; Loading @@ -44,6 +49,9 @@ public class GetFileControllerTest { @MockBean private FileDAO fileDao; @MockBean private JobDAO jobDAO; @Autowired private MockMvc mockMvc; Loading Loading @@ -135,54 +143,113 @@ public class GetFileControllerTest { verify(gmsClient).isMemberOf(eq("<token>"), eq("group1")); } private void prepareMocksForPrivateFile() { @Test public void getPrivateFileByOwnerId() throws Exception { Map<String, Object> claims = new HashMap<>(); claims.put("sub", "123"); when(tokenParser.getClaims(any())).thenReturn(claims); when(gmsClient.isMemberOf(any(), any())).thenReturn(true); FileInfo fileInfo = new FileInfo(); fileInfo.setOsPath(tempFile.getAbsolutePath()); fileInfo.setVirtualPath("/path/to/myfile"); fileInfo.setGroupRead(Collections.singletonList("group1")); fileInfo.setOsPath(tempFile.getAbsolutePath()); fileInfo.setOwnerId("123"); when(fileDao.getFileInfo(any())).thenReturn(Optional.of(fileInfo)); mockMvc.perform(get("/path/to/myfile") .header("Authorization", "Bearer: <token>")) .andDo(print()) .andExpect(status().isOk()); } @Test public void getPrivateFileByOwnerId() throws Exception { public void testPrivateFileNullToken() throws Exception { Map<String, Object> claims = new HashMap<>(); claims.put("sub", "123"); FileInfo fileInfo = new FileInfo(); fileInfo.setVirtualPath("/path/to/myfile"); when(tokenParser.getClaims(any())).thenReturn(claims); when(fileDao.getFileInfo(any())).thenReturn(Optional.of(fileInfo)); mockMvc.perform(get("/path/to/myfile")) .andDo(print()) .andExpect(status().isForbidden()); } @Test public void testGetFileWithJobId() throws Exception { FileInfo fileInfo = new FileInfo(); fileInfo.setVirtualPath("/path/to/myfile"); fileInfo.setOsPath(tempFile.getAbsolutePath()); fileInfo.setOwnerId("123"); fileInfo.setVirtualPath("/path/to/myfile"); fileInfo.setPublic(true); when(fileDao.getFileInfo(any())).thenReturn(Optional.of(fileInfo)); when(jobDAO.isJobExisting(eq("abcdef"))).thenReturn(true); mockMvc.perform(get("/path/to/myfile") .header("Authorization", "Bearer: <token>")) .param("jobId", "abcdef")) .andDo(print()) .andExpect(status().isOk()); verify(jobDAO, times(1)).updateJobPhase(eq(ExecutionPhase.COMPLETED), eq("abcdef")); } @Test public void testPrivateFileNullToken() throws Exception { public void testGetFileWithInvalidJobId() throws Exception { mockMvc.perform(get("/path/to/myfile") .param("jobId", "abcdef")) .andDo(print()) .andExpect(status().isBadRequest()); } @Test public void testGetFileNotReadable() throws Exception { File unreadableFile = Files.newTemporaryFile(); try { unreadableFile.setReadable(false); FileInfo fileInfo = new FileInfo(); fileInfo.setOsPath(unreadableFile.getAbsolutePath()); fileInfo.setVirtualPath("/path/to/myfile"); fileInfo.setPublic(true); when(fileDao.getFileInfo(any())).thenReturn(Optional.of(fileInfo)); mockMvc.perform(get("/path/to/myfile")) Exception ex = mockMvc.perform(get("/path/to/myfile")) .andDo(print()) .andExpect(status().isForbidden()); .andReturn().getResolvedException(); assertTrue(ex instanceof JobException); JobException jobEx = (JobException) ex; assertTrue(jobEx.getErrorDetail().contains("not readable"), jobEx.getErrorDetail()); } catch (Throwable t) { throw t; } finally { assertTrue(unreadableFile.delete()); } } private void prepareMocksForPrivateFile() { Map<String, Object> claims = new HashMap<>(); claims.put("sub", "123"); when(tokenParser.getClaims(any())).thenReturn(claims); when(gmsClient.isMemberOf(any(), any())).thenReturn(true); FileInfo fileInfo = new FileInfo(); fileInfo.setOsPath(tempFile.getAbsolutePath()); fileInfo.setVirtualPath("/path/to/myfile"); fileInfo.setGroupRead(Collections.singletonList("group1")); when(fileDao.getFileInfo(any())).thenReturn(Optional.of(fileInfo)); } } src/test/java/it/inaf/ia2/transfer/controller/PutFileControllerTest.java +57 −2 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ 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.Mockito.spy; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; Loading @@ -32,9 +33,11 @@ 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.MockHttpServletRequestBuilder; 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.request.MockMvcRequestBuilders.put; 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; Loading Loading @@ -94,7 +97,7 @@ public class PutFileControllerTest { putGenericFileWithNameConflict("test", "test-1", "test-2"); } public void putGenericFileWithNameConflict(String name1, String name2, String name3) throws Exception { private void putGenericFileWithNameConflict(String name1, String name2, String name3) throws Exception { createBaseFileInfo(name1); Loading Loading @@ -172,6 +175,58 @@ public class PutFileControllerTest { assertTrue(file.delete()); } @Test public void testPutFileWithoutNodeInDatabase() throws Exception { MockMultipartFile fakeFile = new MockMultipartFile("file", "foo.txt", "text/plain", "content".getBytes()); mockMvc.perform(putMultipart("/path/to/foo.txt") .file(fakeFile)) .andDo(print()) .andExpect(status().isNotFound()); } @Test public void testPutWithInputStream() throws Exception { createBaseFileInfo(); mockMvc.perform(put("/path/to/stream.txt")) .andDo(print()) .andExpect(status().isOk()); } @Test public void testJobError() throws Exception { createBaseFileInfo(); when(jobDAO.isJobExisting(eq("abcdef"))).thenReturn(true); MockHttpServletRequestBuilder errorBuilder = put("/path/to/error"); errorBuilder.with(new RequestPostProcessor() { @Override public MockHttpServletRequest postProcessRequest(MockHttpServletRequest request) { MockHttpServletRequest spyRequest = spy(request); when(spyRequest.getInputStream()).thenThrow(new RuntimeException()); return spyRequest; } }); try { mockMvc.perform(errorBuilder .param("jobId", "abcdef")); } catch (Exception ex) { } verify(jobDAO, times(1)).setJobError(eq("abcdef"), any()); } private FileInfo createBaseFileInfo() { String randomFileName = UUID.randomUUID().toString(); return createBaseFileInfo(randomFileName); } private FileInfo createBaseFileInfo(String fileName) { FileInfo fileInfo = new FileInfo(); fileInfo.setOsPath(getTestFilePath(fileName)); Loading @@ -183,7 +238,7 @@ public class PutFileControllerTest { } private String getTestFilePath(String fileName) { return temporaryDirectory.toPath().resolve(fileName).toFile().getAbsolutePath(); return temporaryDirectory.toPath().resolve("subdir").resolve(fileName).toFile().getAbsolutePath(); } private MockMultipartHttpServletRequestBuilder putMultipart(String uri) { Loading Loading
src/main/java/it/inaf/ia2/transfer/auth/GmsClient.java +2 −2 Original line number Diff line number Diff line Loading @@ -31,8 +31,8 @@ public class GmsClient { private final RestTemplate restTemplate; @Autowired public GmsClient() { restTemplate = new RestTemplate(); public GmsClient(RestTemplate restTemplate) { this.restTemplate = restTemplate; } @Cacheable("gms_cache") Loading
src/test/java/it/inaf/ia2/transfer/auth/GmsClientTest.java 0 → 100644 +52 −0 Original line number Diff line number Diff line /* * 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.auth; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; import org.mockito.InjectMocks; import org.mockito.Mock; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; import org.mockito.junit.jupiter.MockitoExtension; import org.springframework.http.HttpEntity; import org.springframework.http.HttpMethod; import org.springframework.http.ResponseEntity; import org.springframework.web.client.RestTemplate; @ExtendWith(MockitoExtension.class) public class GmsClientTest { @Mock private RestTemplate restTemplate; @InjectMocks private GmsClient gmsClient; @Test public void testIsMemberOf() { mockGmsResponse("group1\n"); assertTrue(gmsClient.isMemberOf("<token>", "group1")); } @Test public void testIsNotMemberOf() { mockGmsResponse(""); assertFalse(gmsClient.isMemberOf("<token>", "group1")); } private void mockGmsResponse(String body) { ResponseEntity<String> mockedResponse = mock(ResponseEntity.class); when(mockedResponse.getBody()).thenReturn(body); when(restTemplate.exchange(any(String.class), eq(HttpMethod.GET), any(HttpEntity.class), eq(String.class))).thenReturn(mockedResponse); } }
src/test/java/it/inaf/ia2/transfer/controller/GetFileControllerTest.java +84 −17 Original line number Diff line number Diff line Loading @@ -8,18 +8,23 @@ package it.inaf.ia2.transfer.controller; import it.inaf.ia2.transfer.persistence.model.FileInfo; import it.inaf.ia2.aa.jwt.TokenParser; import it.inaf.ia2.transfer.auth.GmsClient; import it.inaf.ia2.transfer.exception.JobException; import it.inaf.ia2.transfer.persistence.FileDAO; import it.inaf.ia2.transfer.persistence.JobDAO; import java.io.File; import java.util.Collections; import java.util.HashMap; import java.util.Map; import java.util.Optional; import net.ivoa.xml.uws.v1.ExecutionPhase; import org.assertj.core.util.Files; import org.junit.jupiter.api.AfterEach; import static org.junit.jupiter.api.Assertions.assertTrue; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; 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; Loading @@ -44,6 +49,9 @@ public class GetFileControllerTest { @MockBean private FileDAO fileDao; @MockBean private JobDAO jobDAO; @Autowired private MockMvc mockMvc; Loading Loading @@ -135,54 +143,113 @@ public class GetFileControllerTest { verify(gmsClient).isMemberOf(eq("<token>"), eq("group1")); } private void prepareMocksForPrivateFile() { @Test public void getPrivateFileByOwnerId() throws Exception { Map<String, Object> claims = new HashMap<>(); claims.put("sub", "123"); when(tokenParser.getClaims(any())).thenReturn(claims); when(gmsClient.isMemberOf(any(), any())).thenReturn(true); FileInfo fileInfo = new FileInfo(); fileInfo.setOsPath(tempFile.getAbsolutePath()); fileInfo.setVirtualPath("/path/to/myfile"); fileInfo.setGroupRead(Collections.singletonList("group1")); fileInfo.setOsPath(tempFile.getAbsolutePath()); fileInfo.setOwnerId("123"); when(fileDao.getFileInfo(any())).thenReturn(Optional.of(fileInfo)); mockMvc.perform(get("/path/to/myfile") .header("Authorization", "Bearer: <token>")) .andDo(print()) .andExpect(status().isOk()); } @Test public void getPrivateFileByOwnerId() throws Exception { public void testPrivateFileNullToken() throws Exception { Map<String, Object> claims = new HashMap<>(); claims.put("sub", "123"); FileInfo fileInfo = new FileInfo(); fileInfo.setVirtualPath("/path/to/myfile"); when(tokenParser.getClaims(any())).thenReturn(claims); when(fileDao.getFileInfo(any())).thenReturn(Optional.of(fileInfo)); mockMvc.perform(get("/path/to/myfile")) .andDo(print()) .andExpect(status().isForbidden()); } @Test public void testGetFileWithJobId() throws Exception { FileInfo fileInfo = new FileInfo(); fileInfo.setVirtualPath("/path/to/myfile"); fileInfo.setOsPath(tempFile.getAbsolutePath()); fileInfo.setOwnerId("123"); fileInfo.setVirtualPath("/path/to/myfile"); fileInfo.setPublic(true); when(fileDao.getFileInfo(any())).thenReturn(Optional.of(fileInfo)); when(jobDAO.isJobExisting(eq("abcdef"))).thenReturn(true); mockMvc.perform(get("/path/to/myfile") .header("Authorization", "Bearer: <token>")) .param("jobId", "abcdef")) .andDo(print()) .andExpect(status().isOk()); verify(jobDAO, times(1)).updateJobPhase(eq(ExecutionPhase.COMPLETED), eq("abcdef")); } @Test public void testPrivateFileNullToken() throws Exception { public void testGetFileWithInvalidJobId() throws Exception { mockMvc.perform(get("/path/to/myfile") .param("jobId", "abcdef")) .andDo(print()) .andExpect(status().isBadRequest()); } @Test public void testGetFileNotReadable() throws Exception { File unreadableFile = Files.newTemporaryFile(); try { unreadableFile.setReadable(false); FileInfo fileInfo = new FileInfo(); fileInfo.setOsPath(unreadableFile.getAbsolutePath()); fileInfo.setVirtualPath("/path/to/myfile"); fileInfo.setPublic(true); when(fileDao.getFileInfo(any())).thenReturn(Optional.of(fileInfo)); mockMvc.perform(get("/path/to/myfile")) Exception ex = mockMvc.perform(get("/path/to/myfile")) .andDo(print()) .andExpect(status().isForbidden()); .andReturn().getResolvedException(); assertTrue(ex instanceof JobException); JobException jobEx = (JobException) ex; assertTrue(jobEx.getErrorDetail().contains("not readable"), jobEx.getErrorDetail()); } catch (Throwable t) { throw t; } finally { assertTrue(unreadableFile.delete()); } } private void prepareMocksForPrivateFile() { Map<String, Object> claims = new HashMap<>(); claims.put("sub", "123"); when(tokenParser.getClaims(any())).thenReturn(claims); when(gmsClient.isMemberOf(any(), any())).thenReturn(true); FileInfo fileInfo = new FileInfo(); fileInfo.setOsPath(tempFile.getAbsolutePath()); fileInfo.setVirtualPath("/path/to/myfile"); fileInfo.setGroupRead(Collections.singletonList("group1")); when(fileDao.getFileInfo(any())).thenReturn(Optional.of(fileInfo)); } }
src/test/java/it/inaf/ia2/transfer/controller/PutFileControllerTest.java +57 −2 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ 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.Mockito.spy; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; Loading @@ -32,9 +33,11 @@ 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.MockHttpServletRequestBuilder; 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.request.MockMvcRequestBuilders.put; 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; Loading Loading @@ -94,7 +97,7 @@ public class PutFileControllerTest { putGenericFileWithNameConflict("test", "test-1", "test-2"); } public void putGenericFileWithNameConflict(String name1, String name2, String name3) throws Exception { private void putGenericFileWithNameConflict(String name1, String name2, String name3) throws Exception { createBaseFileInfo(name1); Loading Loading @@ -172,6 +175,58 @@ public class PutFileControllerTest { assertTrue(file.delete()); } @Test public void testPutFileWithoutNodeInDatabase() throws Exception { MockMultipartFile fakeFile = new MockMultipartFile("file", "foo.txt", "text/plain", "content".getBytes()); mockMvc.perform(putMultipart("/path/to/foo.txt") .file(fakeFile)) .andDo(print()) .andExpect(status().isNotFound()); } @Test public void testPutWithInputStream() throws Exception { createBaseFileInfo(); mockMvc.perform(put("/path/to/stream.txt")) .andDo(print()) .andExpect(status().isOk()); } @Test public void testJobError() throws Exception { createBaseFileInfo(); when(jobDAO.isJobExisting(eq("abcdef"))).thenReturn(true); MockHttpServletRequestBuilder errorBuilder = put("/path/to/error"); errorBuilder.with(new RequestPostProcessor() { @Override public MockHttpServletRequest postProcessRequest(MockHttpServletRequest request) { MockHttpServletRequest spyRequest = spy(request); when(spyRequest.getInputStream()).thenThrow(new RuntimeException()); return spyRequest; } }); try { mockMvc.perform(errorBuilder .param("jobId", "abcdef")); } catch (Exception ex) { } verify(jobDAO, times(1)).setJobError(eq("abcdef"), any()); } private FileInfo createBaseFileInfo() { String randomFileName = UUID.randomUUID().toString(); return createBaseFileInfo(randomFileName); } private FileInfo createBaseFileInfo(String fileName) { FileInfo fileInfo = new FileInfo(); fileInfo.setOsPath(getTestFilePath(fileName)); Loading @@ -183,7 +238,7 @@ public class PutFileControllerTest { } private String getTestFilePath(String fileName) { return temporaryDirectory.toPath().resolve(fileName).toFile().getAbsolutePath(); return temporaryDirectory.toPath().resolve("subdir").resolve(fileName).toFile().getAbsolutePath(); } private MockMultipartHttpServletRequestBuilder putMultipart(String uri) { Loading