Skip to content

Commit

Permalink
โœจ user delete
Browse files Browse the repository at this point in the history
  • Loading branch information
HaiSeong committed Aug 16, 2024
1 parent b0a5430 commit 54a18cb
Show file tree
Hide file tree
Showing 8 changed files with 165 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,14 @@ List<Long> findRecipeIdsByCategoryAndKeyword(

int countByAuthorId(long userId);

@Query("""
SELECT r.id
FROM Recipe r
WHERE r.author.id = :userId
ORDER BY r.id DESC
""")
List<Long> findRecipeIdsByUserId(long userId);

@Query("""
SELECT r.id
FROM Recipe r
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import net.pengcook.user.dto.UsernameCheckResponse;
import net.pengcook.user.service.UserService;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PatchMapping;
import org.springframework.web.bind.annotation.PathVariable;
Expand Down Expand Up @@ -48,6 +49,12 @@ public UpdateProfileResponse updateUserProfile(
return userService.updateProfile(userInfo.getId(), updateProfileRequest);
}

@DeleteMapping("/user/me")
@ResponseStatus(HttpStatus.NO_CONTENT)
public void deleteUser(@LoginUser UserInfo userInfo) {
userService.deleteUser(userInfo);
}

@GetMapping("/user/username/check")
public UsernameCheckResponse checkUsername(@RequestParam @NotBlank String username) {
return userService.checkUsername(username);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,8 @@
@Repository
public interface UserBlockRepository extends JpaRepository<UserBlock, Long> {
List<UserBlock> findAllByBlockerId(long id);

void deleteByBlockeeId(long userId);

void deleteByBlockerId(long userId);
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,8 @@
import org.springframework.data.jpa.repository.JpaRepository;

public interface UserReportRepository extends JpaRepository<UserReport, Long> {

void deleteByReporteeId(long userId);

void deleteByReporterId(long userId);
}
28 changes: 28 additions & 0 deletions backend/src/main/java/net/pengcook/user/service/UserService.java
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
package net.pengcook.user.service;

import jakarta.transaction.Transactional;
import java.util.List;
import java.util.stream.Collectors;
import lombok.AllArgsConstructor;
import net.pengcook.authentication.domain.UserInfo;
import net.pengcook.comment.repository.CommentRepository;
import net.pengcook.like.repository.RecipeLikeRepository;
import net.pengcook.recipe.repository.RecipeRepository;
import net.pengcook.recipe.service.RecipeService;
import net.pengcook.user.domain.BlockedUserGroup;
import net.pengcook.user.domain.User;
import net.pengcook.user.domain.UserBlock;
Expand All @@ -27,8 +32,12 @@
@AllArgsConstructor
public class UserService {

private final RecipeService recipeService;

private final UserRepository userRepository;
private final RecipeRepository recipeRepository;
private final CommentRepository commentRepository;
private final RecipeLikeRepository recipeLikeRepository;
private final UserBlockRepository userBlockRepository;
private final UserReportRepository userReportRepository;

Expand Down Expand Up @@ -91,4 +100,23 @@ public BlockedUserGroup getBlockedUserGroup(long blockerId) {
.map(UserBlock::getBlockee)
.collect(Collectors.collectingAndThen(Collectors.toSet(), BlockedUserGroup::new));
}

@Transactional
public void deleteUser(UserInfo userInfo) {
User user = userRepository.findById(userInfo.getId())
.orElseThrow(() -> new NotFoundException("์‚ฌ์šฉ์ž๋ฅผ ์ฐพ์„ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค."));

commentRepository.deleteByUserId(userInfo.getId());
recipeLikeRepository.deleteByUserId(userInfo.getId());
userBlockRepository.deleteByBlockerId(userInfo.getId());
userBlockRepository.deleteByBlockeeId(userInfo.getId());
userReportRepository.deleteByReporterId(userInfo.getId());
userReportRepository.deleteByReporteeId(userInfo.getId());
List<Long> userRecipes = recipeRepository.findRecipeIdsByUserId(userInfo.getId());
for (Long recipeId : userRecipes) {
recipeService.deleteRecipe(userInfo, recipeId);
}

userRepository.delete(user);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,19 @@
import net.pengcook.user.dto.UpdateProfileResponse;
import net.pengcook.user.dto.UserBlockRequest;
import net.pengcook.user.dto.UserReportRequest;
import net.pengcook.user.repository.UserRepository;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.jdbc.Sql;

@WithLoginUserTest
@Sql("/data/users.sql")
class UserControllerTest extends RestDocsSetting {

@Autowired
UserRepository userRepository;

@Test
@WithLoginUser(email = "[email protected]")
@DisplayName("๋กœ๊ทธ์ธ๋œ ์‚ฌ์šฉ์ž์˜ ์ •๋ณด๋ฅผ ์กฐํšŒํ•œ๋‹ค.")
Expand Down Expand Up @@ -286,4 +291,23 @@ void blockUser() {
.body("blocker.id", is(1))
.body("blockee.id", is(2));
}

@Test
@WithLoginUser(email = "[email protected]")
@DisplayName("์‚ฌ์šฉ์ž๋ฅผ ์‚ญ์ œํ•œ๋‹ค.")
void deleteUser() {
RestAssured.given(spec).log().all()
.filter(document(DEFAULT_RESTDOCS_PATH,
"์‚ฌ์šฉ์ž๋ฅผ ์‚ญ์ œํ•ฉ๋‹ˆ๋‹ค.",
"์‚ฌ์šฉ์ž ์‚ญ์ œ API"
))
.contentType(ContentType.JSON)
.when().delete("/user/me")
.then().log().all()
.statusCode(204);

boolean exists = userRepository.existsByEmail("[email protected]");

assertThat(exists).isFalse();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.junit.jupiter.api.Assertions.assertAll;

import net.pengcook.authentication.domain.UserInfo;
import net.pengcook.comment.repository.CommentRepository;
import net.pengcook.like.repository.RecipeLikeRepository;
import net.pengcook.recipe.repository.RecipeRepository;
import net.pengcook.user.domain.BlockedUserGroup;
import net.pengcook.user.domain.UserReport;
import net.pengcook.user.dto.ProfileResponse;
Expand All @@ -19,20 +23,22 @@
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
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.context.annotation.Import;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.jdbc.Sql;

@DataJpaTest
@Import(UserService.class)
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@Sql(scripts = "/data/users.sql")
class UserServiceTest {

@Autowired
UserRepository userRepository;
@Autowired
RecipeRepository recipeRepository;
@Autowired
CommentRepository commentRepository;
@Autowired
RecipeLikeRepository recipeLikeRepository;
@Autowired
UserReportRepository userReportRepository;
@Autowired
UserService userService;
Expand Down Expand Up @@ -185,4 +191,50 @@ void getBlockedUserGroup() {
() -> assertThat(blockedUserGroup.isBlocked(4L)).isFalse()
);
}

@Test
@DisplayName("์‚ฌ์šฉ์ž๋ฅผ ์‚ญ์ œํ•œ๋‹ค.")
void deleteUser() {
UserInfo userInfo = new UserInfo(1L, "[email protected]");

userService.deleteUser(userInfo);

assertThat(userRepository.existsById(userInfo.getId())).isFalse();
}

@Test
@DisplayName("์‚ฌ์šฉ์ž๋ฅผ ์‚ญ์ œํ•˜๋ฉด ์‚ฌ์šฉ์ž๊ฐ€ ์ž‘์„ฑํ–ˆ๋˜ ๋ชจ๋“  ๊ฒŒ์‹œ๊ธ€๋„ ์ง€์šด๋‹ค.")
void deleteUserWithRecipes() {
UserInfo userInfo = new UserInfo(1L, "[email protected]");

userService.deleteUser(userInfo);
boolean deletedUserRecipes = recipeRepository.findAll().stream()
.noneMatch(recipe -> recipe.getAuthor().getId() == userInfo.getId());

assertThat(deletedUserRecipes).isTrue();
}

@Test
@DisplayName("์‚ฌ์šฉ์ž๋ฅผ ์‚ญ์ œํ•˜๋ฉด ์‚ฌ์šฉ์ž๊ฐ€ ์ž‘์„ฑํ–ˆ๋˜ ๋ชจ๋“  ๋Œ“๊ธ€๋„ ์ง€์šด๋‹ค.")
void deleteUserWithComments() {
UserInfo userInfo = new UserInfo(1L, "[email protected]");

userService.deleteUser(userInfo);
boolean deletedUserComments = commentRepository.findAll().stream()
.noneMatch(comment -> comment.getUser().getId() == userInfo.getId());

assertThat(deletedUserComments).isTrue();
}

@Test
@DisplayName("์‚ฌ์šฉ์ž๋ฅผ ์‚ญ์ œํ•˜๋ฉด ์‚ฌ์šฉ์ž๊ฐ€ ์ž‘์„ฑํ–ˆ๋˜ ๋ชจ๋“  ์ข‹์•„์š”๋„ ์ง€์šด๋‹ค.")
void deleteUserWithLikes() {
UserInfo userInfo = new UserInfo(1L, "[email protected]");

userService.deleteUser(userInfo);
boolean deletedUserLikes = recipeLikeRepository.findAll().stream()
.noneMatch(like -> like.getUser().getId() == userInfo.getId());

assertThat(deletedUserLikes).isTrue();
}
}
33 changes: 32 additions & 1 deletion backend/src/test/resources/data/users.sql
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,11 @@ ALTER TABLE ingredient_recipe ALTER COLUMN id RESTART;
TRUNCATE TABLE recipe_step;
ALTER TABLE recipe_step ALTER COLUMN id RESTART;

ALTER TABLE users ALTER COLUMN id RESTART WITH 1;
TRUNCATE TABLE comment;
ALTER TABLE comment ALTER COLUMN id RESTART;

TRUNCATE TABLE recipe_like;
ALTER TABLE recipe_like ALTER COLUMN id RESTART;

TRUNCATE TABLE user_block;
ALTER TABLE user_block ALTER COLUMN id RESTART WITH 1;
Expand Down Expand Up @@ -152,10 +156,37 @@ VALUES (1, 1, 'REQUIRED'), -- ๊น€์น˜๋ณถ์Œ๋ฐฅ
(17, 13, 'REQUIRED'), -- ๋ฒ ์ง€ํ„ฐ๋ธ” ์Šคํ”„
(18, 14, 'OPTIONAL'); -- ์นด๋ ˆ๋ผ์ด์Šค

INSERT INTO comment (user_id, recipe_id, message, created_at)
VALUES ('2', '1', 'great', '2024-01-01'),
('1', '1', 'thank you','2024-01-02'),
('1', '3', 'thank you','2024-01-02'),
('1', '4', 'thank you too','2024-01-02'),
('1', '5', 'thank you a lot','2024-01-02'),
('2', '2', 'good', '2024-05-05');

INSERT INTO recipe_like (recipe_id, user_id)
VALUES (1, 1),
(1, 2),
(1, 3),
(1, 4),
(1, 5),
(2, 3),
(2, 4),
(2, 5),
(2, 6),
(2, 7),
(4, 4),
(4, 1),
(4, 3),
(4, 6),
(4, 5),
(5, 1);

INSERT INTO recipe_step (recipe_id, image, description, sequence)
VALUES (1, '๋ ˆ์‹œํ”ผ1 ์„ค๋ช…1 ์ด๋ฏธ์ง€', '๋ ˆ์‹œํ”ผ1 ์„ค๋ช…1', 1),
(1, '๋ ˆ์‹œํ”ผ1 ์„ค๋ช…3 ์ด๋ฏธ์ง€', '๋ ˆ์‹œํ”ผ1 ์„ค๋ช…3', 3),
(1, '๋ ˆ์‹œํ”ผ1 ์„ค๋ช…2 ์ด๋ฏธ์ง€', '๋ ˆ์‹œํ”ผ1 ์„ค๋ช…2', 2);

INSERT INTO user_block (blocker_id, blockee_id)
VALUES (1, 2),
(1, 3)

0 comments on commit 54a18cb

Please sign in to comment.