Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[feat] 점주 id를 UUID로 변경 #53

Merged
merged 25 commits into from
Aug 15, 2024
Merged
Show file tree
Hide file tree
Changes from 23 commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
09e4ff2
[style] ArgumentResolver 개행
Dr-KoKo Aug 14, 2024
ec571d2
[fix] LoginVendor 및 LoginCustomer의 id 변경
Dr-KoKo Aug 14, 2024
36fc073
[feat] POST /vendor/login 로그인 앤드 포인트
Dr-KoKo Aug 14, 2024
ce5579f
[fix] Vendor의 id를 UUID로 수정
Dr-KoKo Aug 14, 2024
ead21ee
[fix] Vendor id 변경으로 인한 VendorRepositoryTest 변경
Dr-KoKo Aug 14, 2024
40d0622
[fix] Vendor id 변경으로 인한 SignUPVendorServiceTest 변경
Dr-KoKo Aug 14, 2024
0867773
[fix] Vendor id 변경으로 인한 VendorApiControllerTest 변경
Dr-KoKo Aug 14, 2024
12e1c60
[feat] Vendor의 비밀번호 일치 여부를 확인하는 도메인 메서드
Dr-KoKo Aug 14, 2024
afb72d6
[feat] VendorRepository에서 Email로 조회하는 메서드
Dr-KoKo Aug 14, 2024
c4af228
[feat] Vendor가 로그인하기 위한 서비스 구현
Dr-KoKo Aug 14, 2024
5d5a8e4
[docs] SignInVendorService가 던지는 예외 명시
Dr-KoKo Aug 14, 2024
4fb4598
[fix] matches 메서드 파라미터 순서 오류 수정
Dr-KoKo Aug 14, 2024
01fdfd5
[fix] TestVendor 생성자 수정
Dr-KoKo Aug 14, 2024
bd81090
[test] Vendor.matches() 테스트
Dr-KoKo Aug 14, 2024
26ac760
[test] SignInVendorServiceTest
Dr-KoKo Aug 14, 2024
ae6fb5a
[feat] 판매자 로그인 endpoint
Dr-KoKo Aug 14, 2024
76e54d0
[test] 로그인 컨트롤러 테스트 코드 작성
Dr-KoKo Aug 14, 2024
4be2e7a
[merge] branch 'refs/heads/main' into feature/9_Dr-KoKo_점주_로그인
Dr-KoKo Aug 14, 2024
c5c2790
[fix] LoginCustomer는 다른 이슈에서 처리될 예정
Dr-KoKo Aug 14, 2024
ccf540d
[feat] Vendor 예외 처리
Dr-KoKo Aug 14, 2024
15f5820
[test] 점포 생성 테스트 코드 수정
Dr-KoKo Aug 14, 2024
c1f178d
[test] status 검증 수정
Dr-KoKo Aug 14, 2024
b03b4a8
[fix] 로그인시 응답 메시지 생성
Dr-KoKo Aug 14, 2024
a30705c
[fix] Id 전략 변경으로 인한 SignUpVendorService 수정
Dr-KoKo Aug 15, 2024
595ba22
[test] SignUpVendorServiceTest에서 SaveAndFlush를 mocking하게 수정
Dr-KoKo Aug 15, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 9 additions & 3 deletions src/main/java/camp/woowak/lab/vendor/domain/Vendor.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package camp.woowak.lab.vendor.domain;

import java.util.UUID;

