Skip to content

Commit

Permalink
Merge pull request #30 from SWM-WeLike2Coding/test/userWithdraw
Browse files Browse the repository at this point in the history
test: 회원 탈퇴 시, 상태 처리 확인 위한 테스트 코드 작성
  • Loading branch information
kjungw1025 authored Aug 2, 2024
2 parents 04e3820 + 0840a56 commit 376baf8
Show file tree
Hide file tree
Showing 8 changed files with 158 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package com.wl2c.elswhereuserservice.domain.batch;

import com.wl2c.elswhereuserservice.domain.user.repository.UserRepository;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

@Component
@RequiredArgsConstructor
@EnableScheduling
@Slf4j
public class UserWithdrawScheduler {

private final UserRepository userRepository;

@Value("${app.user.delete-period}")
private Long deletePeriod;

@Scheduled(cron = "0 0 * * * *")
@Transactional
public void deleteInactiveUser() {
userRepository.deleteAllByWithdrawnUser(deletePeriod);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import com.wl2c.elswhereuserservice.domain.user.model.dto.response.ResponseUserInfoDto;
import com.wl2c.elswhereuserservice.domain.user.service.UserInfoService;
import com.wl2c.elswhereuserservice.domain.user.service.UserService;
import com.wl2c.elswhereuserservice.domain.user.service.UserWithdrawService;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.validation.Valid;
Expand All @@ -22,6 +23,7 @@ public class UserController {

private final UserService userService;
private final UserInfoService userInfoService;
private final UserWithdrawService userWithdrawService;

/**
* 내 정보 조회
Expand Down Expand Up @@ -55,4 +57,15 @@ public ResponseRefreshTokenDto refreshToken(HttpServletRequest request,
@Valid @RequestBody RequestRefreshTokenDto dto) {
return userService.refreshToken(request, dto.getRefreshToken());
}

/**
* 회원탈퇴
*
* <p>회원은 바로 삭제되지 않고, 7일 뒤에 서버 배치작업에 의해 자동 삭제됩니다.</p>
* <p>회원 관련 조회시에는 '탈퇴한 회원'이라고 조회됩니다.</p>
*/
@DeleteMapping
public void withdraw(HttpServletRequest request) {
userWithdrawService.withdraw(parseLong(request.getHeader("requestId")));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
import jakarta.persistence.*;
import jakarta.validation.constraints.NotNull;
import lombok.*;
import org.hibernate.annotations.OnDelete;
import org.hibernate.annotations.OnDeleteAction;

import java.math.BigDecimal;

Expand All @@ -22,6 +24,7 @@ public class Holding extends BaseEntity {

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "user_id")
@OnDelete(action = OnDeleteAction.CASCADE)
private User user;

@NotNull
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
import jakarta.persistence.*;
import jakarta.validation.constraints.NotNull;
import lombok.*;
import org.hibernate.annotations.OnDelete;
import org.hibernate.annotations.OnDeleteAction;

import static jakarta.persistence.EnumType.STRING;

Expand All @@ -20,6 +22,7 @@ public class Interest extends BaseEntity {

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "user_id")
@OnDelete(action = OnDeleteAction.CASCADE)
private User user;

@NotNull
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.wl2c.elswhereuserservice.domain.user.model.entity;

import com.wl2c.elswhereuserservice.domain.user.service.UserInfoService;
import com.wl2c.elswhereuserservice.domain.user.model.SocialType;
import com.wl2c.elswhereuserservice.domain.user.model.UserStatus;
import com.wl2c.elswhereuserservice.global.auth.role.UserRole;
Expand All @@ -19,6 +20,8 @@
@Table(name = "users")
public class User extends BaseEntity {

public static String DELETED_USER = "탈퇴한 회원";

@Id
@GeneratedValue
@Column(name = "user_id")
Expand Down Expand Up @@ -71,6 +74,20 @@ private User (@NonNull String socialId,
this.userRole = userRole;
}

public String getName() {
if (!getUserStatus().isActive()) {
return DELETED_USER;
}
return this.name;
}

public String getNickname() {
if (!getUserStatus().isActive()) {
return DELETED_USER;
}
return this.nickname;
}

/**
* 닉네임을 변경합니다.
*
Expand All @@ -79,4 +96,14 @@ private User (@NonNull String socialId,
public void changeNickName(String nickname) {
this.nickname = nickname;
}

/**
* User 상태를 변경합니다.
* User정보 캐시를 삭제하기위해 {@link UserInfoService}.invalidateUserInfo를 호출해야 합니다.
*
* @param userStatus 상태
*/
public void changeStatus(UserStatus userStatus) {
this.userStatus = userStatus;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import com.wl2c.elswhereuserservice.domain.user.model.entity.User;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;

Expand All @@ -14,4 +15,10 @@ public interface UserRepository extends JpaRepository<User, Long> {

@Query("select u from User u where u.nickname = :nickname")
Optional<User> findByNickname(@Param("nickname") String nickname);

@Modifying(clearAutomatically = true)
@Query("delete from User u " +
"where u.userStatus = 'INACTIVE' " +
"and FUNCTION('DATEDIFF', u.lastModifiedAt, u.createdAt) >= :period ")
void deleteAllByWithdrawnUser(@Param("period") Long period);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package com.wl2c.elswhereuserservice.domain.user.service;

import com.wl2c.elswhereuserservice.domain.user.exception.UserNotFoundException;
import com.wl2c.elswhereuserservice.domain.user.model.entity.User;
import com.wl2c.elswhereuserservice.domain.user.repository.UserRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import static com.wl2c.elswhereuserservice.domain.user.model.UserStatus.INACTIVE;


@Service
@RequiredArgsConstructor
@Transactional(readOnly = true)
public class UserWithdrawService {

private final UserRepository userRepository;
private final UserInfoService cacheService;

@Transactional
public void withdraw(Long userId) {
User user = userRepository.findById(userId).orElseThrow(UserNotFoundException::new);
user.changeStatus(INACTIVE);
cacheService.invalidateUserInfo(userId);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package com.wl2c.elswhereuserservice.domain.user.service;

import com.wl2c.elswhereuserservice.domain.user.model.SocialType;
import com.wl2c.elswhereuserservice.domain.user.model.UserStatus;
import com.wl2c.elswhereuserservice.domain.user.model.entity.User;
import com.wl2c.elswhereuserservice.domain.user.repository.UserRepository;
import com.wl2c.elswhereuserservice.mock.UserMock;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;

import java.util.Optional;

import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

@ExtendWith(MockitoExtension.class)
class UserWithdrawServiceTest {

@Mock
private UserRepository userRepository;

@Mock
private UserInfoService cacheService;

@InjectMocks
private UserWithdrawService userWithdrawService;

@Test
@DisplayName("회원 탈퇴 - INACTIVE로 상태 변경이 잘 되는지 확인")
void withdraw() {
// given
User user = UserMock.create(SocialType.GOOGLE, "[email protected]");
when(userRepository.findById(user.getId())).thenReturn(Optional.of(user));

// when
userWithdrawService.withdraw(user.getId());

// then
assertThat(user.getUserStatus()).isEqualTo(UserStatus.INACTIVE);
verify(cacheService).invalidateUserInfo(user.getId());
}
}

0 comments on commit 376baf8

Please sign in to comment.