Handle point history cleanup when deleting posts

This commit is contained in:
Tim
2025-09-17 12:29:09 +08:00
parent b28e8d4bc9
commit 28e3ebb911
3 changed files with 115 additions and 10 deletions

View File

@@ -10,8 +10,11 @@ import org.springframework.data.redis.core.RedisTemplate;
import static org.junit.jupiter.api.Assertions.*;
import java.util.Optional;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Optional;
import org.mockito.ArgumentCaptor;
import static org.mockito.Mockito.*;
@@ -39,12 +42,14 @@ class PostServiceTest {
ApplicationContext context = mock(ApplicationContext.class);
PointService pointService = mock(PointService.class);
PostChangeLogService postChangeLogService = mock(PostChangeLogService.class);
PointHistoryRepository pointHistoryRepository = mock(PointHistoryRepository.class);
RedisTemplate redisTemplate = mock(RedisTemplate.class);
PostService service = new PostService(postRepo, userRepo, catRepo, tagRepo, lotteryRepo,
pollPostRepo, pollVoteRepo, notifService, subService, commentService, commentRepo,
reactionRepo, subRepo, notificationRepo, postReadService,
imageUploader, taskScheduler, emailSender, context, pointService, postChangeLogService, PublishMode.DIRECT, redisTemplate);
imageUploader, taskScheduler, emailSender, context, pointService, postChangeLogService,
pointHistoryRepository, PublishMode.DIRECT, redisTemplate);
when(context.getBean(PostService.class)).thenReturn(service);
Post post = new Post();
@@ -60,6 +65,7 @@ class PostServiceTest {
when(reactionRepo.findByPost(post)).thenReturn(List.of());
when(subRepo.findByPost(post)).thenReturn(List.of());
when(notificationRepo.findByPost(post)).thenReturn(List.of());
when(pointHistoryRepository.findByPost(post)).thenReturn(List.of());
service.deletePost(1L, "alice");
@@ -90,12 +96,14 @@ class PostServiceTest {
ApplicationContext context = mock(ApplicationContext.class);
PointService pointService = mock(PointService.class);
PostChangeLogService postChangeLogService = mock(PostChangeLogService.class);
PointHistoryRepository pointHistoryRepository = mock(PointHistoryRepository.class);
RedisTemplate redisTemplate = mock(RedisTemplate.class);
PostService service = new PostService(postRepo, userRepo, catRepo, tagRepo, lotteryRepo,
pollPostRepo, pollVoteRepo, notifService, subService, commentService, commentRepo,
reactionRepo, subRepo, notificationRepo, postReadService,
imageUploader, taskScheduler, emailSender, context, pointService, postChangeLogService, PublishMode.DIRECT, redisTemplate);
imageUploader, taskScheduler, emailSender, context, pointService, postChangeLogService,
pointHistoryRepository, PublishMode.DIRECT, redisTemplate);
when(context.getBean(PostService.class)).thenReturn(service);
Post post = new Post();
@@ -117,6 +125,7 @@ class PostServiceTest {
when(reactionRepo.findByPost(post)).thenReturn(List.of());
when(subRepo.findByPost(post)).thenReturn(List.of());
when(notificationRepo.findByPost(post)).thenReturn(List.of());
when(pointHistoryRepository.findByPost(post)).thenReturn(List.of());
service.deletePost(1L, "admin");
@@ -147,12 +156,14 @@ class PostServiceTest {
ApplicationContext context = mock(ApplicationContext.class);
PointService pointService = mock(PointService.class);
PostChangeLogService postChangeLogService = mock(PostChangeLogService.class);
PointHistoryRepository pointHistoryRepository = mock(PointHistoryRepository.class);
RedisTemplate redisTemplate = mock(RedisTemplate.class);
PostService service = new PostService(postRepo, userRepo, catRepo, tagRepo, lotteryRepo,
pollPostRepo, pollVoteRepo, notifService, subService, commentService, commentRepo,
reactionRepo, subRepo, notificationRepo, postReadService,
imageUploader, taskScheduler, emailSender, context, pointService, postChangeLogService, PublishMode.DIRECT, redisTemplate);
imageUploader, taskScheduler, emailSender, context, pointService, postChangeLogService,
pointHistoryRepository, PublishMode.DIRECT, redisTemplate);
when(context.getBean(PostService.class)).thenReturn(service);
when(postRepo.countByAuthorAfter(eq("alice"), any())).thenReturn(1L);
@@ -162,6 +173,77 @@ class PostServiceTest {
null, null, null, null, null, null, null, null, null));
}
@Test
void deletePostRemovesPointHistoriesAndRecalculatesPoints() {
PostRepository postRepo = mock(PostRepository.class);
UserRepository userRepo = mock(UserRepository.class);
CategoryRepository catRepo = mock(CategoryRepository.class);
TagRepository tagRepo = mock(TagRepository.class);
LotteryPostRepository lotteryRepo = mock(LotteryPostRepository.class);
PollPostRepository pollPostRepo = mock(PollPostRepository.class);
PollVoteRepository pollVoteRepo = mock(PollVoteRepository.class);
NotificationService notifService = mock(NotificationService.class);
SubscriptionService subService = mock(SubscriptionService.class);
CommentService commentService = mock(CommentService.class);
CommentRepository commentRepo = mock(CommentRepository.class);
ReactionRepository reactionRepo = mock(ReactionRepository.class);
PostSubscriptionRepository subRepo = mock(PostSubscriptionRepository.class);
NotificationRepository notificationRepo = mock(NotificationRepository.class);
PostReadService postReadService = mock(PostReadService.class);
ImageUploader imageUploader = mock(ImageUploader.class);
TaskScheduler taskScheduler = mock(TaskScheduler.class);
EmailSender emailSender = mock(EmailSender.class);
ApplicationContext context = mock(ApplicationContext.class);
PointService pointService = mock(PointService.class);
PostChangeLogService postChangeLogService = mock(PostChangeLogService.class);
PointHistoryRepository pointHistoryRepository = mock(PointHistoryRepository.class);
RedisTemplate redisTemplate = mock(RedisTemplate.class);
PostService service = new PostService(postRepo, userRepo, catRepo, tagRepo, lotteryRepo,
pollPostRepo, pollVoteRepo, notifService, subService, commentService, commentRepo,
reactionRepo, subRepo, notificationRepo, postReadService,
imageUploader, taskScheduler, emailSender, context, pointService, postChangeLogService,
pointHistoryRepository, PublishMode.DIRECT, redisTemplate);
when(context.getBean(PostService.class)).thenReturn(service);
Post post = new Post();
post.setId(10L);
User author = new User();
author.setId(20L);
author.setRole(Role.USER);
post.setAuthor(author);
User historyUser = new User();
historyUser.setId(30L);
PointHistory history = new PointHistory();
history.setUser(historyUser);
history.setPost(post);
when(postRepo.findById(10L)).thenReturn(Optional.of(post));
when(userRepo.findByUsername("author")).thenReturn(Optional.of(author));
when(commentRepo.findByPostAndParentIsNullOrderByCreatedAtAsc(post)).thenReturn(List.of());
when(reactionRepo.findByPost(post)).thenReturn(List.of());
when(subRepo.findByPost(post)).thenReturn(List.of());
when(notificationRepo.findByPost(post)).thenReturn(List.of());
when(pointHistoryRepository.findByPost(post)).thenReturn(List.of(history));
when(pointService.recalculateUserPoints(historyUser)).thenReturn(0);
service.deletePost(10L, "author");
ArgumentCaptor<List<PointHistory>> captor = ArgumentCaptor.forClass(List.class);
verify(pointHistoryRepository).saveAll(captor.capture());
List<PointHistory> savedHistories = captor.getValue();
assertEquals(1, savedHistories.size());
PointHistory savedHistory = savedHistories.get(0);
assertNull(savedHistory.getPost());
assertNotNull(savedHistory.getDeletedAt());
assertTrue(savedHistory.getDeletedAt().isBefore(LocalDateTime.now().plusSeconds(1)));
verify(pointService).recalculateUserPoints(historyUser);
verify(userRepo).saveAll(any());
}
@Test
void finalizeLotteryNotifiesAuthor() {
PostRepository postRepo = mock(PostRepository.class);