Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
import org.runimo.runimo.auth.service.dto.SignupUserResponse;
import org.runimo.runimo.auth.service.dto.UserSignupCommand;
import org.runimo.runimo.external.FileStorageService;
import org.runimo.runimo.item.domain.Egg;
import org.runimo.runimo.rewards.service.eggs.EggGrantService;
import org.runimo.runimo.user.domain.AppleUserToken;
import org.runimo.runimo.user.domain.SocialProvider;
import org.runimo.runimo.user.domain.User;
Expand All @@ -28,6 +30,7 @@ public class SignUpUsecaseImpl implements SignUpUsecase {
private static final int REGISTER_CUTOFF_MIN = 10;
private final UserRegisterService userRegisterService;
private final FileStorageService fileStorageService;
private final EggGrantService eggGrantService;
private final JwtTokenFactory jwtTokenFactory;
private final SignupTokenRepository signupTokenRepository;
private final AppleUserTokenRepository appleUserTokenRepository;
Expand All @@ -50,8 +53,11 @@ public SignupUserResponse register(UserSignupCommand command) {
if (payload.socialProvider() == SocialProvider.APPLE) {
createAppleUserToken(savedUser.getId(), signupToken);
}
Egg grantedEgg = eggGrantService.grantGreetingEggToUser(savedUser);

removeSignupToken(payload.token());
return new SignupUserResponse(savedUser, jwtTokenFactory.generateTokenPair(savedUser));
return new SignupUserResponse(savedUser, jwtTokenFactory.generateTokenPair(savedUser),
grantedEgg);
}

private void removeSignupToken(String token) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,26 @@
package org.runimo.runimo.auth.service.dto;

import org.runimo.runimo.item.domain.Egg;
import org.runimo.runimo.user.domain.User;

public record SignupUserResponse(
Long userId,
String nickname,
String imgUrl,
TokenPair tokenPair
TokenPair tokenPair,
String greetingEggName,
String greetingEggType,
String greetingEggImgUrl
) {

public SignupUserResponse(final User user, final TokenPair tokenPair) {
public SignupUserResponse(final User user, final TokenPair tokenPair, final Egg greetingEgg) {
this(user.getId(),
user.getNickname(),
user.getImgUrl(),
tokenPair);
tokenPair,
greetingEgg.getName(),
greetingEgg.getEggType().getName(),
greetingEgg.getImgUrl()
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,13 @@ public class EggGrantService {
private final EggTypeRepository eggTypeRepository;

@Transactional
public void grantGreetingEggToUser(User user) {
public Egg grantGreetingEggToUser(User user) {
if (!user.checkUserFirstRun()) {
return;
return Egg.EMPTY;
}
Egg grantedEgg = eggFactory.createGreetingEgg();
userItemProcessor.updateItemQuantity(user.getId(), grantedEgg.getId(), GREETING_EGG_AMOUNT);
return grantedEgg;
}

@Transactional
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

import lombok.RequiredArgsConstructor;
import org.runimo.runimo.auth.exceptions.SignUpException;
import org.runimo.runimo.rewards.service.eggs.EggGrantService;
import org.runimo.runimo.user.domain.SocialProvider;
import org.runimo.runimo.user.domain.User;
import org.runimo.runimo.user.enums.UserHttpResponseCode;
Expand All @@ -18,7 +17,6 @@ public class UserRegisterService {

private final UserCreator userCreator;
private final UserItemCreator userItemCreator;
private final EggGrantService eggGrantService;
private final OAuthInfoRepository oAuthInfoRepository;

@Transactional
Expand All @@ -28,13 +26,12 @@ public User registerUser(UserRegisterCommand command) {
userCreator.createUserOAuthInfo(savedUser, command.socialProvider(), command.providerId());
userCreator.createLovePoint(savedUser.getId());
userItemCreator.createAll(savedUser.getId());
eggGrantService.grantGreetingEggToUser(savedUser);
return savedUser;
}

public void validateExistingUser(String providerId, SocialProvider socialProvider) {
if(oAuthInfoRepository.existsByProviderIdAndProvider(
providerId, socialProvider)) {
if (oAuthInfoRepository.existsByProviderIdAndProvider(
providerId, socialProvider)) {
throw new SignUpException(UserHttpResponseCode.SIGNIN_FAIL_ALREADY_EXIST);
}
}
Expand Down
123 changes: 80 additions & 43 deletions src/test/java/org/runimo/runimo/auth/service/SignUpUsecaseTest.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package org.runimo.runimo.auth.service;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
Expand All @@ -17,8 +19,12 @@
import org.runimo.runimo.auth.jwt.JwtTokenFactory;
import org.runimo.runimo.auth.jwt.SignupTokenPayload;
import org.runimo.runimo.auth.repository.SignupTokenRepository;
import org.runimo.runimo.auth.service.dto.SignupUserResponse;
import org.runimo.runimo.auth.service.dto.UserSignupCommand;
import org.runimo.runimo.external.FileStorageService;
import org.runimo.runimo.item.EggFixtures;
import org.runimo.runimo.rewards.service.eggs.EggGrantService;
import org.runimo.runimo.user.UserFixtures;
import org.runimo.runimo.user.domain.Gender;
import org.runimo.runimo.user.domain.SocialProvider;
import org.runimo.runimo.user.enums.UserHttpResponseCode;
Expand All @@ -27,53 +33,84 @@

class SignUpUsecaseTest {

@Mock
private UserRegisterService userRegisterService;
@Mock
private FileStorageService fileStorageService;
@Mock
private JwtTokenFactory jwtTokenFactory;
@Mock
private SignupTokenRepository signupTokenRepository;
@Mock
private AppleUserTokenRepository appleUserTokenRepository;
@Mock
private JwtResolver jwtResolver;
@Mock
private UserRegisterService userRegisterService;
@Mock
private FileStorageService fileStorageService;
@Mock
private EggGrantService eggGrantService;
@Mock
private JwtTokenFactory jwtTokenFactory;
@Mock
private SignupTokenRepository signupTokenRepository;
@Mock
private AppleUserTokenRepository appleUserTokenRepository;
@Mock
private JwtResolver jwtResolver;

private SignUpUsecase sut;
private SignUpUsecase sut;

@BeforeEach
void setUp() {
MockitoAnnotations.openMocks(this);
sut = new SignUpUsecaseImpl(
userRegisterService,
fileStorageService,
jwtTokenFactory,
signupTokenRepository,
appleUserTokenRepository,
jwtResolver
);
}
@BeforeEach
void setUp() {
MockitoAnnotations.openMocks(this);
sut = new SignUpUsecaseImpl(
userRegisterService,
fileStorageService,
eggGrantService,
jwtTokenFactory,
signupTokenRepository,
appleUserTokenRepository,
jwtResolver
);
}

@Test
void 유저가_이미_존재하면_실패() {
// given
String registerToken = "dummy.token.value";
SignupTokenPayload payload = new SignupTokenPayload(registerToken, "socialId123",
SocialProvider.KAKAO);
@Test
void 회원가입_시_환영_알_지급() {
// given
String registerToken = "dummy.token.value";
SignupTokenPayload payload = new SignupTokenPayload(registerToken, "socialId123",
SocialProvider.KAKAO);

when(jwtResolver.getSignupTokenPayload(registerToken)).thenReturn(payload);
when(signupTokenRepository.findByIdAndCreatedAtAfter(eq(registerToken), any()))
.thenReturn(Optional.of(new SignupToken(
registerToken, "refresh", "refresh", SocialProvider.KAKAO)));
when(jwtResolver.getSignupTokenPayload(registerToken)).thenReturn(payload);
when(signupTokenRepository.findByIdAndCreatedAtAfter(eq(registerToken), any()))
.thenReturn(Optional.of(new SignupToken(
registerToken, "refresh", "refresh", SocialProvider.KAKAO)));
when(userRegisterService.registerUser(any())).thenReturn(UserFixtures.getUserWithId(1L));
when(eggGrantService.grantGreetingEggToUser(any())).thenReturn(
EggFixtures.createDefaultEgg());
when(jwtTokenFactory.generateTokenPair(any())).thenReturn(UserFixtures.TEST_TOKEN_PAIR);

doThrow(new org.runimo.runimo.auth.exceptions.SignUpException(
UserHttpResponseCode.SIGNIN_FAIL_ALREADY_EXIST))
.when(userRegisterService)
.validateExistingUser(payload.providerId(), payload.socialProvider());
SignupUserResponse response = sut
.register(new UserSignupCommand(registerToken, "nickname", null, Gender.UNKNOWN));

assertThrows(SignUpException.class, () -> {
sut.register(new UserSignupCommand(registerToken, "nickname", null, Gender.UNKNOWN));
});
}
assertEquals(1L, response.userId());
assertEquals(UserFixtures.TEST_USER_NICKNAME, response.nickname());
assertEquals(UserFixtures.TEST_USER_IMG_URL, response.imgUrl());
assertNotNull(response.tokenPair());
assertEquals(EggFixtures.TEST_EGG_NAME, response.greetingEggName());
assertEquals(EggFixtures.TEST_EGG_TYPE_NAME, response.greetingEggType());
assertEquals(EggFixtures.TEST_EGG_IMG_URL, response.greetingEggImgUrl());
}

@Test
void 유저가_이미_존재하면_실패() {
// given
String registerToken = "dummy.token.value";
SignupTokenPayload payload = new SignupTokenPayload(registerToken, "socialId123",
SocialProvider.KAKAO);

when(jwtResolver.getSignupTokenPayload(registerToken)).thenReturn(payload);
when(signupTokenRepository.findByIdAndCreatedAtAfter(eq(registerToken), any()))
.thenReturn(Optional.of(new SignupToken(
registerToken, "refresh", "refresh", SocialProvider.KAKAO)));

doThrow(new org.runimo.runimo.auth.exceptions.SignUpException(
UserHttpResponseCode.SIGNIN_FAIL_ALREADY_EXIST))
.when(userRegisterService)
.validateExistingUser(payload.providerId(), payload.socialProvider());

assertThrows(SignUpException.class, () -> {
sut.register(new UserSignupCommand(registerToken, "nickname", null, Gender.UNKNOWN));
});
}
}
51 changes: 51 additions & 0 deletions src/test/java/org/runimo/runimo/item/EggFixtures.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package org.runimo.runimo.item;

import org.runimo.runimo.item.domain.Egg;
import org.runimo.runimo.item.domain.EggType;

public final class EggFixtures {

public static final String TEST_EGG_CODE = "TEST_EGG";
public static final String TEST_EGG_NAME = "Test Egg";
public static final String TEST_EGG_DESCRIPTION = "A test egg for testing purposes";
public static final String TEST_EGG_IMG_URL = "test_egg.png";

public static final String TEST_EGG_TYPE_NAME = "Test Type";
public static final String TEST_EGG_TYPE_CODE = "TEST";
public static final Long TEST_EGG_TYPE_DISTANCE = 1000L;
public static final Integer TEST_EGG_TYPE_LEVEL = 1;

public static Egg createDefaultEgg() {
return Egg.builder()
.itemCode(TEST_EGG_CODE)
.name(TEST_EGG_NAME)
.description(TEST_EGG_DESCRIPTION)
.imgUrl(TEST_EGG_IMG_URL)
.eggType(createDefaultEggType())
.hatchRequireAmount(10L)
.build();
}

public static Egg createCustomEgg(String itemCode, String name, String description,
String imgUrl, EggType eggType, Long hatchRequireAmount) {
return Egg.builder()
.itemCode(itemCode)
.name(name)
.description(description)
.imgUrl(imgUrl)
.eggType(eggType)
.hatchRequireAmount(hatchRequireAmount)
.build();
}

public static EggType createDefaultEggType() {
return EggType.of(TEST_EGG_TYPE_NAME, TEST_EGG_TYPE_CODE, TEST_EGG_TYPE_DISTANCE,
TEST_EGG_TYPE_LEVEL);
}

public static EggType createCustomEggType(String name, String code,
Long requiredDistanceInMeters, Integer level) {
return EggType.of(name, code, requiredDistanceInMeters, level);
}

}
15 changes: 11 additions & 4 deletions src/test/java/org/runimo/runimo/user/UserFixtures.java
Original file line number Diff line number Diff line change
@@ -1,23 +1,30 @@
package org.runimo.runimo.user;

import org.runimo.runimo.auth.service.dto.TokenPair;
import org.runimo.runimo.user.domain.User;
import org.springframework.test.util.ReflectionTestUtils;

public final class UserFixtures {

public static final String TEST_USER_NICKNAME = "test";
public static final String TEST_USER_IMG_URL = "test";
public static final TokenPair TEST_TOKEN_PAIR = new TokenPair(
"test-access-token-1", "test-refresh-token-1"
);

public static User getDefaultUser() {
return User.builder()
.nickname("test")
.imgUrl("test")
.nickname(TEST_USER_NICKNAME)
.imgUrl(TEST_USER_IMG_URL)
.totalDistanceInMeters(0L)
.totalTimeInSeconds(0L)
.build();
}

public static User getUserWithId(Long id) {
User user = User.builder()
.nickname("test")
.imgUrl("test")
.nickname(TEST_USER_NICKNAME)
.imgUrl(TEST_USER_NICKNAME)
.totalDistanceInMeters(0L)
.totalTimeInSeconds(0L)
.build();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,10 @@ void tearDown() {
1L,
"test-user",
"https://test-image.com",
new TokenPair(token, "token2")
new TokenPair(token, "token2"),
"마당알",
"MADANG",
"test.url"
));

AuthSignupRequest request = new AuthSignupRequest(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.runimo.runimo.rewards.service.eggs.EggGrantService;
import org.runimo.runimo.user.domain.Gender;
import org.runimo.runimo.user.domain.SocialProvider;
import org.runimo.runimo.user.domain.User;
Expand All @@ -30,9 +29,6 @@ class UserRegisterServiceTest {
@Mock
private UserItemCreator userItemCreator;

@Mock
private EggGrantService eggGrantService;

@InjectMocks
private UserRegisterService userRegisterService;

Expand Down Expand Up @@ -66,6 +62,5 @@ void setUp() {
providerId);
verify(userCreator, times(1)).createLovePoint(anyLong());
verify(userItemCreator, times(1)).createAll(anyLong());
verify(eggGrantService, times(1)).grantGreetingEggToUser(mockUser);
}
}