Refactor some code in image service.

This commit is contained in:
2019-08-04 21:47:58 +02:00
parent bb5ae901f7
commit 54b081e700
5 changed files with 159 additions and 42 deletions

View File

@@ -0,0 +1,21 @@
package org.codiki.core.services;
/**
* Exception thrown when a user attempts to access to a resource that is not his own or he hasn't access rights.
*/
public class IllegalAccessException extends RuntimeException {
public IllegalAccessException() {
}
public IllegalAccessException(String message) {
super(message);
}
public IllegalAccessException(String message, Throwable cause) {
super(message, cause);
}
public IllegalAccessException(Throwable cause) {
super(cause);
}
}

View File

@@ -1,6 +1,7 @@
package org.codiki.images; package org.codiki.images;
import org.codiki.core.entities.dto.ImageDTO; import org.codiki.core.entities.dto.ImageDTO;
import org.codiki.core.services.IllegalAccessException;
import org.codiki.core.utils.StringUtils; import org.codiki.core.utils.StringUtils;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@@ -11,7 +12,6 @@ import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import java.io.IOException; import java.io.IOException;
import java.security.Principal; import java.security.Principal;
@@ -36,17 +36,17 @@ public class ImageController {
@PostMapping("/uploadAvatar") @PostMapping("/uploadAvatar")
public ResponseEntity<String> uploadAvatar(@RequestParam("file") MultipartFile pFile, public ResponseEntity<String> uploadAvatar(@RequestParam("file") MultipartFile pFile,
final HttpServletRequest pRequest,
final HttpServletResponse pResponse,
final Principal pPrincipal) { final Principal pPrincipal) {
LOG.debug("Upload avatar."); LOG.debug("Upload avatar.");
ResponseEntity<String> result; ResponseEntity<String> result;
try { try {
result = ResponseEntity.ok(imageService.uploadAvatar(pFile, pResponse, pPrincipal)); result = ResponseEntity.ok(imageService.uploadAvatar(pFile, pPrincipal));
} catch(final Exception pEx) { } catch(IllegalAccessException ex) {
LOG.error("Error during avatar upload.", pEx); result = ResponseEntity.status(HttpServletResponse.SC_UNAUTHORIZED).build();
result = ResponseEntity.status(HttpStatus.EXPECTATION_FAILED) } catch(Exception ex) {
.body(StringUtils.concat("Fail to upload ", pFile.getOriginalFilename() + ".")); LOG.error("Error during avatar upload.", ex);
result = ResponseEntity.status(HttpServletResponse.SC_INTERNAL_SERVER_ERROR)
.body(StringUtils.concat("Fail to upload ", pFile.getOriginalFilename() + "."));
} }
return result; return result;
} }
@@ -55,13 +55,13 @@ public class ImageController {
public ResponseEntity<String> uploadImage(@RequestParam("file") MultipartFile pFile, public ResponseEntity<String> uploadImage(@RequestParam("file") MultipartFile pFile,
final HttpServletResponse pResponse, final HttpServletResponse pResponse,
final Principal pPrincipal) throws IOException { final Principal pPrincipal) throws IOException {
ResponseEntity<String> result = null; ResponseEntity<String> result;
try { try {
result = ResponseEntity.status(HttpStatus.OK) result = ResponseEntity.status(HttpStatus.OK)
.body(imageService.uploadImage(pFile, pPrincipal)); .body(imageService.uploadImage(pFile, pPrincipal));
} catch(NoSuchElementException pEx) { } catch(IllegalAccessException pEx) {
pResponse.sendError(HttpServletResponse.SC_UNAUTHORIZED); result = ResponseEntity.status(HttpServletResponse.SC_UNAUTHORIZED).build();
} catch(final Exception pEx) { } catch(Exception ex) {
result = ResponseEntity.status(HttpStatus.EXPECTATION_FAILED) result = ResponseEntity.status(HttpStatus.EXPECTATION_FAILED)
.body(StringUtils.concat("Fail to upload ", pFile.getOriginalFilename() + ".")); .body(StringUtils.concat("Fail to upload ", pFile.getOriginalFilename() + "."));
} }

View File

@@ -6,13 +6,12 @@ import org.codiki.core.entities.persistence.User;
import org.codiki.core.repositories.ImageRepository; import org.codiki.core.repositories.ImageRepository;
import org.codiki.core.repositories.UserRepository; import org.codiki.core.repositories.UserRepository;
import org.codiki.core.services.FileUploadService; import org.codiki.core.services.FileUploadService;
import org.codiki.core.services.IllegalAccessException;
import org.codiki.core.services.UserService; import org.codiki.core.services.UserService;
import org.springframework.core.io.Resource; import org.springframework.core.io.Resource;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.security.Principal; import java.security.Principal;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
@@ -48,24 +47,23 @@ public class ImageService {
this.imageRepository = imageRepository; this.imageRepository = imageRepository;
} }
/**
* Save the uploaded file in persistence folder and set it as profil picture to uploader-user.
* @param pFile Uploaded file
* @param pPrincipal Uploader-user.
* @return Name of the uploaded file.
* @throws IllegalAccessException If the user isn't allowed to upload file
*/
public String uploadAvatar(final MultipartFile pFile, public String uploadAvatar(final MultipartFile pFile,
final HttpServletResponse pResponse, final Principal pPrincipal) throws IllegalAccessException {
final Principal pPrincipal) throws IOException {
final String avatarFileName = fileUploadService.uploadProfileImage(pFile); final String avatarFileName = fileUploadService.uploadProfileImage(pFile);
final Optional<User> connectedUser = userService.getUserByPrincipal(pPrincipal); userService.getUserByPrincipal(pPrincipal)
if(connectedUser.isPresent()) { .ifPresentOrElse(user -> {
final Optional<User> userFromDb = userRepository.findById(connectedUser.get().getId()); user.setImage(avatarFileName);
if(userFromDb.isPresent()) { userRepository.save(user);
userFromDb.get().setImage(avatarFileName); }, IllegalAccessException::new);
userRepository.save(userFromDb.get());
} else {
pResponse.sendError(HttpServletResponse.SC_UNAUTHORIZED);
}
} else {
pResponse.sendError(HttpServletResponse.SC_UNAUTHORIZED);
}
return avatarFileName; return avatarFileName;
} }
@@ -73,16 +71,13 @@ public class ImageService {
final String imageFileName = fileUploadService.uploadImage(pFile); final String imageFileName = fileUploadService.uploadImage(pFile);
userService.getUserByPrincipal(pPrincipal) userService.getUserByPrincipal(pPrincipal)
.map(User::getId) .ifPresentOrElse(user -> {
.map(userRepository::findById)
.orElseThrow(NoSuchElementException::new)
.ifPresent(user -> {
final Image image = new Image(); final Image image = new Image();
image.setLink(imageFileName); image.setLink(imageFileName);
image.setDate(new Date()); image.setDate(new Date());
image.setUser(user); image.setUser(user);
imageRepository.save(image); imageRepository.save(image);
}); }, IllegalAccessException::new);
return imageFileName; return imageFileName;
} }
@@ -96,13 +91,12 @@ public class ImageService {
} }
public List<ImageDTO> getUserImages(final Principal pPrincipal) { public List<ImageDTO> getUserImages(final Principal pPrincipal) {
return userService.getUserByPrincipal(pPrincipal) return imageRepository.getByUserId(userService.getUserByPrincipal(pPrincipal)
.map(User::getId) .map(User::getId)
.map(imageRepository::getByUserId) .orElseThrow(NoSuchElementException::new))
.orElseThrow(NoSuchElementException::new) .stream()
.stream() .map(ImageDTO::new)
.map(ImageDTO::new) .collect(Collectors.toList());
.collect(Collectors.toList());
} }
public Optional<ImageDTO> getImageDetails(final String pImageLink) { public Optional<ImageDTO> getImageDetails(final String pImageLink) {

View File

@@ -37,6 +37,8 @@ spring:
url: jdbc:postgresql://localhost:5432/codiki url: jdbc:postgresql://localhost:5432/codiki
username: codiki username: codiki
password: P@ssword password: P@ssword
# TODO: Delete all Lazy relationships and set following property to false
# open-in-view: false
# Because detection is disabled you have to set correct dialect by hand. # Because detection is disabled you have to set correct dialect by hand.
database-platform: org.hibernate.dialect.PostgreSQL9Dialect database-platform: org.hibernate.dialect.PostgreSQL9Dialect
# Disable feature detection by this undocumented parameter. # Disable feature detection by this undocumented parameter.

View File

@@ -0,0 +1,100 @@
package org.codiki.images;
import org.codiki.core.entities.dto.ImageDTO;
import org.codiki.core.entities.persistence.Image;
import org.codiki.core.entities.persistence.User;
import org.codiki.core.repositories.ImageRepository;
import org.codiki.core.repositories.UserRepository;
import org.codiki.core.services.FileUploadService;
import org.codiki.core.services.UserService;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
import java.security.Principal;
import java.util.Collections;
import java.util.List;
import java.util.NoSuchElementException;
import java.util.Optional;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.catchThrowable;
import static org.mockito.BDDMockito.given;
import static org.mockito.Mockito.mock;
@RunWith(MockitoJUnitRunner.class)
public class ImageServiceTest {
private ImageService imageService;
@Mock
private UserService userService;
@Mock
private UserRepository userRepository;
@Mock
private FileUploadService fileUploadService;
@Mock
private ImageRepository imageRepository;
@Before
public void setUp() {
imageService = new ImageService(userService,
userRepository,
fileUploadService,
imageRepository);
}
@Test
public void getUserImages_should_return_ImageDTO_list() {
// given
Principal principal = mock(Principal.class);
User user = new User();
user.setId(1L);
given(userService.getUserByPrincipal(principal)).willReturn(Optional.of(user));
Image image = new Image();
image.setId(2L);
image.setLink("linkValue");
given(imageRepository.getByUserId(1L)).willReturn(Collections.singletonList(image));
// when
List<ImageDTO> result = imageService.getUserImages(principal);
// then
assertThat(result).isNotNull().hasSize(1);
assertThat(result.get(0).getId()).isEqualTo(2L);
assertThat(result.get(0).getLink()).isEqualTo("linkValue");
}
@Test
public void getUserImages_should_throw_a_NoSuchElementException_if_user_doesnt_exist() {
// given
Principal principal = mock(Principal.class);
given(userService.getUserByPrincipal(principal)).willReturn(Optional.empty());
// when
Throwable throwable = catchThrowable(() -> imageService.getUserImages(principal));
// then
assertThat(throwable).isNotNull().isExactlyInstanceOf(NoSuchElementException.class);
}
@Test
public void getUserImages_should_return_an_empty_list_if_user_doesnt_have_any_image() {
// given
Principal principal = mock(Principal.class);
User user = new User();
user.setId(1L);
given(userService.getUserByPrincipal(principal)).willReturn(Optional.of(user));
given(imageRepository.getByUserId(1L)).willReturn(Collections.emptyList());
// when
List<ImageDTO> result = imageService.getUserImages(principal);
// then
assertThat(result).isNotNull().isEmpty();
}
}