It manages the storage and inquiry of sessions using an external session

repository.

- Enable Redis Http Session
- Embedded Redis Settings
- Refactor integration tests
This commit is contained in:
Rebwon
2021-09-22 14:31:45 +09:00
committed by MaengSol
parent eaa84b2a50
commit 107f3aa91d
5 changed files with 119 additions and 41 deletions

View File

@@ -46,12 +46,20 @@ dependencies {
implementation 'com.lmax:disruptor:3.4.4'
implementation 'org.springframework.boot:spring-boot-starter-log4j2'
implementation 'org.springframework.boot:spring-boot-starter-mail'
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
implementation 'org.springframework.security:spring-security-crypto:5.5.2'
implementation 'org.springframework.boot:spring-boot-starter-validation'
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'it.ozimov:embedded-redis:0.7.2'
testImplementation 'it.ozimov:embedded-redis:0.7.2'
implementation 'org.springframework.boot:spring-boot-starter-data-redis'
implementation 'org.springframework.session:spring-session-data-redis'
testImplementation 'io.github.javaunit:autoparams:0.2.12'
testImplementation 'com.tngtech.archunit:archunit-junit5:0.20.1'

View File

@@ -0,0 +1,34 @@
package com.yam.app.common.configuration;
import java.io.IOException;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import redis.embedded.RedisServer;
@Slf4j
@Profile({"test", "local"})
@Configuration
public class EmbeddedRedisConfiguration {
@Value("${spring.redis.port}")
private int redisPort;
private RedisServer redisServer;
@PostConstruct
public void redisServer() throws IOException {
redisServer = new RedisServer(redisPort);
redisServer.start();
}
@PreDestroy
public void stopRedis() {
if (redisServer != null) {
redisServer.stop();
}
}
}

View File

@@ -0,0 +1,33 @@
package com.yam.app.common.configuration;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession;
@Configuration
@EnableRedisHttpSession
public class RedisConfiguration {
@Value("${spring.redis.host}")
private String redisHost;
@Value("${spring.redis.port}")
private int redisPort;
@Bean
public RedisConnectionFactory redisConnectionFactory() {
return new LettuceConnectionFactory(redisHost, redisPort);
}
@Bean
public RedisTemplate<byte[], byte[]> redisTemplate() {
RedisTemplate<byte[], byte[]> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(redisConnectionFactory());
return redisTemplate;
}
}

View File

@@ -10,6 +10,12 @@ spring:
timeout: 5000
starttls:
enable: true
session:
store-type: redis
redis:
host: localhost
password:
port: 6379
app:
mail:

View File

@@ -10,21 +10,22 @@ import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.redirectedUrl;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import static org.springframework.test.web.servlet.setup.SharedHttpSessionConfigurer.sharedHttpSession;
import com.fasterxml.jackson.databind.ObjectMapper;
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.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.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;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;
@SpringBootTest
@AutoConfigureMockMvc
@@ -39,6 +40,17 @@ final class AccountIntegrationTests {
@Autowired
private ObjectMapper objectMapper;
@Autowired
private WebApplicationContext wac;
@BeforeEach
void setUp() {
mockMvc = MockMvcBuilders
.webAppContextSetup(wac)
.apply(sharedHttpSession())
.build();
}
@Test
@DisplayName("새로운 계정 등록에 적절한 파라미터가 입력되고, 계정이 성공적으로 등록된다.")
void new_account_request_in_register_correctly() throws Exception {
@@ -80,50 +92,35 @@ final class AccountIntegrationTests {
}
@Test
@DisplayName("로그인에 적절한 파라미터를 입력하고 로그인 요청이 성공적으로 완료된다.")
void login_success() throws Exception {
@DisplayName("로그인에 적절한 파라미터를 입력하여, 성공하고 "
+ "이후 자신의 정보를 조회하는 시나리오 테스트.")
void login_success_and_authentication_member_find_info_success_scenarios() throws Exception {
//Arrange
var command = new LoginAccountCommand();
command.setEmail("loginCheck@gmail.com");
command.setPassword("password!");
//Act
final var actions = mockMvc.perform(post(LOGIN)
.accept(MediaType.APPLICATION_JSON)
.contentType(MediaType.APPLICATION_JSON)
.content(objectMapper.writeValueAsString(command))
);
//Assert
actions
.andDo(print())
.andExpect(status().isOk());
}
@Test
@DisplayName("인증된 기본 사용자가 자신의 정보를 조회한다.")
void authentication_member_find_info_success() throws Exception {
//Arrange
var session = new MockHttpSession();
var sessionManager = new SessionManager(session);
sessionManager.setPrincipal(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())
mockMvc.perform(post(LOGIN)
.accept(MediaType.APPLICATION_JSON)
.contentType(MediaType.APPLICATION_JSON)
.content(objectMapper.writeValueAsString(command))
)
.andExpect(status().isOk())
.andExpect(jsonPath("$.success").value(true))
.andExpect(jsonPath("$.message").doesNotExist())
.andExpect(jsonPath("$.data.id").isNumber())
.andExpect(jsonPath("$.data.email").isString())
.andExpect(jsonPath("$.data.nickname").isString());
.andDo(
result -> {
final var actions = mockMvc.perform(get(FIND_INFO)
.accept(MediaType.APPLICATION_JSON)
.contentType(MediaType.APPLICATION_JSON)
);
actions
.andExpect(status().isOk())
.andExpect(jsonPath("$.success").value(true))
.andExpect(jsonPath("$.message").doesNotExist())
.andExpect(jsonPath("$.data.id").isNumber())
.andExpect(jsonPath("$.data.email").isString())
.andExpect(jsonPath("$.data.nickname").isString());
});
}
}