import camp.woowak.lab.payaccount.domain.PayAccount;
import camp.woowak.lab.vendor.exception.InvalidVendorCreationException;
import camp.woowak.lab.web.authentication.PasswordEncoder;
Expand All @@ -14,8 +16,8 @@
@Entity
public class Vendor {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@GeneratedValue(strategy = GenerationType.UUID)
private UUID id;
@Column(nullable = false, length = 50)
private String name;
@Column(unique = true, nullable = false, length = 100)
Expand Down Expand Up @@ -43,7 +45,11 @@ public Vendor(String name, String email, String password, String phone, PayAccou
this.payAccount = payAccount;
}

public Long getId() {
public UUID getId() {
return id;
}

public boolean matches(String password, PasswordEncoder passwordEncoder) {
return passwordEncoder.matches(password, this.password);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package camp.woowak.lab.vendor.exception;

import camp.woowak.lab.common.exception.NotFoundException;

public class NotFoundVendorException extends NotFoundException {
public NotFoundVendorException() {
super(VendorErrorCode.NOT_FOUND_VENDOR);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package camp.woowak.lab.vendor.exception;

import camp.woowak.lab.common.exception.BadRequestException;

public class PasswordMismatchException extends BadRequestException {
public PasswordMismatchException() {
super(VendorErrorCode.WRONG_PASSWORD);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@ public enum VendorErrorCode implements ErrorCode {
INVALID_NAME_EMPTY(HttpStatus.BAD_REQUEST, "v1_7", "이름이 입력되지 않았습니다."),
INVALID_NAME_RANGE(HttpStatus.BAD_REQUEST, "v1_8", "이름은 50자를 넘을 수 없습니다."),
INVALID_PAY_ACCOUNT_EMPTY(HttpStatus.BAD_REQUEST, "v_1_9", "포인트 계좌가 입력되지 않았습니다."),
DUPLICATE_EMAIL(HttpStatus.BAD_REQUEST, "v_2", "이미 가입된 이메일입니다.");
DUPLICATE_EMAIL(HttpStatus.BAD_REQUEST, "v_2", "이미 가입된 이메일입니다."),
NOT_FOUND_VENDOR(HttpStatus.BAD_REQUEST, "v3", "존재하지 않는 점주입니다."),
WRONG_PASSWORD(HttpStatus.BAD_REQUEST, "v4_1", "잘못된 비밀번호입니다.");

private final int status;
private final String errorCode;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,17 @@
package camp.woowak.lab.vendor.repository;

import java.util.Optional;
import java.util.UUID;

import org.springframework.data.jpa.repository.JpaRepository;

import camp.woowak.lab.vendor.domain.Vendor;
import camp.woowak.lab.vendor.exception.NotFoundVendorException;

public interface VendorRepository extends JpaRepository<Vendor, UUID> {
Optional<Vendor> findByEmail(String email);

public interface VendorRepository extends JpaRepository<Vendor, Long> {
default Vendor findByEmailOrThrow(String email) {
return findByEmail(email).orElseThrow(NotFoundVendorException::new);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package camp.woowak.lab.vendor.service;

import java.util.UUID;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import camp.woowak.lab.vendor.domain.Vendor;
import camp.woowak.lab.vendor.exception.PasswordMismatchException;
import camp.woowak.lab.vendor.repository.VendorRepository;
import camp.woowak.lab.vendor.service.command.SignInVendorCommand;
import camp.woowak.lab.web.authentication.PasswordEncoder;

@Service
@Transactional(readOnly = true)
Dr-KoKo marked this conversation as resolved.
Show resolved Hide resolved
public class SignInVendorService {
private final VendorRepository repository;
private final PasswordEncoder passwordEncoder;

public SignInVendorService(VendorRepository repository, PasswordEncoder passwordEncoder) {
this.repository = repository;
this.passwordEncoder = passwordEncoder;
}

/**
* @throws PasswordMismatchException 비밀번호가 일치하지 않으면
*/
public UUID signIn(SignInVendorCommand cmd) {
Vendor findVendor = repository.findByEmailOrThrow(cmd.email());
if (!findVendor.matches(cmd.password(), passwordEncoder)) {
throw new PasswordMismatchException();
}
return findVendor.getId();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,16 +26,16 @@ public SignUpVendorService(
this.passwordEncoder = passwordEncoder;
}

public Long signUp(SignUpVendorCommand cmd) {
public String signUp(SignUpVendorCommand cmd) {
PayAccount newPayAccount = new PayAccount();
payAccountRepository.save(newPayAccount);
Vendor newVendor =
new Vendor(cmd.name(), cmd.email(), cmd.password(), cmd.phone(), newPayAccount, passwordEncoder);
Vendor savedVendor;
try {
vendorRepository.save(newVendor);
savedVendor = vendorRepository.save(
Dr-KoKo marked this conversation as resolved.
Show resolved Hide resolved
new Vendor(cmd.name(), cmd.email(), cmd.password(), cmd.phone(), newPayAccount, passwordEncoder));
} catch (DataIntegrityViolationException e) {
throw new DuplicateEmailException();
}
return newVendor.getId();
return savedVendor.getId().toString();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package camp.woowak.lab.vendor.service.command;

public record SignInVendorCommand(
String email,
String password
) {
}
Original file line number Diff line number Diff line change
@@ -1,23 +1,34 @@
package camp.woowak.lab.web.api.vendor;

import java.util.UUID;

import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;

import camp.woowak.lab.vendor.service.SignInVendorService;
import camp.woowak.lab.vendor.service.SignUpVendorService;
import camp.woowak.lab.vendor.service.command.SignInVendorCommand;
import camp.woowak.lab.vendor.service.command.SignUpVendorCommand;
import camp.woowak.lab.web.authentication.LoginVendor;
import camp.woowak.lab.web.dto.request.vendor.SignInVendorRequest;
import camp.woowak.lab.web.dto.request.vendor.SignUpVendorRequest;
import camp.woowak.lab.web.dto.response.vendor.SignInVendorResponse;
import camp.woowak.lab.web.dto.response.vendor.SignUpVendorResponse;
import camp.woowak.lab.web.resolver.session.SessionConst;
import jakarta.servlet.http.HttpSession;
import jakarta.validation.Valid;

@RestController
public class VendorApiController {
private final SignUpVendorService signUpVendorService;
private final SignInVendorService signInVendorService;

public VendorApiController(SignUpVendorService signUpVendorService) {
public VendorApiController(SignUpVendorService signUpVendorService, SignInVendorService signInVendorService) {
this.signUpVendorService = signUpVendorService;
this.signInVendorService = signInVendorService;
}

@PostMapping("/vendors")
Expand All @@ -26,7 +37,16 @@ public SignUpVendorResponse signUpVendor(@Valid @RequestBody SignUpVendorRequest

SignUpVendorCommand command =
new SignUpVendorCommand(request.name(), request.email(), request.password(), request.phone());
Long registeredId = signUpVendorService.signUp(command);
String registeredId = signUpVendorService.signUp(command);
return new SignUpVendorResponse(registeredId);
}

@PostMapping("/vendors/login")
@ResponseStatus(HttpStatus.NO_CONTENT)
public SignInVendorResponse login(@Valid @RequestBody SignInVendorRequest request, HttpSession session) {
SignInVendorCommand command = new SignInVendorCommand(request.email(), request.password());
UUID vendorId = signInVendorService.signIn(command);
session.setAttribute(SessionConst.SESSION_VENDOR_KEY, new LoginVendor(vendorId));
return new SignInVendorResponse("success");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,23 @@
import camp.woowak.lab.common.advice.DomainExceptionHandler;
import camp.woowak.lab.vendor.exception.DuplicateEmailException;
import camp.woowak.lab.vendor.exception.InvalidVendorCreationException;
import camp.woowak.lab.vendor.exception.NotFoundVendorException;
import camp.woowak.lab.vendor.exception.PasswordMismatchException;
import lombok.extern.slf4j.Slf4j;

@Slf4j
@DomainExceptionHandler(basePackageClasses = VendorApiController.class)
public class VendorApiControllerAdvice {
@ExceptionHandler(PasswordMismatchException.class)
public ResponseEntity<ProblemDetail> handlePasswordMismatchException(PasswordMismatchException ex) {
return ResponseEntity.of(ProblemDetail.forStatusAndDetail(HttpStatus.BAD_REQUEST, ex.getMessage())).build();
}

@ExceptionHandler(NotFoundVendorException.class)
public ResponseEntity<ProblemDetail> handleNotFoundVendorException(NotFoundVendorException ex) {
return ResponseEntity.of(ProblemDetail.forStatusAndDetail(HttpStatus.BAD_REQUEST, ex.getMessage())).build();
}

@ExceptionHandler(InvalidVendorCreationException.class)
public ResponseEntity<ProblemDetail> handleInvalidVendorCreationException(InvalidVendorCreationException ex) {
return ResponseEntity.of(ProblemDetail.forStatusAndDetail(HttpStatus.BAD_REQUEST, ex.getMessage())).build();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
package camp.woowak.lab.web.authentication;

public interface LoginMember {
Long getId();
Object getId();
kimhyun5u marked this conversation as resolved.
Show resolved Hide resolved
}
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
package camp.woowak.lab.web.authentication;

import java.util.UUID;

public class LoginVendor implements LoginMember {
private final Long id;
private final UUID id;

public LoginVendor(Long id) {
public LoginVendor(UUID id) {
this.id = id;
}

@Override
public Long getId() {
public UUID getId() {
return id;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package camp.woowak.lab.web.dto.request.vendor;

import org.hibernate.validator.constraints.Length;

import jakarta.validation.constraints.Email;
import jakarta.validation.constraints.NotBlank;

public record SignInVendorRequest(
@NotBlank @Email
String email,
@NotBlank @Length(min = 8, max = 30)
String password
) {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package camp.woowak.lab.web.dto.response.vendor;

public record SignInVendorResponse(
String message
) {
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package camp.woowak.lab.web.dto.response.vendor;

public record SignUpVendorResponse(
Long id
String id
) {
}
9 changes: 9 additions & 0 deletions src/test/java/camp/woowak/lab/fixture/VendorFixture.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package camp.woowak.lab.fixture;

import java.util.UUID;

import camp.woowak.lab.payaccount.domain.PayAccount;
import camp.woowak.lab.vendor.TestVendor;
import camp.woowak.lab.vendor.domain.Vendor;
import camp.woowak.lab.web.authentication.PasswordEncoder;

Expand All @@ -9,6 +12,12 @@ default PayAccount createPayAccount() {
return new PayAccount();
}

default Vendor createSavedVendor(UUID id, PayAccount payAccount, PasswordEncoder passwordEncoder) {
return new TestVendor(
id, "vendorName", "[email protected]", "vendorPassword", "010-0000-0000", payAccount,
passwordEncoder);
}

default Vendor createVendor(PayAccount payAccount, PasswordEncoder passwordEncoder) {
return new Vendor("vendorName", "[email protected]", "vendorPassword", "010-0000-0000", payAccount,
passwordEncoder);
Expand Down
21 changes: 21 additions & 0 deletions src/test/java/camp/woowak/lab/vendor/TestVendor.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package camp.woowak.lab.vendor;

import java.util.UUID;

import camp.woowak.lab.payaccount.domain.PayAccount;
import camp.woowak.lab.vendor.domain.Vendor;
import camp.woowak.lab.web.authentication.PasswordEncoder;

public class TestVendor extends Vendor {
private UUID id;

public TestVendor(UUID id, String name, String email, String password, String phone, PayAccount payAccount,
PasswordEncoder passwordEncoder) {
super(name, email, password, phone, payAccount, passwordEncoder);
this.id = id;
}

public UUID getId() {
return id;
}
}
41 changes: 40 additions & 1 deletion src/test/java/camp/woowak/lab/vendor/domain/VendorTest.java
Original file line number Diff line number Diff line change
@@ -1,18 +1,21 @@
package camp.woowak.lab.vendor.domain;

import java.util.UUID;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;

import camp.woowak.lab.fixture.VendorFixture;
import camp.woowak.lab.payaccount.domain.PayAccount;
import camp.woowak.lab.payaccount.domain.TestPayAccount;
import camp.woowak.lab.vendor.exception.InvalidVendorCreationException;
import camp.woowak.lab.web.authentication.NoOpPasswordEncoder;
import camp.woowak.lab.web.authentication.PasswordEncoder;

class VendorTest {
class VendorTest implements VendorFixture {

private PayAccount payAccount;
private PasswordEncoder passwordEncoder;
Expand Down Expand Up @@ -209,4 +212,40 @@ void failWithNull() {
}
}
}

@Nested
@DisplayName("비밀번화 확인은")
class Matches {
@Test
@DisplayName("[성공] 비밀번호가 일치하면 true를 반환한다.")
void return_true() {
// given
Vendor savedVendor = createSavedVendor(UUID.randomUUID(), createPayAccount(), passwordEncoder);

// when
boolean matches = savedVendor.matches("vendorPassword", passwordEncoder);

// then
Assertions.assertTrue(matches);
}

@Test
@DisplayName("[예외] 비밀번호가 불일치하면 false를 반환한다.")
void return_false() {
// given
Vendor savedVendor = createSavedVendor(UUID.randomUUID(), createPayAccount(), passwordEncoder);

// when
boolean matches = savedVendor.matches("something_wrong", passwordEncoder);

// then
Assertions.assertFalse(matches);
}

@Test
void test() {
boolean matches = passwordEncoder.matches("vendorPassword", "vendorPassword");
Assertions.assertTrue(matches);
}
}
}
Loading