diff --git a/src/docs/asciidoc/member.adoc b/src/docs/asciidoc/member.adoc new file mode 100644 index 00000000..9390883c --- /dev/null +++ b/src/docs/asciidoc/member.adoc @@ -0,0 +1,158 @@ += Spring REST Docs +:toc: left +:toclevels: 2 +:sectlinks: + +[[resources-post]] +== 회원 + +[[resources-post-create]] +=== 회원 가입 + +==== HTTP request +include::{snippets}/member-signup/http-request.adoc[] + + +==== HTTP response +include::{snippets}/member-signup/http-response.adoc[] + +==== response-body 설명 +include::{snippets}/member-signup/response-fields.adoc[] + + + +=== 프로필 이미지 변경 + +==== HTTP request +include::{snippets}/member-change-profile-image/http-request.adoc[] + +==== HTTP response +include::{snippets}/member-change-profile-image/http-response.adoc[] + +==== response-body 설명 +include::{snippets}/member-change-profile-image/response-fields.adoc[] + + +=== 임시 비밀번호 발급 + +==== HTTP request +include::{snippets}/member-temporary-password/http-request.adoc[] + +==== request-body 설명 +include::{snippets}/member-temporary-password/request-fields.adoc[] + +==== HTTP response +include::{snippets}/member-temporary-password/http-response.adoc[] + +==== response-body 설명 +include::{snippets}/email-verification-send/response-fields.adoc[] + + +=== 비밀번호 변경 + +==== HTTP request + +include::{snippets}/member-change-password/http-request.adoc[] + +==== request-body 설명 +include::{snippets}/member-change-password/request-fields.adoc[] + +==== HTTP response + +include::{snippets}/member-change-password/http-response.adoc[] + +==== response-body 설명 +include::{snippets}/member-change-password/response-fields.adoc[] + + + + +=== 회원 탈퇴 + +==== HTTP request + +include::{snippets}/member-withdraw/http-request.adoc[] + + +==== HTTP response + +include::{snippets}/member-withdraw/http-response.adoc[] + +==== response-body 설명 +include::{snippets}/member-withdraw/response-fields.adoc[] + + + + + +=== 회원 상태 + +==== HTTP request + +include::{snippets}/member-get-status/http-request.adoc[] + + +==== HTTP response + +include::{snippets}/member-get-status/http-response.adoc[] + +==== response-body 설명 +include::{snippets}/member-get-status/response-fields.adoc[] + + + + +=== 개인 정보 조회 + +==== HTTP request + +include::{snippets}/member-get-member-page/http-request.adoc[] + + +==== HTTP response + +include::{snippets}/member-get-member-page/http-response.adoc[] + +==== response-body 설명 +include::{snippets}/member-get-member-page/response-fields.adoc[] + + + + +=== 자기소개 변경 + +==== HTTP request + +include::{snippets}/member-change-about-me/http-request.adoc[] + +==== request-body 설명 +include::{snippets}/member-change-about-me/request-fields.adoc[] + + + +==== HTTP response + +include::{snippets}/member-change-about-me/http-response.adoc[] + +==== response-body 설명 +include::{snippets}/member-change-about-me/response-fields.adoc[] + + + +=== MBTI 변경 + +==== HTTP request + +include::{snippets}/member-change-mbti/http-request.adoc[] + +==== request-body 설명 +include::{snippets}/member-change-mbti/request-fields.adoc[] + + + +==== HTTP response + +include::{snippets}/member-change-mbti/http-response.adoc[] + +==== response-body 설명 +include::{snippets}/member-change-mbti/response-fields.adoc[] \ No newline at end of file diff --git a/src/main/java/com/aliens/backend/auth/domain/Member.java b/src/main/java/com/aliens/backend/auth/domain/Member.java index 3ec76785..ff2bcbf2 100644 --- a/src/main/java/com/aliens/backend/auth/domain/Member.java +++ b/src/main/java/com/aliens/backend/auth/domain/Member.java @@ -1,6 +1,12 @@ package com.aliens.backend.auth.domain; import com.aliens.backend.auth.controller.dto.LoginMember; +import com.aliens.backend.member.controller.dto.MemberPage; +import com.aliens.backend.member.domain.Image; +import com.aliens.backend.member.domain.MemberInfo; +import com.aliens.backend.member.domain.MemberStatus; +import com.aliens.backend.member.controller.dto.EncodedSignUp; +import com.aliens.backend.uploader.S3File; import jakarta.persistence.*; import java.util.ArrayList; @@ -14,6 +20,9 @@ public class Member { @Column private Long id; + @Column + private String name; + @Column private String email; @@ -21,30 +30,80 @@ public class Member { private String password; @Column - private MemberRole role; + private MemberRole role = MemberRole.MEMBER; + + @Column + private MemberStatus status = MemberStatus.NOT_APPLIED_NOT_MATCHED; + + @Column + private Boolean withdraw = false; - @OneToMany(mappedBy = "member", cascade = CascadeType.REMOVE) + @OneToMany(mappedBy = "member", + cascade = {CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REMOVE}) private List tokens = new ArrayList<>(); + @OneToOne(cascade = {CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REMOVE}) + @JoinColumn(name = "image_id") + private Image image; + + @OneToOne(mappedBy = "member", + cascade = {CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REMOVE}) + private MemberInfo memberInfo; + protected Member() { } - public Member(final String email, final String password, final MemberRole role) { - this.email = email; + public static Member of(final EncodedSignUp request, final Image image) { + Member member = new Member(); + member.name = request.name(); + member.email = request.email(); + member.password = request.password(); + member.image = image; + return member; + } + + public void changePassword(final String password) { this.password = password; - this.role = role; + } + + public void putMemberInfo(final MemberInfo memberInfo) { + this.memberInfo = memberInfo; } public boolean isCorrectPassword(String password) { return this.password.equals(password); } + public void withdraw() { + withdraw = true; + } + public LoginMember getLoginMember() { - return new LoginMember(id,role); + return new LoginMember(id, role); + } + + public MemberPage getMemberPage() { + return new MemberPage(name, image.getURL()); + } + + public boolean isWithdraw() { + return withdraw; + } + + public String getStatus() { + return status.getMessage(); + } + + public String getProfileName() { + return image.getName(); + } + + public void changeProfileImage(final S3File newFile) { + image.change(newFile); } @Override public String toString() { - return String.format("email: %s, password : %s, role : %s", this.email, this.password, this.role); + return String.format("email: %s, role : %s", this.email, this.role); } } \ No newline at end of file diff --git a/src/main/java/com/aliens/backend/auth/domain/repository/MemberRepository.java b/src/main/java/com/aliens/backend/auth/domain/repository/MemberRepository.java index 960c9431..674370a6 100644 --- a/src/main/java/com/aliens/backend/auth/domain/repository/MemberRepository.java +++ b/src/main/java/com/aliens/backend/auth/domain/repository/MemberRepository.java @@ -9,4 +9,5 @@ @Repository public interface MemberRepository extends JpaRepository { Optional findByEmail(String email); + Optional findByEmailAndName(String email, String name); } diff --git a/src/main/java/com/aliens/backend/auth/service/AuthService.java b/src/main/java/com/aliens/backend/auth/service/AuthService.java index 137f00b7..2bfaa408 100644 --- a/src/main/java/com/aliens/backend/auth/service/AuthService.java +++ b/src/main/java/com/aliens/backend/auth/service/AuthService.java @@ -40,7 +40,11 @@ public AuthToken login(LoginRequest loginRequest) { } private Member getMemberEntityFromEmail(final String email) { - return memberRepository.findByEmail(email).orElseThrow(() -> new RestApiException(MemberError.NULL_MEMBER)); + Member member = memberRepository.findByEmail(email).orElseThrow(() -> new RestApiException(MemberError.NULL_MEMBER)); + if (member.isWithdraw()) { + throw new RestApiException(MemberError.WITHDRAW_MEMBER); + } + return member; } private void passwordCheck(final String password, final Member member) { diff --git a/src/main/java/com/aliens/backend/email/domain/EmailAuthentication.java b/src/main/java/com/aliens/backend/email/domain/EmailAuthentication.java index 4e18f23e..187fbe06 100644 --- a/src/main/java/com/aliens/backend/email/domain/EmailAuthentication.java +++ b/src/main/java/com/aliens/backend/email/domain/EmailAuthentication.java @@ -3,7 +3,7 @@ import jakarta.persistence.*; @Entity -@Table(schema = "EMAIL_AUTHENTICATION") +@Table(name = "EMAIL_AUTHENTICATION") public class EmailAuthentication { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) diff --git a/src/main/java/com/aliens/backend/email/service/EmailContent.java b/src/main/java/com/aliens/backend/email/service/EmailContent.java index 3cde1922..33bc29ef 100644 --- a/src/main/java/com/aliens/backend/email/service/EmailContent.java +++ b/src/main/java/com/aliens/backend/email/service/EmailContent.java @@ -5,11 +5,11 @@ @Component public class EmailContent { - public String getTitle() { + public String getAuthenticationMailTitle() { return "[FriendShip] Account Verification 회원가입 이메일 인증"; } - public String getContent(String token, String domainUrl) { + public String getAuthenticationMailContent(String token, String domainUrl) { String englishContent = "Thank you for registering with FriendShip App.\n" + "To ensure the security of your account, we need to verify your email address.\n\n" + "Please click the link below to verify your email and activate your account:\n" @@ -38,4 +38,16 @@ public String getContent(String token, String domainUrl) { return englishContent + koreanContent; } + + public String getTemporaryMailTitle() { + return "[FriendShip] 임시 비밀번호 발급"; + } + + public String getTemporaryMailContent(final String tmpPassword) { + String englishContent = "The temporary password has been issued. Your temporary password is: " + tmpPassword; + + String koreanContent = "임시 비밀번호가 발급되었습니다. 임시 비밀번호는 다음과 같습니다: " + tmpPassword; + + return englishContent + "\n\n" + koreanContent; + } } diff --git a/src/main/java/com/aliens/backend/email/service/EmailSender.java b/src/main/java/com/aliens/backend/email/service/EmailSender.java index 66565afb..059b4ace 100644 --- a/src/main/java/com/aliens/backend/email/service/EmailSender.java +++ b/src/main/java/com/aliens/backend/email/service/EmailSender.java @@ -1,6 +1,7 @@ package com.aliens.backend.email.service; import com.aliens.backend.global.property.EmailProperties; +import com.aliens.backend.member.controller.dto.event.TemporaryPasswordEvent; import org.springframework.mail.SimpleMailMessage; import org.springframework.mail.javamail.JavaMailSender; import org.springframework.stereotype.Component; @@ -28,10 +29,25 @@ public void sendAuthenticationEmail(final String email, final String emailToken) private SimpleMailMessage createAuthenticationMail(final String email, final String emailToken) { SimpleMailMessage authenticationEmail = new SimpleMailMessage(); authenticationEmail.setTo(email); - authenticationEmail.setSubject(emailContent.getTitle()); + authenticationEmail.setSubject(emailContent.getAuthenticationMailTitle()); - String content = emailContent.getContent(emailToken, emailProperties.getDomainUrl()); + String content = emailContent.getAuthenticationMailContent(emailToken, emailProperties.getDomainUrl()); authenticationEmail.setText(content); return authenticationEmail; } + + public void sendTemporaryPassword(final TemporaryPasswordEvent event) { + SimpleMailMessage mailMessage = createTemporaryPassword(event); + javaMailSender.send(mailMessage); + } + + private SimpleMailMessage createTemporaryPassword(final TemporaryPasswordEvent event) { + SimpleMailMessage temporaryPasswordEmail = new SimpleMailMessage(); + temporaryPasswordEmail.setTo(event.email()); + temporaryPasswordEmail.setSubject(emailContent.getTemporaryMailTitle()); + + String content = emailContent.getTemporaryMailContent(event.tmpPassword()); + temporaryPasswordEmail.setText(content); + return temporaryPasswordEmail; + } } diff --git a/src/main/java/com/aliens/backend/email/service/EmailService.java b/src/main/java/com/aliens/backend/email/service/EmailService.java index e4c20697..770e7052 100644 --- a/src/main/java/com/aliens/backend/email/service/EmailService.java +++ b/src/main/java/com/aliens/backend/email/service/EmailService.java @@ -6,6 +6,8 @@ import com.aliens.backend.global.encode.SymmetricKeyEncoder; import com.aliens.backend.global.error.EmailError; import com.aliens.backend.global.exception.RestApiException; +import com.aliens.backend.member.controller.dto.event.TemporaryPasswordEvent; +import org.springframework.context.event.EventListener; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -58,4 +60,9 @@ public String authenticateEmail(final String token) throws Exception { private EmailAuthentication getEmailAuthentication(final Long emailEntityId) { return emailAuthenticationRepository.findById(emailEntityId).orElseThrow(() -> new RestApiException(EmailError.NULL_EMAIL)); } + + @EventListener + public void listen(TemporaryPasswordEvent event) { + emailSender.sendTemporaryPassword(event); + } } diff --git a/src/main/java/com/aliens/backend/uploader/AWSConfig.java b/src/main/java/com/aliens/backend/global/config/AWSConfig.java similarity index 90% rename from src/main/java/com/aliens/backend/uploader/AWSConfig.java rename to src/main/java/com/aliens/backend/global/config/AWSConfig.java index 1a2d5a6c..97966e07 100644 --- a/src/main/java/com/aliens/backend/uploader/AWSConfig.java +++ b/src/main/java/com/aliens/backend/global/config/AWSConfig.java @@ -1,5 +1,6 @@ -package com.aliens.backend.uploader; +package com.aliens.backend.global.config; +import com.aliens.backend.global.property.S3UploadProperties; import com.amazonaws.auth.AWSStaticCredentialsProvider; import com.amazonaws.auth.BasicAWSCredentials; import com.amazonaws.services.s3.AmazonS3Client; diff --git a/src/main/java/com/aliens/backend/global/encode/SymmetricKeyEncoder.java b/src/main/java/com/aliens/backend/global/encode/SymmetricKeyEncoder.java index f8ddeb27..050c0b35 100644 --- a/src/main/java/com/aliens/backend/global/encode/SymmetricKeyEncoder.java +++ b/src/main/java/com/aliens/backend/global/encode/SymmetricKeyEncoder.java @@ -1,5 +1,7 @@ package com.aliens.backend.global.encode; +import com.aliens.backend.global.error.CommonError; +import com.aliens.backend.global.exception.RestApiException; import com.aliens.backend.global.property.SymmetricEncoderProperties; import org.springframework.stereotype.Component; @@ -16,18 +18,26 @@ public SymmetricKeyEncoder(final SymmetricEncoderProperties symmetricEncoderProp this.symmetricEncoderProperties = symmetricEncoderProperties; } - public String encrypt(String plaintext) throws Exception { - Cipher cipher = Cipher.getInstance("AES"); - cipher.init(Cipher.ENCRYPT_MODE, symmetricEncoderProperties.getEncodeKey()); - byte[] encryptedBytes = cipher.doFinal(plaintext.getBytes(StandardCharsets.UTF_8)); - return Base64.getEncoder().encodeToString(encryptedBytes); + public String encrypt(String plaintext) { + try { + Cipher cipher = Cipher.getInstance(symmetricEncoderProperties.getChipper()); + cipher.init(Cipher.ENCRYPT_MODE, symmetricEncoderProperties.getEncodeKey()); + byte[] encryptedBytes = cipher.doFinal(plaintext.getBytes(StandardCharsets.UTF_8)); + return Base64.getEncoder().encodeToString(encryptedBytes); + } catch (Exception e) { + throw new RestApiException(CommonError.ENCODE_ERROR); + } } - public String decrypt(String ciphertext) throws Exception { - Cipher cipher = Cipher.getInstance("AES"); - cipher.init(Cipher.DECRYPT_MODE, symmetricEncoderProperties.getEncodeKey()); - byte[] decodedBytes = Base64.getDecoder().decode(ciphertext); - byte[] decryptedBytes = cipher.doFinal(decodedBytes); - return new String(decryptedBytes, StandardCharsets.UTF_8); + public String decrypt(String ciphertext) { + try { + Cipher cipher = Cipher.getInstance(symmetricEncoderProperties.getChipper()); + cipher.init(Cipher.DECRYPT_MODE, symmetricEncoderProperties.getEncodeKey()); + byte[] decodedBytes = Base64.getDecoder().decode(ciphertext); + byte[] decryptedBytes = cipher.doFinal(decodedBytes); + return new String(decryptedBytes, StandardCharsets.UTF_8); + } catch (Exception e) { + throw new RestApiException(CommonError.ENCODE_ERROR); + } } } diff --git a/src/main/java/com/aliens/backend/global/error/CommonError.java b/src/main/java/com/aliens/backend/global/error/CommonError.java index fd278ed6..d710d59a 100644 --- a/src/main/java/com/aliens/backend/global/error/CommonError.java +++ b/src/main/java/com/aliens/backend/global/error/CommonError.java @@ -4,7 +4,8 @@ public enum CommonError implements ErrorCode { - INTERNAL_SERVER_ERROR(HttpStatus.NOT_FOUND, "S1", "에러"); + INTERNAL_SERVER_ERROR(HttpStatus.NOT_FOUND, "S1", "에러"), + ENCODE_ERROR(HttpStatus.BANDWIDTH_LIMIT_EXCEEDED,"S2" ,"암-복호화 실패" ); private final HttpStatus httpStatusCode; private final String developCode; diff --git a/src/main/java/com/aliens/backend/global/error/EmailError.java b/src/main/java/com/aliens/backend/global/error/EmailError.java index 6d344b8f..2d0ff139 100644 --- a/src/main/java/com/aliens/backend/global/error/EmailError.java +++ b/src/main/java/com/aliens/backend/global/error/EmailError.java @@ -5,6 +5,7 @@ public enum EmailError implements ErrorCode { NULL_EMAIL(HttpStatus.UNPROCESSABLE_ENTITY, "E1", "해당 EmailAuthentication 엔티티 조회 불가"), + NOT_AUTHENTICATED_EMAIL(HttpStatus.UNPROCESSABLE_ENTITY, "E2", "인증되지 않은 이메일"), ; private final HttpStatus httpStatusCode; diff --git a/src/main/java/com/aliens/backend/global/error/MemberError.java b/src/main/java/com/aliens/backend/global/error/MemberError.java index 6999d5f6..d8ef8ac4 100644 --- a/src/main/java/com/aliens/backend/global/error/MemberError.java +++ b/src/main/java/com/aliens/backend/global/error/MemberError.java @@ -8,7 +8,7 @@ public enum MemberError implements ErrorCode { INVALID_EMAIL(HttpStatus.BAD_REQUEST, "M2", "올바르지 않은 형식의 이메일"), NULL_MEMBER(HttpStatus.UNPROCESSABLE_ENTITY, "M3", "해당 Member 엔티티 조회 불가"), INCORRECT_PASSWORD(HttpStatus.SERVICE_UNAVAILABLE, "M4", "비밀번호 틀림"), - ; + WITHDRAW_MEMBER(HttpStatus.BAD_REQUEST,"M5" ,"탈퇴한 회원에 대한 접근" ); private final HttpStatus httpStatusCode; private final String developCode; diff --git a/src/main/java/com/aliens/backend/uploader/S3UploadProperties.java b/src/main/java/com/aliens/backend/global/property/S3UploadProperties.java similarity index 67% rename from src/main/java/com/aliens/backend/uploader/S3UploadProperties.java rename to src/main/java/com/aliens/backend/global/property/S3UploadProperties.java index 1329fd30..43845eb5 100644 --- a/src/main/java/com/aliens/backend/uploader/S3UploadProperties.java +++ b/src/main/java/com/aliens/backend/global/property/S3UploadProperties.java @@ -1,4 +1,4 @@ -package com.aliens.backend.uploader; +package com.aliens.backend.global.property; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; @@ -18,6 +18,12 @@ public class S3UploadProperties { @Value("${cloud.aws.region.static}") private String region; + @Value("${cloud.aws.default.file-name}") + private String fileName; + + @Value("${cloud.aws.default.file-url}") + private String fileUrl; + public String getBucket() { return bucket; } @@ -33,4 +39,12 @@ public String getSecretKey() { public String getRegion() { return region; } + + public String getDefaultFileName() { + return fileName; + } + + public String getDefaultFileURL() { + return fileUrl; + } } \ No newline at end of file diff --git a/src/main/java/com/aliens/backend/global/property/SymmetricEncoderProperties.java b/src/main/java/com/aliens/backend/global/property/SymmetricEncoderProperties.java index 1ac075ea..d3b62394 100644 --- a/src/main/java/com/aliens/backend/global/property/SymmetricEncoderProperties.java +++ b/src/main/java/com/aliens/backend/global/property/SymmetricEncoderProperties.java @@ -13,6 +13,9 @@ public class SymmetricEncoderProperties { @Value("${encode.symmetric.key}") private String secretKey; + @Value("${encode.symmetric.chipper}") + private String chipper; + private SecretKeySpec encodeKey; @PostConstruct @@ -24,4 +27,8 @@ public void init() { public SecretKeySpec getEncodeKey() { return encodeKey; } + + public String getChipper() { + return chipper; + } } diff --git a/src/main/java/com/aliens/backend/member/controller/MemberController.java b/src/main/java/com/aliens/backend/member/controller/MemberController.java new file mode 100644 index 00000000..83b30708 --- /dev/null +++ b/src/main/java/com/aliens/backend/member/controller/MemberController.java @@ -0,0 +1,92 @@ +package com.aliens.backend.member.controller; + +import com.aliens.backend.auth.controller.dto.LoginMember; +import com.aliens.backend.global.config.resolver.Login; +import com.aliens.backend.member.controller.dto.request.SignUpRequest; +import com.aliens.backend.member.controller.dto.request.TemporaryPasswordRequest; +import com.aliens.backend.member.controller.dto.response.MemberPageResponse; +import com.aliens.backend.member.sevice.MemberInfoService; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; + +import java.util.Collections; +import java.util.Map; + +@RequestMapping("/members") +@RestController +public class MemberController { + + private final MemberInfoService memberInfoService; + + public MemberController(final MemberInfoService memberInfoService) { + this.memberInfoService = memberInfoService; + } + + @PostMapping() + public ResponseEntity> signUp(@RequestPart SignUpRequest signUpRequest, + @RequestPart MultipartFile profileImage) { + String result = memberInfoService.signUp(signUpRequest, profileImage); + Map response = Collections.singletonMap("response", result); + return ResponseEntity.ok(response); + } + + @PostMapping("/temporary-password") + public ResponseEntity> temporaryPassword(@RequestBody TemporaryPasswordRequest request) { + String result = memberInfoService.generateTemporaryPassword(request); + Map response = Collections.singletonMap("response", result); + return ResponseEntity.ok(response); + } + + @PatchMapping("/password") + public ResponseEntity> changePassword(@Login LoginMember loginMember, + @RequestBody String newPassword ) { + String result = memberInfoService.changePassword(loginMember, newPassword); + Map response = Collections.singletonMap("response", result); + return ResponseEntity.ok(response); + } + + @PostMapping("/profile-image") + public ResponseEntity> changeProfileImage(@Login LoginMember loginMember, + @RequestPart MultipartFile newProfileImage) { + String result = memberInfoService.changeProfileImage(loginMember, newProfileImage); + Map response = Collections.singletonMap("response", result); + return ResponseEntity.ok(response); + } + + @PatchMapping("/about-me") + public ResponseEntity> changeAboutMe(@Login LoginMember loginMember, + @RequestBody String newAboutMe) { + String result = memberInfoService.changeAboutMe(loginMember, newAboutMe); + Map response = Collections.singletonMap("response", result); + return ResponseEntity.ok(response); + } + + @PatchMapping("/mbti") + public ResponseEntity> changeMBTI(@Login LoginMember loginMember, + @RequestBody String newMBTI) { + String result = memberInfoService.changeMBTI(loginMember, newMBTI); + Map response = Collections.singletonMap("response", result); + return ResponseEntity.ok(response); + } + + @PatchMapping("/withdraw") + public ResponseEntity> withdraw(@Login LoginMember loginMember) { + String result = memberInfoService.withdraw(loginMember); + Map response = Collections.singletonMap("response", result); + return ResponseEntity.ok(response); + } + + @GetMapping("/status") + public ResponseEntity> getStatus(@Login LoginMember loginMember) { + String result = memberInfoService.getStatus(loginMember); + Map response = Collections.singletonMap("response", result); + return ResponseEntity.ok(response); + } + + @GetMapping() + public ResponseEntity getMemberPage(@Login LoginMember loginMember) { + MemberPageResponse result = memberInfoService.getMemberPage(loginMember); + return ResponseEntity.ok(result); + } +} diff --git a/src/main/java/com/aliens/backend/member/controller/dto/EncodedMember.java b/src/main/java/com/aliens/backend/member/controller/dto/EncodedMember.java new file mode 100644 index 00000000..8fbd9e33 --- /dev/null +++ b/src/main/java/com/aliens/backend/member/controller/dto/EncodedMember.java @@ -0,0 +1,8 @@ +package com.aliens.backend.member.controller.dto; + +public record EncodedMember(String gender, + String mbti, + String birthday, + String nationality, + String aboutMe){ +} diff --git a/src/main/java/com/aliens/backend/member/controller/dto/EncodedMemberPage.java b/src/main/java/com/aliens/backend/member/controller/dto/EncodedMemberPage.java new file mode 100644 index 00000000..7ac29ba3 --- /dev/null +++ b/src/main/java/com/aliens/backend/member/controller/dto/EncodedMemberPage.java @@ -0,0 +1,8 @@ +package com.aliens.backend.member.controller.dto; + +public record EncodedMemberPage(String mbti, + String gender, + String nationality, + String birthday, + String aboutMe) { +} diff --git a/src/main/java/com/aliens/backend/member/controller/dto/EncodedSignUp.java b/src/main/java/com/aliens/backend/member/controller/dto/EncodedSignUp.java new file mode 100644 index 00000000..b52435c5 --- /dev/null +++ b/src/main/java/com/aliens/backend/member/controller/dto/EncodedSignUp.java @@ -0,0 +1,6 @@ +package com.aliens.backend.member.controller.dto; + +public record EncodedSignUp(String name, + String email, + String password) { +} diff --git a/src/main/java/com/aliens/backend/member/controller/dto/MemberPage.java b/src/main/java/com/aliens/backend/member/controller/dto/MemberPage.java new file mode 100644 index 00000000..436fbde0 --- /dev/null +++ b/src/main/java/com/aliens/backend/member/controller/dto/MemberPage.java @@ -0,0 +1,5 @@ +package com.aliens.backend.member.controller.dto; + +public record MemberPage(String name, + String profileImageURL) { +} diff --git a/src/main/java/com/aliens/backend/member/controller/dto/event/TemporaryPasswordEvent.java b/src/main/java/com/aliens/backend/member/controller/dto/event/TemporaryPasswordEvent.java new file mode 100644 index 00000000..23482065 --- /dev/null +++ b/src/main/java/com/aliens/backend/member/controller/dto/event/TemporaryPasswordEvent.java @@ -0,0 +1,4 @@ +package com.aliens.backend.member.controller.dto.event; + +public record TemporaryPasswordEvent(String email, String tmpPassword){ +} diff --git a/src/main/java/com/aliens/backend/member/controller/dto/request/SignUpRequest.java b/src/main/java/com/aliens/backend/member/controller/dto/request/SignUpRequest.java new file mode 100644 index 00000000..75fc3462 --- /dev/null +++ b/src/main/java/com/aliens/backend/member/controller/dto/request/SignUpRequest.java @@ -0,0 +1,11 @@ +package com.aliens.backend.member.controller.dto.request; + +public record SignUpRequest(String email, + String password, + String name, + String mbti, + String gender, + String nationality, + String birthday, + String aboutMe) { +} \ No newline at end of file diff --git a/src/main/java/com/aliens/backend/member/controller/dto/request/TemporaryPasswordRequest.java b/src/main/java/com/aliens/backend/member/controller/dto/request/TemporaryPasswordRequest.java new file mode 100644 index 00000000..374502e0 --- /dev/null +++ b/src/main/java/com/aliens/backend/member/controller/dto/request/TemporaryPasswordRequest.java @@ -0,0 +1,4 @@ +package com.aliens.backend.member.controller.dto.request; + +public record TemporaryPasswordRequest(String email, String name) { +} diff --git a/src/main/java/com/aliens/backend/member/controller/dto/response/MemberPageResponse.java b/src/main/java/com/aliens/backend/member/controller/dto/response/MemberPageResponse.java new file mode 100644 index 00000000..5d5f2bfc --- /dev/null +++ b/src/main/java/com/aliens/backend/member/controller/dto/response/MemberPageResponse.java @@ -0,0 +1,11 @@ +package com.aliens.backend.member.controller.dto.response; + + +public record MemberPageResponse(String name, + String mbti, + String gender, + String nationality, + String birthday, + String selfIntroduction, + String profileImageURL) { +} diff --git a/src/main/java/com/aliens/backend/member/controller/dto/response/MemberResponse.java b/src/main/java/com/aliens/backend/member/controller/dto/response/MemberResponse.java new file mode 100644 index 00000000..c94b8483 --- /dev/null +++ b/src/main/java/com/aliens/backend/member/controller/dto/response/MemberResponse.java @@ -0,0 +1,22 @@ +package com.aliens.backend.member.controller.dto.response; + +public enum MemberResponse { + + SIGN_UP_SUCCESS("회원가입이 완료되었습니다."), + WITHDRAW_SUCCESS("회원 탈퇴되었습니다."), + TEMPORARY_PASSWORD_GENERATED_SUCCESS("임시 비밀번호가 발급되었습니다. 이메일을 확인해주세요."), + PASSWORD_CHANGE_SUCCESS("비밀번호 변경이 완료되었습니다."), + PROFILE_IMAGE_CHANGE_SUCCESS("프로필 이미지 변경이 완료되었습니다."), + ABOUT_ME_CHANGE_SUCCESS("자기소개 변경이 완료되었습니다."), + MBTI_CHANGE_SUCCESS("MBTI 변경이 완료되었습니다."); + + private final String message; + + MemberResponse(final String message) { + this.message = message; + } + + public String getMessage() { + return message; + } +} \ No newline at end of file diff --git a/src/main/java/com/aliens/backend/member/domain/Image.java b/src/main/java/com/aliens/backend/member/domain/Image.java new file mode 100644 index 00000000..25ea0fc6 --- /dev/null +++ b/src/main/java/com/aliens/backend/member/domain/Image.java @@ -0,0 +1,41 @@ +package com.aliens.backend.member.domain; + +import com.aliens.backend.uploader.S3File; +import jakarta.persistence.*; + +@Entity +public class Image { + + @Id @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column + private Long id; + + @Column + String name; + + @Column + String url; + + protected Image() { + } + + public static Image from(final S3File imageFile) { + Image image = new Image(); + image.name = imageFile.fileName(); + image.url = imageFile.fileURL(); + return image; + } + + public void change(final S3File newFile) { + name = newFile.fileName(); + url = newFile.fileURL(); + } + + public String getName() { + return name; + } + + public String getURL() { + return url; + } +} diff --git a/src/main/java/com/aliens/backend/member/domain/MemberInfo.java b/src/main/java/com/aliens/backend/member/domain/MemberInfo.java new file mode 100644 index 00000000..9768957c --- /dev/null +++ b/src/main/java/com/aliens/backend/member/domain/MemberInfo.java @@ -0,0 +1,59 @@ +package com.aliens.backend.member.domain; + +import com.aliens.backend.auth.domain.Member; +import com.aliens.backend.member.controller.dto.EncodedMember; +import com.aliens.backend.member.controller.dto.EncodedMemberPage; +import jakarta.persistence.*; + +@Entity +public class MemberInfo { + + @Id + private Long id; + + @MapsId + @OneToOne(cascade = {CascadeType.PERSIST,CascadeType.MERGE}) + @JoinColumn(name = "id") + private Member member; + + @Column + private String mbti; + + @Column + private String gender; + + @Column + private String nationality; + + @Column + private String birthday; + + @Column(name = "about_me") + private String aboutMe; + + protected MemberInfo() { + } + + public static MemberInfo of(EncodedMember request, Member member) { + MemberInfo memberInfo = new MemberInfo(); + memberInfo.member =member; + memberInfo.gender = request.gender(); + memberInfo.mbti = request.mbti(); + memberInfo.nationality = request.nationality(); + memberInfo.birthday = request.birthday(); + memberInfo.aboutMe = request.aboutMe(); + return memberInfo; + } + + public void changeAboutMe(final String newAboutMe) { + aboutMe = newAboutMe; + } + + public void changeMBTI(final String newMBTI) { + mbti = newMBTI; + } + + public EncodedMemberPage getMemberPage() { + return new EncodedMemberPage(mbti,gender,nationality,birthday,aboutMe); + } +} diff --git a/src/main/java/com/aliens/backend/member/domain/MemberStatus.java b/src/main/java/com/aliens/backend/member/domain/MemberStatus.java new file mode 100644 index 00000000..a1389901 --- /dev/null +++ b/src/main/java/com/aliens/backend/member/domain/MemberStatus.java @@ -0,0 +1,19 @@ +package com.aliens.backend.member.domain; + +public enum MemberStatus { + + APPLIED_MATCHED("AppliedAndMatched"), + NOT_APPLIED_MATCHED("NotAppliedAndMatched"), + APPLIED_NOT_MATCHED("AppliedAndNotMatched"), + NOT_APPLIED_NOT_MATCHED("NotAppliedAndNotMatched"); + + private final String message; + + MemberStatus(final String message) { + this.message = message; + } + + public String getMessage() { + return message; + } +} \ No newline at end of file diff --git a/src/main/java/com/aliens/backend/member/domain/repository/ImageRepository.java b/src/main/java/com/aliens/backend/member/domain/repository/ImageRepository.java new file mode 100644 index 00000000..4416b3de --- /dev/null +++ b/src/main/java/com/aliens/backend/member/domain/repository/ImageRepository.java @@ -0,0 +1,9 @@ +package com.aliens.backend.member.domain.repository; + +import com.aliens.backend.member.domain.Image; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface ImageRepository extends JpaRepository { +} diff --git a/src/main/java/com/aliens/backend/member/domain/repository/MemberInfoRepository.java b/src/main/java/com/aliens/backend/member/domain/repository/MemberInfoRepository.java new file mode 100644 index 00000000..38008a41 --- /dev/null +++ b/src/main/java/com/aliens/backend/member/domain/repository/MemberInfoRepository.java @@ -0,0 +1,9 @@ +package com.aliens.backend.member.domain.repository; + +import com.aliens.backend.member.domain.MemberInfo; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface MemberInfoRepository extends JpaRepository { +} diff --git a/src/main/java/com/aliens/backend/member/sevice/MemberInfoService.java b/src/main/java/com/aliens/backend/member/sevice/MemberInfoService.java new file mode 100644 index 00000000..61a3e966 --- /dev/null +++ b/src/main/java/com/aliens/backend/member/sevice/MemberInfoService.java @@ -0,0 +1,226 @@ +package com.aliens.backend.member.sevice; + +import com.aliens.backend.auth.controller.dto.LoginMember; +import com.aliens.backend.auth.domain.Member; +import com.aliens.backend.auth.domain.repository.MemberRepository; +import com.aliens.backend.auth.service.PasswordEncoder; +import com.aliens.backend.email.domain.EmailAuthentication; +import com.aliens.backend.email.domain.repository.EmailAuthenticationRepository; +import com.aliens.backend.global.encode.SymmetricKeyEncoder; +import com.aliens.backend.global.error.EmailError; +import com.aliens.backend.global.error.MemberError; +import com.aliens.backend.global.exception.RestApiException; +import com.aliens.backend.global.property.S3UploadProperties; +import com.aliens.backend.member.controller.dto.*; +import com.aliens.backend.member.controller.dto.event.TemporaryPasswordEvent; +import com.aliens.backend.member.controller.dto.request.TemporaryPasswordRequest; +import com.aliens.backend.member.controller.dto.response.MemberPageResponse; +import com.aliens.backend.member.controller.dto.response.MemberResponse; +import com.aliens.backend.member.controller.dto.request.SignUpRequest; +import com.aliens.backend.member.domain.*; +import com.aliens.backend.member.domain.repository.MemberInfoRepository; +import com.aliens.backend.uploader.AwsS3Uploader; +import com.aliens.backend.uploader.S3File; +import org.springframework.context.ApplicationEventPublisher; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.multipart.MultipartFile; + +import java.util.*; + +@Service +public class MemberInfoService { + private final AwsS3Uploader uploader; + private final SymmetricKeyEncoder symmetricKeyEncoder; + private final PasswordEncoder passwordEncoder; + private final ApplicationEventPublisher publisher; + + private final S3UploadProperties s3UploadProperties; + private final MemberRepository memberRepository; + private final MemberInfoRepository memberInfoRepository; + private final EmailAuthenticationRepository emailAuthenticationRepository; + + public MemberInfoService(final AwsS3Uploader uploader, + final SymmetricKeyEncoder symmetricKeyEncoder, + final PasswordEncoder passwordEncoder, + final ApplicationEventPublisher publisher, + final S3UploadProperties s3UploadProperties, final MemberRepository memberRepository, + final MemberInfoRepository memberInfoRepository, + final EmailAuthenticationRepository emailAuthenticationRepository) + { + this.uploader = uploader; + this.symmetricKeyEncoder = symmetricKeyEncoder; + this.passwordEncoder = passwordEncoder; + this.s3UploadProperties = s3UploadProperties; + this.memberRepository = memberRepository; + this.memberInfoRepository = memberInfoRepository; + this.emailAuthenticationRepository = emailAuthenticationRepository; + this.publisher = publisher; + } + + @Transactional + public String signUp(final SignUpRequest request, final MultipartFile profileImage) { + checkEmail(request.email()); + + Image image = saveImage(profileImage); + + Member member = getMemberEntity(request, image); + + MemberInfo memberInfo = getMemberInfoEntity(request, member); + member.putMemberInfo(memberInfo); + + memberInfoRepository.save(memberInfo); + + return MemberResponse.SIGN_UP_SUCCESS.getMessage(); + } + + private void checkEmail(final String email) { + Optional emailEntity = emailAuthenticationRepository.findByEmail(email); + if (emailEntity.isEmpty()) { + throw new RestApiException(EmailError.NULL_EMAIL); + } + if (!emailEntity.get().isAuthenticated()) { + throw new RestApiException(EmailError.NOT_AUTHENTICATED_EMAIL); + } + } + + private Image saveImage(final MultipartFile profileImage) { + if (profileImage == null || profileImage.isEmpty()) { + return Image.from(new S3File(s3UploadProperties.getDefaultFileName(), + s3UploadProperties.getDefaultFileURL())); + } + + S3File uploadedFile = uploader.upload(profileImage); + return Image.from(uploadedFile); + } + + private Member getMemberEntity(final SignUpRequest request, final Image image) { + EncodedSignUp encodedSignUp = encodeForMember(request); + return Member.of(encodedSignUp, image); + } + + private EncodedSignUp encodeForMember(final SignUpRequest request) { + return new EncodedSignUp(request.name(), request.email(), passwordEncoder.encrypt(request.password())); + } + + private MemberInfo getMemberInfoEntity(final SignUpRequest request, final Member member) { + EncodedMember encodedInfo = encodeForMemberInfo(request); + return MemberInfo.of(encodedInfo, member); + } + + private EncodedMember encodeForMemberInfo(final SignUpRequest request) { + return new EncodedMember( + symmetricKeyEncoder.encrypt(request.gender()), + symmetricKeyEncoder.encrypt(request.mbti()), + symmetricKeyEncoder.encrypt(request.birthday()), + symmetricKeyEncoder.encrypt(request.nationality()), + symmetricKeyEncoder.encrypt(request.aboutMe())); + } + + @Transactional + public String withdraw(final LoginMember loginMember) { + Member member = getMember(loginMember); + member.withdraw(); + return MemberResponse.WITHDRAW_SUCCESS.getMessage(); + } + + private Member getMember(final LoginMember loginMember) { + return memberRepository.findById(loginMember.memberId()).orElseThrow(() -> new RestApiException(MemberError.NULL_MEMBER)); + } + + @Transactional + public String changePassword(final LoginMember loginMember, final String newPassword) { + Member member = getMember(loginMember); + member.changePassword(passwordEncoder.encrypt(newPassword)); + return MemberResponse.PASSWORD_CHANGE_SUCCESS.getMessage(); + } + + @Transactional + public String changeProfileImage(final LoginMember loginMember, final MultipartFile newProfileImage) { + Member member = getMember(loginMember); + changeImageInDB(newProfileImage, member); + return MemberResponse.PROFILE_IMAGE_CHANGE_SUCCESS.getMessage(); + } + + private void changeImageInDB(final MultipartFile newProfileImage, final Member member) { + String savedProfileName = member.getProfileName(); + + if (!savedProfileName.equals(s3UploadProperties.getDefaultFileName())) { + uploader.delete(savedProfileName); + } + + S3File newFile = uploader.upload(newProfileImage); + member.changeProfileImage(newFile); + } + + @Transactional + public String changeAboutMe(final LoginMember loginMember, final String newAboutMe) { + MemberInfo memberInfo = getMemberInfo(loginMember); + memberInfo.changeAboutMe(symmetricKeyEncoder.encrypt(newAboutMe)); + return MemberResponse.ABOUT_ME_CHANGE_SUCCESS.getMessage(); + } + + @Transactional + public String changeMBTI(final LoginMember loginMember, final String newMBTI) { + MemberInfo memberInfo = getMemberInfo(loginMember); + memberInfo.changeMBTI(symmetricKeyEncoder.encrypt(newMBTI)); + return MemberResponse.MBTI_CHANGE_SUCCESS.getMessage(); + } + + private MemberInfo getMemberInfo(final LoginMember loginMember) { + return memberInfoRepository.findById(loginMember.memberId()).orElseThrow(()-> new RestApiException(MemberError.NULL_MEMBER)); + } + + @Transactional(readOnly = true) + public String getStatus(final LoginMember loginMember) { + Member member = getMember(loginMember); + return member.getStatus(); + } + + @Transactional(readOnly = true) + public MemberPageResponse getMemberPage(final LoginMember loginMember) { + MemberInfo memberInfo = getMemberInfo(loginMember); + EncodedMemberPage encodedMemberPage = memberInfo.getMemberPage(); + + Member member = getMember(loginMember); + MemberPage memberPage = member.getMemberPage(); + + return new MemberPageResponse(memberPage.name(), + symmetricKeyEncoder.decrypt(encodedMemberPage.mbti()), + symmetricKeyEncoder.decrypt(encodedMemberPage.gender()), + symmetricKeyEncoder.decrypt(encodedMemberPage.nationality()), + symmetricKeyEncoder.decrypt(encodedMemberPage.birthday()), + symmetricKeyEncoder.decrypt(encodedMemberPage.aboutMe()), + memberPage.profileImageURL()); + } + + @Transactional + public String generateTemporaryPassword(final TemporaryPasswordRequest request) { + Member member = memberRepository.findByEmailAndName(request.email(), request.name()).orElseThrow(() -> new RestApiException(MemberError.NULL_MEMBER)); + + String tmpPassword = getRandomPassword(); + member.changePassword(passwordEncoder.encrypt(tmpPassword)); + + TemporaryPasswordEvent event = new TemporaryPasswordEvent(request.email(),tmpPassword); + publisher.publishEvent(event); + + return MemberResponse.TEMPORARY_PASSWORD_GENERATED_SUCCESS.getMessage(); + } + + private String getRandomPassword() { + Random random = new Random(); + List password = new ArrayList<>(); + + for (int i = 0; i < 6; i++) { + int ranNum = random.nextInt(45) + 1; + password.add(ranNum); + } + + StringBuilder passwordBuilder = new StringBuilder(); + for (Integer num : password) { + passwordBuilder.append(num); + } + + return passwordBuilder.toString(); + } +} diff --git a/src/main/java/com/aliens/backend/uploader/AwsS3Uploader.java b/src/main/java/com/aliens/backend/uploader/AwsS3Uploader.java index 3149da73..eb9b010f 100644 --- a/src/main/java/com/aliens/backend/uploader/AwsS3Uploader.java +++ b/src/main/java/com/aliens/backend/uploader/AwsS3Uploader.java @@ -1,5 +1,6 @@ package com.aliens.backend.uploader; +import com.aliens.backend.global.property.S3UploadProperties; import com.amazonaws.services.s3.AmazonS3Client; import com.amazonaws.services.s3.model.ObjectMetadata; import org.springframework.http.MediaType; @@ -24,8 +25,12 @@ public AwsS3Uploader(final AmazonS3Client amazonS3Client, final S3UploadProperti this.s3UploadProperties = s3UploadProperties; } - public List upload(UploadFileRequest request) { - return request.files().parallelStream().map(this::uploadToS3).toList(); + public List upload(List files) { + return files.stream().map(this::uploadToS3).toList(); + } + + public S3File upload(MultipartFile file) { + return uploadToS3(file); } private S3File uploadToS3(MultipartFile multipartFile) { diff --git a/src/test/java/com/aliens/backend/auth/service/TokenProviderTest.java b/src/test/java/com/aliens/backend/auth/provider/TokenProviderTest.java similarity index 95% rename from src/test/java/com/aliens/backend/auth/service/TokenProviderTest.java rename to src/test/java/com/aliens/backend/auth/provider/TokenProviderTest.java index 07b94f05..6c892df8 100644 --- a/src/test/java/com/aliens/backend/auth/service/TokenProviderTest.java +++ b/src/test/java/com/aliens/backend/auth/provider/TokenProviderTest.java @@ -1,7 +1,8 @@ -package com.aliens.backend.auth.service; +package com.aliens.backend.auth.provider; import com.aliens.backend.auth.controller.dto.LoginMember; import com.aliens.backend.auth.domain.MemberRole; +import com.aliens.backend.auth.service.TokenProvider; import com.aliens.backend.global.exception.RestApiException; import com.aliens.backend.global.property.JWTProperties; import org.junit.jupiter.api.Assertions; @@ -92,6 +93,7 @@ void expiredTokenTest() { @DisplayName("기간이 유효한 토큰 검증") void notExpiredTokenTest() { //Given + jwtProperties.setAccessTokenValidTime(86400000L); //AccessToken 유효기한 원상복구 String accessToken = tokenProvider.generateAccessToken(givenLoginMember); //When @@ -130,9 +132,11 @@ void getTokenIdFromExpiredTokenFailTest() { //Given jwtProperties.setRefreshTokenValidTime(1L); //RefreshToken 유효기한 짧게변경 String expiredRefreshToken = tokenProvider.generateRefreshToken(givenLoginMember, givenTokenId); - jwtProperties.setRefreshTokenValidTime(2592000000L); //RefreshToken 유효기한 원상복구 //When & Then Assertions.assertThrows(RestApiException.class, () -> tokenProvider.getTokenIdFromToken(expiredRefreshToken)); + + //CleanUp + jwtProperties.setRefreshTokenValidTime(2592000000L); //RefreshToken 유효기한 원상복구 } } diff --git a/src/test/java/com/aliens/backend/auth/service/AuthServiceTest.java b/src/test/java/com/aliens/backend/auth/service/AuthServiceTest.java index 986f20fd..332a3eb5 100644 --- a/src/test/java/com/aliens/backend/auth/service/AuthServiceTest.java +++ b/src/test/java/com/aliens/backend/auth/service/AuthServiceTest.java @@ -4,9 +4,12 @@ import com.aliens.backend.auth.controller.dto.LoginRequest; import com.aliens.backend.auth.domain.Member; import com.aliens.backend.auth.domain.repository.MemberRepository; -import com.aliens.backend.auth.domain.MemberRole; import com.aliens.backend.global.exception.RestApiException; import com.aliens.backend.global.property.JWTProperties; +import com.aliens.backend.member.controller.dto.EncodedSignUp; +import com.aliens.backend.member.domain.Image; +import com.aliens.backend.member.domain.repository.ImageRepository; +import com.aliens.backend.uploader.S3File; import org.junit.jupiter.api.*; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.CsvSource; @@ -23,25 +26,32 @@ class AuthServiceTest { @Autowired MemberRepository memberRepository; @Autowired + ImageRepository imageRepository; + @Autowired PasswordEncoder passwordEncoder; Member member; + String name; String email; String password; LoginRequest loginRequest; @BeforeEach void setUp() { + name = "김명준"; email = "tmp@example.com"; password = "tmpPassword"; - member = new Member(email, passwordEncoder.encrypt(password), MemberRole.MEMBER); - loginRequest = new LoginRequest(email, password); + EncodedSignUp encodedSignUp = new EncodedSignUp(name, email, passwordEncoder.encrypt(password)); + Image image = Image.from(new S3File("tmpFileName", "tmpFileURL")); + member = Member.of(encodedSignUp, image); memberRepository.save(member); + loginRequest = new LoginRequest(email, password); } @AfterEach void afterDown() { memberRepository.deleteAll(); + imageRepository.deleteAll(); } @Test diff --git a/src/test/java/com/aliens/backend/docs/MemberDocTest.java b/src/test/java/com/aliens/backend/docs/MemberDocTest.java new file mode 100644 index 00000000..e9d1e5dc --- /dev/null +++ b/src/test/java/com/aliens/backend/docs/MemberDocTest.java @@ -0,0 +1,287 @@ +package com.aliens.backend.docs; + +import com.aliens.backend.auth.service.TokenProvider; +import com.aliens.backend.member.controller.dto.request.SignUpRequest; +import com.aliens.backend.member.controller.dto.request.TemporaryPasswordRequest; +import com.aliens.backend.member.controller.dto.response.MemberPageResponse; +import com.aliens.backend.member.controller.dto.response.MemberResponse; +import com.aliens.backend.member.domain.MemberStatus; +import com.aliens.backend.member.sevice.MemberInfoService; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.restdocs.AutoConfigureRestDocs; +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.http.MediaType; +import org.springframework.mock.web.MockMultipartFile; +import org.springframework.test.web.servlet.MockMvc; + +import java.nio.charset.StandardCharsets; +import java.util.Collections; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.when; +import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document; +import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.*; +import static org.springframework.restdocs.payload.PayloadDocumentation.*; +import static org.springframework.restdocs.payload.PayloadDocumentation.fieldWithPath; +import static org.springframework.restdocs.request.RequestDocumentation.partWithName; +import static org.springframework.restdocs.request.RequestDocumentation.requestParts; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +@AutoConfigureMockMvc +@AutoConfigureRestDocs +@SpringBootTest +class MemberDocTest { + + @Autowired + private MockMvc mockMvc; + @MockBean + private MemberInfoService memberInfoService; + @MockBean + private TokenProvider tokenProvider; + + ObjectMapper objectMapper; + MockMultipartFile multipartFile; + String accessToken; + + @BeforeEach + void setUp() { + multipartFile = new MockMultipartFile("profile-data", + "profile-data", + "image/png", + "test data".getBytes()); + accessToken= "accessToken"; + objectMapper = new ObjectMapper(); + } + + @Test + @DisplayName("회원가입 API 테스트") + void signUp() throws Exception { + final SignUpRequest request = createSignUpRequest(); + final String response = MemberResponse.SIGN_UP_SUCCESS.getMessage(); + when(memberInfoService.signUp(any(),any())).thenReturn(response); + + MockMultipartFile signUpRequestFile = getSignUpRequestFile(request); + + // When and Then + mockMvc.perform(multipart("/members") + .file(signUpRequestFile) + .file("profileImage", multipartFile.getBytes()) + .contentType(MediaType.MULTIPART_FORM_DATA) + .accept(MediaType.APPLICATION_JSON) + .characterEncoding("UTF-8") + ) + .andExpect(status().isOk()) + .andDo(document("member-signup", + requestParts( + partWithName("signUpRequest").description("회원가입 요청 데이터"), + partWithName("profileImage").description("프로필 이미지 파일") + ), + responseFields( + fieldWithPath("response").description("회원가입 결과") + ) + )); + } + + @Test + @DisplayName("프로필 이미지 변경 API 테스트") + void changeProfileImage() throws Exception { + String response = MemberResponse.PROFILE_IMAGE_CHANGE_SUCCESS.getMessage(); + when(memberInfoService.changeProfileImage(any(),any())).thenReturn(response); + + mockMvc.perform(multipart("/members/profile-image") + .file("newProfileImage", multipartFile.getBytes()) + .header("Authorization", accessToken) + .contentType(MediaType.MULTIPART_FORM_DATA)) + .andExpect(status().isOk()) + .andDo(document("member-change-profile-image", + requestParts( + partWithName("newProfileImage").description("새로운 프로필 이미지 파일") + ), + responseFields( + fieldWithPath("response").description("프로필 이미지 변경 결과") + ) + )); + } + + @Test + @DisplayName("임시 비밀번호 발급 API 테스트") + void generateTemporaryPassword() throws Exception { + final TemporaryPasswordRequest request = new TemporaryPasswordRequest("tmp@example.com", "tmpName"); + final String response = MemberResponse.TEMPORARY_PASSWORD_GENERATED_SUCCESS.getMessage(); + when(memberInfoService.generateTemporaryPassword(any())).thenReturn(response); + + this.mockMvc.perform(post("/members/temporary-password") + .content(objectMapper.writeValueAsString(request)) + .contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()) + .andDo(document("member-temporary-password", + requestFields( + fieldWithPath("email").description("이메일"), + fieldWithPath("name").description("이름") + ), + responseFields( + fieldWithPath("response").description("임시 비밀번호 발급 결과") + ) + )); + } + + @Test + @DisplayName("비밀번호 변경 API 테스트") + void changePassword() throws Exception { + String newPassword = "newPassword"; + String response = MemberResponse.PASSWORD_CHANGE_SUCCESS.getMessage(); + when(memberInfoService.changePassword(any(), any())).thenReturn(response); + + this.mockMvc.perform(patch("/members/password") + .header("Authorization", accessToken) + .content(objectMapper.writeValueAsString(Collections.singletonMap("newPassword", newPassword))) + .contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()) + .andDo(document("member-change-password", + requestFields( + fieldWithPath("newPassword").description("새로운 비밀번호") + ), + responseFields( + fieldWithPath("response").description("비밀번호 변경 결과") + ) + )); + } + + @Test + @DisplayName("회원 탈퇴 API 테스트") + void withdraw() throws Exception { + String response = MemberResponse.WITHDRAW_SUCCESS.getMessage(); + when(memberInfoService.withdraw(any())).thenReturn(response); + + mockMvc.perform(patch("/members/withdraw") + .header("Authorization", accessToken) + ) + .andExpect(status().isOk()) + .andDo(document("member-withdraw", + responseFields( + fieldWithPath("response").description("회원 탈퇴 결과") + ) + )); + } + + @Test + @DisplayName("상태 요청 API 테스트") + void getStatus() throws Exception { + String response = MemberStatus.NOT_APPLIED_NOT_MATCHED.getMessage(); + when(memberInfoService.getStatus(any())).thenReturn(response); + + mockMvc.perform(get("/members/status") + .header("Authorization", accessToken) + ) + .andExpect(status().isOk()) + .andDo(document("member-get-status", + responseFields( + fieldWithPath("response").description("상태 요청 결과") + ) + )); + } + + @Test + @DisplayName("회원 개인정보 요청 API 테스트") + void getMemberPage() throws Exception { + MemberPageResponse response = getMemberPageResponse(); + when(memberInfoService.getMemberPage(any())).thenReturn(response); + + mockMvc.perform(get("/members") + .header("Authorization", accessToken) + ) + .andExpect(status().isOk()) + .andDo(document("member-get-member-page", + responseFields( + fieldWithPath("name").description("이름"), + fieldWithPath("mbti").description("MBTI"), + fieldWithPath("gender").description("성별"), + fieldWithPath("nationality").description("국적"), + fieldWithPath("birthday").description("생년월일"), + fieldWithPath("selfIntroduction").description("자기 소개"), + fieldWithPath("profileImageURL").description("프로필 이미지 주소") + ) + )); + } + + + @Test + @DisplayName("자기소개 변경 API 테스트") + void changeAboutMe() throws Exception { + String newAboutMe = "새로운 자기소개"; + String response = MemberResponse.PASSWORD_CHANGE_SUCCESS.getMessage(); + when(memberInfoService.changeAboutMe(any(),any())).thenReturn(response); + + mockMvc.perform(patch("/members/about-me") + .header("Authorization", accessToken) + .content(objectMapper.writeValueAsString(Collections.singletonMap("newAboutMe", newAboutMe))) + .contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()) + .andDo(document("member-change-about-me", + requestFields( + fieldWithPath("newAboutMe").description("새로운 자기소개") + ), + responseFields( + fieldWithPath("response").description("자기소개 변경 결과") + ) + )); + } + + @Test + @DisplayName("MBTI 변경 API 테스트") + void changeMBTI() throws Exception { + String newMBTI = "ENFP"; + String response = MemberResponse.MBTI_CHANGE_SUCCESS.getMessage(); + when(memberInfoService.changeMBTI(any(),any())).thenReturn(response); + + mockMvc.perform(patch("/members/mbti") + .header("Authorization", accessToken) + .content(objectMapper.writeValueAsString(Collections.singletonMap("newMBTI", newMBTI))) + .contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()) + .andDo(document("member-change-mbti", + requestFields( + fieldWithPath("newMBTI").description("새로운 MBTI") + ), + responseFields( + fieldWithPath("response").description("MBTI 변경 결과") + ) + )); + } + + public SignUpRequest createSignUpRequest() { + SignUpRequest signUpRequest = new SignUpRequest("tmp@example.com", + "password", + "tmpName", + "INTJ", + "MALE", + "KOREA", + "1998-11-25", + "반갑습니다" + ); + return signUpRequest; + } + + public MockMultipartFile getSignUpRequestFile(final SignUpRequest request) throws JsonProcessingException { + String signupRequestJson = objectMapper.writeValueAsString(request); + MockMultipartFile signUpRequestFile = new MockMultipartFile( + "signUpRequest", + "signupRequest.json", + MediaType.APPLICATION_JSON_VALUE, + signupRequestJson.getBytes(StandardCharsets.UTF_8) + ); + return signUpRequestFile; + } + + public MemberPageResponse getMemberPageResponse() { + MemberPageResponse response = new MemberPageResponse("name","MBTI","MALE","KOREA","1998-11-25","반갑습니다","tmpImage.com"); + return response; + } +} \ No newline at end of file diff --git a/src/test/java/com/aliens/backend/email/sender/EmailContentTest.java b/src/test/java/com/aliens/backend/email/sender/EmailContentTest.java index defae0b3..4ef4f257 100644 --- a/src/test/java/com/aliens/backend/email/sender/EmailContentTest.java +++ b/src/test/java/com/aliens/backend/email/sender/EmailContentTest.java @@ -14,24 +14,47 @@ class EmailContentTest { EmailContent emailContent; @Test - @DisplayName("메일 내용 가져오기") - void getContentTest() { + @DisplayName("이메일 인증 내용 가져오기") + void getAuthenticationEmailContentTest() { //Given String token = "tmpToken"; String domainURL = "tmp.com"; //When - String result = emailContent.getContent(token, domainURL); + String result = emailContent.getAuthenticationMailContent(token, domainURL); //Then Assertions.assertNotNull(result); } @Test - @DisplayName("메일 제목 가져오기") - void getTitleTest() { + @DisplayName("이메일 인증 제목 가져오기") + void getAuthenticationEmailTitleTest() { //When - String result = emailContent.getTitle(); + String result = emailContent.getAuthenticationMailTitle(); + + //Then + Assertions.assertNotNull(result); + } + + @Test + @DisplayName("임시 비밀번호 발급 내용 가져오기") + void getTemporaryPasswordContent() { + //Given + String tmpPassword = "tmpPassword"; + + //When + String result = emailContent.getTemporaryMailContent(tmpPassword); + + //Then + Assertions.assertNotNull(result); + } + + @Test + @DisplayName("임시 비밀번호 발급 제목 가져오기") + void getTemporaryPasswordTitle() { + //When + String result = emailContent.getTemporaryMailTitle(); //Then Assertions.assertNotNull(result); diff --git a/src/test/java/com/aliens/backend/email/sender/EmailSenderTest.java b/src/test/java/com/aliens/backend/email/sender/EmailSenderTest.java index b97cd4e4..7c5b4dc3 100644 --- a/src/test/java/com/aliens/backend/email/sender/EmailSenderTest.java +++ b/src/test/java/com/aliens/backend/email/sender/EmailSenderTest.java @@ -1,6 +1,7 @@ package com.aliens.backend.email.sender; import com.aliens.backend.email.service.EmailSender; +import com.aliens.backend.member.controller.dto.event.TemporaryPasswordEvent; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.mockito.ArgumentMatchers; @@ -10,7 +11,6 @@ import org.springframework.mail.SimpleMailMessage; import org.springframework.mail.javamail.JavaMailSender; -import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; @SpringBootTest @@ -35,4 +35,17 @@ void sendAuthenticationEmailTest() { // Then verify(javaMailSender).send(ArgumentMatchers.any(SimpleMailMessage.class)); } + + @Test + @DisplayName("임시 비밀반호 발급 이메일 전송 테스트") + void sendTemporaryPasswordEmailTest() { + // Given + TemporaryPasswordEvent event = new TemporaryPasswordEvent("tmp@example.com","tmpPassword"); + + // When + emailSender.sendTemporaryPassword(event); + + // Then + verify(javaMailSender).send(ArgumentMatchers.any(SimpleMailMessage.class)); + } } diff --git a/src/test/java/com/aliens/backend/email/service/EmailServiceTest.java b/src/test/java/com/aliens/backend/email/service/EmailServiceTest.java index b47d90ca..03b8958f 100644 --- a/src/test/java/com/aliens/backend/email/service/EmailServiceTest.java +++ b/src/test/java/com/aliens/backend/email/service/EmailServiceTest.java @@ -7,6 +7,8 @@ import org.junit.jupiter.api.*; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.mail.javamail.JavaMailSender; @SpringBootTest class EmailServiceTest { @@ -17,6 +19,8 @@ class EmailServiceTest { SymmetricKeyEncoder symmetricKeyEncoder; @Autowired EmailAuthenticationRepository emailAuthenticationRepository; + @MockBean + JavaMailSender javaMailSender; String givenEmail; EmailAuthentication emailEntity; diff --git a/src/test/java/com/aliens/backend/encode/SymmetricKeyEncoderTest.java b/src/test/java/com/aliens/backend/encode/SymmetricKeyEncoderTest.java index fc62098c..85d6386f 100644 --- a/src/test/java/com/aliens/backend/encode/SymmetricKeyEncoderTest.java +++ b/src/test/java/com/aliens/backend/encode/SymmetricKeyEncoderTest.java @@ -15,7 +15,7 @@ class SymmetricKeyEncoderTest { @Test @DisplayName("문자열 암호화 성공") - void encryptTest() throws Exception { + void encryptTest() { //Given String givenInput = "testText"; @@ -28,7 +28,7 @@ void encryptTest() throws Exception { @Test @DisplayName("문자열 복호화 성공") - void decryptTest() throws Exception { + void decryptTest() { //Given String givenInput = "testText"; String code = symmetricKeyEncoder.encrypt(givenInput); diff --git a/src/test/java/com/aliens/backend/member/MemberInfoServiceTest.java b/src/test/java/com/aliens/backend/member/MemberInfoServiceTest.java new file mode 100644 index 00000000..13f06680 --- /dev/null +++ b/src/test/java/com/aliens/backend/member/MemberInfoServiceTest.java @@ -0,0 +1,260 @@ +package com.aliens.backend.member; + +import com.aliens.backend.auth.controller.dto.LoginMember; +import com.aliens.backend.auth.domain.Member; +import com.aliens.backend.auth.domain.repository.MemberRepository; +import com.aliens.backend.auth.service.PasswordEncoder; +import com.aliens.backend.email.domain.EmailAuthentication; +import com.aliens.backend.email.domain.repository.EmailAuthenticationRepository; +import com.aliens.backend.global.encode.SymmetricKeyEncoder; +import com.aliens.backend.member.controller.dto.*; +import com.aliens.backend.member.controller.dto.request.SignUpRequest; +import com.aliens.backend.member.controller.dto.request.TemporaryPasswordRequest; +import com.aliens.backend.member.controller.dto.response.MemberPageResponse; +import com.aliens.backend.member.controller.dto.response.MemberResponse; +import com.aliens.backend.member.domain.Image; +import com.aliens.backend.member.domain.MemberInfo; +import com.aliens.backend.member.domain.repository.ImageRepository; +import com.aliens.backend.member.domain.repository.MemberInfoRepository; +import com.aliens.backend.member.domain.MemberStatus; +import com.aliens.backend.member.sevice.MemberInfoService; +import com.aliens.backend.uploader.AwsS3Uploader; +import com.aliens.backend.uploader.S3File; +import org.junit.jupiter.api.*; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.mail.javamail.JavaMailSender; +import org.springframework.mock.web.MockMultipartFile; +import org.springframework.web.multipart.MultipartFile; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.when; + +@SpringBootTest +class MemberInfoServiceTest { + + @Autowired + MemberInfoRepository memberInfoRepository; + @Autowired + MemberInfoService memberInfoService; + @Autowired + EmailAuthenticationRepository emailAuthenticationRepository; + @Autowired + ImageRepository imageRepository; + @Autowired + MemberRepository memberRepository; + @Autowired + SymmetricKeyEncoder symmetricKeyEncoder; + @Autowired + PasswordEncoder passwordEncoder; + + @MockBean + AwsS3Uploader awsS3Uploader; + @MockBean + JavaMailSender javaMailSender; + + MockMultipartFile file; + LoginMember loginMember; + String givenName = "김명준"; + String givenEmail = "tmp@example"; + String givenPassword = "tmpPassword"; + String givenGender = "MALE"; + String givenMbti = "INTJ"; + String givenBirthday = "1998-11-25"; + String givenNationality = "KOREA"; + String givenAboutMe = "반갑습니다."; + String givenFileName = "tmpFile"; + String givenFileURL = "example.com"; + + @BeforeEach + void setUp() { + setUpEmailEntity(givenEmail); + Image image = setUpImage(); + Member member = setUpMember(image); + setUpMemberInfo(member); + setUpLoginMember(member); + setUpMockMultipartFile(); + } + + @AfterEach + void setDown() { + emailAuthenticationRepository.deleteAll(); + memberInfoRepository.deleteAll(); + memberRepository.deleteAll(); + imageRepository.deleteAll(); + } + + @Test + @DisplayName("회원가입") + void signUpTest() { + //Given + S3File tmpFile = new S3File(givenFileName, givenFileURL); + when(awsS3Uploader.upload((MultipartFile) any())).thenReturn(tmpFile); + SignUpRequest signUpRequest = createSignUpRequest(); + + //When + String result = memberInfoService.signUp(signUpRequest, file); + + //Then + Assertions.assertEquals(MemberResponse.SIGN_UP_SUCCESS.getMessage(),result); + } + + @Test + @DisplayName("회원 탈퇴") + void withdrawTest() { + //When + String result = memberInfoService.withdraw(loginMember); + + //Then + Assertions.assertEquals(MemberResponse.WITHDRAW_SUCCESS.getMessage(),result); + } + + @Test + @DisplayName("임시 비밀번호 발급") + void temporaryPassword() { + //Given + TemporaryPasswordRequest temporaryPasswordRequest = new TemporaryPasswordRequest(givenEmail,givenName); + + //When + String result = memberInfoService.generateTemporaryPassword(temporaryPasswordRequest); + + //Then + Assertions.assertEquals(MemberResponse.TEMPORARY_PASSWORD_GENERATED_SUCCESS.getMessage(),result); + } + + @Test + @DisplayName("비밀번호 변경") + void changePassword() { + //Given + String newPassword = "newPassword"; + + //When + String result = memberInfoService.changePassword(loginMember, newPassword); + + //Then + Assertions.assertEquals(MemberResponse.PASSWORD_CHANGE_SUCCESS.getMessage(),result); + } + + @Test + @DisplayName("프로필 이미지 변경") + void changeProfileImage() { + //Given + S3File tmpFile = new S3File(givenFileName, givenFileURL); + when(awsS3Uploader.upload((MultipartFile) any())).thenReturn(tmpFile); + + //When + String result = memberInfoService.changeProfileImage(loginMember, file); + + //Then + Assertions.assertEquals(MemberResponse.PROFILE_IMAGE_CHANGE_SUCCESS.getMessage(),result); + } + + @Test + @DisplayName("자기소개 변경") + void changeAboutMe() { + //Given + String newAboutMe = "newAboutMe"; + + //When + String result = memberInfoService.changeAboutMe(loginMember, newAboutMe); + + //Then + Assertions.assertEquals(MemberResponse.ABOUT_ME_CHANGE_SUCCESS.getMessage(),result); + } + + @Test + @DisplayName("MBTI 변경") + void changeMBTI() { + //Given + String newMBTI = "ESTJ"; + + //When + String result = memberInfoService.changeMBTI(loginMember, newMBTI); + + //Then + Assertions.assertEquals(MemberResponse.MBTI_CHANGE_SUCCESS.getMessage(),result); + } + + @Test + @DisplayName("상태 요청") + void getStatus() { + //When + String result = memberInfoService.getStatus(loginMember); + + //Then + Assertions.assertEquals(MemberStatus.NOT_APPLIED_NOT_MATCHED.getMessage(),result); + } + + @Test + @DisplayName("회원 개인정보 요청") + void getMemberInfo() { + //Given + MemberPageResponse expectedResponse = new MemberPageResponse(givenName, + givenMbti, + givenGender, + givenNationality, + givenBirthday, + givenAboutMe, + givenFileURL); + + //When + MemberPageResponse result = memberInfoService.getMemberPage(loginMember); + + //Then + Assertions.assertEquals(expectedResponse,result); + } + + public void setUpLoginMember(final Member member) { + loginMember = member.getLoginMember(); + } + + public void setUpMemberInfo(final Member member) { + EncodedMember encodedRequest = new EncodedMember(symmetricKeyEncoder.encrypt(givenGender), + symmetricKeyEncoder.encrypt(givenMbti), + symmetricKeyEncoder.encrypt(givenBirthday), + symmetricKeyEncoder.encrypt(givenNationality), + symmetricKeyEncoder.encrypt(givenAboutMe)); + + MemberInfo memberInfo = MemberInfo.of(encodedRequest, member); + memberInfoRepository.save(memberInfo); + } + + public Member setUpMember(final Image image) { + EncodedSignUp signUp = new EncodedSignUp(givenName, givenEmail, passwordEncoder.encrypt(givenPassword)); + Member member = Member.of(signUp, image); + return member; + } + + public Image setUpImage() { + Image image = Image.from(new S3File(givenFileName, givenFileURL)); + return image; + } + + public void setUpMockMultipartFile() { + String fileName = "test"; + String path = "/test"; + String contentType = "image/png"; + byte[] content = fileName.getBytes(); + file = new MockMultipartFile(fileName, path, contentType, content); + } + + public void setUpEmailEntity(final String givenEmail) { + EmailAuthentication emailEntity = new EmailAuthentication(givenEmail); + emailEntity.authenticate(); + emailAuthenticationRepository.save(emailEntity); + } + + public SignUpRequest createSignUpRequest() { + SignUpRequest signUpRequest = new SignUpRequest(givenEmail, + "password", + "tmpName", + "INTJ", + "MALE", + "KOREA", + "1998-11-25", + "반갑습니다" + ); + return signUpRequest; + } +} diff --git a/src/test/java/com/aliens/backend/uploader/AwsS3MockConfig.java b/src/test/java/com/aliens/backend/uploader/AwsS3MockConfig.java index 53db67e0..17f9842b 100644 --- a/src/test/java/com/aliens/backend/uploader/AwsS3MockConfig.java +++ b/src/test/java/com/aliens/backend/uploader/AwsS3MockConfig.java @@ -1,5 +1,6 @@ package com.aliens.backend.uploader; +import com.aliens.backend.global.property.S3UploadProperties; import com.amazonaws.auth.AWSStaticCredentialsProvider; import com.amazonaws.auth.AnonymousAWSCredentials; import com.amazonaws.client.builder.AwsClientBuilder; diff --git a/src/test/java/com/aliens/backend/uploader/AwsS3UploaderTest.java b/src/test/java/com/aliens/backend/uploader/AwsS3UploaderTest.java index bf1ad5be..fc8b93a0 100644 --- a/src/test/java/com/aliens/backend/uploader/AwsS3UploaderTest.java +++ b/src/test/java/com/aliens/backend/uploader/AwsS3UploaderTest.java @@ -9,6 +9,7 @@ import org.springframework.boot.test.context.SpringBootTest; import org.springframework.context.annotation.Import; import org.springframework.mock.web.MockMultipartFile; +import org.springframework.web.multipart.MultipartFile; import java.util.List; @@ -35,7 +36,7 @@ void uploadTest() { String contentType = "image/png"; MockMultipartFile file = new MockMultipartFile("test", path, contentType, "test".getBytes()); - UploadFileRequest request = new UploadFileRequest(List.of(file,file,file)); + List request = List.of(file,file,file); // When List S3Files = awsS3Uploader.upload(request);