diff --git a/build.gradle b/build.gradle index d6f01fd..b59b961 100644 --- a/build.gradle +++ b/build.gradle @@ -60,6 +60,7 @@ dependencies { implementation("com.sun.mail:javax.mail:1.6.2") // test h2 db + testImplementation 'org.springframework.boot:spring-boot-starter-test' testImplementation 'com.h2database:h2' } diff --git a/src/main/java/NextLevel/demo/img/MustLastParameterException.java b/src/main/java/NextLevel/demo/img/MustLastParameterException.java new file mode 100644 index 0000000..406cca6 --- /dev/null +++ b/src/main/java/NextLevel/demo/img/MustLastParameterException.java @@ -0,0 +1,7 @@ +package NextLevel.demo.img; + +public class MustLastParameterException extends RuntimeException{ + public MustLastParameterException(String message ){ + super(message); + } +} diff --git a/src/main/java/NextLevel/demo/img/service/ImgPath.java b/src/main/java/NextLevel/demo/img/service/ImgPath.java new file mode 100644 index 0000000..2055749 --- /dev/null +++ b/src/main/java/NextLevel/demo/img/service/ImgPath.java @@ -0,0 +1,30 @@ +package NextLevel.demo.img.service; + +import lombok.Getter; +import lombok.Setter; + +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.List; + +@Getter +@Setter +public class ImgPath { + + private List saved; + private List deleted; + + public void save(Path path){ + saved.add(path); + } + + public void delete(Path path){ + deleted.add(path); + } + + public ImgPath(){ + saved = new ArrayList<>(); + deleted = new ArrayList<>(); + } + +} diff --git a/src/main/java/NextLevel/demo/img/service/ImgService.java b/src/main/java/NextLevel/demo/img/service/ImgService.java index 2cfe85d..6401073 100644 --- a/src/main/java/NextLevel/demo/img/service/ImgService.java +++ b/src/main/java/NextLevel/demo/img/service/ImgService.java @@ -11,9 +11,9 @@ public interface ImgService { - ImgEntity saveImg(MultipartFile imgFile, ArrayList imgPaths); - ImgEntity updateImg(MultipartFile imgFile, ImgEntity oldImg, ArrayList imgPaths); - void deleteImg(ImgEntity img); + ImgEntity saveImg(MultipartFile imgFile, ImgPath imgPath); + ImgEntity updateImg(MultipartFile imgFile, ImgEntity oldImg, ImgPath imgPath); + void deleteImg(ImgEntity img, ImgPath imgPath); ImgEntity saveSocialImg(String imgURL); void deleteImgFile(List filePath) throws IOException ; diff --git a/src/main/java/NextLevel/demo/img/service/ImgServiceImpl.java b/src/main/java/NextLevel/demo/img/service/ImgServiceImpl.java index 53e898a..76f4330 100644 --- a/src/main/java/NextLevel/demo/img/service/ImgServiceImpl.java +++ b/src/main/java/NextLevel/demo/img/service/ImgServiceImpl.java @@ -35,7 +35,7 @@ public class ImgServiceImpl implements ImgService { private final ImgRepository imgRepository; // @Transactional(propagation = Propagation.REQUIRES_NEW) - public ImgEntity saveImg(MultipartFile imgFile, ArrayList imgPaths) { + public ImgEntity saveImg(MultipartFile imgFile, ImgPath imgPath) { if(imgFile == null || imgFile.isEmpty()) return null; try { byte[] bytes = imgFile.getBytes(); @@ -43,10 +43,10 @@ public ImgEntity saveImg(MultipartFile imgFile, ArrayList imgPaths) { fileName = addImgNumber(fileName); - Path path = Paths.get(System.getProperty("user.dir") ,IMG_DEFAULT_PATH, fileName); + Path path = getPath(fileName); // Paths.get(System.getProperty("user.dir") ,IMG_DEFAULT_PATH, fileName); Files.write(path, bytes); - imgPaths.add(path); + imgPath.save(path); ImgEntity saved = imgRepository.save(new ImgEntity(fileName)); @@ -61,13 +61,13 @@ public ImgEntity saveImg(MultipartFile imgFile, ArrayList imgPaths) { } // img uri 변경 없이 진짜 파일 값만 덮어쓰기 - public ImgEntity updateImg(MultipartFile imgFile, ImgEntity oldImg, ArrayList imgPaths) { + public ImgEntity updateImg(MultipartFile imgFile, ImgEntity oldImg, ImgPath imgPath) { if(oldImg == null){ - return saveImg(imgFile, imgPaths); + return saveImg(imgFile, imgPath); } try { - Path path = Paths.get(System.getProperty("user.dir"), IMG_DEFAULT_PATH, oldImg.getUri()); + Path path = getPath(oldImg.getUri()); // Paths.get(System.getProperty("user.dir"), IMG_DEFAULT_PATH, oldImg.getUri()); Files.write(path, imgFile.getBytes()); @@ -84,18 +84,14 @@ public ImgEntity updateImg(MultipartFile imgFile, ImgEntity oldImg, ArrayList filePath) throws IOException { Files.deleteIfExists(path); } } + + private Path getPath(String uri) { + return Paths.get(System.getProperty("user.dir") ,IMG_DEFAULT_PATH, uri); + } } diff --git a/src/main/java/NextLevel/demo/img/service/ImgTransactionAop.java b/src/main/java/NextLevel/demo/img/service/ImgTransactionAop.java index 5c9fbdd..484c78e 100644 --- a/src/main/java/NextLevel/demo/img/service/ImgTransactionAop.java +++ b/src/main/java/NextLevel/demo/img/service/ImgTransactionAop.java @@ -2,6 +2,8 @@ import java.nio.file.Path; import java.util.ArrayList; + +import NextLevel.demo.img.MustLastParameterException; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.aspectj.lang.ProceedingJoinPoint; @@ -16,17 +18,31 @@ public class ImgTransactionAop { private final ImgServiceImpl imgService; + /* + joinPoint :: args :: last argument is must ImgPath.class + success : delete all deleted Img File + fail : delete add saved Img File + */ + @Around("@annotation(imgTransaction)") public Object around(ProceedingJoinPoint joinPoint, ImgTransaction imgTransaction) throws Throwable { - ArrayList imgPaths = new ArrayList<>(); + ImgPath path = new ImgPath(); log.info("img transaction start"); try{ Object[] args = joinPoint.getArgs(); - args[args.length-1] = imgPaths; - return joinPoint.proceed(args); + Object lastParameter = args[args.length-1]; + + if(!(lastParameter instanceof ImgPath)) + throw new MustLastParameterException("last parameter must be of type ImgPath.class"); + + args[args.length-1] = path; + + Object result = joinPoint.proceed(args); + imgService.deleteImgFile(path.getDeleted()); + return result; } catch (Exception e){ log.info("img transaction :: error :: roll back all img files"); - imgService.deleteImgFile(imgPaths); + imgService.deleteImgFile(path.getSaved()); throw e; } } diff --git a/src/main/java/NextLevel/demo/notice/controller/NoticeController.java b/src/main/java/NextLevel/demo/notice/controller/NoticeController.java index 8edbd8c..cbb66d8 100644 --- a/src/main/java/NextLevel/demo/notice/controller/NoticeController.java +++ b/src/main/java/NextLevel/demo/notice/controller/NoticeController.java @@ -1,6 +1,7 @@ package NextLevel.demo.notice.controller; import NextLevel.demo.common.SuccessResponse; +import NextLevel.demo.img.service.ImgTransaction; import NextLevel.demo.notice.dto.ResponseNoticeDto; import NextLevel.demo.notice.dto.SaveNoticeDto; import NextLevel.demo.notice.entity.NoticeEntity; @@ -52,8 +53,9 @@ public ResponseEntity updateNotice(@ModelAttribute SaveNoticeDto dto, @PathVa } @PostMapping("/admin/notice/{id}") + @ImgTransaction public ResponseEntity removeNotice(@PathVariable("id") Long id) { - noticeService.removeNotice(id); + noticeService.removeNotice(id, null); return ResponseEntity.ok(new SuccessResponse("success", null)); } } diff --git a/src/main/java/NextLevel/demo/notice/service/NoticeService.java b/src/main/java/NextLevel/demo/notice/service/NoticeService.java index 250419f..4df0dcf 100644 --- a/src/main/java/NextLevel/demo/notice/service/NoticeService.java +++ b/src/main/java/NextLevel/demo/notice/service/NoticeService.java @@ -3,6 +3,7 @@ import NextLevel.demo.exception.CustomException; import NextLevel.demo.exception.ErrorCode; import NextLevel.demo.img.entity.ImgEntity; +import NextLevel.demo.img.service.ImgPath; import NextLevel.demo.img.service.ImgService; import NextLevel.demo.img.service.ImgTransaction; import NextLevel.demo.notice.dto.SaveNoticeDto; @@ -34,13 +35,13 @@ public List getAllNotice() { @ImgTransaction @Transactional - public void addNotice(SaveNoticeDto dto, ArrayList imgPaths) { + public void addNotice(SaveNoticeDto dto, ImgPath imgPath) { NoticeEntity newNotice = dto.toEntity(); List newImgs = new ArrayList(); if(dto.getImgs()!=null && !dto.getImgs().isEmpty()) { dto.getImgs().stream().forEach(file -> { if(file != null && !file.isEmpty()) - newImgs.add(imgService.saveImg(file, imgPaths)); + newImgs.add(imgService.saveImg(file, imgPath)); }); newNotice.setImgs( newImgs @@ -76,7 +77,7 @@ public void updateNotice(SaveNoticeDto dto) { @ImgTransaction @Transactional - public void updateImg(Long noticeId, List imgFiles, ArrayList imgPaths) { + public void updateImg(Long noticeId, List imgFiles, ImgPath imgPath) { NoticeEntity notice = noticeRepository.findById(noticeId).orElseThrow( () -> {throw new CustomException(ErrorCode.NOT_FOUND, "notice");} ); @@ -84,7 +85,7 @@ public void updateImg(Long noticeId, List imgFiles, ArrayList oldImgs = oldNoticeImgs.stream().map(NoticeImgEntity::getImg).toList(); List newImgs = new ArrayList<>(); - imgFiles.stream().forEach(i->newImgs.add(imgService.saveImg(i, imgPaths))); + imgFiles.stream().forEach(i->newImgs.add(imgService.saveImg(i, imgPath))); List newNoticeImgs = new ArrayList<>(); newImgs .stream() @@ -100,11 +101,11 @@ public void updateImg(Long noticeId, List imgFiles, ArrayListimgService.deleteImg(img, imgPath)); } //@Transactional - public void removeNotice(Long noticeId) { + public void removeNotice(Long noticeId, ImgPath imgPath) { NoticeEntity notice = noticeRepository.findById(noticeId).orElseThrow( () -> {throw new CustomException(ErrorCode.NOT_FOUND, "notice");} ); @@ -112,6 +113,6 @@ public void removeNotice(Long noticeId) { noticeRepository.delete(notice); - oldImgs.forEach(imgService::deleteImg); + oldImgs.forEach((img)->imgService.deleteImg(img, imgPath)); } } diff --git a/src/main/java/NextLevel/demo/project/notice/service/ProjectNoticeService.java b/src/main/java/NextLevel/demo/project/notice/service/ProjectNoticeService.java index d542d7b..2cebd4e 100644 --- a/src/main/java/NextLevel/demo/project/notice/service/ProjectNoticeService.java +++ b/src/main/java/NextLevel/demo/project/notice/service/ProjectNoticeService.java @@ -3,6 +3,7 @@ import NextLevel.demo.exception.CustomException; import NextLevel.demo.exception.ErrorCode; import NextLevel.demo.img.entity.ImgEntity; +import NextLevel.demo.img.service.ImgPath; import NextLevel.demo.img.service.ImgServiceImpl; import NextLevel.demo.img.service.ImgTransaction; import NextLevel.demo.project.notice.dto.request.SaveProjectNoticeRequestDto; @@ -36,20 +37,20 @@ public List getAllNotice(Long projectId){ @Transactional @ImgTransaction - public void saveProjectNotice(SaveProjectNoticeRequestDto dto, ArrayList imgPaths) { + public void saveProjectNotice(SaveProjectNoticeRequestDto dto, ImgPath imgPath) { ProjectEntity project = projectValidateService.getProjectEntity(dto.getProjectId()); if(!project.getUser().getId().equals(dto.getUserId())) throw new CustomException(ErrorCode.NOT_AUTHOR); - ImgEntity savedImg = imgService.saveImg(dto.getImg(), imgPaths); + ImgEntity savedImg = imgService.saveImg(dto.getImg(), imgPath); projectNoticeRepository.save(dto.toEntity(savedImg, project)); } @Transactional @ImgTransaction - public void updateNotice(SaveProjectNoticeRequestDto dto, ArrayList imgPaths) { + public void updateNotice(SaveProjectNoticeRequestDto dto, ImgPath imgPath) { ProjectNoticeEntity notice = projectNoticeRepository.findByIdWithProject(dto.getNoticeId()).orElseThrow( ()->{return new CustomException(ErrorCode.NOT_FOUND, "notice");} ); @@ -60,7 +61,7 @@ public void updateNotice(SaveProjectNoticeRequestDto dto, ArrayList imgPa notice.update(dto); if(dto.getImg() != null && !dto.getImg().isEmpty()) { - ImgEntity savedImg = imgService.updateImg(dto.getImg(), notice.getImg(), imgPaths); + ImgEntity savedImg = imgService.updateImg(dto.getImg(), notice.getImg(), imgPath); if(notice.getImg() == null) notice.setImg(savedImg); } diff --git a/src/main/java/NextLevel/demo/project/project/service/ProjectService.java b/src/main/java/NextLevel/demo/project/project/service/ProjectService.java index b6d4e89..77766e9 100644 --- a/src/main/java/NextLevel/demo/project/project/service/ProjectService.java +++ b/src/main/java/NextLevel/demo/project/project/service/ProjectService.java @@ -6,6 +6,7 @@ import NextLevel.demo.funding.service.FundingRollbackService; import NextLevel.demo.funding.service.FundingValidateService; import NextLevel.demo.img.entity.ImgEntity; +import NextLevel.demo.img.service.ImgPath; import NextLevel.demo.img.service.ImgServiceImpl; import NextLevel.demo.img.service.ImgTransaction; import NextLevel.demo.project.project.dto.request.CreateProjectDto; @@ -53,18 +54,18 @@ public class ProjectService { // 추가 @ImgTransaction @Transactional - public void save(CreateProjectDto dto, ArrayList imgPaths) { + public void save(CreateProjectDto dto, ImgPath imgPath) { // user 처리 UserEntity user = userValidateService.getUserInfoWithAccessToken(dto.getUserId()); validateUser(user); if(dto.getTitleImg() == null || dto.getTitleImg().isEmpty()) throw new CustomException(ErrorCode.INPUT_REQUIRED_PARAMETER); - ImgEntity img = imgService.saveImg(dto.getTitleImg(), imgPaths); + ImgEntity img = imgService.saveImg(dto.getTitleImg(), imgPath); ProjectEntity newProject = projectRepository.save(dto.toProjectEntity(user, img)); - projectStoryService.saveNewProjectStory(newProject, dto.getImgs(), imgPaths); + projectStoryService.saveNewProjectStory(newProject, dto.getImgs(), imgPath); tagService.saveNewTags(newProject, dto.getTags()); } private void validateUser(UserEntity user) { @@ -75,7 +76,7 @@ private void validateUser(UserEntity user) { // 수정 @ImgTransaction @Transactional - public void update(CreateProjectDto dto, ArrayList imgPaths) { + public void update(CreateProjectDto dto, ImgPath imgPath) { Optional oldProjectOptional = projectRepository.findByIdWithAll(dto.getId()); if(oldProjectOptional.isEmpty()) @@ -88,7 +89,7 @@ public void update(CreateProjectDto dto, ArrayList imgPaths) { ImgEntity img = oldProject.getTitleImg(); if(dto.getTitleImg() != null) - img = imgService.updateImg(dto.getTitleImg(), oldProject.getTitleImg(), imgPaths); + img = imgService.updateImg(dto.getTitleImg(), oldProject.getTitleImg(), imgPath); // tag 처리 if(dto.getTags() != null && !dto.getTags().isEmpty()) @@ -96,11 +97,31 @@ public void update(CreateProjectDto dto, ArrayList imgPaths) { // img 처리 if(dto.getImgs() != null && !dto.getImgs().isEmpty()) - projectStoryService.updateProjectStory(oldProject, dto.getImgs(), imgPaths); + projectStoryService.updateProjectStory(oldProject, dto.getImgs(), imgPath); projectRepository.save(dto.toProjectEntity(oldProject.getUser(), img)); // 값이 있는 것만 update 형식으로 수정 필요 } + // 삭제 + @Transactional + @ImgTransaction + public void deleteProject(Long id, ImgPath imgPath) { + Optional oldProjectOptional = projectRepository.findById(id); + if(oldProjectOptional.isEmpty()) + throw new CustomException(ErrorCode.NOT_FOUND, "project"); + ProjectEntity oldProject = oldProjectOptional.get(); + + // 펀딩 금액이 남아있다면 모두 환불 처리하기 + fundingRollbackService.rollbackByProject(oldProject); + + // 다른 soft적 처리 필요한 부분 처리하기 + + // img 처리 + projectStoryService.updateProjectStory(oldProject, new ArrayList<>(), imgPath); + + return; // 아직 구현하지 않음 + soft delete 처리 고민중 ..... + } + // get list public ResponseProjectListDto getAllProjects(RequestMainPageProjectListDto dto) { return projectDslRepository.selectProjectDsl(dto); diff --git a/src/main/java/NextLevel/demo/project/story/service/ProjectStoryService.java b/src/main/java/NextLevel/demo/project/story/service/ProjectStoryService.java index 6b3b624..afddb62 100644 --- a/src/main/java/NextLevel/demo/project/story/service/ProjectStoryService.java +++ b/src/main/java/NextLevel/demo/project/story/service/ProjectStoryService.java @@ -1,6 +1,7 @@ package NextLevel.demo.project.story.service; import NextLevel.demo.img.entity.ImgEntity; +import NextLevel.demo.img.service.ImgPath; import NextLevel.demo.img.service.ImgServiceImpl; import NextLevel.demo.img.service.ImgTransaction; import NextLevel.demo.project.project.entity.ProjectEntity; @@ -27,13 +28,13 @@ public class ProjectStoryService { @ImgTransaction @Transactional - public void saveNewProjectStory(ProjectEntity project, List imgFiles, ArrayList imgPaths) { + public void saveNewProjectStory(ProjectEntity project, List imgFiles, ImgPath imgPath) { imgFiles.forEach(imgFile -> { projectStoryRepository.save( ProjectStoryEntity .builder() .project(project) - .img(imgService.saveImg(imgFile, imgPaths)) + .img(imgService.saveImg(imgFile, imgPath)) .build() ); }); @@ -41,24 +42,24 @@ public void saveNewProjectStory(ProjectEntity project, List imgFi @Transactional @ImgTransaction - public void updateProjectStory(ProjectEntity project, List imgFiles, ArrayList imgPaths) { + public void updateProjectStory(ProjectEntity project, List imgFiles, ImgPath imgPath) { List oldImgs = project.getStories().stream().map(projectImg -> projectImg.getImg()).toList(); projectStoryRepository.deleteAllByProjectId(project.getId()); - oldImgs.forEach(img->imgService.deleteImg(img)); - saveNewProjectStory(project, imgFiles, imgPaths); + oldImgs.forEach(img->imgService.deleteImg(img, imgPath)); + saveNewProjectStory(project, imgFiles, imgPath); } @ImgTransaction @Transactional - public void updateProjectStory(Long projectId, Long userId, List imgFiles, ArrayList imgPaths){ + public void updateProjectStory(Long projectId, Long userId, List imgFiles, ImgPath imgPath){ if(imgFiles == null || imgFiles.isEmpty()) return; ProjectEntity project = projectValidateService.validateAuthor(projectId, userId); - updateProjectStory(project, imgFiles, imgPaths); + updateProjectStory(project, imgFiles, imgPath); } public List getProjectStory(Long projectId) { diff --git a/src/main/java/NextLevel/demo/social/controller/SocialController.java b/src/main/java/NextLevel/demo/social/controller/SocialController.java index 31f1b20..26c99fc 100644 --- a/src/main/java/NextLevel/demo/social/controller/SocialController.java +++ b/src/main/java/NextLevel/demo/social/controller/SocialController.java @@ -32,7 +32,7 @@ public ResponseEntity update(@ModelAttribute RequestSocialCreateDto dto) { @DeleteMapping("/social/social/{socialId}") public ResponseEntity delete(@PathVariable("socialId") Long socialId) { - socialService.delete(socialId, JWTUtil.getUserIdFromSecurityContext()); + socialService.delete(socialId, JWTUtil.getUserIdFromSecurityContext(), null); return ResponseEntity.ok().body(new SuccessResponse("success", null)); } diff --git a/src/main/java/NextLevel/demo/social/service/SocialService.java b/src/main/java/NextLevel/demo/social/service/SocialService.java index c241f66..a690153 100644 --- a/src/main/java/NextLevel/demo/social/service/SocialService.java +++ b/src/main/java/NextLevel/demo/social/service/SocialService.java @@ -4,6 +4,7 @@ import NextLevel.demo.exception.ErrorCode; import NextLevel.demo.follow.SelectSocialProfileService; import NextLevel.demo.img.entity.ImgEntity; +import NextLevel.demo.img.service.ImgPath; import NextLevel.demo.img.service.ImgService; import NextLevel.demo.img.service.ImgTransaction; import NextLevel.demo.social.dto.RequestSocialCreateDto; @@ -46,17 +47,18 @@ public class SocialService { @ImgTransaction @Transactional - public void create(RequestSocialCreateDto dto, ArrayList imgPaths) { + public void create(RequestSocialCreateDto dto, ImgPath imgPath) { UserEntity user = userValidateService.getUserInfoWithAccessToken(dto.getUserId()); SocialEntity social = socialRepository.save(dto.toEntity(user)); if(dto.getImg() != null && !dto.getImg().isEmpty()) - saveImgs(dto.getImg(), social, imgPaths); + saveImgs(dto.getImg(), social, imgPath); + } @ImgTransaction @Transactional - public void update(RequestSocialCreateDto dto, ArrayList imgPaths) { + public void update(RequestSocialCreateDto dto, ImgPath imgPath) { SocialEntity social = socialRepository.findById(dto.getId()).orElseThrow( ()->{return new CustomException(ErrorCode.NOT_FOUND, "social");} ); @@ -65,15 +67,16 @@ public void update(RequestSocialCreateDto dto, ArrayList imgPaths) { throw new CustomException(ErrorCode.NOT_AUTHOR); if(dto.getImg() != null && !dto.getImg().isEmpty() && !dto.getImg().get(0).isEmpty()){ - deleteImgs(social.getId(), social.getImgs().stream().map(SocialImgEntity::getImg).toList()); - saveImgs(dto.getImg(), social, imgPaths); + deleteImgs(social.getId(), social.getImgs().stream().map(SocialImgEntity::getImg).toList(), imgPath); + saveImgs(dto.getImg(), social, imgPath); } social.update(dto); } @Transactional - public void delete(Long socialId, Long userId) { + @ImgTransaction + public void delete(Long socialId, Long userId, ImgPath imgPath) { SocialEntity social = socialRepository.findById(socialId).orElseThrow( ()->{return new CustomException(ErrorCode.NOT_FOUND, "social");} ); @@ -81,7 +84,7 @@ public void delete(Long socialId, Long userId) { if(!social.getUser().getId().equals(userId)) throw new CustomException(ErrorCode.NOT_AUTHOR); - deleteImgs(socialId, social.getImgs().stream().map(SocialImgEntity::getImg).toList()); + deleteImgs(socialId, social.getImgs().stream().map(SocialImgEntity::getImg).toList(), imgPath); entityManager.flush(); entityManager.clear(); @@ -133,7 +136,7 @@ public SocialListDto list(Long targetUserId, Long userId) { return SocialListDto.of(user, socials); } - private void saveImgs(List imgFiles, SocialEntity social, ArrayList imgPaths) { + private void saveImgs(List imgFiles, SocialEntity social, ImgPath imgPath) { if(imgFiles.isEmpty()) return; imgFiles.forEach(imgFile -> @@ -141,15 +144,15 @@ private void saveImgs(List imgFiles, SocialEntity social, ArrayLi SocialImgEntity .builder() .social(social) - .img(imgService.saveImg(imgFile, imgPaths)) + .img(imgService.saveImg(imgFile, imgPath)) .build() ) ); } - private void deleteImgs(Long socialId, List imgs) { + private void deleteImgs(Long socialId, List imgs, ImgPath imgPath) { socialImgRepository.deleteAllBySocialId(socialId); - imgs.forEach(img->imgService.deleteImg(img)); + imgs.forEach(img->imgService.deleteImg(img, imgPath)); } } diff --git a/src/main/java/NextLevel/demo/user/service/LoginService.java b/src/main/java/NextLevel/demo/user/service/LoginService.java index bd68209..317a338 100644 --- a/src/main/java/NextLevel/demo/user/service/LoginService.java +++ b/src/main/java/NextLevel/demo/user/service/LoginService.java @@ -2,6 +2,7 @@ import NextLevel.demo.funding.service.CouponService; import NextLevel.demo.img.entity.ImgEntity; +import NextLevel.demo.img.service.ImgPath; import NextLevel.demo.img.service.ImgServiceImpl; import NextLevel.demo.img.service.ImgTransaction; import NextLevel.demo.user.dto.RequestUserCreateDto; @@ -68,13 +69,13 @@ public UserDetailEntity socialLogin(RequestUserCreateDto socialLoginDto) { // user UserController : post register @ImgTransaction @Transactional - public UserDetailEntity register(@Valid RequestUserCreateDto dto, ArrayList imgPaths) { + public UserDetailEntity register(@Valid RequestUserCreateDto dto, ImgPath imgPath) { userValidateService.checkEmailAndNickNameElseThrow(dto.getEmail(), dto.getNickName()); // save img get uri ImgEntity savedImg = null; try { - savedImg = imgService.saveImg(dto.getImg(), imgPaths); + savedImg = imgService.saveImg(dto.getImg(), imgPath); }catch (CustomException e) {;} dto.setImgEntity(savedImg); diff --git a/src/main/java/NextLevel/demo/user/service/UserService.java b/src/main/java/NextLevel/demo/user/service/UserService.java index 732cb8a..d01dcc4 100644 --- a/src/main/java/NextLevel/demo/user/service/UserService.java +++ b/src/main/java/NextLevel/demo/user/service/UserService.java @@ -2,6 +2,7 @@ import NextLevel.demo.exception.CustomException; import NextLevel.demo.exception.ErrorCode; +import NextLevel.demo.img.service.ImgPath; import NextLevel.demo.img.service.ImgService; import NextLevel.demo.img.service.ImgTransaction; import NextLevel.demo.project.project.dto.response.ResponseProjectListDto; @@ -93,7 +94,7 @@ public void updateUserPassword(RequestUpdatePasswordDto dto) { @ImgTransaction @Transactional - public UserEntity updateUserImg(Long userId, MultipartFile img, ArrayList imgPaths) { + public UserEntity updateUserImg(Long userId, MultipartFile img, ImgPath imgPath) { UserEntity oldUser = userRepository.findById(userId).orElseThrow( ()->{throw new CustomException(ErrorCode.ACCESS_TOKEN_ERROR);} ); @@ -101,9 +102,9 @@ public UserEntity updateUserImg(Long userId, MultipartFile img, ArrayList throw new CustomException(ErrorCode.INPUT_REQUIRED_PARAMETER); if(oldUser.getImg() == null) - oldUser.setImg(imgService.saveImg(img, imgPaths)); + oldUser.setImg(imgService.saveImg(img, imgPath)); else - imgService.updateImg(img, oldUser.getImg(), imgPaths); + imgService.updateImg(img, oldUser.getImg(), imgPath); return oldUser; } diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 749817d..818cfda 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -169,4 +169,4 @@ spring: # org.hibernate.SQL: debug # org.hibernate.type.descriptor.sql: trace # org.hibernate.type.descriptor.sql.BasicBinder: trace -# org.hibernate.orm.jdbc.bind: trace \ No newline at end of file +# org.hibernate.orm.jdbc.bind: trace diff --git a/src/test/java/NextLevel/demo/img/ImgServiceTest.java b/src/test/java/NextLevel/demo/img/ImgServiceTest.java index 764f078..d95ba8d 100644 --- a/src/test/java/NextLevel/demo/img/ImgServiceTest.java +++ b/src/test/java/NextLevel/demo/img/ImgServiceTest.java @@ -72,32 +72,6 @@ public void addImgNumberTest() throws Exception { ); } - @Test - public void saveImgTest() throws Exception { - Field maxImgLen = ImgServiceImpl.class.getDeclaredField("MAX_IMG_LEN"); - maxImgLen.setAccessible(true); - maxImgLen.set(imgService, 20); - String fileName = "fileName"; - byte[] imgData = "img byte".getBytes(); - MultipartFile imgFile = new MockMultipartFile(fileName, fileName, "content type", imgData); - Mockito.mockStatic(Files.class).when(()->Files.write(Mockito.any(), Mockito.any(byte[].class))).thenReturn(Paths.get("uri")); - Mockito.mockStatic(Paths.class).when(()->Paths.get(Mockito.anyString(), Mockito.anyString(), Mockito.anyString())).then( - (joinPoint)->{ - String defaultPath = (String) joinPoint.getArguments()[1]; - String imgPath = (String) joinPoint.getArguments()[2]; - return Paths.get(defaultPath + imgPath); - } - ); - - ArrayList paths = new ArrayList<>(); - ImgEntity imgEntity = imgService.saveImg(imgFile, paths); - - Assertions.assertAll( - ()->Assertions.assertTrue(imgEntity != null,"return img entity is not null"), - ()->Assertions.assertTrue(imgEntity.getUri().contains(fileName), "img entity contains uri"), - ()->Assertions.assertTrue(paths.size() == 1, "check ArrayList") - ); - } // @Test // // testImg 폴더에 실제 저장! (resources/static/testImg 폴더 반듯이 필요!!) diff --git a/src/test/java/NextLevel/demo/img/ImgTest.java b/src/test/java/NextLevel/demo/img/ImgTest.java index 63cbedc..d8e001d 100644 --- a/src/test/java/NextLevel/demo/img/ImgTest.java +++ b/src/test/java/NextLevel/demo/img/ImgTest.java @@ -2,6 +2,7 @@ import NextLevel.demo.img.entity.ImgEntity; import NextLevel.demo.img.repository.ImgRepository; +import NextLevel.demo.img.service.ImgPath; import NextLevel.demo.img.service.ImgService; import NextLevel.demo.img.service.ImgServiceImpl; import NextLevel.demo.img.service.ImgTransaction; @@ -12,6 +13,7 @@ import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.Mockito; import org.mockito.junit.jupiter.MockitoExtension; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.mock.web.MockMultipartFile; @@ -42,11 +44,39 @@ public class ImgTest { public void setUp() { Mockito.lenient().when(imgRepository.getImgCount(Mockito.anyInt(), Mockito.anyString())).thenReturn(1L); // img count return 1; imgService = new ImgServiceImpl(imgRepository); + // db 초기화 Mockito.mockStatic(Files.class).when(()->Files.write(Mockito.any(), Mockito.any(byte[].class))).thenReturn(Paths.get("uri")); mockImgFile = new MockMultipartFile(imgName, imgName, "content type", imgData); } +// @Test +// @ImgTransaction +// public void saveImgTest(ImgPath imgPath) { +// ImgEntity img = imgService.saveImg(mockImgFile, imgPath); +// Assertions.assertThat(img.getUri()).isEqualTo(imgName); +// } + + @Transactional + @ImgTransaction + public ImgEntity testImgFail(MultipartFile imgFile, RuntimeException e, ImgPath imgPath) { + ImgEntity img = imgService.saveImg(imgFile, imgPath); + if(e != null) + throw e; + return img; + } + + @Test + public void saveImgTest() { + ImgEntity img = testImgFail(mockImgFile, null, null); + // db에 저장이 되었는지 + 파일이 존재하는지 + ImgEntity dbImg = imgRepository.findById(img.getId()).get(); + + Assertions.assertAll( + ()->Assertions.assertEquals(dbImg.getId(), img.getId(), "dbImg is not equal input img"), + ()->Assertions.assertEquals(dbImg.getUri(), img.getUri(), "dbImg not equal input img") + ); + } // @Transactional // @ImgTransaction // public ImgEntity testImgFail(MultipartFile imgFile, RuntimeException e, ImgPath imgPath) { diff --git a/src/test/java/NextLevel/demo/user/service/userService/UserServiceTest.java b/src/test/java/NextLevel/demo/user/service/userService/UserServiceTest.java index a78768d..1a4a8e9 100644 --- a/src/test/java/NextLevel/demo/user/service/userService/UserServiceTest.java +++ b/src/test/java/NextLevel/demo/user/service/userService/UserServiceTest.java @@ -3,6 +3,7 @@ import NextLevel.demo.exception.CustomException; import NextLevel.demo.exception.ErrorCode; import NextLevel.demo.img.entity.ImgEntity; +import NextLevel.demo.img.service.ImgPath; import NextLevel.demo.img.service.ImgService; import NextLevel.demo.user.dto.user.request.RequestUpdateUserInfoDto; import NextLevel.demo.user.entity.UserEntity; @@ -146,7 +147,7 @@ public void updateUserImgWithNull() { Assertions.assertThrows( CustomException.class, - ()->userService.updateUserImg(1L, null, new ArrayList()) + ()->userService.updateUserImg(1L, null, new ImgPath()) ); } @@ -158,7 +159,7 @@ public void updateUserImgSuccessWhenHaveOldImg() { Mockito.when(userRepository.findById(Mockito.anyLong())).thenReturn(Optional.of(mockUser)); ArgumentCaptor> captor = ArgumentCaptor.forClass(ArrayList.class); - UserEntity user = userService.updateUserImg(0L, Mockito.mock(MultipartFile.class) , new ArrayList()); + UserEntity user = userService.updateUserImg(0L, Mockito.mock(MultipartFile.class) , new ImgPath()); Assertions.assertEquals(oldImg, user.getImg()); } @@ -168,7 +169,7 @@ public void updateUserImgSuccessWhenNoOldImg() { mockUser.setImg(null); Mockito.when(userRepository.findById(Mockito.anyLong())).thenReturn(Optional.of(mockUser)); - UserEntity user = userService.updateUserImg(0L, Mockito.mock(MultipartFile.class), new ArrayList()); + UserEntity user = userService.updateUserImg(0L, Mockito.mock(MultipartFile.class), new ImgPath()); Assertions.assertEquals(mockImg, user.getImg()); }