Skip to content

Commit

Permalink
[feat] Customer id 변경 (#58)
Browse files Browse the repository at this point in the history
* [feat] Customer ID 변경
- 논의 - #36 반영
- Long 에서 UUID 로 변경

* [fix] Customer ID 변경으로 인한 수정
- 논의 - #36 반영
- Long 에서 UUID 로 변경

* [test] SignUpCustomerServiceIntegrationTest 수정
- DataIntegrityViolationException 를 서비스 레이어에서 잡지 못하면 에러 명시된 출럭

* [chore] 불필요한 throws 제거

* [fix] SignUpCustomerService.signUp 변경에 의한 검증 변경
- then().save() -> then().saveAndFlush()

* [fix] Customer id 변경에 의한 수정
- Customer id: Long -> UUID 변경

* [fix] Customer id 변경에 의한 수정
- Customer id: Long -> UUID 변경

* [feat] LoginMember 수정
- getId() 의 반환값 UUID 로 변경

* [feat] LoginMember 수정
- getId() 의 반환값 Object 로 변경

* [chore] 사용하지 않는 () 제거
  • Loading branch information
kimhyun5u authored Aug 15, 2024
1 parent 1c5edcb commit 75a532e
Show file tree
Hide file tree
Showing 12 changed files with 62 additions and 43 deletions.
8 changes: 6 additions & 2 deletions src/main/java/camp/woowak/lab/customer/domain/Customer.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package camp.woowak.lab.customer.domain;

import java.util.UUID;

import camp.woowak.lab.customer.exception.InvalidCreationException;
import camp.woowak.lab.payaccount.domain.PayAccount;
import camp.woowak.lab.web.authentication.PasswordEncoder;
Expand All @@ -10,14 +12,16 @@
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.OneToOne;
import jakarta.persistence.Table;
import lombok.Getter;

@Entity
@Getter
@Table(name = "Customers")
public class Customer {
@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
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@
import camp.woowak.lab.payaccount.repository.PayAccountRepository;
import camp.woowak.lab.web.authentication.PasswordEncoder;
import jakarta.transaction.Transactional;
import lombok.extern.slf4j.Slf4j;

@Slf4j
@Service
public class SignUpCustomerService {
private final CustomerRepository customerRepository;
Expand All @@ -32,18 +34,18 @@ public SignUpCustomerService(CustomerRepository customerRepository, PayAccountRe
* @throws DuplicateEmailException 이메일이 중복되는 경우
*/
@Transactional
public Long signUp(SignUpCustomerCommand cmd) {
public String signUp(SignUpCustomerCommand cmd) {
PayAccount payAccount = new PayAccount();
payAccountRepository.save(payAccount);

Customer newCustomer = new Customer(cmd.name(), cmd.email(), cmd.password(), cmd.phone(), payAccount,
passwordEncoder);

try {
customerRepository.save(newCustomer);
return customerRepository.saveAndFlush(newCustomer).getId().toString();
} catch (DataIntegrityViolationException e) {
log.error("데이터 무결성 위반");
throw new DuplicateEmailException();
}
return newCustomer.getId();
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package camp.woowak.lab.payaccount.repository;

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

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Lock;
Expand All @@ -13,5 +14,5 @@
public interface PayAccountRepository extends JpaRepository<PayAccount, Long> {
@Lock(LockModeType.PESSIMISTIC_WRITE)
@Query("SELECT pa FROM PayAccount pa LEFT JOIN Customer c on c.payAccount = pa where c.id = :customerId")
Optional<PayAccount> findByCustomerIdForUpdate(@Param("customerId") Long customerId);
Optional<PayAccount> findByCustomerIdForUpdate(@Param("customerId") UUID customerId);
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package camp.woowak.lab.payaccount.service.command;

import java.util.UUID;

public record PayAccountChargeCommand(
Long customerId,
UUID customerId,
long amount) {
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ public SignUpCustomerResponse signUp(@Valid @RequestBody SignUpCustomerRequest r
SignUpCustomerCommand command =
new SignUpCustomerCommand(request.name(), request.email(), request.password(), request.phone());

Long registeredId = signUpCustomerService.signUp(command);
String registeredId = signUpCustomerService.signUp(command);

response.setHeader("Location", "/customers/" + registeredId);

Expand Down
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 LoginCustomer implements LoginMember {
private final Long id;
private final UUID id;

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

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

public record SignUpCustomerResponse(Long id) {
public record SignUpCustomerResponse(String id) {
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.dao.DataIntegrityViolationException;

import camp.woowak.lab.customer.exception.DuplicateEmailException;
import camp.woowak.lab.customer.exception.InvalidCreationException;
import camp.woowak.lab.customer.repository.CustomerRepository;
import camp.woowak.lab.customer.service.command.SignUpCustomerCommand;
import camp.woowak.lab.payaccount.repository.PayAccountRepository;
Expand All @@ -27,7 +27,7 @@ class SignUpCustomerServiceIntegrationTest {

@Test
@DisplayName("이메일 중복 시 롤백 테스트")
void testRollbackOnDuplicateEmail() throws InvalidCreationException, DuplicateEmailException {
void testRollbackOnDuplicateEmail() {
// given
SignUpCustomerCommand command1 = new SignUpCustomerCommand("name1", "[email protected]", "password",
"010-1234-5678");
Expand All @@ -43,10 +43,11 @@ void testRollbackOnDuplicateEmail() throws InvalidCreationException, DuplicateEm
// then
try {
service.signUp(command2);
fail("중복 이메일 예외가 발생해야 합니다.");
} catch (DuplicateEmailException e) {
assertEquals(1, customerRepository.count());
assertEquals(1, payAccountRepository.count());
} catch (DataIntegrityViolationException e) {
fail("DataIntegrityViolationException이 발생했습니다.");
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

import static org.mockito.BDDMockito.*;

import java.util.UUID;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
Expand All @@ -14,13 +16,11 @@

import camp.woowak.lab.customer.domain.Customer;
import camp.woowak.lab.customer.exception.DuplicateEmailException;
import camp.woowak.lab.customer.exception.InvalidCreationException;
import camp.woowak.lab.customer.repository.CustomerRepository;
import camp.woowak.lab.customer.service.command.SignUpCustomerCommand;
import camp.woowak.lab.fixture.CustomerFixture;
import camp.woowak.lab.payaccount.domain.PayAccount;
import camp.woowak.lab.payaccount.repository.PayAccountRepository;
import camp.woowak.lab.web.authentication.NoOpPasswordEncoder;
import camp.woowak.lab.web.authentication.PasswordEncoder;

@ExtendWith(MockitoExtension.class)
Expand All @@ -40,13 +40,14 @@ class SignUpCustomerServiceTest implements CustomerFixture {

@Test
@DisplayName("구매자 회원가입 테스트")
void testSignUp() throws InvalidCreationException, DuplicateEmailException {
void testSignUp() {
// given
given(passwordEncoder.encode(Mockito.anyString())).willReturn("password");
PayAccount payAccount = createPayAccount();
Customer customer = createCustomer(payAccount, new NoOpPasswordEncoder());
Customer customerMock = Mockito.mock(Customer.class);
given(payAccountRepository.save(Mockito.any(PayAccount.class))).willReturn(payAccount);
given(customerRepository.save(Mockito.any(Customer.class))).willReturn(customer);
given(customerRepository.saveAndFlush(Mockito.any(Customer.class))).willReturn(customerMock);
when(customerMock.getId()).thenReturn(UUID.randomUUID());

// when
SignUpCustomerCommand command =
Expand All @@ -55,7 +56,7 @@ void testSignUp() throws InvalidCreationException, DuplicateEmailException {

// then
then(payAccountRepository).should().save(Mockito.any(PayAccount.class));
then(customerRepository).should().save(Mockito.any(Customer.class));
then(customerRepository).should().saveAndFlush(Mockito.any(Customer.class));
}

@Test
Expand All @@ -64,7 +65,8 @@ void testSignUpWithExistingEmail() {
// given
given(passwordEncoder.encode(Mockito.anyString())).willReturn("password");
given(payAccountRepository.save(Mockito.any(PayAccount.class))).willReturn(createPayAccount());
when(customerRepository.save(Mockito.any(Customer.class))).thenThrow(DataIntegrityViolationException.class);
when(customerRepository.saveAndFlush(Mockito.any(Customer.class))).thenThrow(
DataIntegrityViolationException.class);

// when
SignUpCustomerCommand command =
Expand All @@ -73,6 +75,6 @@ void testSignUpWithExistingEmail() {
// then
Assertions.assertThrows(DuplicateEmailException.class, () -> service.signUp(command));
then(payAccountRepository).should().save(Mockito.any(PayAccount.class));
then(customerRepository).should().save(Mockito.any(Customer.class));
then(customerRepository).should().saveAndFlush(Mockito.any(Customer.class));
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import static org.assertj.core.api.Assertions.*;

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

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
Expand Down Expand Up @@ -71,7 +72,7 @@ void withdrawAccount() {
@DisplayName("없는 AccountId를 호출하면 NotFoundAccountException을 던진다. 잔고는 유지된다.")
void withdrawAccountNotFound() {
//given
Long unknownAccountId = Long.MAX_VALUE;
UUID unknownAccountId = UUID.randomUUID();
long amount = 100L;
PayAccountChargeCommand command = new PayAccountChargeCommand(unknownAccountId, amount);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;

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

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
Expand Down Expand Up @@ -102,9 +103,9 @@ void successTest() throws Exception {

//when & then
mvc.perform(post(BASE_URL)
.contentType(MediaType.APPLICATION_JSON_VALUE)
.content(objectMapper.writeValueAsBytes(command))
.session(session))
.contentType(MediaType.APPLICATION_JSON_VALUE)
.content(objectMapper.writeValueAsBytes(command))
.session(session))
.andExpect(status().isOk())
.andExpect(jsonPath("$.status").value(HttpStatus.OK.value()))
.andExpect(jsonPath("$.data.balance").value(amount + originBalance));
Expand All @@ -122,9 +123,9 @@ void dailyLimitExceededTest() throws Exception {

//when & then
ResultActions actions = mvc.perform(post(BASE_URL)
.contentType(MediaType.APPLICATION_JSON_VALUE)
.content(objectMapper.writeValueAsBytes(command))
.session(session))
.contentType(MediaType.APPLICATION_JSON_VALUE)
.content(objectMapper.writeValueAsBytes(command))
.session(session))
.andDo(print())
.andExpect(status().isBadRequest());

Expand All @@ -136,16 +137,16 @@ void dailyLimitExceededTest() throws Exception {
void notExistsAccountIdTest() throws Exception {
//given
long amount = 1000L;
Long notExistsId = Long.MAX_VALUE;
UUID notExistsId = UUID.randomUUID();
MockHttpSession notExistsSession = new MockHttpSession();
notExistsSession.setAttribute(SessionConst.SESSION_CUSTOMER_KEY, new LoginCustomer(notExistsId));
PayAccountChargeRequest command = new PayAccountChargeRequest(amount);

//when & then
ResultActions actions = mvc.perform(post(BASE_URL)
.contentType(MediaType.APPLICATION_JSON_VALUE)
.content(objectMapper.writeValueAsBytes(command))
.session(notExistsSession))
.contentType(MediaType.APPLICATION_JSON_VALUE)
.content(objectMapper.writeValueAsBytes(command))
.session(notExistsSession))
.andExpect(status().isNotFound());

validateErrorResponseWithErrorCode(actions, PayAccountErrorCode.ACCOUNT_NOT_FOUND);
Expand All @@ -159,9 +160,9 @@ void nullAmountTest() throws Exception {

//when & then
ResultActions actions = mvc.perform(post(BASE_URL)
.contentType(MediaType.APPLICATION_JSON_VALUE)
.content(objectMapper.writeValueAsBytes(command))
.session(session))
.contentType(MediaType.APPLICATION_JSON_VALUE)
.content(objectMapper.writeValueAsBytes(command))
.session(session))
.andExpect(status().isBadRequest());

verificationPersistedBalance(payAccount.getId(), originBalance);
Expand All @@ -176,9 +177,9 @@ void negativeAmountTest() throws Exception {

//when & then
ResultActions actions = mvc.perform(post(BASE_URL)
.contentType(MediaType.APPLICATION_JSON_VALUE)
.content(objectMapper.writeValueAsBytes(command))
.session(session))
.contentType(MediaType.APPLICATION_JSON_VALUE)
.content(objectMapper.writeValueAsBytes(command))
.session(session))
.andExpect(status().isBadRequest());

validateErrorResponseWithErrorCode(actions, PayAccountErrorCode.INVALID_TRANSACTION_AMOUNT);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;

import java.util.UUID;

import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
Expand Down Expand Up @@ -38,9 +40,10 @@ class CustomerApiControllerTest {
@DisplayName("구매자 회원가입 테스트 - 성공")
void testSignUpCustomer() throws Exception {
// given
String customerId = UUID.randomUUID().toString();
SignUpCustomerRequest request = new SignUpCustomerRequest("name", "[email protected]", "password123",
"010-1234-5678");
given(signUpCustomerService.signUp(any())).willReturn(1L);
given(signUpCustomerService.signUp(any())).willReturn(customerId);

// when & then
mockMvc.perform(post("/customers")
Expand Down

0 comments on commit 75a532e

Please sign in to comment.