diff --git a/README.md b/README.md index 40b4af945..55d034fda 100644 --- a/README.md +++ b/README.md @@ -128,6 +128,77 @@ +
+ +--- +## ๐Ÿš€ 7๋‹จ๊ณ„ - @Configuration + +### ๐Ÿ“ ๊ธฐ๋Šฅ ์š”๊ตฌ์‚ฌํ•ญ +โœ… JWT ๊ด€๋ จ ๋กœ์ง์„ roomescape์™€ ๊ฐ™์€ ๊ณ„์ธต์˜ auth ํŒจํ‚ค์ง€์˜ ํด๋ž˜์Šค๋กœ ๋ถ„๋ฆฌํ•˜์„ธ์š”. +โœ… ๋ถˆํ•„์š”ํ•œ DB ์ ‘๊ทผ์„ ์ตœ์†Œํ™” ํ•˜์„ธ์š”. + + + +### ๐Ÿ’ป ๊ตฌํ˜„ ์ „๋žต + +1. jwt ๋ชจ๋“ˆ ๋ถ„๋ฆฌ + โžก๏ธ Jwt ํ† ํฐ์„ ๋ฐœ๊ธ‰, ํŒŒ์‹ฑํ–ˆ๋˜ `JwtTokenProvider`์™€ + โžก๏ธ Jwt๊ด€๋ จ ํ™˜๊ฒฝ๋ณ€์ˆ˜๋ฅผ ๋‹ด์€ `JwtProperties` ํด๋ž˜์Šค๋ฅผ ์™ธ๋ถ€ jwt ํŒจํ‚ค์ง€๋กœ ๋ถ„๋ฆฌํ•˜๊ณ  + โžก๏ธ ํ•ด๋‹น ๊ฐ์ฒด๋“ค์„ `JwtConfig`๋ฅผ ํ†ตํ•ด ๋นˆ์œผ๋กœ ๋“ฑ๋ก + +์ด๋ ‡๊ฒŒ ๋ถ„๋ฆฌ๋œ ์„ค์ •์„ Application ํด๋ž˜์Šค์— `@Import` + + + + +
+ +--- +## ๐Ÿš€ 8๋‹จ๊ณ„ - Profile๊ณผ Resource + +### ๐Ÿ“ ๊ธฐ๋Šฅ ์š”๊ตฌ์‚ฌํ•ญ +โœ… schema.sql ๋Œ€์‹  ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋ฅผ ์ดˆ๊ธฐํ™” ํ•ด์ฃผ๊ธฐ ์œ„ํ•ด ์‹คํ–‰ํ•˜๋Š” ํด๋ž˜์Šค๋ฅผ ๋งŒ๋“œ์„ธ์š”. +โœ… token ์ƒ์„ฑ์— ํ•„์š”ํ•œ ๋น„๋ฐ€ํ‚ค๊ฐ’์„ ์™ธ๋ถ€ ํŒŒ์ผ๋กœ ๋ถ„๋ฆฌํ•˜์„ธ์š” + + + +### ๐Ÿ’ป ๊ตฌํ˜„ ์ „๋žต + +1. DB ์ดˆ๊ธฐํ™” + โžก๏ธ Production์šฉ๊ณผ DataLoader + โžก๏ธ Test์šฉ TestDataLoader๋ฅผ ๋”ฐ๋กœ ๋งŒ๋“ค์–ด DB ์ดˆ๊ธฐํ™” + +2. prod ํ™˜๊ฒฝ๊ณผ test ํ™˜๊ฒฝ ๋ถ„๋ฆฌ + โžก๏ธ test ์— ๊ด€ํ•œ ์„ค์ •์€ test ํŒจํ‚ค์ง€ ํ•˜์œ„ application.yml ํŒŒ์ผ ์ƒ์„ฑ + + + + + +
+ +--- +## ๐Ÿš€ 9๋‹จ๊ณ„ - ๋ฐฐํฌ ์Šคํฌ๋ฆฝํŠธ + +### ๐Ÿ“ ๊ธฐ๋Šฅ ์š”๊ตฌ์‚ฌํ•ญ +โœ… ec2๋‚˜ ์„œ๋ฒ„์—์„œ ๋ฐฐํฌ๋ฅผ ํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋ฐฐํฌ ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์ž‘์„ฑํ•˜์„ธ์š”. + + + +### ๐Ÿ’ป ๊ตฌํ˜„ ์ „๋žต + +1. EC2 ์ธ์Šคํ„ด์Šค ์ƒ์„ฑ + + + +2. ์ธ์Šคํ„ด์Šค์— ssh ์ ‘์† ํ›„ ๋ฉ”๋ชจ๋ฆฌ ์Šค์™‘ ์„ค์ • + โžก๏ธ ๋ถ€์กฑํ•œ ์ธ์Šคํ„ด์Šค์˜ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ๋””์Šคํฌ๋ฅผ ํ™œ์šฉํ•ด ๋ฉ”๋ชจ๋ฆฌ์˜ ๋‚ด์šฉ์„ ์Šค์™‘ํ•จ์œผ๋กœ์จ, ์‚ฌ์šฉ๊ฐ€๋Šฅํ•œ ๋ฉ”๋ชจ๋ฆฌ ์ƒํ•œ ์˜ฌ๋ฆผ + + +3. github ์— ์ฝ”๋“œ๋ฅผ pull + +4. ํ”„๋กœ์ ํŠธ ๋นŒ๋“œ +5. ๋นŒ๋“œ๋œ jar ํŒŒ์ผ ๋ฐฑ ๊ทธ๋ผ์šด๋“œ๋กœ ์‹คํ–‰ diff --git a/deploy.sh b/deploy.sh new file mode 100644 index 000000000..a8b37249a --- /dev/null +++ b/deploy.sh @@ -0,0 +1,78 @@ +#!/bin/bash + +# ๋ช…๋ น ์—๋Ÿฌ ๋ฐœ์ƒ ์‹œ ์ข…๋ฃŒ +set -e + +PROJECT_ROOT="/home/ubuntu/spring-basic-roomescape-playground" +APP_NAME="spring-basic-roomescape-playground" + +APP_LOG="$PROJECT_ROOT/application.log" +APP_ERROR_LOG="$PROJECT_ROOT/error.log" +DEPLOY_LOG="$PROJECT_ROOT/deploy.log" + +# ๋ฐฐํฌ ์ค‘ ์—๋Ÿฌ ๋ฐœ์ƒ์œผ๋กœ ์ค‘๋‹จ ์‹œ ๋กœ๊ทธ ๊ธฐ๋ก ํ•จ์ˆ˜ +on_error() { + echo "********** [๋ฐฐํฌ ์ค‘ ์—๋Ÿฌ ๋ฐœ์ƒ] : $(date +%Y-%m-%d\ %H:%M:%S) **********" >> $DEPLOY_LOG + echo " -> ์‹คํŒจํ•œ ๋ช…๋ น์–ด: '$BASH_COMMAND'" >> $DEPLOY_LOG + echo " -> ์œ„์น˜: ${BASH_SOURCE[1]}:${LINENO[1]}" >> $DEPLOY_LOG + exit 1 +} +trap on_error ERR + +echo "=========== [๋ฐฐํฌ ์‹œ์ž‘] : $(date +%Y-%m-%d\ %H:%M:%S) ===========" >> $DEPLOY_LOG + +cd $PROJECT_ROOT + +# 1. ์ตœ์‹  ์ฝ”๋“œ pull +echo "> Git pull" >> $DEPLOY_LOG +git pull >> $DEPLOY_LOG 2>&1 + +# 2. ํ”„๋กœ์ ํŠธ ๋นŒ๋“œ +echo "> ํ”„๋กœ์ ํŠธ ๋นŒ๋“œ ์‹œ์ž‘" >> $DEPLOY_LOG +chmod +x ./gradlew +./gradlew build >> $DEPLOY_LOG 2>&1 + +# 3. jar ํŒŒ์ผ ์‹œ๊ฐ„ ์ˆœ ์ •๋ ฌ ํ›„ ๊ฐ€์žฅ ์ƒ๋‹จ์— ์žˆ๋Š”(๊ฐ€์žฅ ์ตœ์‹ ) plain ์ด ์•„๋‹Œ jar ํŒŒ์ผ์„ ์„ ํƒ +JAR_FILE=$(ls -t $PROJECT_ROOT/build/libs/*.jar | grep -v "\-plain.jar$" | head -n 1) + +# 4. ์‹คํ–‰ ์ค‘์ธ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ PID +CURRENT_PID=$(pgrep -f "$APP_NAME" || true) + +# 5. ์‹คํ–‰ ์ค‘์ธ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ์žˆ์œผ๋ฉด ์ข…๋ฃŒ +echo "> ์‹คํ–‰ ์ค‘์ธ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ์žˆ๋‹ค๋ฉด ์ข…๋ฃŒ" >> $DEPLOY_LOG +if [ -z "$CURRENT_PID" ]; then + echo " -> ํ˜„์žฌ ์‹คํ–‰ ์ค‘์ธ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ์—†์Šต๋‹ˆ๋‹ค." >> $DEPLOY_LOG +else + echo " -> ์‹คํ–‰ ์ค‘์ธ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ข…๋ฃŒ (PID: $CURRENT_PID)" >> $DEPLOY_LOG + kill -15 $CURRENT_PID + + for _ in {1..10} + do + if ! ps -p $CURRENT_PID > /dev/null 2>&1; then + echo " โ†’ ์ข…๋ฃŒ ์™„๋ฃŒ" >> $DEPLOY_LOG + break + fi + sleep 1 + done + + if ps -p $CURRENT_PID > /dev/null 2>&1; then + echo " โ†’ ์ •์ƒ ์ข…๋ฃŒ ์‹คํŒจ, ๊ฐ•์ œ ์ข…๋ฃŒ ์‹œ๋„." >> $DEPLOY_LOG + kill -9 $CURRENT_PID + sleep 2 + fi +fi + +# 6. ์ƒˆ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋ฐฑ๊ทธ๋ผ์šด๋“œ ์‹คํ–‰ +echo "> ์ƒˆ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์‹คํ–‰" >> $DEPLOY_LOG +nohup java -Dspring.profiles.active=prod -jar $JAR_FILE > $APP_LOG 2> $APP_ERROR_LOG & # ์ •์ƒ ์ถœ๋ ฅ ๋กœ๊ทธ-> > APP_LOG / ๋น„์ •์ƒ ์ถœ๋ ฅ ๋กœ๊ทธ -> 2> ERROR_LOG + +# 7. ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์‹คํ–‰ ์—ฌ๋ถ€ ์ฒดํฌ +NEW_PID=$(pgrep -f "$APP_NAME") +if [ -n "$NEW_PID" ]; then + echo " -> ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์‹คํ–‰ ์„ฑ๊ณต (PID: $NEW_PID)" >> $DEPLOY_LOG +else + echo " -> ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์‹คํ–‰ ์‹คํŒจ" >> $DEPLOY_LOG + exit 1 +fi + +echo "=========== [๋ฐฐํฌ ์™„๋ฃŒ] : $(date +%Y-%m-%d\ %H:%M:%S) ===========" >> $DEPLOY_LOG diff --git a/src/main/java/jwt/JwtConfig.java b/src/main/java/jwt/JwtConfig.java new file mode 100644 index 000000000..180b7c217 --- /dev/null +++ b/src/main/java/jwt/JwtConfig.java @@ -0,0 +1,15 @@ +package jwt; + +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +@EnableConfigurationProperties(JwtProperties.class) +public class JwtConfig { + + @Bean + public JwtTokenProvider jwtTokenProvider(JwtProperties jwtProperties) { + return new JwtTokenProvider(jwtProperties); + } +} diff --git a/src/main/java/roomescape/auth/JwtProperties.java b/src/main/java/jwt/JwtProperties.java similarity index 95% rename from src/main/java/roomescape/auth/JwtProperties.java rename to src/main/java/jwt/JwtProperties.java index 891c545a1..c2ac86bac 100644 --- a/src/main/java/roomescape/auth/JwtProperties.java +++ b/src/main/java/jwt/JwtProperties.java @@ -1,4 +1,4 @@ -package roomescape.auth; +package jwt; import org.springframework.boot.context.properties.ConfigurationProperties; diff --git a/src/main/java/roomescape/auth/JwtTokenProvider.java b/src/main/java/jwt/JwtTokenProvider.java similarity index 95% rename from src/main/java/roomescape/auth/JwtTokenProvider.java rename to src/main/java/jwt/JwtTokenProvider.java index bbd64492d..fafffde1c 100644 --- a/src/main/java/roomescape/auth/JwtTokenProvider.java +++ b/src/main/java/jwt/JwtTokenProvider.java @@ -1,14 +1,13 @@ -package roomescape.auth; +package jwt; import io.jsonwebtoken.*; import io.jsonwebtoken.security.Keys; -import org.springframework.stereotype.Component; +import roomescape.auth.AuthException; import roomescape.exception.ApplicationException; import roomescape.member.domain.Member; import java.util.Date; -@Component public class JwtTokenProvider { private final String secretKey; diff --git a/src/main/java/roomescape/DataLoader.java b/src/main/java/roomescape/DataLoader.java new file mode 100644 index 000000000..33ed3acd6 --- /dev/null +++ b/src/main/java/roomescape/DataLoader.java @@ -0,0 +1,29 @@ +package roomescape; + +import org.springframework.boot.CommandLineRunner; +import org.springframework.context.annotation.Profile; +import org.springframework.stereotype.Component; +import org.springframework.transaction.annotation.Transactional; +import roomescape.member.domain.Member; +import roomescape.member.domain.MemberRepository; +import roomescape.member.domain.Role; + +@Profile("prod") +@Component +public class DataLoader implements CommandLineRunner { + + private final MemberRepository memberRepository; + + public DataLoader(MemberRepository memberRepository) { + this.memberRepository = memberRepository; + } + + @Override + @Transactional + public void run(String... args) throws Exception { + Member admin = new Member("์–ด๋“œ๋ฏผ", "admin@email.com", "password", Role.ADMIN); + Member user = new Member("๋ธŒ๋ผ์šด", "brown@email.com", "password", Role.USER); + memberRepository.save(admin); + memberRepository.save(user); + } +} diff --git a/src/main/java/roomescape/RoomescapeApplication.java b/src/main/java/roomescape/RoomescapeApplication.java index 3341d1549..dc5591c9c 100644 --- a/src/main/java/roomescape/RoomescapeApplication.java +++ b/src/main/java/roomescape/RoomescapeApplication.java @@ -1,11 +1,12 @@ package roomescape; +import jwt.JwtConfig; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.boot.context.properties.ConfigurationPropertiesScan; +import org.springframework.context.annotation.Import; @SpringBootApplication -@ConfigurationPropertiesScan(basePackages = "roomescape") +@Import(JwtConfig.class) public class RoomescapeApplication { public static void main(String[] args) { SpringApplication.run(RoomescapeApplication.class, args); diff --git a/src/main/java/roomescape/auth/AdminAuthInterceptor.java b/src/main/java/roomescape/auth/AdminAuthInterceptor.java index c86e8580c..1e754761d 100644 --- a/src/main/java/roomescape/auth/AdminAuthInterceptor.java +++ b/src/main/java/roomescape/auth/AdminAuthInterceptor.java @@ -1,5 +1,6 @@ package roomescape.auth; +import jwt.JwtTokenProvider; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import org.springframework.stereotype.Component; diff --git a/src/main/java/roomescape/auth/LoginMemberArgumentResolver.java b/src/main/java/roomescape/auth/LoginMemberArgumentResolver.java index d68e5d806..eb0ec7188 100644 --- a/src/main/java/roomescape/auth/LoginMemberArgumentResolver.java +++ b/src/main/java/roomescape/auth/LoginMemberArgumentResolver.java @@ -1,5 +1,6 @@ package roomescape.auth; +import jwt.JwtTokenProvider; import jakarta.servlet.http.HttpServletRequest; import org.springframework.core.MethodParameter; import org.springframework.stereotype.Component; diff --git a/src/main/java/roomescape/common/CookieUtil.java b/src/main/java/roomescape/common/CookieUtil.java index abd3d08f8..8ef73636c 100644 --- a/src/main/java/roomescape/common/CookieUtil.java +++ b/src/main/java/roomescape/common/CookieUtil.java @@ -10,6 +10,7 @@ public class CookieUtil { public static void setToken(String accessToken, int cookieExpirationSeconds, HttpServletResponse response) { Cookie cookie = new Cookie("token", accessToken); cookie.setHttpOnly(true); + cookie.setSecure(true); cookie.setPath("/"); cookie.setMaxAge(cookieExpirationSeconds); response.addCookie(cookie); diff --git a/src/main/java/roomescape/member/presentation/MemberController.java b/src/main/java/roomescape/member/presentation/MemberController.java index 786774073..718a2df3b 100644 --- a/src/main/java/roomescape/member/presentation/MemberController.java +++ b/src/main/java/roomescape/member/presentation/MemberController.java @@ -8,8 +8,8 @@ import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RestController; import roomescape.auth.AuthenticatedMember; -import roomescape.auth.JwtProperties; -import roomescape.auth.JwtTokenProvider; +import jwt.JwtProperties; +import jwt.JwtTokenProvider; import roomescape.auth.LoginMember; import roomescape.common.CookieUtil; import roomescape.member.application.MemberService; diff --git a/src/main/resources/application-prod.yml b/src/main/resources/application-prod.yml new file mode 100644 index 000000000..fe11db077 --- /dev/null +++ b/src/main/resources/application-prod.yml @@ -0,0 +1,6 @@ +server: + port: 8080 + +spring: + datasource: + url: jdbc:h2:mem:database diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties deleted file mode 100644 index 67d7858cf..000000000 --- a/src/main/resources/application.properties +++ /dev/null @@ -1,14 +0,0 @@ -spring.sql.init.encoding=utf-8 -spring.h2.console.enabled=true -spring.h2.console.path=/h2-console -spring.datasource.url=jdbc:h2:mem:database - - -spring.sql.init.mode=always -spring.jpa.show-sql=true -spring.jpa.properties.hibernate.format_sql=true -spring.jpa.ddl-auto=create-drop -spring.jpa.defer-datasource-initialization=true - -roomescape.auth.jwt.secret= Yn2kjibddFAWtnPJ2AFlL8WXmohJMCvigQggaEypa5E= -roomescape.auth.jwt.expiration=1800000 diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml new file mode 100644 index 000000000..a287b2811 --- /dev/null +++ b/src/main/resources/application.yml @@ -0,0 +1,19 @@ +spring: + + h2: + console: + enabled: true + path: /h2-console + + jpa: + show-sql: true + properties: + hibernate: + format_sql: true + ddl-auto: create + +roomescape: + auth: + jwt: + secret: Yn2kjibddFAWtnPJ2AFlL8WXmohJMCvigQggaEypa5E= + expiration: 1800000 diff --git a/src/main/resources/data.sql b/src/main/resources/data.sql deleted file mode 100644 index 7107f8adc..000000000 --- a/src/main/resources/data.sql +++ /dev/null @@ -1,24 +0,0 @@ -INSERT INTO member (name, email, password, role) -VALUES ('์–ด๋“œ๋ฏผ', 'admin@email.com', 'password', 'ADMIN'), - ('๋ธŒ๋ผ์šด', 'brown@email.com', 'password', 'USER'); - -INSERT INTO theme (name, description, deleted) -VALUES ('ํ…Œ๋งˆ1', 'ํ…Œ๋งˆ1์ž…๋‹ˆ๋‹ค.', false), - ('ํ…Œ๋งˆ2', 'ํ…Œ๋งˆ2์ž…๋‹ˆ๋‹ค.', false), - ('ํ…Œ๋งˆ3', 'ํ…Œ๋งˆ3์ž…๋‹ˆ๋‹ค.', false); - -INSERT INTO time (time_value, deleted) -VALUES ('10:00', false), - ('12:00', false), - ('14:00', false), - ('16:00', false), - ('18:00', false), - ('20:00', false); - -INSERT INTO reservation (member_id, name, date, time_id, theme_id) -VALUES (1, '', '2024-03-01', 1, 1), - (1, '', '2024-03-01', 2, 2), - (1, '', '2024-03-01', 3, 3); - -INSERT INTO reservation (name, date, time_id, theme_id) -VALUES ('๋ธŒ๋ผ์šด', '2024-03-01', 1, 2); diff --git a/src/test/java/roomescape/JpaTest.java b/src/test/java/roomescape/JpaTest.java index 99caee443..f7a71b587 100644 --- a/src/test/java/roomescape/JpaTest.java +++ b/src/test/java/roomescape/JpaTest.java @@ -1,17 +1,24 @@ package roomescape; -import org.assertj.core.api.Assertions; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; import org.springframework.boot.test.autoconfigure.orm.jpa.TestEntityManager; +import org.springframework.test.context.ActiveProfiles; import roomescape.time.domain.Time; import roomescape.time.domain.TimeRepository; +import static org.assertj.core.api.Assertions.*; + @DataJpaTest +@ActiveProfiles("test") public class JpaTest { + @Value("${roomescape.auth.jwt.secret}") + private String secretKey; + @Autowired private TestEntityManager entityManager; @@ -26,6 +33,11 @@ public class JpaTest { Time persistTime = timeRepository.findById(time.getId()).orElse(null); - Assertions.assertThat(persistTime.getValue()).isEqualTo(time.getValue()); + assertThat(persistTime.getValue()).isEqualTo(time.getValue()); + } + + @Test + void ํŒ”๋‹จ๊ณ„() { + assertThat(secretKey).isNotBlank(); } } diff --git a/src/test/java/roomescape/MissionStepTest.java b/src/test/java/roomescape/MissionStepTest.java index 90bec4a2e..2a71e3649 100644 --- a/src/test/java/roomescape/MissionStepTest.java +++ b/src/test/java/roomescape/MissionStepTest.java @@ -1,12 +1,17 @@ package roomescape; +import jwt.JwtTokenProvider; import io.restassured.RestAssured; import io.restassured.http.ContentType; import io.restassured.response.ExtractableResponse; import io.restassured.response.Response; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.web.server.LocalServerPort; +import org.springframework.stereotype.Component; import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.context.ActiveProfiles; import roomescape.reservation.presentation.response.MyReservationResponse; import roomescape.reservation.presentation.response.ReservationResponse; import roomescape.waiting.presentation.response.WaitingResponse; @@ -20,8 +25,17 @@ @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT) @DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD) +@ActiveProfiles("test") public class MissionStepTest { + @LocalServerPort + private int port; + + @BeforeEach + void setUp() { + RestAssured.port = port; + } + @Test void ์ผ๋‹จ๊ณ„() { String token = createToken("admin@email.com", "password"); @@ -154,4 +168,10 @@ private static String createToken(String email, String password) { assertThat(status).isEqualTo("1๋ฒˆ์งธ ์˜ˆ์•ฝ๋Œ€๊ธฐ"); } + + @Test + void ์น ๋‹จ๊ณ„() { + Component componentAnnotation = JwtTokenProvider.class.getAnnotation(Component.class); + assertThat(componentAnnotation).isNull(); + } } diff --git a/src/test/java/roomescape/TestDataLoader.java b/src/test/java/roomescape/TestDataLoader.java new file mode 100644 index 000000000..f3a552051 --- /dev/null +++ b/src/test/java/roomescape/TestDataLoader.java @@ -0,0 +1,71 @@ +package roomescape; + +import org.springframework.boot.CommandLineRunner; +import org.springframework.context.annotation.Profile; +import org.springframework.stereotype.Component; +import org.springframework.transaction.annotation.Transactional; +import roomescape.member.domain.Member; +import roomescape.member.domain.MemberRepository; +import roomescape.member.domain.Role; +import roomescape.reservation.domain.Reservation; +import roomescape.reservation.domain.ReservationRepository; +import roomescape.theme.domain.Theme; +import roomescape.theme.domain.ThemeRepository; +import roomescape.time.domain.Time; +import roomescape.time.domain.TimeRepository; + +@Profile("test") +@Component +public class TestDataLoader implements CommandLineRunner { + + private final MemberRepository memberRepository; + private final TimeRepository timeRepository; + private final ThemeRepository themeRepository; + private final ReservationRepository reservationRepository; + + public TestDataLoader(MemberRepository memberRepository, TimeRepository timeRepository, + ThemeRepository themeRepository, ReservationRepository reservationRepository) { + this.memberRepository = memberRepository; + this.timeRepository = timeRepository; + this.themeRepository = themeRepository; + this.reservationRepository = reservationRepository; + } + + @Override + @Transactional + public void run(String... args) throws Exception { + Member admin = new Member("์–ด๋“œ๋ฏผ", "admin@email.com", "password", Role.ADMIN); + Member user = new Member("๋ธŒ๋ผ์šด", "brown@email.com", "password", Role.USER); + memberRepository.save(admin); + memberRepository.save(user); + + Theme theme1 = new Theme("ํ…Œ๋งˆ1", "ํ…Œ๋งˆ1์ž…๋‹ˆ๋‹ค."); + Theme theme2 = new Theme("ํ…Œ๋งˆ2", "ํ…Œ๋งˆ2์ž…๋‹ˆ๋‹ค."); + Theme theme3 = new Theme("ํ…Œ๋งˆ3", "ํ…Œ๋งˆ3์ž…๋‹ˆ๋‹ค."); + themeRepository.save(theme1); + themeRepository.save(theme2); + themeRepository.save(theme3); + + Time time1 = new Time("10:00"); + Time time2 = new Time("12:00"); + Time time3 = new Time("14:00"); + Time time4 = new Time("16:00"); + Time time5 = new Time("18:00"); + Time time6 = new Time("20:00"); + timeRepository.save(time1); + timeRepository.save(time2); + timeRepository.save(time3); + timeRepository.save(time4); + timeRepository.save(time5); + timeRepository.save(time6); + + Reservation reservation1 = new Reservation(admin, "2024-03-01", time1, theme1); + Reservation reservation2 = new Reservation(admin, "2024-03-01", time2, theme2); + Reservation reservation3 = new Reservation(admin, "2024-03-01", time3, theme3); + Reservation reservation4 = new Reservation("๋ธŒ๋ผ์šด", "2024-03-01", time1, theme2); + reservationRepository.save(reservation1); + reservationRepository.save(reservation2); + reservationRepository.save(reservation3); + reservationRepository.save(reservation4); + } +} diff --git a/src/test/java/roomescape/auth/JwtTokenProviderTest.java b/src/test/java/roomescape/auth/JwtTokenProviderTest.java index 1f8566e5a..469d1826b 100644 --- a/src/test/java/roomescape/auth/JwtTokenProviderTest.java +++ b/src/test/java/roomescape/auth/JwtTokenProviderTest.java @@ -1,5 +1,7 @@ package roomescape.auth; +import jwt.JwtProperties; +import jwt.JwtTokenProvider; import org.junit.jupiter.api.Test; import roomescape.exception.ApplicationException; import roomescape.member.domain.Member; diff --git a/src/test/java/roomescape/member/application/MemberServiceTest.java b/src/test/java/roomescape/member/application/MemberServiceTest.java index 50aad2d66..5e5fe1b44 100644 --- a/src/test/java/roomescape/member/application/MemberServiceTest.java +++ b/src/test/java/roomescape/member/application/MemberServiceTest.java @@ -4,6 +4,7 @@ import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.ActiveProfiles; import org.springframework.transaction.annotation.Transactional; import roomescape.exception.ApplicationException; import roomescape.member.domain.Member; @@ -17,6 +18,7 @@ @SpringBootTest @Transactional +@ActiveProfiles("test") class MemberServiceTest { @Autowired diff --git a/src/test/java/roomescape/reservation/application/ReservationServiceConcurrencyTest.java b/src/test/java/roomescape/reservation/application/ReservationServiceConcurrencyTest.java index 6974c2d97..dce23d6db 100644 --- a/src/test/java/roomescape/reservation/application/ReservationServiceConcurrencyTest.java +++ b/src/test/java/roomescape/reservation/application/ReservationServiceConcurrencyTest.java @@ -1,11 +1,11 @@ package roomescape.reservation.application; -import org.assertj.core.api.SoftAssertions; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.context.ActiveProfiles; import roomescape.member.domain.Member; import roomescape.member.domain.MemberRepository; import roomescape.member.domain.Role; @@ -15,7 +15,6 @@ import roomescape.theme.domain.ThemeRepository; import roomescape.time.domain.Time; import roomescape.time.domain.TimeRepository; -import roomescape.waiting.domain.repository.WaitingRepository; import java.util.ArrayList; import java.util.List; @@ -27,6 +26,7 @@ import static org.assertj.core.api.SoftAssertions.assertSoftly; @SpringBootTest +@ActiveProfiles("test") @DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS) public class ReservationServiceConcurrencyTest { diff --git a/src/test/java/roomescape/reservation/application/ReservationServiceTest.java b/src/test/java/roomescape/reservation/application/ReservationServiceTest.java index c1976da7b..dc24254dc 100644 --- a/src/test/java/roomescape/reservation/application/ReservationServiceTest.java +++ b/src/test/java/roomescape/reservation/application/ReservationServiceTest.java @@ -4,6 +4,7 @@ import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.ActiveProfiles; import org.springframework.transaction.annotation.Transactional; import roomescape.auth.LoginMember; import roomescape.exception.ApplicationException; @@ -29,6 +30,7 @@ @SpringBootTest @Transactional +@ActiveProfiles("test") class ReservationServiceTest { @Autowired diff --git a/src/test/java/roomescape/waiting/application/WaitingServiceConcurrencyTest.java b/src/test/java/roomescape/waiting/application/WaitingServiceConcurrencyTest.java index 351761e30..82a216f27 100644 --- a/src/test/java/roomescape/waiting/application/WaitingServiceConcurrencyTest.java +++ b/src/test/java/roomescape/waiting/application/WaitingServiceConcurrencyTest.java @@ -5,6 +5,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.context.ActiveProfiles; import roomescape.member.domain.Member; import roomescape.member.domain.MemberRepository; import roomescape.member.domain.Role; @@ -13,13 +14,10 @@ import roomescape.time.domain.Time; import roomescape.time.domain.TimeRepository; import roomescape.waiting.application.command.WaitingCommand; -import roomescape.waiting.domain.WaitingOrderCounter; -import roomescape.waiting.domain.repository.WaitingOrderCounterRepository; import roomescape.waiting.domain.repository.WaitingRepository; import java.util.ArrayList; import java.util.List; -import java.util.Optional; import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; @@ -28,14 +26,13 @@ import static org.assertj.core.api.Assertions.assertThat; @SpringBootTest +@ActiveProfiles("test") @DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS) class WaitingServiceConcurrencyTest { @Autowired private WaitingRepository waitingRepository; @Autowired - private WaitingOrderCounterRepository orderCounterRepository; - @Autowired private MemberRepository memberRepository; @Autowired private TimeRepository timeRepository; diff --git a/src/test/java/roomescape/waiting/application/WaitingServiceTest.java b/src/test/java/roomescape/waiting/application/WaitingServiceTest.java index bf589ccbd..03536adfa 100644 --- a/src/test/java/roomescape/waiting/application/WaitingServiceTest.java +++ b/src/test/java/roomescape/waiting/application/WaitingServiceTest.java @@ -5,6 +5,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.context.ActiveProfiles; import org.springframework.transaction.annotation.Transactional; import roomescape.auth.AuthException; import roomescape.auth.LoginMember; @@ -32,6 +33,7 @@ @SpringBootTest @Transactional +@ActiveProfiles("test") class WaitingServiceTest { @Autowired diff --git a/src/test/resources/application-test.yml b/src/test/resources/application-test.yml new file mode 100644 index 000000000..2574fb4ef --- /dev/null +++ b/src/test/resources/application-test.yml @@ -0,0 +1,6 @@ +server: + port: 0 + +spring: + datasource: + url: jdbc:h2:mem:test_db