Refactor code
- Remove util class - Add SessionManager - Refactor test code
This commit is contained in:
@@ -6,9 +6,9 @@ import com.yam.app.account.domain.LoginAccountProcessor;
|
||||
import com.yam.app.account.domain.RegisterAccountEvent;
|
||||
import com.yam.app.account.domain.RegisterAccountProcessor;
|
||||
import com.yam.app.account.presentation.AccountResponse;
|
||||
import com.yam.app.account.presentation.ConfirmRegisterAccountRequestCommand;
|
||||
import com.yam.app.account.presentation.LoginAccountRequestCommand;
|
||||
import com.yam.app.account.presentation.RegisterAccountRequestCommand;
|
||||
import com.yam.app.account.presentation.ConfirmRegisterAccountCommand;
|
||||
import com.yam.app.account.presentation.LoginAccountCommand;
|
||||
import com.yam.app.account.presentation.RegisterAccountCommand;
|
||||
import org.springframework.context.ApplicationEventPublisher;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
@@ -36,30 +36,30 @@ public class AccountFacade {
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public AccountResponse register(RegisterAccountRequestCommand request) {
|
||||
public AccountResponse register(RegisterAccountCommand command) {
|
||||
var entity = registerProcessor.process(
|
||||
request.getEmail(),
|
||||
request.getNickname(),
|
||||
request.getPassword()
|
||||
command.getEmail(),
|
||||
command.getNickname(),
|
||||
command.getPassword()
|
||||
);
|
||||
publisher.publishEvent(new RegisterAccountEvent(entity));
|
||||
return translator.toResponse(entity);
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public void registerConfirm(ConfirmRegisterAccountRequestCommand request) {
|
||||
confirmRegisterProcessor.registerConfirm(request.getToken(), request.getEmail());
|
||||
public void registerConfirm(ConfirmRegisterAccountCommand command) {
|
||||
confirmRegisterProcessor.registerConfirm(command.getToken(), command.getEmail());
|
||||
}
|
||||
|
||||
@Transactional(readOnly = true)
|
||||
public void login(LoginAccountRequestCommand request) {
|
||||
loginProcessor.login(request.getEmail(), request.getPassword());
|
||||
public void login(LoginAccountCommand command) {
|
||||
loginProcessor.login(command.getEmail(), command.getPassword());
|
||||
}
|
||||
|
||||
@Transactional(readOnly = true)
|
||||
public AccountResponse getLoginAccount(String email) {
|
||||
public AccountResponse findInfo(String email) {
|
||||
return translator.toResponse(accountReader.findByEmail(email)
|
||||
.orElseThrow(IllegalStateException::new));
|
||||
.orElseThrow(IllegalArgumentException::new));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,14 +1,16 @@
|
||||
package com.yam.app.account.infrastructure;
|
||||
|
||||
import java.io.Serializable;
|
||||
import javax.validation.constraints.Email;
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import lombok.Data;
|
||||
import lombok.Getter;
|
||||
import lombok.ToString;
|
||||
|
||||
@Data
|
||||
@Getter
|
||||
@ToString
|
||||
public final class AccountPrincipal implements Serializable {
|
||||
|
||||
@NotBlank
|
||||
@Email
|
||||
private final String email;
|
||||
|
||||
public AccountPrincipal(String email) {
|
||||
this.email = email;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ import com.yam.app.account.domain.LoginAccountProcessor;
|
||||
import com.yam.app.account.domain.PasswordEncrypter;
|
||||
import com.yam.app.account.domain.RegisterAccountProcessor;
|
||||
import com.yam.app.account.domain.TokenVerifier;
|
||||
import javax.servlet.http.HttpSession;
|
||||
import org.mybatis.spring.SqlSessionTemplate;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
@@ -65,8 +66,9 @@ public class AppConfiguration {
|
||||
|
||||
@Bean
|
||||
public LoginAccountProcessor loginAccountProcessor(AccountReader accountReader,
|
||||
PasswordEncrypter passwordEncrypter) {
|
||||
return new SessionBasedLoginAccountProcessor(accountReader, passwordEncrypter);
|
||||
PasswordEncrypter passwordEncrypter, HttpSession httpSession) {
|
||||
return new SessionBasedLoginAccountProcessor(accountReader, passwordEncrypter,
|
||||
new SessionManager(httpSession));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,27 +0,0 @@
|
||||
package com.yam.app.account.infrastructure;
|
||||
|
||||
import javax.servlet.http.HttpSession;
|
||||
import org.springframework.web.context.request.RequestContextHolder;
|
||||
import org.springframework.web.context.request.ServletRequestAttributes;
|
||||
|
||||
public final class LoginSessionUtils {
|
||||
|
||||
public static final String LOGIN_ACCOUNT_EMAIL = "LOGIN_ACCOUNT_EMAIL";
|
||||
|
||||
private LoginSessionUtils() {
|
||||
}
|
||||
|
||||
private static HttpSession getHttpSession() {
|
||||
return ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes())
|
||||
.getRequest()
|
||||
.getSession(true);
|
||||
}
|
||||
|
||||
public static AccountPrincipal getAccountPrincipal() {
|
||||
return (AccountPrincipal) getHttpSession().getAttribute(LOGIN_ACCOUNT_EMAIL);
|
||||
}
|
||||
|
||||
public static void setAccountPrincipal(AccountPrincipal accountPrincipal) {
|
||||
getHttpSession().setAttribute(LOGIN_ACCOUNT_EMAIL, accountPrincipal);
|
||||
}
|
||||
}
|
||||
@@ -8,11 +8,14 @@ public final class SessionBasedLoginAccountProcessor implements LoginAccountProc
|
||||
|
||||
private final AccountReader accountReader;
|
||||
private final PasswordEncrypter passwordEncrypter;
|
||||
private final SessionManager sessionManager;
|
||||
|
||||
public SessionBasedLoginAccountProcessor(AccountReader accountReader,
|
||||
PasswordEncrypter passwordEncrypter) {
|
||||
PasswordEncrypter passwordEncrypter,
|
||||
SessionManager sessionManager) {
|
||||
this.accountReader = accountReader;
|
||||
this.passwordEncrypter = passwordEncrypter;
|
||||
this.sessionManager = sessionManager;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -28,6 +31,6 @@ public final class SessionBasedLoginAccountProcessor implements LoginAccountProc
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
|
||||
LoginSessionUtils.setAccountPrincipal(new AccountPrincipal(email));
|
||||
sessionManager.setPrincipal(new AccountPrincipal(email));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
package com.yam.app.account.infrastructure;
|
||||
|
||||
import javax.servlet.http.HttpSession;
|
||||
|
||||
public final class SessionManager {
|
||||
|
||||
public static final String LOGIN_ACCOUNT = "LOGIN_ACCOUNT_EMAIL";
|
||||
|
||||
private final HttpSession httpSession;
|
||||
|
||||
public SessionManager(HttpSession httpSession) {
|
||||
this.httpSession = httpSession;
|
||||
}
|
||||
|
||||
public void setPrincipal(AccountPrincipal principal) {
|
||||
this.httpSession.setAttribute(LOGIN_ACCOUNT, principal);
|
||||
}
|
||||
|
||||
public AccountPrincipal fetchPrincipal() {
|
||||
return (AccountPrincipal) httpSession.getAttribute(LOGIN_ACCOUNT);
|
||||
}
|
||||
}
|
||||
@@ -29,7 +29,7 @@ public final class AccountCommandApi {
|
||||
|
||||
@PostMapping("/api/accounts")
|
||||
public ResponseEntity<AccountResponse> register(
|
||||
@RequestBody @Valid RegisterAccountRequestCommand command) {
|
||||
@RequestBody @Valid RegisterAccountCommand command) {
|
||||
return ResponseEntity.ok(accountFacade.register(command));
|
||||
}
|
||||
|
||||
@@ -40,7 +40,7 @@ public final class AccountCommandApi {
|
||||
*/
|
||||
@GetMapping("/api/accounts/authorize")
|
||||
public ResponseEntity<Void> registerConfirm(
|
||||
@ModelAttribute @Valid ConfirmRegisterAccountRequestCommand command) throws Exception {
|
||||
@ModelAttribute @Valid ConfirmRegisterAccountCommand command) throws Exception {
|
||||
try {
|
||||
accountFacade.registerConfirm(command);
|
||||
} catch (Exception e) {
|
||||
|
||||
@@ -29,31 +29,29 @@ public final class AccountQueryApi {
|
||||
|
||||
@PostMapping("/api/accounts/login")
|
||||
public ResponseEntity<Void> login(
|
||||
@Valid @RequestBody LoginAccountRequestCommand request) {
|
||||
@Valid @RequestBody LoginAccountCommand request) {
|
||||
try {
|
||||
accountFacade.login(request);
|
||||
} catch (IllegalStateException e) {
|
||||
return new ResponseEntity<>(HttpStatus.UNAUTHORIZED);
|
||||
return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build();
|
||||
}
|
||||
|
||||
return ResponseEntity.ok().build();
|
||||
}
|
||||
|
||||
@GetMapping("/api/accounts/me")
|
||||
public ResponseEntity<AccountResponse> getAccount(
|
||||
public ResponseEntity<AccountResponse> findInfo(
|
||||
@LoginAccount AccountPrincipal accountPrincipal) {
|
||||
if (accountPrincipal == null) {
|
||||
return new ResponseEntity<>(HttpStatus.UNAUTHORIZED);
|
||||
return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build();
|
||||
}
|
||||
|
||||
AccountResponse accountResponse;
|
||||
try {
|
||||
accountResponse = accountFacade.getLoginAccount(accountPrincipal.getEmail());
|
||||
return ResponseEntity.ok(accountFacade.findInfo(
|
||||
accountPrincipal.getEmail()));
|
||||
} catch (Exception e) {
|
||||
return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
|
||||
return ResponseEntity.badRequest().build();
|
||||
}
|
||||
|
||||
return ResponseEntity.ok(accountResponse);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ import javax.validation.constraints.NotBlank;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public final class ConfirmRegisterAccountRequestCommand {
|
||||
public final class ConfirmRegisterAccountCommand {
|
||||
|
||||
@NotBlank
|
||||
private String token;
|
||||
@@ -6,7 +6,7 @@ import javax.validation.constraints.Pattern;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public final class LoginAccountRequestCommand {
|
||||
public final class LoginAccountCommand {
|
||||
|
||||
@NotBlank
|
||||
@Email
|
||||
@@ -1,16 +1,14 @@
|
||||
package com.yam.app.account.presentation;
|
||||
|
||||
import com.yam.app.account.infrastructure.LoginSessionUtils;
|
||||
import com.yam.app.account.infrastructure.SessionManager;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpSession;
|
||||
import org.springframework.core.MethodParameter;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.bind.support.WebDataBinderFactory;
|
||||
import org.springframework.web.context.request.NativeWebRequest;
|
||||
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
|
||||
import org.springframework.web.method.support.ModelAndViewContainer;
|
||||
|
||||
@Component
|
||||
public final class LoginAccountMethodArgumentResolver implements HandlerMethodArgumentResolver {
|
||||
|
||||
@Override
|
||||
@@ -28,7 +26,7 @@ public final class LoginAccountMethodArgumentResolver implements HandlerMethodAr
|
||||
return null;
|
||||
}
|
||||
|
||||
return session.getAttribute(LoginSessionUtils.LOGIN_ACCOUNT_EMAIL);
|
||||
|
||||
var sessionManager = new SessionManager(session);
|
||||
return sessionManager.fetchPrincipal();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ import javax.validation.constraints.Pattern;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public final class RegisterAccountRequestCommand {
|
||||
public final class RegisterAccountCommand {
|
||||
|
||||
@Email
|
||||
@NotBlank
|
||||
@@ -8,16 +8,8 @@ import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
||||
@Configuration
|
||||
public class WebConfiguration implements WebMvcConfigurer {
|
||||
|
||||
private final LoginAccountMethodArgumentResolver loginAccountMethodArgumentResolver;
|
||||
|
||||
public WebConfiguration(
|
||||
LoginAccountMethodArgumentResolver loginAccountMethodArgumentResolver) {
|
||||
this.loginAccountMethodArgumentResolver = loginAccountMethodArgumentResolver;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {
|
||||
resolvers.add(loginAccountMethodArgumentResolver);
|
||||
|
||||
resolvers.add(new LoginAccountMethodArgumentResolver());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,6 +25,6 @@ final class ArchUnitTests {
|
||||
.whereLayer("Presentation").mayOnlyBeAccessedByLayers("Application", "Integration")
|
||||
.whereLayer("Application").mayOnlyBeAccessedByLayers("Presentation", "Domain")
|
||||
.whereLayer("Domain").mayOnlyBeAccessedByLayers("Application", "Infrastructure")
|
||||
.whereLayer("Infrastructure").mayOnlyBeAccessedByLayers("Presentation")
|
||||
.whereLayer("Infrastructure").mayOnlyBeAccessedByLayers("Presentation", "Integration")
|
||||
.whereLayer("Integration").mayNotBeAccessedByAnyLayer();
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ final class ConfirmRegisterAccountProcessorTest {
|
||||
// Act
|
||||
confirmRegisterAccountProcessor.registerConfirm(account.getEmailCheckToken(),
|
||||
account.getEmail());
|
||||
Account updatedAccount = accountRepository.findByEmail(account.getEmail()).get();
|
||||
var updatedAccount = accountRepository.findByEmail(account.getEmail()).get();
|
||||
|
||||
// Assert
|
||||
assertThat(updatedAccount.isEmailVerified()).isTrue();
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package com.yam.app.account.domain;
|
||||
|
||||
public class PasswordEncrypterStub implements PasswordEncrypter {
|
||||
public final class PasswordEncrypterStub implements PasswordEncrypter {
|
||||
|
||||
@Override
|
||||
public String encode(CharSequence rawPassword) {
|
||||
|
||||
@@ -12,31 +12,43 @@ import java.util.Collection;
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.DynamicTest;
|
||||
import org.junit.jupiter.api.TestFactory;
|
||||
import org.springframework.mock.web.MockHttpSession;
|
||||
|
||||
@DisplayName("세션 기반 회원 로그인 처리기")
|
||||
final class SessionBasedLoginAccountProcessorTest {
|
||||
|
||||
@TestFactory
|
||||
@DisplayName("세션 회원 로그인 검증 테스트")
|
||||
@DisplayName("회원 로그인 검증 테스트")
|
||||
Collection<DynamicTest> login_success() {
|
||||
//Arrange
|
||||
var accountRepository = new FakeAccountRepository();
|
||||
var accountNotConfirm = Account.of("hello1@naver.com", "hello1",
|
||||
var fakeObject = new FakeAccountRepository();
|
||||
final var accountRepository = fakeObject;
|
||||
final var accountReader = fakeObject;
|
||||
var accountNotYetConfirm = Account.of("hello1@naver.com", "hello1",
|
||||
"password!");
|
||||
var accountCompleted = Account.of("hello@naver.com", "hello",
|
||||
"password!");
|
||||
accountCompleted.completeRegister();
|
||||
accountRepository.save(accountCompleted);
|
||||
accountRepository.save(accountNotConfirm);
|
||||
accountRepository.save(accountNotYetConfirm);
|
||||
|
||||
var passwordEncryptor = new PasswordEncrypterStub();
|
||||
var loginAccountProcessor = new SessionBasedLoginAccountProcessor(accountRepository,
|
||||
passwordEncryptor);
|
||||
var sessionManager = new SessionManager(new MockHttpSession());
|
||||
var loginProcessor = new SessionBasedLoginAccountProcessor(accountReader,
|
||||
new PasswordEncrypterStub(), sessionManager);
|
||||
|
||||
return Arrays.asList(
|
||||
dynamicTest("로그인이 성공적으로 완료되며, 세션에 값이 저장된다.", () -> {
|
||||
// Act
|
||||
loginProcessor.login("hello@naver.com", "password!");
|
||||
|
||||
// Assert
|
||||
var result = sessionManager.fetchPrincipal();
|
||||
assertThat(result).isNotNull();
|
||||
}),
|
||||
dynamicTest("이메일이 유효하지 않은 경우 예외를 리턴한다.", () -> {
|
||||
// Act
|
||||
var throwable = catchThrowable(
|
||||
() -> loginAccountProcessor.login("dwqko@naver.com",
|
||||
() -> loginProcessor.login("dwqko@naver.com",
|
||||
accountCompleted.getPassword())
|
||||
);
|
||||
|
||||
@@ -46,8 +58,8 @@ final class SessionBasedLoginAccountProcessorTest {
|
||||
dynamicTest("이메일은 유효하나 검증을 완료하지 않은 경우 예외를 리턴한다.", () -> {
|
||||
// Act
|
||||
var throwable = catchThrowable(
|
||||
() -> loginAccountProcessor.login(accountNotConfirm.getEmail(),
|
||||
accountNotConfirm.getPassword())
|
||||
() -> loginProcessor.login(accountNotYetConfirm.getEmail(),
|
||||
accountNotYetConfirm.getPassword())
|
||||
);
|
||||
|
||||
// Assert
|
||||
@@ -56,7 +68,7 @@ final class SessionBasedLoginAccountProcessorTest {
|
||||
dynamicTest("비밀번호가 유효하지 않은 경우 예외를 리턴한다.", () -> {
|
||||
// Act
|
||||
var throwable = catchThrowable(
|
||||
() -> loginAccountProcessor.login(accountCompleted.getEmail(), "11111111!")
|
||||
() -> loginProcessor.login(accountCompleted.getEmail(), "11111111!")
|
||||
);
|
||||
|
||||
// Assert
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
package com.yam.app.account.integration;
|
||||
|
||||
import static com.yam.app.account.presentation.AccountApiUri.EMAIL_CONFIRM;
|
||||
import static com.yam.app.account.presentation.AccountApiUri.FIND_INFO;
|
||||
import static com.yam.app.account.presentation.AccountApiUri.LOGIN;
|
||||
import static com.yam.app.account.presentation.AccountApiUri.REGISTER;
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
|
||||
@@ -8,14 +12,17 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.yam.app.account.presentation.LoginAccountRequestCommand;
|
||||
import com.yam.app.account.presentation.RegisterAccountRequestCommand;
|
||||
import com.yam.app.account.infrastructure.AccountPrincipal;
|
||||
import com.yam.app.account.infrastructure.SessionManager;
|
||||
import com.yam.app.account.presentation.LoginAccountCommand;
|
||||
import com.yam.app.account.presentation.RegisterAccountCommand;
|
||||
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.web.servlet.AutoConfigureMockMvc;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.mock.web.MockHttpSession;
|
||||
import org.springframework.test.context.ActiveProfiles;
|
||||
import org.springframework.test.web.servlet.MockMvc;
|
||||
|
||||
@@ -25,25 +32,27 @@ import org.springframework.test.web.servlet.MockMvc;
|
||||
@ActiveProfiles("test")
|
||||
final class AccountIntegrationTests {
|
||||
|
||||
private static final String EMAIL_CONFIRM_SUCCESS_REDIRECT_URI = "http://localhost:3000/login";
|
||||
|
||||
@Autowired
|
||||
private MockMvc mockMvc;
|
||||
@Autowired
|
||||
private ObjectMapper objectMapper;
|
||||
|
||||
@Test
|
||||
@DisplayName("새로운 계정을 등록하는 회원가입 시나리오")
|
||||
@DisplayName("새로운 계정 등록에 적절한 파라미터가 입력되고, 계정이 성공적으로 등록된다.")
|
||||
void new_account_request_in_register_correctly() throws Exception {
|
||||
// Arrange
|
||||
var request = new RegisterAccountRequestCommand();
|
||||
request.setEmail("msolo021015@gmail.com");
|
||||
request.setNickname("rebwon");
|
||||
request.setPassword("password!");
|
||||
var command = new RegisterAccountCommand();
|
||||
command.setEmail("msolo021015@gmail.com");
|
||||
command.setNickname("rebwon");
|
||||
command.setPassword("password!");
|
||||
|
||||
// Act
|
||||
final var actions = mockMvc.perform(post("/api/accounts")
|
||||
final var actions = mockMvc.perform(post(REGISTER)
|
||||
.accept(MediaType.APPLICATION_JSON)
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.content(objectMapper.writeValueAsString(request))
|
||||
.content(objectMapper.writeValueAsString(command))
|
||||
);
|
||||
|
||||
// Assert
|
||||
@@ -56,10 +65,10 @@ final class AccountIntegrationTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("이메일과 토큰을 검증하고 회원의 상태를 업데이트하는 시나리오")
|
||||
@DisplayName("이메일 인증에 적절한 토큰과 이메일 정보가 입력되고, 이메일 인증 상태가 성공적으로 압데이트 된다.")
|
||||
void email_and_token_verify_request_in_correctly() throws Exception {
|
||||
// Act
|
||||
final var actions = mockMvc.perform(get("/api/accounts/authorize")
|
||||
final var actions = mockMvc.perform(get(EMAIL_CONFIRM)
|
||||
.accept(MediaType.APPLICATION_JSON)
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.param("token", "emailchecktoken")
|
||||
@@ -70,22 +79,22 @@ final class AccountIntegrationTests {
|
||||
actions
|
||||
.andDo(print())
|
||||
.andExpect(status().isSeeOther())
|
||||
.andExpect(redirectedUrl("http://localhost:3000/login"));
|
||||
.andExpect(redirectedUrl(EMAIL_CONFIRM_SUCCESS_REDIRECT_URI));
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("로그인 요청을 성공하여 서버의 세션 등록을 완료하는 시나리오")
|
||||
@DisplayName("로그인에 적절한 파라미터를 입력하고 로그인 요청이 성공적으로 완료된다.")
|
||||
void login_success() throws Exception {
|
||||
//Arrange
|
||||
LoginAccountRequestCommand request = new LoginAccountRequestCommand();
|
||||
request.setEmail("loginCheck@gmail.com");
|
||||
request.setPassword("password!");
|
||||
var command = new LoginAccountCommand();
|
||||
command.setEmail("loginCheck@gmail.com");
|
||||
command.setPassword("password!");
|
||||
|
||||
//Act
|
||||
final var actions = mockMvc.perform(post("/api/accounts/login")
|
||||
final var actions = mockMvc.perform(post(LOGIN)
|
||||
.accept(MediaType.APPLICATION_JSON)
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.content(objectMapper.writeValueAsString(request))
|
||||
.content(objectMapper.writeValueAsString(command))
|
||||
);
|
||||
|
||||
//Assert
|
||||
@@ -94,4 +103,28 @@ final class AccountIntegrationTests {
|
||||
.andExpect(status().isOk());
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("인증된 기본 사용자가 자신의 정보를 조회한다.")
|
||||
void authentication_member_find_info_success() throws Exception {
|
||||
//Arrange
|
||||
var session = new MockHttpSession();
|
||||
session.setAttribute(SessionManager.LOGIN_ACCOUNT,
|
||||
new AccountPrincipal("loginCheck@gmail.com"));
|
||||
|
||||
//Act
|
||||
final var actions = mockMvc.perform(get(FIND_INFO)
|
||||
.session(session)
|
||||
.accept(MediaType.APPLICATION_JSON)
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
);
|
||||
|
||||
//Assert
|
||||
actions
|
||||
.andDo(print())
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.id").isNumber())
|
||||
.andExpect(jsonPath("$.email").isString())
|
||||
.andExpect(jsonPath("$.nickname").isString());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
package com.yam.app.account.presentation;
|
||||
|
||||
public interface AccountApiUri {
|
||||
|
||||
String REGISTER = "/api/accounts";
|
||||
String EMAIL_CONFIRM = "/api/accounts/authorize";
|
||||
String LOGIN = "/api/accounts/login";
|
||||
String FIND_INFO = "/api/accounts/me";
|
||||
|
||||
}
|
||||
@@ -1,5 +1,7 @@
|
||||
package com.yam.app.account.presentation;
|
||||
|
||||
import static com.yam.app.account.presentation.AccountApiUri.EMAIL_CONFIRM;
|
||||
import static com.yam.app.account.presentation.AccountApiUri.REGISTER;
|
||||
import static org.mockito.Mockito.doThrow;
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
|
||||
@@ -35,7 +37,6 @@ final class AccountCommandApiTests {
|
||||
@DisplayName("이메일 검증 HTTP API")
|
||||
class RegisterConfirmApi {
|
||||
|
||||
private static final String EMAIL_AUTHORIZE_API = "/api/accounts/authorize";
|
||||
private static final String TOKEN = "token";
|
||||
private static final String EMAIL = "email";
|
||||
|
||||
@@ -44,12 +45,12 @@ final class AccountCommandApiTests {
|
||||
@DisplayName("HTTP 파라메타가 비었거나 null인 검증요청을 보낸 경우 400 HTTP Code 리턴한다.")
|
||||
void http_param_is_empty_or_null(String args) throws Exception {
|
||||
// Arrange
|
||||
var request = new ConfirmRegisterAccountRequestCommand();
|
||||
request.setToken(args);
|
||||
request.setEmail(args);
|
||||
var command = new ConfirmRegisterAccountCommand();
|
||||
command.setToken(args);
|
||||
command.setEmail(args);
|
||||
|
||||
// Act
|
||||
final var actions = mockMvc.perform(get(EMAIL_AUTHORIZE_API)
|
||||
final var actions = mockMvc.perform(get(EMAIL_CONFIRM)
|
||||
.accept(MediaType.APPLICATION_JSON)
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.param(TOKEN, args)
|
||||
@@ -67,14 +68,14 @@ final class AccountCommandApiTests {
|
||||
@DisplayName("HTTP 파라메타가 유효하지 않은 값으로 검증요청을 보낸 경우 400 HTTP Code 리턴한다.")
|
||||
void http_param_is_not_valid(String arg) throws Exception {
|
||||
// Arrange
|
||||
var request = new ConfirmRegisterAccountRequestCommand();
|
||||
request.setToken(arg);
|
||||
request.setEmail(arg);
|
||||
var command = new ConfirmRegisterAccountCommand();
|
||||
command.setToken(arg);
|
||||
command.setEmail(arg);
|
||||
|
||||
// Act
|
||||
doThrow(IllegalStateException.class).when(accountFacade).registerConfirm(request);
|
||||
doThrow(IllegalStateException.class).when(accountFacade).registerConfirm(command);
|
||||
|
||||
final var actions = mockMvc.perform(get(EMAIL_AUTHORIZE_API)
|
||||
final var actions = mockMvc.perform(get(EMAIL_CONFIRM)
|
||||
.accept(MediaType.APPLICATION_JSON)
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.param(TOKEN, arg)
|
||||
@@ -92,22 +93,20 @@ final class AccountCommandApiTests {
|
||||
@DisplayName("회원가입 등록 HTTP API")
|
||||
class RegisterApi {
|
||||
|
||||
private static final String REGISTER_API = "/api/accounts";
|
||||
|
||||
@ParameterizedTest
|
||||
@AutoSource
|
||||
@DisplayName("Accept와 Content-Type을 지정하지 않아, HttpMediaTypeNotSupportedException 발생.")
|
||||
void register_account_api_not_use_accept_header_and_content_type(String arg)
|
||||
throws Exception {
|
||||
// Arrange
|
||||
var request = new RegisterAccountRequestCommand();
|
||||
request.setEmail(arg);
|
||||
request.setNickname(arg);
|
||||
request.setPassword(arg);
|
||||
var command = new RegisterAccountCommand();
|
||||
command.setEmail(arg);
|
||||
command.setNickname(arg);
|
||||
command.setPassword(arg);
|
||||
|
||||
// Act
|
||||
final var actions = mockMvc.perform(post(REGISTER_API)
|
||||
.content(objectMapper.writeValueAsString(request))
|
||||
final var actions = mockMvc.perform(post(REGISTER)
|
||||
.content(objectMapper.writeValueAsString(command))
|
||||
);
|
||||
|
||||
// Assert
|
||||
@@ -120,16 +119,16 @@ final class AccountCommandApiTests {
|
||||
@DisplayName("HTTP 입력이 Null이거나 Emtpy인 경우 검증에 실패하여 에러를 응답한다.")
|
||||
void register_http_parameter_is_null_and_empty(String arg) throws Exception {
|
||||
// Arrange
|
||||
var request = new RegisterAccountRequestCommand();
|
||||
request.setEmail(arg);
|
||||
request.setNickname(arg);
|
||||
request.setPassword(arg);
|
||||
var command = new RegisterAccountCommand();
|
||||
command.setEmail(arg);
|
||||
command.setNickname(arg);
|
||||
command.setPassword(arg);
|
||||
|
||||
// Act
|
||||
final var actions = mockMvc.perform(post(REGISTER_API)
|
||||
final var actions = mockMvc.perform(post(REGISTER)
|
||||
.accept(MediaType.APPLICATION_JSON)
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.content(objectMapper.writeValueAsString(request))
|
||||
.content(objectMapper.writeValueAsString(command))
|
||||
);
|
||||
|
||||
// Assert
|
||||
@@ -139,20 +138,20 @@ final class AccountCommandApiTests {
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@AutoSource
|
||||
@DisplayName("HTTP 입력 파라미터가 이메일, 비밀번호 검증에 실패하여 에러를 응답한다.")
|
||||
@ValueSource(strings = {"@@@@@@@@@", "@naver.com", "jiwon"})
|
||||
@DisplayName("요청 Body의 이메일 형식이 맞지 않는 경우 400 에러를 반환한다.")
|
||||
void register_http_parameter_is_invalid_email_and_password(String arg) throws Exception {
|
||||
// Arrange
|
||||
var request = new RegisterAccountRequestCommand();
|
||||
request.setEmail(arg);
|
||||
request.setNickname(arg);
|
||||
request.setPassword(arg);
|
||||
var command = new RegisterAccountCommand();
|
||||
command.setEmail(arg);
|
||||
command.setNickname("jiwon");
|
||||
command.setPassword("password1!");
|
||||
|
||||
// Act
|
||||
final var actions = mockMvc.perform(post(REGISTER_API)
|
||||
final var actions = mockMvc.perform(post(REGISTER)
|
||||
.accept(MediaType.APPLICATION_JSON)
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.content(objectMapper.writeValueAsString(request))
|
||||
.content(objectMapper.writeValueAsString(command))
|
||||
);
|
||||
|
||||
// Assert
|
||||
@@ -163,19 +162,19 @@ final class AccountCommandApiTests {
|
||||
|
||||
@ParameterizedTest
|
||||
@ValueSource(strings = {"1", "a", "1a234567890123456"})
|
||||
@DisplayName("요청 Body 의 비밀번호 형식이 맞지 않은 경우 400 에러를 반환한다.")
|
||||
@DisplayName("요청 Body의 비밀번호 형식이 맞지 않은 경우 400 에러를 반환한다.")
|
||||
void http_json_password_is_invalid(String args) throws Exception {
|
||||
// Arrange
|
||||
var request = new RegisterAccountRequestCommand();
|
||||
request.setEmail("jiwon@naver.com");
|
||||
request.setNickname("jiwon");
|
||||
request.setPassword(args);
|
||||
var command = new RegisterAccountCommand();
|
||||
command.setEmail("jiwon@naver.com");
|
||||
command.setNickname("jiwon");
|
||||
command.setPassword(args);
|
||||
|
||||
// Act
|
||||
final var actions = mockMvc.perform(post(REGISTER_API)
|
||||
final var actions = mockMvc.perform(post(REGISTER)
|
||||
.accept(MediaType.APPLICATION_JSON)
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.content(objectMapper.writeValueAsString(request))
|
||||
.content(objectMapper.writeValueAsString(command))
|
||||
);
|
||||
|
||||
// Assert
|
||||
|
||||
@@ -1,18 +1,15 @@
|
||||
package com.yam.app.account.presentation;
|
||||
|
||||
import static org.mockito.Mockito.doNothing;
|
||||
import static com.yam.app.account.presentation.AccountApiUri.FIND_INFO;
|
||||
import static com.yam.app.account.presentation.AccountApiUri.LOGIN;
|
||||
import static org.mockito.Mockito.doThrow;
|
||||
import static org.mockito.Mockito.when;
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.yam.app.account.application.AccountFacade;
|
||||
import com.yam.app.account.infrastructure.AccountPrincipal;
|
||||
import com.yam.app.account.infrastructure.LoginSessionUtils;
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Nested;
|
||||
import org.junit.jupiter.api.Test;
|
||||
@@ -23,7 +20,6 @@ import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
|
||||
import org.springframework.boot.test.mock.mockito.MockBean;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.mock.web.MockHttpSession;
|
||||
import org.springframework.test.web.servlet.MockMvc;
|
||||
|
||||
@DisplayName("Account Query HTTP API")
|
||||
@@ -42,39 +38,10 @@ class AccountQueryApiTest {
|
||||
class LoginApi {
|
||||
|
||||
@Test
|
||||
@DisplayName("로그인한 회원이 요청하면 세션에서 Account 정보를 성공적으로 반환 받는다.")
|
||||
void login_member_get_account_session_request() throws Exception {
|
||||
//Arrange
|
||||
var session = new MockHttpSession();
|
||||
session.setAttribute(LoginSessionUtils.LOGIN_ACCOUNT_EMAIL,
|
||||
new AccountPrincipal("loginCheck@gmail.com"));
|
||||
|
||||
when(accountFacade.getLoginAccount("loginCheck@gmail.com"))
|
||||
.thenReturn(new AccountResponse(1L, "loginCheck@gmail.com",
|
||||
"loginNick"));
|
||||
|
||||
//Act
|
||||
final var actions = mockMvc.perform(get("/api/accounts/me")
|
||||
.session(session)
|
||||
.accept(MediaType.APPLICATION_JSON)
|
||||
.contentType(MediaType.APPLICATION_JSON));
|
||||
|
||||
//Assert
|
||||
actions
|
||||
.andDo(print())
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.id").isNumber())
|
||||
.andExpect(jsonPath("$.email").isString())
|
||||
.andExpect(jsonPath("$.nickname").isString());
|
||||
|
||||
session.clearAttributes();
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("세션이 없는 상태로 Account 정보를 요청하면 401 에러를 반환한다.")
|
||||
@DisplayName("인증되지 않은 상태로 요청을 보낸 경우 401 에러를 반환한다.")
|
||||
void no_current_session_account_request() throws Exception {
|
||||
//Act
|
||||
final var actions = mockMvc.perform(get("/api/accounts/me")
|
||||
final var actions = mockMvc.perform(get(FIND_INFO)
|
||||
.accept(MediaType.APPLICATION_JSON)
|
||||
.contentType(MediaType.APPLICATION_JSON));
|
||||
|
||||
@@ -84,39 +51,18 @@ class AccountQueryApiTest {
|
||||
.andExpect(status().isUnauthorized());
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("정상적인 이메일과 비밀번호를 보내 로그인에 성공하고 200을 반환한다.")
|
||||
void login_success() throws Exception {
|
||||
//Arrange
|
||||
LoginAccountRequestCommand request = new LoginAccountRequestCommand();
|
||||
request.setEmail("jiwon@gmail.com");
|
||||
request.setPassword("password!");
|
||||
doNothing().when(accountFacade).login(request);
|
||||
|
||||
//Act
|
||||
final var actions = mockMvc.perform(post("/api/accounts/login")
|
||||
.accept(MediaType.APPLICATION_JSON)
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.content(objectMapper.writeValueAsString(request))
|
||||
);
|
||||
|
||||
//Assert
|
||||
actions
|
||||
.andDo(print())
|
||||
.andExpect(status().isOk());
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("이메일, 비밀번호 형식은 유효하나 로그인이 실패한 경우 401 에러를 반환한다.")
|
||||
void login_fail() throws Exception {
|
||||
// Arrange
|
||||
var request = new LoginAccountRequestCommand();
|
||||
var request = new LoginAccountCommand();
|
||||
request.setEmail("wejiwef@naver.com");
|
||||
request.setPassword("password1!");
|
||||
doThrow(IllegalStateException.class).when(accountFacade).login(request);
|
||||
|
||||
// Act
|
||||
final var actions = mockMvc.perform(post("/api/accounts/login")
|
||||
doThrow(IllegalStateException.class).when(accountFacade).login(request);
|
||||
|
||||
final var actions = mockMvc.perform(post(LOGIN)
|
||||
.accept(MediaType.APPLICATION_JSON)
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.content(objectMapper.writeValueAsString(request))
|
||||
@@ -130,16 +76,15 @@ class AccountQueryApiTest {
|
||||
|
||||
@ParameterizedTest
|
||||
@ValueSource(strings = {"1", "a", "1a234567890123456"})
|
||||
@DisplayName("요청 Body 의 비밀번호 형식이 맞지 않은 경우 400 에러를 반환한다.")
|
||||
@DisplayName("요청 Body의 비밀번호 형식이 맞지 않은 경우 400 에러를 반환한다.")
|
||||
void http_json_password_is_invalid(String args) throws Exception {
|
||||
// Arrange
|
||||
var request = new LoginAccountRequestCommand();
|
||||
var request = new LoginAccountCommand();
|
||||
request.setEmail("jiwon22@gmail.com");
|
||||
request.setPassword(args);
|
||||
doThrow(IllegalStateException.class).when(accountFacade).login(request);
|
||||
|
||||
// Act
|
||||
final var actions = mockMvc.perform(post("/api/accounts/login")
|
||||
final var actions = mockMvc.perform(post(LOGIN)
|
||||
.accept(MediaType.APPLICATION_JSON)
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.content(objectMapper.writeValueAsString(request))
|
||||
@@ -153,19 +98,18 @@ class AccountQueryApiTest {
|
||||
|
||||
@ParameterizedTest
|
||||
@ValueSource(strings = {"@@@@@@@@@", "@naver.com", "jiwon"})
|
||||
@DisplayName("요청 Body 의 이메일 형식이 맞지 않은 경우 400 에러를 반환한다.")
|
||||
void http_json_email_is_invalid() throws Exception {
|
||||
@DisplayName("요청 Body의 이메일 형식이 맞지 않은 경우 400 에러를 반환한다.")
|
||||
void http_json_email_is_invalid(String email) throws Exception {
|
||||
// Arrange
|
||||
var request = new LoginAccountRequestCommand();
|
||||
request.setEmail("DQWJIDWQ291");
|
||||
request.setPassword("1abcabcabc");
|
||||
doThrow(IllegalStateException.class).when(accountFacade).login(request);
|
||||
var command = new LoginAccountCommand();
|
||||
command.setEmail(email);
|
||||
command.setPassword("password!1");
|
||||
|
||||
// Act
|
||||
final var actions = mockMvc.perform(post("/api/accounts/login")
|
||||
final var actions = mockMvc.perform(post(LOGIN)
|
||||
.accept(MediaType.APPLICATION_JSON)
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.content(objectMapper.writeValueAsString(request))
|
||||
.content(objectMapper.writeValueAsString(command))
|
||||
);
|
||||
|
||||
// Assert
|
||||
@@ -176,18 +120,18 @@ class AccountQueryApiTest {
|
||||
|
||||
@ParameterizedTest
|
||||
@NullAndEmptySource
|
||||
@DisplayName("요청 Body 의 이메일,비밀번호가 null 이거나 비어있다면 400 에러를 반환한다.")
|
||||
@DisplayName("요청 Body의 이메일,비밀번호가 null 이거나 비어있다면 400 에러를 반환한다.")
|
||||
void http_json_value_is_empty_or_null(String args) throws Exception {
|
||||
//Arrange
|
||||
var request = new LoginAccountRequestCommand();
|
||||
request.setEmail(args);
|
||||
request.setPassword(args);
|
||||
var command = new LoginAccountCommand();
|
||||
command.setEmail(args);
|
||||
command.setPassword(args);
|
||||
|
||||
//Act
|
||||
final var actions = mockMvc.perform(post("/api/accounts/login")
|
||||
final var actions = mockMvc.perform(post(LOGIN)
|
||||
.accept(MediaType.APPLICATION_JSON)
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.content(objectMapper.writeValueAsString(request))
|
||||
.content(objectMapper.writeValueAsString(command))
|
||||
);
|
||||
|
||||
//Assert
|
||||
|
||||
Reference in New Issue
Block a user