From 8cc2dcddf77406f0a092279a8b62fe452a8e0693 Mon Sep 17 00:00:00 2001 From: Vitor Hideyoshi Date: Tue, 24 Oct 2023 01:01:37 -0300 Subject: [PATCH 1/3] Implements Better Error Handling in Micro Services --- .../security/service/AuthServiceImpl.java | 20 +-- .../base/user/api/UserController.java | 3 +- .../service/StorageService.java | 147 +++++++++--------- 3 files changed, 85 insertions(+), 85 deletions(-) diff --git a/src/main/java/com/hideyoshi/backendportfolio/base/security/service/AuthServiceImpl.java b/src/main/java/com/hideyoshi/backendportfolio/base/security/service/AuthServiceImpl.java index 9b8cd41..101fc74 100644 --- a/src/main/java/com/hideyoshi/backendportfolio/base/security/service/AuthServiceImpl.java +++ b/src/main/java/com/hideyoshi/backendportfolio/base/security/service/AuthServiceImpl.java @@ -155,9 +155,10 @@ public class AuthServiceImpl implements AuthService { user.setProvider(Provider.LOCAL); UserDTO authenticatedUser = this.userService.saveUser(user); - authenticatedUser.setProfilePictureUrl( - this.storageService.getFileUrl(authenticatedUser.getUsername(), "profile") - .getPresignedUrl() + + var profilePicture = this.storageService.getFileUrl(authenticatedUser.getUsername(), "profile"); + profilePicture.ifPresent( + storageServiceDownloadResponse -> authenticatedUser.setProfilePictureUrl(storageServiceDownloadResponse.getPresignedUrl()) ); return this.generateUserWithTokens( @@ -169,9 +170,9 @@ public class AuthServiceImpl implements AuthService { @Override public void loginUser(HttpServletRequest request, HttpServletResponse response, @Valid UserDTO user) throws IOException { - user.setProfilePictureUrl( - this.storageService.getFileUrl(user.getUsername(), "profile") - .getPresignedUrl() + var profilePicture = this.storageService.getFileUrl(user.getUsername(), "profile"); + profilePicture.ifPresent( + storageServiceDownloadResponse -> user.setProfilePictureUrl(storageServiceDownloadResponse.getPresignedUrl()) ); AuthDTO authObject = this.generateUserWithTokens( @@ -202,9 +203,10 @@ public class AuthServiceImpl implements AuthService { DecodedJWT decodedJWT = verifier.verify(refreshToken); UserDTO user = this.userService.getUser(decodedJWT.getSubject()); - user.setProfilePictureUrl( - this.storageService.getFileUrl(user.getUsername(), "profile") - .getPresignedUrl() + + var profilePicture = this.storageService.getFileUrl(user.getUsername(), "profile"); + profilePicture.ifPresent( + storageServiceDownloadResponse -> user.setProfilePictureUrl(storageServiceDownloadResponse.getPresignedUrl()) ); HttpSession httpSession = request.getSession(); diff --git a/src/main/java/com/hideyoshi/backendportfolio/base/user/api/UserController.java b/src/main/java/com/hideyoshi/backendportfolio/base/user/api/UserController.java index 7394d64..1c88292 100644 --- a/src/main/java/com/hideyoshi/backendportfolio/base/user/api/UserController.java +++ b/src/main/java/com/hideyoshi/backendportfolio/base/user/api/UserController.java @@ -8,6 +8,7 @@ import com.hideyoshi.backendportfolio.base.user.service.UserService; import com.hideyoshi.backendportfolio.microservice.storageService.enums.FileTypeEnum; import com.hideyoshi.backendportfolio.microservice.storageService.model.StorageServiceUploadResponse; import com.hideyoshi.backendportfolio.microservice.storageService.service.StorageService; +import com.hideyoshi.backendportfolio.util.exception.BadRequestException; import com.hideyoshi.backendportfolio.util.guard.UserResourceGuard; import com.hideyoshi.backendportfolio.util.guard.UserResourceGuardEnum; import lombok.RequiredArgsConstructor; @@ -95,7 +96,7 @@ public class UserController { user.getUsername(), "profile", fileType - ); + ).orElseThrow(() -> new BadRequestException("File not found")); } @DeleteMapping("/profile-picture") diff --git a/src/main/java/com/hideyoshi/backendportfolio/microservice/storageService/service/StorageService.java b/src/main/java/com/hideyoshi/backendportfolio/microservice/storageService/service/StorageService.java index fbfa10c..6aee545 100644 --- a/src/main/java/com/hideyoshi/backendportfolio/microservice/storageService/service/StorageService.java +++ b/src/main/java/com/hideyoshi/backendportfolio/microservice/storageService/service/StorageService.java @@ -1,6 +1,7 @@ package com.hideyoshi.backendportfolio.microservice.storageService.service; import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonMappingException; import com.fasterxml.jackson.databind.ObjectMapper; import com.hideyoshi.backendportfolio.microservice.storageService.config.StorageServiceConfig; import com.hideyoshi.backendportfolio.microservice.storageService.enums.FileTypeEnum; @@ -24,6 +25,7 @@ import java.io.UnsupportedEncodingException; import java.net.URI; import java.net.URISyntaxException; import java.util.HashMap; +import java.util.Optional; @Log4j2 @Service @@ -40,49 +42,28 @@ public class StorageService { private final String PARAMETER_FILE_TYPE = "file_type"; - private final String PARAMETER_KEY_STRING = "string_url"; - - public StorageServiceUploadResponse getNewFileUrl(String username, String filePostfix, FileTypeEnum fileTypeEnum) { + public Optional getNewFileUrl(String username, String filePostfix, FileTypeEnum fileTypeEnum) { HashMap values = new HashMap<>() {{ put(PARAMETER_USERNAME, username); put(PARAMETER_FILE_POSTFIX, filePostfix); put(PARAMETER_FILE_TYPE, fileTypeEnum.getFileExtension()); }}; - String requestBody = null; + URI uri = URI.create(storageServiceConfig.getFileServicePath() + "/file"); + String requestBody = this.writeToRequestBody(values); + + StorageServiceUploadResponse uploadResponse = null; try { - requestBody = objectMapper - .writeValueAsString(values); - } catch (JsonProcessingException e) { - throw new RuntimeException(e); - } - - HttpPost request = new HttpPost(URI.create(storageServiceConfig.getFileServicePath() + "/file")); - request.setHeader("Content-Type", "application/json"); - - try { - request.setEntity(new ByteArrayEntity(requestBody.getBytes("UTF-8"))); - } catch (UnsupportedEncodingException e) { - throw new RuntimeException(e); - } - - CloseableHttpClient httpClient = HttpClientBuilder.create() - .setRedirectStrategy(new LaxRedirectStrategy()).build(); - - try { - return httpClient.execute( - request, - response -> { - String responseString = EntityUtils.toString(response.getEntity(), "UTF-8"); - return objectMapper.readValue(responseString, StorageServiceUploadResponse.class); - } - ); + var response = this.postRequest(uri, requestBody); + uploadResponse = objectMapper.readValue(response, StorageServiceUploadResponse.class); } catch (IOException e) { - throw new RuntimeException(e); + log.warn("File not found: " + username + "/" + filePostfix); } + + return Optional.ofNullable(uploadResponse); } - public StorageServiceDownloadResponse getFileUrl(String username, String filePostfix) { + public Optional getFileUrl(String username, String filePostfix) { URI uri = null; try { uri = new URIBuilder(storageServiceConfig.getFileServicePath() + "/file") @@ -90,26 +71,20 @@ public class StorageService { .addParameter(PARAMETER_FILE_POSTFIX, filePostfix) .build(); } catch (URISyntaxException e) { - throw new RuntimeException(e); + log.warn("Invalid File: " + username + "/" + filePostfix); + return Optional.empty(); } - HttpGet request = new HttpGet(uri); - request.setHeader("Content-Type", "application/json"); - - CloseableHttpClient httpClient = HttpClientBuilder.create() - .setRedirectStrategy(new LaxRedirectStrategy()).build(); + StorageServiceDownloadResponse downloadResponse = null; try { - return httpClient.execute( - request, - response -> { - String responseString = EntityUtils.toString(response.getEntity(), "UTF-8"); - return objectMapper.readValue(responseString, StorageServiceDownloadResponse.class); - } - ); + var responseString = this.getRequest(uri); + downloadResponse = objectMapper.readValue(responseString, StorageServiceDownloadResponse.class); } catch (IOException e) { - throw new RuntimeException(e); + log.warn("File not found: " + username + "/" + filePostfix); } + + return Optional.ofNullable(downloadResponse); } public void deleteFile(String username, String filePostfix) { @@ -120,24 +95,13 @@ public class StorageService { .addParameter(PARAMETER_FILE_POSTFIX, filePostfix) .build(); } catch (URISyntaxException e) { - throw new RuntimeException(e); + log.warn("File not found: " + username + "/" + filePostfix); } - HttpDelete request = new HttpDelete(uri); - request.setHeader("Content-Type", "application/json"); - - CloseableHttpClient httpClient = HttpClientBuilder.create() - .setRedirectStrategy(new LaxRedirectStrategy()).build(); - try { - httpClient.execute( - request, - response -> { - return null; - } - ); + this.deleteRequest(uri); } catch (IOException e) { - throw new RuntimeException(e); + log.warn("File not found: " + username + "/" + filePostfix); } } @@ -147,17 +111,31 @@ public class StorageService { put(PARAMETER_FILE_POSTFIX, filePostfix); }}; - ObjectMapper objectMapper = new ObjectMapper(); + URI uri = URI.create(storageServiceConfig.getFileServicePath() + "/file/process"); + String requestBody = this.writeToRequestBody(values); - String requestBody = null; try { - requestBody = objectMapper - .writeValueAsString(values); - } catch (JsonProcessingException e) { - throw new RuntimeException(e); + this.postRequest(uri, requestBody); + } catch (IOException e) { + log.warn("File not found: " + username + "/" + filePostfix); } + } - HttpPost request = new HttpPost(URI.create(storageServiceConfig.getFileServicePath() + "/file/process")); + private String getRequest(URI requestURI) throws IOException { + HttpGet request = new HttpGet(requestURI); + request.setHeader("Content-Type", "application/json"); + + CloseableHttpClient httpClient = HttpClientBuilder.create() + .setRedirectStrategy(new LaxRedirectStrategy()).build(); + + return httpClient.execute( + request, + response -> EntityUtils.toString(response.getEntity(), "UTF-8") + ); + } + + private String postRequest(URI requestURI, String requestBody) throws IOException { + HttpPost request = new HttpPost(requestURI); request.setHeader("Content-Type", "application/json"); try { @@ -169,17 +147,36 @@ public class StorageService { CloseableHttpClient httpClient = HttpClientBuilder.create() .setRedirectStrategy(new LaxRedirectStrategy()).build(); + return httpClient.execute( + request, + response -> EntityUtils.toString(response.getEntity(), "UTF-8") + ); + } + + private void deleteRequest(URI requestURI) throws IOException { + HttpDelete request = new HttpDelete(requestURI); + request.setHeader("Content-Type", "application/json"); + + CloseableHttpClient httpClient = HttpClientBuilder.create() + .setRedirectStrategy(new LaxRedirectStrategy()).build(); + + httpClient.execute( + request, + response -> { + return null; + } + ); + } + + private String writeToRequestBody(HashMap values) { + String requestBody = null; try { - httpClient.execute( - request, - response -> { - String responseString = EntityUtils.toString(response.getEntity(), "UTF-8"); - return objectMapper.readValue(responseString, StorageServiceUploadResponse.class); - } - ); - } catch (IOException e) { + requestBody = objectMapper + .writeValueAsString(values); + } catch (JsonProcessingException e) { throw new RuntimeException(e); } + return requestBody; } } From 686c800a95bbf75cc34b6fdbfd80cb59ad834322 Mon Sep 17 00:00:00 2001 From: Vitor Hideyoshi Date: Tue, 24 Oct 2023 01:02:15 -0300 Subject: [PATCH 2/3] Fixes Minor Edge Cases and Improves UserService Testing --- .../base/user/service/UserServiceImpl.java | 42 ++++++-- .../user/service/UserServiceImplTest.java | 101 ++++++++++++++++-- 2 files changed, 127 insertions(+), 16 deletions(-) diff --git a/src/main/java/com/hideyoshi/backendportfolio/base/user/service/UserServiceImpl.java b/src/main/java/com/hideyoshi/backendportfolio/base/user/service/UserServiceImpl.java index 9573a1c..925fb3a 100644 --- a/src/main/java/com/hideyoshi/backendportfolio/base/user/service/UserServiceImpl.java +++ b/src/main/java/com/hideyoshi/backendportfolio/base/user/service/UserServiceImpl.java @@ -1,5 +1,6 @@ package com.hideyoshi.backendportfolio.base.user.service; +import com.hideyoshi.backendportfolio.base.user.entity.Provider; import com.hideyoshi.backendportfolio.base.user.entity.Role; import com.hideyoshi.backendportfolio.base.user.entity.User; import com.hideyoshi.backendportfolio.base.user.model.UserDTO; @@ -34,19 +35,13 @@ public class UserServiceImpl implements UserService { throw new BadRequestException(String.format("User %s already exists. Try another UserName.", userOnDB.getUsername())); }); + user.setPassword(this.validatePassword(user)); + + user.setRoles(this.validateRoles(user.getRoles())); + log.info(String.format("Saving to the database user of name: %s", user.getName())); - - if (Objects.nonNull(user.getPassword())) { - user.setPassword(passwordEncoder.encode(user.getPassword())); - } else { - user.setPassword(""); - } UserDTO userSaved = new UserDTO(userRepo.save(user.toEntity())); - if (!userSaved.getRoles().contains(Role.USER)) { - userSaved.getRoles().add(Role.USER); - } - return userSaved; } @@ -147,4 +142,31 @@ public class UserServiceImpl implements UserService { public UserDetails loadUserByUsername(String username) { return this.getUser(username); } + + private String validatePassword(UserDTO user) { + String password = null; + if (Objects.nonNull(user.getPassword())) { + password = passwordEncoder.encode(user.getPassword()); + } else if (!user.getProvider().equals(Provider.LOCAL)) { + password = ""; + } + + if (Objects.isNull(password)) { + throw new BadRequestException("Password cannot be empty."); + } + + return password; + } + + private List validateRoles(List roles) { + if (Objects.isNull(roles)) { + roles = List.of(Role.USER); + } + + if (!roles.contains(Role.USER)) { + roles.add(Role.USER); + } + + return roles; + } } diff --git a/src/test/java/com/hideyoshi/backendportfolio/base/user/service/UserServiceImplTest.java b/src/test/java/com/hideyoshi/backendportfolio/base/user/service/UserServiceImplTest.java index 03ad33c..a178583 100644 --- a/src/test/java/com/hideyoshi/backendportfolio/base/user/service/UserServiceImplTest.java +++ b/src/test/java/com/hideyoshi/backendportfolio/base/user/service/UserServiceImplTest.java @@ -38,13 +38,11 @@ class UserServiceImplTest { @Mock private UserRepository userRepository; - private PasswordEncoder passwordEncoder; - @BeforeEach void setUp() { - this.passwordEncoder = new BCryptPasswordEncoder(); - this.underTest = new UserServiceImpl(userRepository,passwordEncoder); + PasswordEncoder passwordEncoder = new BCryptPasswordEncoder(); + this.underTest = new UserServiceImpl(userRepository, passwordEncoder); } @Test @@ -58,8 +56,10 @@ class UserServiceImplTest { // Given UserDTO user = this.createUser(); + // When UserDTO userSaved = this.underTest.saveUser(user); + //Then ArgumentCaptor userArgumentCaptor = ArgumentCaptor.forClass(User.class); @@ -68,6 +68,30 @@ class UserServiceImplTest { assertThat(userSaved).isInstanceOf(UserDTO.class); } + @Test + void canSaveOAuthUser() { + + BDDMockito.when(userRepository.findByUsername(ArgumentMatchers.any(String.class))) + .thenReturn(Optional.ofNullable(null)); + + BDDMockito.when(userRepository.save(ArgumentMatchers.any(User.class))) + .thenReturn(createOAuthUser().toEntity()); + + // Given + UserDTO user = this.createOAuthUser(); + + // When + UserDTO userSaved = this.underTest.saveUser(user); + + //Then + ArgumentCaptor userArgumentCaptor = ArgumentCaptor.forClass(User.class); + + verify(userRepository).save(userArgumentCaptor.capture()); + assertThat(userArgumentCaptor.getValue()).isEqualTo(user.toEntity()); + assertThat(userArgumentCaptor.getValue().getPassword()).isEmpty(); + assertThat(userSaved).isInstanceOf(UserDTO.class); + } + @Test void cannotSaveUser() { @@ -77,7 +101,6 @@ class UserServiceImplTest { // Given UserDTO user = this.createUser(); - // When //Then assertThrows( BadRequestException.class, @@ -88,6 +111,29 @@ class UserServiceImplTest { ); } + @Test + void cannotSaveUserWithEmptyPassword() { + + BDDMockito.when(userRepository.findByUsername(ArgumentMatchers.any(String.class))) + .thenReturn(Optional.ofNullable(null)); + + + // Given + UserDTO user = this.createUser(); + + // When + user.setPassword(null); + + //Then + assertThrows( + BadRequestException.class, + () -> { + this.underTest.saveUser(user); + }, + "Password cannot be empty." + ); + } + @Test void canAlterUser() { BDDMockito.when(userRepository.findById(ArgumentMatchers.any(Long.class))) @@ -125,6 +171,7 @@ class UserServiceImplTest { @Test void canAddRoleToUser() { UserDTO user = this.createUser(); + user.setRoles(List.of()); BDDMockito.when(userRepository.findById(ArgumentMatchers.any(Long.class))) .thenReturn(Optional.ofNullable(user.toEntity())); @@ -347,6 +394,40 @@ class UserServiceImplTest { ); } + @Test + void canDeleteUser() { + UserDTO user = this.createUser(); + + BDDMockito.when(userRepository.findById(ArgumentMatchers.any(Long.class))) + .thenReturn(Optional.ofNullable(user.toEntity())); + + // When + this.underTest.deleteUser(user.getId()); + // Then + ArgumentCaptor argumentCaptor = ArgumentCaptor.forClass(User.class); + + verify(userRepository).delete(argumentCaptor.capture()); + assertThat(argumentCaptor.getValue().getId()).isEqualTo(user.getId()); + } + + @Test + void cannotDeleteUser() { + UserDTO user = this.createUser(); + + BDDMockito.when(userRepository.findById(ArgumentMatchers.any(Long.class))) + .thenReturn(Optional.ofNullable(null)); + + // When + // Then + assertThrows( + BadRequestException.class, + () -> { + this.underTest.deleteUser(user.getId()); + }, + "User doesn't exist." + ); + } + private UserDTO createUser() { return UserDTO.builder() .id(1L) @@ -355,8 +436,16 @@ class UserServiceImplTest { .username("Superman") .password("password") .provider(Provider.LOCAL) - .roles(List.of(Role.USER)) .build(); } + private UserDTO createOAuthUser() { + return UserDTO.builder() + .id(1L) + .name("Clark Kent") + .email("superman@gmail.com") + .username("Superman") + .provider(Provider.GOOGLE) + .build(); + } } \ No newline at end of file From 2ad112e8c3f077c738a88d04177e52a460cf9cdd Mon Sep 17 00:00:00 2001 From: Vitor Hideyoshi Date: Tue, 24 Oct 2023 02:04:27 -0300 Subject: [PATCH 3/3] Implements Tests for StorageService --- .../model/StorageServiceUploadResponse.java | 6 +- .../service/StorageService.java | 6 +- .../user/service/UserServiceImplTest.java | 1 - .../service/StorageServiceTest.java | 198 ++++++++++++++++++ src/test/resources/application.yml | 3 + 5 files changed, 206 insertions(+), 8 deletions(-) create mode 100644 src/test/java/com/hideyoshi/backendportfolio/microservice/storageService/service/StorageServiceTest.java diff --git a/src/main/java/com/hideyoshi/backendportfolio/microservice/storageService/model/StorageServiceUploadResponse.java b/src/main/java/com/hideyoshi/backendportfolio/microservice/storageService/model/StorageServiceUploadResponse.java index 6044aa6..358ff47 100644 --- a/src/main/java/com/hideyoshi/backendportfolio/microservice/storageService/model/StorageServiceUploadResponse.java +++ b/src/main/java/com/hideyoshi/backendportfolio/microservice/storageService/model/StorageServiceUploadResponse.java @@ -2,12 +2,10 @@ package com.hideyoshi.backendportfolio.microservice.storageService.model; import com.fasterxml.jackson.annotation.JsonProperty; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.Getter; -import lombok.NonNull; +import lombok.*; @Getter +@NoArgsConstructor @AllArgsConstructor public class StorageServiceUploadResponse { diff --git a/src/main/java/com/hideyoshi/backendportfolio/microservice/storageService/service/StorageService.java b/src/main/java/com/hideyoshi/backendportfolio/microservice/storageService/service/StorageService.java index 6aee545..a0e03b8 100644 --- a/src/main/java/com/hideyoshi/backendportfolio/microservice/storageService/service/StorageService.java +++ b/src/main/java/com/hideyoshi/backendportfolio/microservice/storageService/service/StorageService.java @@ -121,7 +121,7 @@ public class StorageService { } } - private String getRequest(URI requestURI) throws IOException { + protected String getRequest(URI requestURI) throws IOException { HttpGet request = new HttpGet(requestURI); request.setHeader("Content-Type", "application/json"); @@ -134,7 +134,7 @@ public class StorageService { ); } - private String postRequest(URI requestURI, String requestBody) throws IOException { + protected String postRequest(URI requestURI, String requestBody) throws IOException { HttpPost request = new HttpPost(requestURI); request.setHeader("Content-Type", "application/json"); @@ -153,7 +153,7 @@ public class StorageService { ); } - private void deleteRequest(URI requestURI) throws IOException { + protected void deleteRequest(URI requestURI) throws IOException { HttpDelete request = new HttpDelete(requestURI); request.setHeader("Content-Type", "application/json"); diff --git a/src/test/java/com/hideyoshi/backendportfolio/base/user/service/UserServiceImplTest.java b/src/test/java/com/hideyoshi/backendportfolio/base/user/service/UserServiceImplTest.java index a178583..a4903f0 100644 --- a/src/test/java/com/hideyoshi/backendportfolio/base/user/service/UserServiceImplTest.java +++ b/src/test/java/com/hideyoshi/backendportfolio/base/user/service/UserServiceImplTest.java @@ -32,7 +32,6 @@ import static org.mockito.Mockito.verify; @DirtiesContext(classMode= DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD) class UserServiceImplTest { - @InjectMocks private UserServiceImpl underTest; @Mock diff --git a/src/test/java/com/hideyoshi/backendportfolio/microservice/storageService/service/StorageServiceTest.java b/src/test/java/com/hideyoshi/backendportfolio/microservice/storageService/service/StorageServiceTest.java new file mode 100644 index 0000000..9946414 --- /dev/null +++ b/src/test/java/com/hideyoshi/backendportfolio/microservice/storageService/service/StorageServiceTest.java @@ -0,0 +1,198 @@ +package com.hideyoshi.backendportfolio.microservice.storageService.service; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.hideyoshi.backendportfolio.microservice.storageService.config.StorageServiceConfig; +import com.hideyoshi.backendportfolio.microservice.storageService.enums.FileTypeEnum; +import com.hideyoshi.backendportfolio.microservice.storageService.model.StorageServiceDownloadResponse; +import com.hideyoshi.backendportfolio.microservice.storageService.model.StorageServiceUploadResponse; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mockito; +import org.mockito.junit.jupiter.MockitoExtension; +import org.springframework.test.annotation.DirtiesContext; + +import java.io.IOException; + +import static org.assertj.core.api.Assertions.assertThat; + +@ExtendWith(MockitoExtension.class) +@DirtiesContext(classMode= DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD) +public class StorageServiceTest { + + private StorageService storageService; + + @BeforeEach + void setUp() { + StorageServiceConfig config = new StorageServiceConfig(); + + this.storageService = new StorageService(new ObjectMapper(), config); + } + + @Test + void testGetNewFileUrlIfFileExists() { + StorageService storageService = Mockito.spy(this.storageService); + + // Given + String username = "test"; + String filePostfix = "test"; + FileTypeEnum fileTypeEnum = FileTypeEnum.JPEG; + + // When + try { + String responseString = "{\"presigned_url\":\"https://test.com\", \"file_key\":\"test\"}"; + Mockito.doReturn(responseString).when(storageService).postRequest(Mockito.any(), Mockito.any()); + } catch (IOException e) { + assert false; + } + + // Then + var response = storageService.getNewFileUrl(username, filePostfix, fileTypeEnum); + + assertThat(response).isPresent(); + assertThat(response.get()).isInstanceOf(StorageServiceUploadResponse.class); + } + + @Test + void testGetNewFileUrlIfFileDoesNotExist() { + StorageService storageService = Mockito.spy(this.storageService); + + // Given + String username = "test"; + String filePostfix = "test"; + FileTypeEnum fileTypeEnum = FileTypeEnum.JPEG; + + // When + try { + Mockito.doThrow(new IOException()).when(storageService).postRequest(Mockito.any(), Mockito.any()); + } catch (IOException e) { + assert false; + } + + // Then + var response = storageService.getNewFileUrl(username, filePostfix, fileTypeEnum); + + assertThat(response).isNotPresent(); + } + + @Test + void getFileUrlIfExists() { + StorageService storageService = Mockito.spy(this.storageService); + + // Given + String username = "test"; + String filePostfix = "test"; + + // When + try { + String responseString = "{\"presigned_url\":\"http://test.com\"}"; + Mockito.doReturn(responseString).when(storageService).getRequest(Mockito.any()); + } catch (IOException e) { + assert false; + } + + // Then + var response = storageService.getFileUrl(username, filePostfix); + + assertThat(response).isPresent(); + assertThat(response.get()).isInstanceOf(StorageServiceDownloadResponse.class); + } + + @Test + void getFileUrlIfNotExists() { + StorageService storageService = Mockito.spy(this.storageService); + + // Given + String username = "test"; + String filePostfix = "test"; + + // When + try { + Mockito.doThrow(new IOException()).when(storageService).getRequest(Mockito.any()); + } catch (IOException e) { + assert false; + } + + // Then + var response = storageService.getFileUrl(username, filePostfix); + + assertThat(response).isNotPresent(); + } + + @Test + void deleteFileIfExists() { + StorageService storageService = Mockito.spy(this.storageService); + + // Given + String username = "test"; + String filePostfix = "test"; + + // When + try { + Mockito.doNothing().when(storageService).deleteRequest(Mockito.any()); + } catch (IOException e) { + assert false; + } + + // Then + storageService.deleteFile(username, filePostfix); + } + + @Test + void deleteFileIfNotExists() { + StorageService storageService = Mockito.spy(this.storageService); + + // Given + String username = "test"; + String filePostfix = "test"; + + // When + try { + Mockito.doThrow(new IOException()).when(storageService).deleteRequest(Mockito.any()); + } catch (IOException e) { + assert false; + } + + // Then + storageService.deleteFile(username, filePostfix); + } + + @Test + void processFileIfExists() { + StorageService storageService = Mockito.spy(this.storageService); + + // Given + String username = "test"; + String filePostfix = "test"; + + // When + try { + Mockito.doNothing().when(storageService).deleteRequest(Mockito.any()); + } catch (IOException e) { + assert false; + } + + // Then + storageService.deleteFile(username, filePostfix); + } + + @Test + void processFileIfNotExists() { + StorageService storageService = Mockito.spy(this.storageService); + + // Given + String username = "test"; + String filePostfix = "test"; + + // When + try { + Mockito.doThrow(new IOException()).when(storageService).deleteRequest(Mockito.any()); + } catch (IOException e) { + assert false; + } + + // Then + storageService.deleteFile(username, filePostfix); + } + +} diff --git a/src/test/resources/application.yml b/src/test/resources/application.yml index e2daa91..106728a 100644 --- a/src/test/resources/application.yml +++ b/src/test/resources/application.yml @@ -13,6 +13,9 @@ com: username: "YoshiUnfriendly" password: "passwd" + microservice: + storageServicePath: undertest + spring: liquibase: