Skip to content

Commit

Permalink
chore: conflicts are fixed
Browse files Browse the repository at this point in the history
  • Loading branch information
psychology50 committed Feb 10, 2025
2 parents c260063 + 741ab52 commit 308ef2a
Show file tree
Hide file tree
Showing 141 changed files with 6,198 additions and 0 deletions.
19 changes: 19 additions & 0 deletions .github/workflows/open-api-code-review.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
name: Code Review

permissions:
contents: read
pull-requests: write

on:
pull_request:
types: [ opened ]

jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: anc95/ChatGPT-CodeReview@main
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
OPENAI_API_KEY: ${{ secrets.OPEN_API_KEY }}
LANGUAGE: Korean
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package kr.co.pennyway.api.apis.storage.service;

import kr.co.pennyway.infra.client.aws.s3.AwsS3Provider;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.net.URI;

@Slf4j
@Service
@RequiredArgsConstructor
public class StorageService {
private final AwsS3Provider awsS3Provider;

public URI getPresignedUrl(String type, String ext, String userId, String chatroomId) {
return awsS3Provider.generatedPresignedUrl(type, ext, userId, chatroomId);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package kr.co.pennyway.api.apis.users.service;

import kr.co.pennyway.domain.domains.device.domain.DeviceToken;
import kr.co.pennyway.domain.domains.device.service.DeviceTokenService;
import kr.co.pennyway.domain.domains.user.domain.User;
import kr.co.pennyway.domain.domains.user.exception.UserErrorCode;
import kr.co.pennyway.domain.domains.user.exception.UserErrorException;
import kr.co.pennyway.domain.domains.user.service.UserService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Optional;

@Slf4j
@Service
@RequiredArgsConstructor
public class DeviceTokenRegisterService {
private final UserService userService;
private final DeviceTokenService deviceTokenService;

@Transactional
public DeviceToken execute(Long userId, String token) {
User user = userService.readUser(userId).orElseThrow(() -> new UserErrorException(UserErrorCode.NOT_FOUND));

return getOrCreateDevice(user, token);
}

/**
* μ‚¬μš©μžμ˜ λ””λ°”μ΄μŠ€ 토큰을 κ°€μ Έμ˜€κ±°λ‚˜ μƒμ„±ν•œλ‹€.
* <p>
* 이미 λ“±λ‘λœ λ””λ°”μ΄μŠ€ 토큰인 경우 λ§ˆμ§€λ§‰ 둜그인 μ‹œκ°„μ„ κ°±μ‹ ν•œλ‹€.
*/
private DeviceToken getOrCreateDevice(User user, String token) {
Optional<DeviceToken> deviceToken = deviceTokenService.readDeviceByUserIdAndToken(user.getId(), token);

if (deviceToken.isPresent()) {
DeviceToken device = deviceToken.get();
device.activate();
device.updateLastSignedInAt();
return device;
} else {
return deviceTokenService.createDevice(DeviceToken.of(token, user));
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package kr.co.pennyway.api.common.security.jwt;

import kr.co.pennyway.infra.common.jwt.JwtClaims;

import java.util.function.Function;

public class JwtClaimsParserUtil {
/**
* JwtClaimsμ—μ„œ key에 ν•΄λ‹Ήν•˜λŠ” 값을 λ°˜ν™˜ν•˜λŠ” λ©”μ„œλ“œ
*
* @return key에 ν•΄λ‹Ήν•˜λŠ” 값이 μ—†κ±°λ‚˜, νƒ€μž…μ΄ μΌμΉ˜ν•˜μ§€ μ•Šμ„ 경우 null을 λ°˜ν™˜ν•œλ‹€.
*/
@SuppressWarnings("unchecked")
public static <T> T getClaimsValue(JwtClaims claims, String key, Class<T> type) {
Object value = claims.getClaims().get(key);
if (value != null && type.isAssignableFrom(value.getClass())) {
return (T) value;
}
return null;
}

/**
* JwtClaimsμ—μ„œ valueConverterλ₯Ό μ΄μš©ν•˜μ—¬ key에 ν•΄λ‹Ήν•˜λŠ” 값을 λ°˜ν™˜ν•˜λŠ” λ©”μ„œλ“œ
*
* @param valueConverter : String νƒ€μž…μ˜ 값을 T νƒ€μž…μœΌλ‘œ λ³€ν™˜ν•˜λŠ” ν•¨μˆ˜
* @return key에 ν•΄λ‹Ήν•˜λŠ” 값이 없을 경우 null을 λ°˜ν™˜ν•œλ‹€.
*/
public static <T> T getClaimsValue(JwtClaims claims, String key, Function<String, T> valueConverter) {
Object value = claims.getClaims().get(key);
if (value != null) {
return valueConverter.apply((String) value);
}
return null;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
package kr.co.pennyway.api.apis.users.service;

import com.querydsl.jpa.impl.JPAQueryFactory;
import kr.co.pennyway.api.apis.auth.service.PhoneVerificationService;
import kr.co.pennyway.api.config.ExternalApiDBTestConfig;
import kr.co.pennyway.api.config.fixture.UserFixture;
import kr.co.pennyway.domain.common.redis.phone.PhoneCodeService;
import kr.co.pennyway.domain.config.JpaConfig;
import kr.co.pennyway.domain.domains.user.domain.User;
import kr.co.pennyway.domain.domains.user.exception.UserErrorCode;
import kr.co.pennyway.domain.domains.user.exception.UserErrorException;
import kr.co.pennyway.domain.domains.user.service.UserService;
import kr.co.pennyway.infra.client.aws.s3.AwsS3Provider;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.junit.jupiter.MockitoExtension;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.transaction.annotation.Transactional;

import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.springframework.test.util.AssertionErrors.assertEquals;

@ExtendWith(MockitoExtension.class)
@DataJpaTest(properties = "spring.jpa.hibernate.ddl-auto=create")
@ContextConfiguration(classes = {JpaConfig.class, UserProfileUpdateService.class, UserService.class})
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
public class NameUpdateServiceTest extends ExternalApiDBTestConfig {
@Autowired
private UserService userService;

@Autowired
private UserProfileUpdateService userProfileUpdateService;

@MockBean
private AwsS3Provider awsS3Provider;

@MockBean
private PhoneVerificationService phoneVerificationService;

@MockBean
private PhoneCodeService phoneCodeService;

@MockBean
private JPAQueryFactory queryFactory;

@Test
@Transactional
@DisplayName("μ‚¬μš©μžκ°€ μ‚­μ œλœ μœ μ €μΈ 경우 NOT_FOUND μ—λŸ¬λ₯Ό λ°˜ν™˜ν•œλ‹€.")
void updateNameWhenUserIsDeleted() {
// given
String newName = "μ–‘μž¬μ„œ";
User originUser = UserFixture.GENERAL_USER.toUser();
userService.createUser(originUser);
userService.deleteUser(originUser);

// when - then
UserErrorException ex = assertThrows(UserErrorException.class, () -> userProfileUpdateService.updateName(originUser.getId(), newName));
assertEquals("μ‚­μ œλœ μ‚¬μš©μžμΈ 경우 Not Foundλ₯Ό λ°˜ν™˜ν•œλ‹€.", UserErrorCode.NOT_FOUND, ex.getBaseErrorCode());
}

@Test
@Transactional
@DisplayName("μ‚¬μš©μžμ˜ 이름이 μ„±κ³΅μ μœΌλ‘œ λ³€κ²½λœλ‹€.")
void updateName() {
// given
User originUser = UserFixture.GENERAL_USER.toUser();
userService.createUser(originUser);
String newName = "μ–‘μž¬μ„œ";

// when
userProfileUpdateService.updateName(originUser.getId(), newName);

// then
User updatedUser = userService.readUser(originUser.getId()).orElseThrow();
assertEquals("μ‚¬μš©μž 이름이 λ³€κ²½λ˜μ–΄ μžˆμ–΄μ•Ό ν•œλ‹€.", newName, updatedUser.getName());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
package kr.co.pennyway.api.apis.users.usecase;

import com.querydsl.jpa.impl.JPAQueryFactory;
import kr.co.pennyway.api.apis.users.dto.DeviceTokenDto;
import kr.co.pennyway.api.apis.users.service.DeviceTokenRegisterService;
import kr.co.pennyway.api.config.ExternalApiDBTestConfig;
import kr.co.pennyway.api.config.fixture.DeviceTokenFixture;
import kr.co.pennyway.api.config.fixture.UserFixture;
import kr.co.pennyway.domain.config.JpaConfig;
import kr.co.pennyway.domain.domains.device.domain.DeviceToken;
import kr.co.pennyway.domain.domains.device.service.DeviceTokenService;
import kr.co.pennyway.domain.domains.user.domain.User;
import kr.co.pennyway.domain.domains.user.service.UserService;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.junit.jupiter.MockitoExtension;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.transaction.annotation.Transactional;

import static org.springframework.test.util.AssertionErrors.*;

@ExtendWith(MockitoExtension.class)
@DataJpaTest(properties = "spring.jpa.hibernate.ddl-auto=create")
@ContextConfiguration(classes = {JpaConfig.class, DeviceTokenRegisterService.class, UserService.class, DeviceTokenService.class})
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
public class DeviceTokenRegisterServiceTest extends ExternalApiDBTestConfig {
@Autowired
private UserService userService;

@Autowired
private DeviceTokenService deviceTokenService;

@Autowired
private DeviceTokenRegisterService deviceTokenRegisterService;

@MockBean
private JPAQueryFactory queryFactory;

private User requestUser;

@BeforeEach
void setUp() {
requestUser = userService.createUser(UserFixture.GENERAL_USER.toUser());
}

@Test
@Transactional
@DisplayName("[1] token 등둝 μš”μ²­μ΄ 듀어왔을 λ•Œ, μƒˆλ‘œμš΄ λ””λ°”μ΄μŠ€ 토큰을 λ“±λ‘ν•œλ‹€.")
void registerNewDevice() {
// given
DeviceTokenDto.RegisterReq request = DeviceTokenFixture.INIT.toRegisterReq();

// when
DeviceToken response = deviceTokenRegisterService.execute(requestUser.getId(), request.token());

// then
deviceTokenService.readDeviceByUserIdAndToken(requestUser.getId(), request.token()).ifPresentOrElse(
device -> {
assertEquals("μš”μ²­ν•œ λ””λ°”μ΄μŠ€ 토큰과 동일해야 ν•œλ‹€.", response.getToken(), device.getToken());
assertEquals("λ””λ°”μ΄μŠ€ IDκ°€ μΌμΉ˜ν•΄μ•Ό ν•œλ‹€.", response.getId(), device.getId());
assertTrue("λ””λ°”μ΄μŠ€κ°€ μ‚¬μš©μž ID와 μ—°κ²°λ˜μ–΄ μžˆμ–΄μ•Ό ν•œλ‹€.", device.getUser().getId().equals(requestUser.getId()));
System.out.println("device = " + device);
},
() -> fail("μ‹ κ·œ λ””λ°”μ΄μŠ€κ°€ λ“±λ‘λ˜μ–΄ μžˆμ–΄μ•Ό ν•œλ‹€.")
);
}

@Test
@Transactional
@DisplayName("[2] token에 λŒ€ν•œ ν™œμ„±ν™” λ””λ°”μ΄μŠ€ 토큰이 이미 μ‘΄μž¬ν•˜λŠ” 경우 κΈ°μ‘΄ 데이터λ₯Ό λ°˜ν™˜ν•œλ‹€.")
void registerNewDeviceWhenDeviceIsAlreadyExists() {
// given
DeviceToken originDeviceToken = DeviceTokenFixture.INIT.toDevice(requestUser);
deviceTokenService.createDevice(originDeviceToken);
DeviceTokenDto.RegisterReq request = DeviceTokenFixture.INIT.toRegisterReq();

// when
DeviceToken response = deviceTokenRegisterService.execute(requestUser.getId(), request.token());

// then
deviceTokenService.readDeviceByUserIdAndToken(requestUser.getId(), request.token()).ifPresentOrElse(
device -> {
assertEquals("μš”μ²­ν•œ λ””λ°”μ΄μŠ€ 토큰과 동일해야 ν•œλ‹€.", response.getToken(), device.getToken());
assertEquals("λ””λ°”μ΄μŠ€ IDκ°€ μΌμΉ˜ν•΄μ•Ό ν•œλ‹€.", originDeviceToken.getId(), device.getId());
assertTrue("λ””λ°”μ΄μŠ€κ°€ μ‚¬μš©μž ID와 μ—°κ²°λ˜μ–΄ μžˆμ–΄μ•Ό ν•œλ‹€.", device.getUser().getId().equals(requestUser.getId()));
assertTrue("λ””λ°”μ΄μŠ€κ°€ ν™œμ„±ν™” μƒνƒœμ—¬μ•Ό ν•œλ‹€.", device.getActivated());
System.out.println("device = " + device);
},
() -> fail("μ‹ κ·œ λ””λ°”μ΄μŠ€κ°€ λ“±λ‘λ˜μ–΄ μžˆμ–΄μ•Ό ν•œλ‹€.")
);
}

@Test
@Transactional
@DisplayName("[3] token 등둝 μš”μ²­μ΄ 듀어왔을 λ•Œ, ν™œμ„±ν™”λ˜μ§€ μ•Šμ€ λ””λ°”μ΄μŠ€ 토큰이 μ‘΄μž¬ν•˜λŠ” 경우 토큰을 ν™œμ„±ν™” μƒνƒœλ‘œ λ³€κ²½ν•œλ‹€.")
void registerNewDeviceWhenDeviceIsNotActivated() {
// given
DeviceToken originDeviceToken = DeviceTokenFixture.INIT.toDevice(requestUser);
originDeviceToken.deactivate();
deviceTokenService.createDevice(originDeviceToken);
DeviceTokenDto.RegisterReq request = DeviceTokenFixture.INIT.toRegisterReq();

// when
DeviceToken response = deviceTokenRegisterService.execute(requestUser.getId(), request.token());

// then
assertTrue("λ””λ°”μ΄μŠ€κ°€ ν™œμ„±ν™” μƒνƒœμ—¬μ•Ό ν•œλ‹€.", response.getActivated());
}
}
Loading

0 comments on commit 308ef2a

Please sign in to comment.