diff --git a/src/main/java/com/projectlyrics/server/domain/auth/api/AuthController.java b/src/main/java/com/projectlyrics/server/domain/auth/api/AuthController.java index f913e49f..d9d9dcb8 100644 --- a/src/main/java/com/projectlyrics/server/domain/auth/api/AuthController.java +++ b/src/main/java/com/projectlyrics/server/domain/auth/api/AuthController.java @@ -25,19 +25,21 @@ public class AuthController { @PostMapping("/sign-in") public ResponseEntity signIn( - @RequestBody @Valid AuthSignInRequest request + @RequestBody @Valid AuthSignInRequest request, + @RequestHeader("Device-Id") String deviceId ) { return ResponseEntity .status(HttpStatus.OK) - .body(authCommandService.signIn(request)); + .body(authCommandService.signIn(request, deviceId)); } @PostMapping("/sign-up") public ResponseEntity signUp( - @RequestBody @Valid AuthSignUpRequest request + @RequestBody @Valid AuthSignUpRequest request, + @RequestHeader("Device-Id") String deviceId ) { return ResponseEntity - .ok(authCommandService.signUp(request)); + .ok(authCommandService.signUp(request, deviceId)); } @PostMapping("/token") diff --git a/src/main/java/com/projectlyrics/server/domain/auth/authentication/interceptor/DeviceIdInterceptor.java b/src/main/java/com/projectlyrics/server/domain/auth/authentication/interceptor/DeviceIdInterceptor.java new file mode 100644 index 00000000..bcfed90e --- /dev/null +++ b/src/main/java/com/projectlyrics/server/domain/auth/authentication/interceptor/DeviceIdInterceptor.java @@ -0,0 +1,36 @@ +package com.projectlyrics.server.domain.auth.authentication.interceptor; + +import com.projectlyrics.server.domain.auth.exception.NotRegisteredDeviceException; +import com.projectlyrics.server.domain.auth.repository.AuthRepository; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import lombok.RequiredArgsConstructor; +import org.springframework.context.annotation.Profile; +import org.springframework.stereotype.Component; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.servlet.HandlerInterceptor; + +@Profile({"dev", "local"}) +@Component +@Transactional +@RequiredArgsConstructor +public class DeviceIdInterceptor implements HandlerInterceptor { + + private final AuthRepository authRepository; + + @Override + public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { + if (included(request)) { + authRepository.findByDeviceId(request.getHeader("Device-Id")) + .orElseThrow(NotRegisteredDeviceException::new); + } + + return true; + } + + private boolean included(HttpServletRequest request) { + String requestURI = request.getRequestURI(); + return !requestURI.matches("/api/v1/auth/sign-in") && + !requestURI.matches("/api/v1/auth/sign-up"); + } +} diff --git a/src/main/java/com/projectlyrics/server/domain/auth/domain/Auth.java b/src/main/java/com/projectlyrics/server/domain/auth/domain/Auth.java index b1fcc9b3..204d2c3e 100644 --- a/src/main/java/com/projectlyrics/server/domain/auth/domain/Auth.java +++ b/src/main/java/com/projectlyrics/server/domain/auth/domain/Auth.java @@ -22,22 +22,31 @@ public class Auth { private AuthProvider authProvider; @Indexed private String refreshToken; + @Indexed + private String deviceId; private Auth( String socialId, AuthProvider authProvider, - String refreshToken + String refreshToken, + String deviceId ) { this.socialId = socialId; this.authProvider = authProvider; this.refreshToken = refreshToken; + this.deviceId = deviceId; } - public static Auth create(SocialInfo socialInfo, String refreshToken) { + public static Auth create( + SocialInfo socialInfo, + String refreshToken, + String deviceId + ) { return new Auth( socialInfo.getSocialId(), socialInfo.getAuthProvider(), - refreshToken + refreshToken, + deviceId ); } } diff --git a/src/main/java/com/projectlyrics/server/domain/auth/exception/NotRegisteredDeviceException.java b/src/main/java/com/projectlyrics/server/domain/auth/exception/NotRegisteredDeviceException.java new file mode 100644 index 00000000..60b53518 --- /dev/null +++ b/src/main/java/com/projectlyrics/server/domain/auth/exception/NotRegisteredDeviceException.java @@ -0,0 +1,11 @@ +package com.projectlyrics.server.domain.auth.exception; + +import com.projectlyrics.server.domain.common.message.ErrorCode; +import com.projectlyrics.server.global.exception.FeelinException; + +public class NotRegisteredDeviceException extends FeelinException { + + public NotRegisteredDeviceException() { + super(ErrorCode.NOT_REGISTERED_DEVICE); + } +} diff --git a/src/main/java/com/projectlyrics/server/domain/auth/repository/AuthRepository.java b/src/main/java/com/projectlyrics/server/domain/auth/repository/AuthRepository.java index db780982..cd87735a 100644 --- a/src/main/java/com/projectlyrics/server/domain/auth/repository/AuthRepository.java +++ b/src/main/java/com/projectlyrics/server/domain/auth/repository/AuthRepository.java @@ -8,4 +8,5 @@ public interface AuthRepository extends CrudRepository { Optional findByRefreshToken(String refreshToken); + Optional findByDeviceId(String deviceId); } diff --git a/src/main/java/com/projectlyrics/server/domain/auth/service/AuthCommandService.java b/src/main/java/com/projectlyrics/server/domain/auth/service/AuthCommandService.java index 5c16409c..6dc5a521 100644 --- a/src/main/java/com/projectlyrics/server/domain/auth/service/AuthCommandService.java +++ b/src/main/java/com/projectlyrics/server/domain/auth/service/AuthCommandService.java @@ -41,13 +41,13 @@ public class AuthCommandService { private final LikeCommandRepository likeCommandRepository; private final NotificationCommandRepository notificationCommandRepository; - public AuthTokenResponse signUp(AuthSignUpRequest request) { + public AuthTokenResponse signUp(AuthSignUpRequest request, String deviceId) { SocialInfo socialInfo = authQueryService.getSocialInfo(AuthGetSocialInfo.from(request)); checkIfAlreadyExists(socialInfo); User user = userCommandRepository.save(User.create(UserCreate.of(socialInfo, request))); - AuthToken authToken = issueAndSaveToken(user); + AuthToken authToken = issueAndSaveToken(user, deviceId); return AuthTokenResponse.of(authToken, user.getId()); } @@ -60,12 +60,12 @@ else if (userQueryRepository.existsBySocialInfoAndForceDelete(socialInfo)) { } } - public AuthTokenResponse signIn(AuthSignInRequest request) { + public AuthTokenResponse signIn(AuthSignInRequest request, String deviceId) { SocialInfo socialInfo = authQueryService.getSocialInfo(AuthGetSocialInfo.from(request)); User user = userQueryRepository.findBySocialIdAndAuthProvider(socialInfo.getSocialId(), socialInfo.getAuthProvider()) .orElseThrow(UserNotFoundException::new); - AuthToken authToken = issueAndSaveToken(user); + AuthToken authToken = issueAndSaveToken(user, deviceId); return AuthTokenResponse.of(authToken, user.getId()); } @@ -75,13 +75,13 @@ public AuthTokenResponse reissueToken(String refreshToken) { User user = userQueryRepository.findBySocialIdAndAuthProvider(auth.getSocialId(), auth.getAuthProvider()) .orElseThrow(UserNotFoundException::new); - AuthToken authToken = issueAndSaveToken(user); + AuthToken authToken = issueAndSaveToken(user, auth.getDeviceId()); return AuthTokenResponse.of(authToken, user.getId()); } - private AuthToken issueAndSaveToken(User user) { + private AuthToken issueAndSaveToken(User user, String deviceId) { AuthToken authToken = jwtProvider.issueTokens(user.getId(), user.getNickname().getValue(), user.getRole()); - authRepository.save(Auth.create(user.getSocialInfo(), authToken.refreshToken())); + authRepository.save(Auth.create(user.getSocialInfo(), authToken.refreshToken(), deviceId)); return authToken; } diff --git a/src/main/java/com/projectlyrics/server/domain/common/message/ErrorCode.java b/src/main/java/com/projectlyrics/server/domain/common/message/ErrorCode.java index 3be32e10..c91c719c 100644 --- a/src/main/java/com/projectlyrics/server/domain/common/message/ErrorCode.java +++ b/src/main/java/com/projectlyrics/server/domain/common/message/ErrorCode.java @@ -32,6 +32,7 @@ public enum ErrorCode { INVALID_TOKEN_PREFIX(HttpStatus.BAD_REQUEST, "01009", "Bearer 인증 형식이 아닙니다."), INVALID_SOCIAL_TOKEN(HttpStatus.UNAUTHORIZED, "01010", "유효하지 않은 소셜 인증 토큰입니다."), AUTH_NOT_FOUND(HttpStatus.NOT_FOUND, "01011", "해당 인증 정보를 찾을 수 없습니다."), + NOT_REGISTERED_DEVICE(HttpStatus.NOT_FOUND, "01012", "타 기기에서 로그인했거나 등록되지 않은 기기입니다."), // User USER_NOT_FOUND(HttpStatus.NOT_FOUND, "02000", "해당 유저가 존재하지 않습니다."), diff --git a/src/main/java/com/projectlyrics/server/domain/song/repository/impl/JdbcSongCommandRepository.java b/src/main/java/com/projectlyrics/server/domain/song/repository/impl/JdbcSongCommandRepository.java index d2e79785..3a371af9 100644 --- a/src/main/java/com/projectlyrics/server/domain/song/repository/impl/JdbcSongCommandRepository.java +++ b/src/main/java/com/projectlyrics/server/domain/song/repository/impl/JdbcSongCommandRepository.java @@ -7,26 +7,42 @@ import org.springframework.stereotype.Repository; import java.util.List; +import java.util.Objects; @RequiredArgsConstructor @Repository public class JdbcSongCommandRepository implements SongCommandRepository { private final JdbcTemplate jdbcTemplate; - private final String insertQuery = "INSERT INTO songs (id, artist_id, spotify_id, name, release_date, album_name, image_url) VALUES (?, ?, ?, ?, ?, ?, ?)"; + private final String insertQuery = "INSERT INTO songs (artist_id, spotify_id, name, release_date, album_name, image_url) VALUES (?, ?, ?, ?, ?, ?)"; + private final String insertQueryWithId = "INSERT INTO songs (id, artist_id, spotify_id, name, release_date, album_name, image_url) VALUES (?, ?, ?, ?, ?, ?, ?)"; @Override public Song save(Song song) { - jdbcTemplate.update( - insertQuery, - song.getId(), - song.getArtist().getId(), - song.getSpotifyId(), - song.getName(), - song.getReleaseDate(), - song.getAlbumName(), - song.getImageUrl() - ); + if (Objects.nonNull(song.getId())) { + jdbcTemplate.update( + insertQueryWithId, + song.getId(), + song.getArtist().getId(), + song.getSpotifyId(), + song.getName(), + song.getReleaseDate(), + song.getAlbumName(), + song.getImageUrl() + ); + } + + else { + jdbcTemplate.update( + insertQuery, + song.getArtist().getId(), + song.getSpotifyId(), + song.getName(), + song.getReleaseDate(), + song.getAlbumName(), + song.getImageUrl() + ); + } return song; } @@ -38,13 +54,12 @@ public void saveAll(List songs) { songs, songs.size(), (ps, song) -> { - ps.setLong(1, song.getId()); - ps.setLong(2, song.getArtist().getId()); - ps.setString(3, song.getSpotifyId()); - ps.setString(4, song.getName()); - ps.setDate(5, java.sql.Date.valueOf(song.getReleaseDate())); - ps.setString(6, song.getAlbumName()); - ps.setString(7, song.getImageUrl()); + ps.setLong(1, song.getArtist().getId()); + ps.setString(2, song.getSpotifyId()); + ps.setString(3, song.getName()); + ps.setDate(4, java.sql.Date.valueOf(song.getReleaseDate())); + ps.setString(5, song.getAlbumName()); + ps.setString(6, song.getImageUrl()); } ); } diff --git a/src/main/java/com/projectlyrics/server/global/configuration/WebConfig.java b/src/main/java/com/projectlyrics/server/global/configuration/WebConfig.java index 1e1c4ecd..ef3edbf4 100644 --- a/src/main/java/com/projectlyrics/server/global/configuration/WebConfig.java +++ b/src/main/java/com/projectlyrics/server/global/configuration/WebConfig.java @@ -2,10 +2,12 @@ import com.projectlyrics.server.domain.auth.authentication.AuthArgumentResolver; import com.projectlyrics.server.domain.auth.authentication.interceptor.AuthInterceptor; +import com.projectlyrics.server.domain.auth.authentication.interceptor.DeviceIdInterceptor; import com.projectlyrics.server.domain.auth.authentication.interceptor.SlackInterceptor; import com.projectlyrics.server.domain.auth.authentication.interceptor.AdminInterceptor; import com.projectlyrics.server.global.converter.ProfileCharacterConverter; import lombok.RequiredArgsConstructor; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Configuration; import org.springframework.format.FormatterRegistry; import org.springframework.web.method.support.HandlerMethodArgumentResolver; @@ -13,6 +15,7 @@ import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; import java.util.List; +import java.util.Objects; @Configuration @RequiredArgsConstructor @@ -23,6 +26,9 @@ public class WebConfig implements WebMvcConfigurer { private final AdminInterceptor adminInterceptor; private final SlackInterceptor slackInterceptor; + @Autowired(required = false) + private DeviceIdInterceptor deviceIdInterceptor; + @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(authInterceptor) @@ -33,6 +39,13 @@ public void addInterceptors(InterceptorRegistry registry) { .excludePathPatterns("/api/v1/auth/token") .excludePathPatterns("/api/v1/slack/interactive"); + if (Objects.nonNull(deviceIdInterceptor)) { + registry.addInterceptor(deviceIdInterceptor) + .addPathPatterns("/api/**") + .excludePathPatterns("/api/v1/auth/sign-in") + .addPathPatterns("/api/v1/auth/sign-up"); + } + registry.addInterceptor(adminInterceptor) .addPathPatterns("/api/v1/artists/**") .addPathPatterns("/api/v1/notifications/public") diff --git a/src/main/java/com/projectlyrics/server/global/dev/DummyDataInitializer.java b/src/main/java/com/projectlyrics/server/global/dev/DummyDataInitializer.java index 88b6cfb7..ed27d332 100644 --- a/src/main/java/com/projectlyrics/server/global/dev/DummyDataInitializer.java +++ b/src/main/java/com/projectlyrics/server/global/dev/DummyDataInitializer.java @@ -19,7 +19,7 @@ import java.util.List; @Slf4j -@Profile({"dev"}) +@Profile({"local"}) @Component @RequiredArgsConstructor public class DummyDataInitializer { @@ -27,27 +27,54 @@ public class DummyDataInitializer { private final ArtistCommandRepository artistCommandRepository; private final SongCommandRepository songCommandRepository; -// @PostConstruct + @PostConstruct public void init() { - List artists = saveInitialArtists(); - saveInitialSongs(artists); + List artists = getArtists(); + saveSongs(artists); + } + + private List getArtists() { + List artists = new ArrayList<>(); + + try { + CSVReader reader = new CSVReader(new FileReader("src/main/resources/no_songs_artists.csv")); + String[] line; + + while ((line = reader.readNext()) != null) { + ArtistCreate artistCreate = new ArtistCreate( + Long.parseLong(line[4]), + null, + null, + null, + line[10], + null + ); + + artists.add(Artist.create(artistCreate)); + } + + } catch (Exception e) { + log.error("failed to read csv file", e); + } + + return artists; } private List saveInitialArtists() { List artists = new ArrayList<>(); try { - CSVReader reader = new CSVReader(new FileReader("src/main/resources/artists.csv")); + CSVReader reader = new CSVReader(new FileReader("src/main/resources/no_songs_artists.csv")); String[] line; while ((line = reader.readNext()) != null) { ArtistCreate artistCreate = new ArtistCreate( - Long.parseLong(line[0]), - line[1], - line[2], - line[3], - line[4], - line[5] + Long.parseLong(line[4]), + line[8], + null, + null, + line[10], + line[8] ); artists.add(Artist.create(artistCreate)); @@ -59,22 +86,22 @@ private List saveInitialArtists() { return artistCommandRepository.saveAll(artists); } - private void saveInitialSongs(List artists) { + private void saveSongs(List artists) { List songs = new ArrayList<>(); try { - CSVReader reader = new CSVReader(new FileReader("src/main/resources/songs.csv")); + CSVReader reader = new CSVReader(new FileReader("src/main/resources/missing_songs.csv")); String[] line; while ((line = reader.readNext()) != null) { SongCreate songCreate = new SongCreate( - Long.parseLong(line[0]), - line[3], + null, + line[0], line[1], - parse(line[6]), - line[5], + parse(line[2]), + line[3], line[4], - findArtist(Long.parseLong(line[2]), artists) + findArtist(line[5], artists) ); songs.add(Song.create(songCreate)); @@ -94,10 +121,10 @@ private LocalDate parse(String date) { } } - private Artist findArtist(Long id, List artists) { + private Artist findArtist(String spotifyId, List artists) { return artists.stream() - .filter(artist -> artist.getId().equals(id)) + .filter(artist -> artist.getSpotifyId().equals(spotifyId)) .findFirst() - .orElse(null); + .orElseThrow(RuntimeException::new); } } diff --git a/src/test/java/com/projectlyrics/server/domain/auth/api/AuthControllerTest.java b/src/test/java/com/projectlyrics/server/domain/auth/api/AuthControllerTest.java index bbcc065e..8dae94ea 100644 --- a/src/test/java/com/projectlyrics/server/domain/auth/api/AuthControllerTest.java +++ b/src/test/java/com/projectlyrics/server/domain/auth/api/AuthControllerTest.java @@ -39,17 +39,21 @@ class AuthControllerTest extends RestDocsTest { + private static final String deviceIdHeader = "Device-Id"; + private static final String deviceIdValue = "device_id"; + @Test void 로그인할_때_소셜_로그인_인증된_유저는_인증_토큰과_200응답을_해야_한다() throws Exception { //given AuthSignInRequest request = new AuthSignInRequest("socialAccessToken", AuthProvider.KAKAO); AuthTokenResponse response = new AuthTokenResponse(accessToken, refreshToken, 1L); - given(authCommandService.signIn(any())) + given(authCommandService.signIn(any(), any())) .willReturn(response); //when then mockMvc.perform(post("/api/v1/auth/sign-in") .contentType(MediaType.APPLICATION_JSON) + .header(deviceIdHeader, deviceIdValue) .content(mapper.writeValueAsString(request))) .andExpect(status().isOk()) .andExpect(content().json(mapper.writeValueAsString(response))) @@ -62,13 +66,14 @@ class AuthControllerTest extends RestDocsTest { //given AuthSignInRequest request = new AuthSignInRequest("socialAccessToken", AuthProvider.KAKAO); UserNotFoundException e = new UserNotFoundException(); - given(authCommandService.signIn(any())) + given(authCommandService.signIn(any(), any())) .willThrow(e); ErrorResponse response = ErrorResponse.of(e.getErrorCode()); //when then mockMvc.perform(post("/api/v1/auth/sign-in") .contentType(MediaType.APPLICATION_JSON) + .header(deviceIdHeader, deviceIdValue) .content(mapper.writeValueAsString(request))) .andExpect(status().isNotFound()) .andExpect(content().json(mapper.writeValueAsString(response))) @@ -80,12 +85,13 @@ class AuthControllerTest extends RestDocsTest { //given AuthSignInRequest request = new AuthSignInRequest("socialAccessToken", AuthProvider.KAKAO); ErrorResponse response = ErrorResponse.of(ErrorCode.INVALID_SOCIAL_TOKEN); - given(authCommandService.signIn(any())) + given(authCommandService.signIn(any(), any())) .willThrow(FeignException.class); //when then mockMvc.perform(post("/api/v1/auth/sign-in") .contentType(MediaType.APPLICATION_JSON) + .header(deviceIdHeader, deviceIdValue) .content(mapper.writeValueAsString(request))) .andExpect(status().isUnauthorized()) .andExpect(content().json(mapper.writeValueAsString(response))) @@ -125,12 +131,13 @@ private RestDocumentationResultHandler getSignInDocument(boolean successCase) { false ); AuthTokenResponse response = new AuthTokenResponse(accessToken, refreshToken, 1L); - given(authCommandService.signUp(any())) + given(authCommandService.signUp(any(), any())) .willReturn(response); //when then mockMvc.perform(post("/api/v1/auth/sign-up") .contentType(MediaType.APPLICATION_JSON) + .header(deviceIdHeader, deviceIdValue) .content(mapper.writeValueAsString(request))) .andExpect(status().isOk()) .andExpect(content().json(mapper.writeValueAsString(response))) @@ -152,12 +159,13 @@ private RestDocumentationResultHandler getSignInDocument(boolean successCase) { ); NotAgreeToTermsException e = new NotAgreeToTermsException(); ErrorResponse response = ErrorResponse.of(e.getErrorCode()); - given(authCommandService.signUp(any())) + given(authCommandService.signUp(any(), any())) .willThrow(e); //when then mockMvc.perform(post("/api/v1/auth/sign-up") .contentType(MediaType.APPLICATION_JSON) + .header(deviceIdHeader, deviceIdValue) .content(mapper.writeValueAsString(request))) .andExpect(status().isBadRequest()) .andExpect(content().json(mapper.writeValueAsString(response))) @@ -179,12 +187,13 @@ private RestDocumentationResultHandler getSignInDocument(boolean successCase) { ); AlreadyExistsUserException e = new AlreadyExistsUserException(); ErrorResponse response = ErrorResponse.of(e.getErrorCode()); - given(authCommandService.signUp(any())) + given(authCommandService.signUp(any(), any())) .willThrow(e); //when then mockMvc.perform(post("/api/v1/auth/sign-up") .contentType(MediaType.APPLICATION_JSON) + .header(deviceIdHeader, deviceIdValue) .content(mapper.writeValueAsString(request))) .andExpect(status().isBadRequest()) .andExpect(content().json(mapper.writeValueAsString(response))) @@ -205,12 +214,13 @@ private RestDocumentationResultHandler getSignInDocument(boolean successCase) { false ); ErrorResponse response = ErrorResponse.of(ErrorCode.INVALID_SOCIAL_TOKEN); - given(authCommandService.signUp(any())) + given(authCommandService.signUp(any(), any())) .willThrow(FeignException.class); //when then mockMvc.perform(post("/api/v1/auth/sign-up") .contentType(MediaType.APPLICATION_JSON) + .header(deviceIdHeader, deviceIdValue) .content(mapper.writeValueAsString(request))) .andExpect(status().isUnauthorized()) .andExpect(content().json(mapper.writeValueAsString(response))) @@ -369,7 +379,7 @@ private FieldDescriptor[] getTokenResponseField() { @Test void 만료된_토큰이면_400응답을_해야_한다() throws Exception { //given - String expiredToken = "eyJhbGciOiJIUzI1NiJ9.eyJ1c2VySWQiOjEsIm5pY2tuYW1lIjoidGVzdDEiLCJ0b2tlblR5cGUiOiJhY2Nlc3NUb2tlbiIsImlhdCI6MTcyMTEzNTI2MCwiZXhwIjoxNzIxMTM1MjYwfQ.Xj-lRRIWkYj_7JlfLl0hcjEfgABrnL7s8M2aBCdN71U"; + String expiredToken = "eyJhbGciOiJIUzI1NiJ9.eyJ1c2VySWQiOjQ3LCJuaWNrbmFtZSI6ImtvbnUiLCJyb2xlIjoiVVNFUiIsInRva2VuVHlwZSI6ImFjY2Vzc1Rva2VuIiwiaWF0IjoxNzMwNzM5MDgzLCJleHAiOjE3MzA3MzkyNjN9.pwyi1iqtdAGE3bYrglojj0FuSBl4J2Lzgm228mvEWxA"; //when then mockMvc.perform(get("/api/v1/auth/validate-token") diff --git a/src/test/java/com/projectlyrics/server/domain/auth/service/AuthCommandServiceIntegrationTest.java b/src/test/java/com/projectlyrics/server/domain/auth/service/AuthCommandServiceIntegrationTest.java index 96e35b16..5f694728 100644 --- a/src/test/java/com/projectlyrics/server/domain/auth/service/AuthCommandServiceIntegrationTest.java +++ b/src/test/java/com/projectlyrics/server/domain/auth/service/AuthCommandServiceIntegrationTest.java @@ -93,6 +93,7 @@ public class AuthCommandServiceIntegrationTest extends IntegrationTest { private User user; private AuthSignUpRequest request; + private String deviceId; @BeforeEach void setUp() { @@ -107,6 +108,7 @@ void setUp() { List.of(new AuthSignUpRequest.TermsInput(true, "title", "agreement")), false ); + deviceId = "device-id"; } @Test @@ -116,7 +118,7 @@ void setUp() { .when(kakaoSocialDataApiClient).getUserInfo(any()); // when - AuthTokenResponse response = sut.signUp(request); + AuthTokenResponse response = sut.signUp(request, deviceId); // then User signedUpUser = userQueryRepository.findBySocialIdAndAuthProvider(user.getSocialInfo().getSocialId(), AuthProvider.KAKAO).get(); @@ -134,7 +136,7 @@ void setUp() { .when(kakaoSocialDataApiClient).getUserInfo(any()); // when, then - assertThatThrownBy(() -> sut.signUp(request)) + assertThatThrownBy(() -> sut.signUp(request, deviceId)) .isInstanceOf(AlreadyExistsUserException.class); } @@ -147,7 +149,7 @@ void setUp() { .when(kakaoSocialDataApiClient).getUserInfo(any()); // when, then - assertThatThrownBy(() -> sut.signUp(request)) + assertThatThrownBy(() -> sut.signUp(request, deviceId)) .isInstanceOf(ForcedWithdrawalUserException.class); } @@ -169,14 +171,14 @@ void setUp() { .when(kakaoSocialDataApiClient).getUserInfo(any()); // when, then - assertThatThrownBy(() -> sut.signUp(unAgreedRequest)) + assertThatThrownBy(() -> sut.signUp(unAgreedRequest, deviceId)) .isInstanceOf(NotAgreeToTermsException.class); } @Test void 소셜_인증에_실패한_경우_회원가입에_실패해야_한다() throws Exception { // when, then - assertThatThrownBy(() -> sut.signUp(request)) + assertThatThrownBy(() -> sut.signUp(request, deviceId)) .isInstanceOf(FeignException.class); } @@ -187,7 +189,7 @@ void setUp() { .when(kakaoSocialDataApiClient).getUserInfo(any()); // when - AuthTokenResponse response = sut.signUp(request); + AuthTokenResponse response = sut.signUp(request, deviceId); Auth auth = authRepository.findByRefreshToken(response.refreshToken()).get(); // then @@ -202,7 +204,7 @@ void setUp() { .when(kakaoSocialDataApiClient).getUserInfo(any()); // when - AuthTokenResponse response = sut.signIn(new AuthSignInRequest("accessToken", AuthProvider.KAKAO)); + AuthTokenResponse response = sut.signIn(new AuthSignInRequest("accessToken", AuthProvider.KAKAO), deviceId); // then Long userId = jwtExtractor.parseJwtClaim(response.accessToken()).id(); @@ -217,7 +219,7 @@ void setUp() { .when(appleSocialService).getSocialData(any()); // when - AuthTokenResponse response = sut.signIn(new AuthSignInRequest("accessToken", AuthProvider.APPLE)); + AuthTokenResponse response = sut.signIn(new AuthSignInRequest("accessToken", AuthProvider.APPLE), deviceId); // then Long userId = jwtExtractor.parseJwtClaim(response.accessToken()).id(); @@ -231,7 +233,7 @@ void setUp() { .when(kakaoSocialDataApiClient).getUserInfo(any()); // when, then - assertThatThrownBy(() -> sut.signIn(new AuthSignInRequest("accessToken", AuthProvider.KAKAO))) + assertThatThrownBy(() -> sut.signIn(new AuthSignInRequest("accessToken", AuthProvider.KAKAO), deviceId)) .isInstanceOf(UserNotFoundException.class); } @@ -241,7 +243,7 @@ void setUp() { String socialAccessToken = "accessToken"; // when, then - assertThatThrownBy(() -> sut.signIn(new AuthSignInRequest(socialAccessToken, AuthProvider.KAKAO))) + assertThatThrownBy(() -> sut.signIn(new AuthSignInRequest(socialAccessToken, AuthProvider.KAKAO), deviceId)) .isInstanceOf(FeignException.class); } @@ -250,7 +252,7 @@ void setUp() { // given doReturn(new KakaoUserInfo(user.getSocialInfo().getSocialId())) .when(kakaoSocialDataApiClient).getUserInfo(any()); - AuthTokenResponse signUpResponse = sut.signUp(request); + AuthTokenResponse signUpResponse = sut.signUp(request, deviceId); // when AuthTokenResponse reissuedToken = sut.reissueToken(signUpResponse.refreshToken()); @@ -267,7 +269,7 @@ void setUp() { // given doReturn(new KakaoUserInfo(user.getSocialInfo().getSocialId())) .when(kakaoSocialDataApiClient).getUserInfo(any()); - AuthTokenResponse signUpResponse = sut.signUp(request); + AuthTokenResponse signUpResponse = sut.signUp(request, deviceId); // when AuthTokenResponse reissuedToken = sut.reissueToken(signUpResponse.refreshToken()); @@ -283,7 +285,7 @@ void setUp() { // given doReturn(new KakaoUserInfo(user.getSocialInfo().getSocialId())) .when(kakaoSocialDataApiClient).getUserInfo(any()); - AuthTokenResponse signUpResponse = sut.signUp(request); + AuthTokenResponse signUpResponse = sut.signUp(request, deviceId); // when sut.signOut(jwtExtractor.parseJwtClaim(signUpResponse.accessToken()).id()); @@ -297,7 +299,7 @@ void setUp() { // given doReturn(new KakaoUserInfo(user.getSocialInfo().getSocialId())) .when(kakaoSocialDataApiClient).getUserInfo(any()); - AuthTokenResponse signUpResponse = sut.signUp(request); + AuthTokenResponse signUpResponse = sut.signUp(request, deviceId); // when sut.delete(jwtExtractor.parseJwtClaim(signUpResponse.accessToken()).id()); @@ -312,7 +314,7 @@ void setUp() { // given doReturn(new KakaoUserInfo(user.getSocialInfo().getSocialId())) .when(kakaoSocialDataApiClient).getUserInfo(any()); - AuthTokenResponse signUpResponse = sut.signUp(request); + AuthTokenResponse signUpResponse = sut.signUp(request, deviceId); Note note = writeNote(jwtExtractor.parseJwtClaim(signUpResponse.accessToken()).id()); // when diff --git a/src/test/resources/application.yml b/src/test/resources/application.yml index aef7c6f2..8635e3f5 100644 --- a/src/test/resources/application.yml +++ b/src/test/resources/application.yml @@ -2,11 +2,40 @@ spring: profiles: active: test +jwt: + secret: lyrics2024lyrics2024lyrics2024lyrics2024lyrics2024lyrics2024lyrics2024lyrics2024lyrics2024 + +logging: + pattern: + dateformat: yyyy-MM-dd HH:mm:ss.SSSz,Asia/Seoul + +server: + port: 8080 + +firebase: + key-file: src/main/resources/firebase-key.json + +slack: + token: secret + signing: + secret: secret + channel: + id: secret + +admin: 1 + --- spring: config: activate: on-profile: test + + datasource: + driver-class-name: org.h2.Driver + url: jdbc:h2:mem:test;NON_KEYWORDS=USER;MODE=MYSQL;DB_CLOSE_DELAY=-1 + username: sa + password: + jpa: hibernate: ddl-auto: create-drop @@ -18,26 +47,23 @@ spring: default_batch_fetch_size: 1000 open-in-view: false +--- +spring: + config: + activate: + on-profile: local + datasource: - driver-class-name: org.h2.Driver - url: jdbc:h2:mem:test;NON_KEYWORDS=USER;MODE=MYSQL;DB_CLOSE_DELAY=-1 - username: sa + url: jdbc:mysql://localhost:3306/lyrics?serverTimezone=UTC&useSSL=false&characterEncoding=UTF-8&rewriteBatchedStatements=true + username: root password: - -jwt: - secret: omgomgomgomgomgomgomgomgomgomgomgomgomgomgomgomg - -server: - port: 8080 - -firebase: - key-file: src/main/resources/firebase-key.json - -slack: - token: secret - signing: - secret: secret - channel: - id: secret - -admin: 1 \ No newline at end of file + + jpa: + hibernate: + ddl-auto: create + properties: + hibernate: + show_sql: true + format_sql: true + globally_quoted_identifiers: true + default_batch_fetch_size: 1000