fix(interaction): 收藏计数同步维护并新增评论数接口
This commit is contained in:
1 parent
88794b816e
commit
65e8fbfc70
11 files changed
+382
-47
No files matched your search
+43
@@ -0,0 +1,43 @@
|
||||
// Author: fruit.com.cn
|
||||
|
||||
package com.fruitshorts.app.controller;
|
||||
|
||||
import com.fruitshorts.app.support.ControllerContractSupport;
|
||||
import com.fruitshorts.interaction.service.CommentService;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.test.web.servlet.MockMvc;
|
||||
|
||||
import static org.mockito.BDDMockito.given;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||
|
||||
/** 评论总数接口契约。 */
|
||||
class AppCommentControllerContractTest {
|
||||
|
||||
private CommentService commentService;
|
||||
private MockMvc mockMvc;
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
commentService = mock(CommentService.class);
|
||||
mockMvc = ControllerContractSupport.mockMvcOf(
|
||||
new AppCommentController(commentService));
|
||||
}
|
||||
|
||||
@Test
|
||||
void should_return_comment_count_as_string_when_requested() throws Exception {
|
||||
given(commentService.countByDrama(7L)).willReturn(9L);
|
||||
|
||||
mockMvc.perform(get("/app/comments/count").param("dramaId", "7"))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.code").value(0))
|
||||
.andExpect(jsonPath("$.data").value("9"))
|
||||
.andExpect(jsonPath("$.data").isString());
|
||||
|
||||
verify(commentService).countByDrama(7L);
|
||||
}
|
||||
}
|
||||
+57
@@ -0,0 +1,57 @@
|
||||
// Author: fruit.com.cn
|
||||
|
||||
package com.fruitshorts.app.service;
|
||||
|
||||
import com.baomidou.mybatisplus.core.MybatisConfiguration;
|
||||
import com.baomidou.mybatisplus.core.conditions.Wrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.TableInfoHelper;
|
||||
import com.fruitshorts.content.dal.entity.Drama;
|
||||
import com.fruitshorts.content.dal.mapper.DramaEpisodeMapper;
|
||||
import com.fruitshorts.content.dal.mapper.DramaMapper;
|
||||
import com.fruitshorts.content.dal.mapper.DramaReviewRecordMapper;
|
||||
import com.fruitshorts.content.service.DramaCategoryService;
|
||||
import com.fruitshorts.content.service.DramaService;
|
||||
import org.apache.ibatis.builder.MapperBuilderAssistant;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.isNull;
|
||||
import static org.mockito.BDDMockito.given;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
/** 收藏数减操作必须使用不低于 0 的原子 SQL。 */
|
||||
class DramaServiceFavoriteCountTest {
|
||||
|
||||
@BeforeAll
|
||||
static void initTableInfo() {
|
||||
TableInfoHelper.initTableInfo(
|
||||
new MapperBuilderAssistant(new MybatisConfiguration(), ""), Drama.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
void should_use_greatest_zero_when_favorite_count_decrements() {
|
||||
DramaMapper dramaMapper = mock(DramaMapper.class);
|
||||
DramaService dramaService = new DramaService(
|
||||
dramaMapper,
|
||||
mock(DramaEpisodeMapper.class),
|
||||
mock(DramaReviewRecordMapper.class),
|
||||
mock(DramaCategoryService.class));
|
||||
given(dramaMapper.update(isNull(), any())).willReturn(1);
|
||||
ArgumentCaptor<Wrapper<Drama>> captor = ArgumentCaptor.forClass(Wrapper.class);
|
||||
|
||||
dramaService.adjustFavoriteCount(7L, -1);
|
||||
|
||||
verify(dramaMapper).update(isNull(), captor.capture());
|
||||
Wrapper<Drama> wrapper = captor.getValue();
|
||||
LambdaUpdateWrapper<Drama> update = (LambdaUpdateWrapper<Drama>) wrapper;
|
||||
assertThat(update.getSqlSet())
|
||||
.contains("GREATEST(favorite_count - 1, 0)");
|
||||
assertThat(update.getSqlSegment()).contains("id");
|
||||
}
|
||||
}
|
||||
+80
@@ -0,0 +1,80 @@
|
||||
// Author: fruit.com.cn
|
||||
|
||||
package com.fruitshorts.playback.service;
|
||||
|
||||
import com.fruitshorts.content.service.DramaService;
|
||||
import com.fruitshorts.playback.dal.entity.UserFavorite;
|
||||
import com.fruitshorts.playback.dal.mapper.UserFavoriteMapper;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.BDDMockito.given;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
/** 收藏关系变化时同步维护短剧收藏数。 */
|
||||
class FavoriteServiceTest {
|
||||
|
||||
private UserFavoriteMapper favoriteMapper;
|
||||
private DramaService dramaService;
|
||||
private FavoriteService favoriteService;
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
favoriteMapper = mock(UserFavoriteMapper.class);
|
||||
dramaService = mock(DramaService.class);
|
||||
favoriteService = new FavoriteService(favoriteMapper, dramaService);
|
||||
}
|
||||
|
||||
@Test
|
||||
void should_increment_favorite_count_when_new_favorite_is_created() {
|
||||
given(favoriteMapper.selectOne(any())).willReturn(null);
|
||||
given(favoriteMapper.insert(any(UserFavorite.class))).willReturn(1);
|
||||
|
||||
boolean favorite = favoriteService.toggle(1L, 7L);
|
||||
|
||||
assertThat(favorite).isTrue();
|
||||
verify(dramaService).adjustFavoriteCount(7L, 1);
|
||||
}
|
||||
|
||||
@Test
|
||||
void should_decrement_favorite_count_when_toggle_removes_relation() {
|
||||
given(favoriteMapper.selectOne(any())).willReturn(new UserFavorite());
|
||||
given(favoriteMapper.physicalDelete(1L, 7L)).willReturn(1);
|
||||
|
||||
boolean favorite = favoriteService.toggle(1L, 7L);
|
||||
|
||||
assertThat(favorite).isFalse();
|
||||
verify(dramaService).adjustFavoriteCount(7L, -1);
|
||||
}
|
||||
|
||||
@Test
|
||||
void should_only_decrement_when_remove_actually_deletes_relation() {
|
||||
given(favoriteMapper.physicalDelete(1L, 7L)).willReturn(1);
|
||||
given(favoriteMapper.physicalDelete(1L, 8L)).willReturn(0);
|
||||
|
||||
favoriteService.remove(1L, 7L);
|
||||
favoriteService.remove(1L, 8L);
|
||||
|
||||
verify(dramaService).adjustFavoriteCount(7L, -1);
|
||||
verify(dramaService, never()).adjustFavoriteCount(8L, -1);
|
||||
}
|
||||
|
||||
@Test
|
||||
void should_decrement_each_deleted_drama_when_batch_remove_is_called() {
|
||||
given(favoriteMapper.physicalDelete(1L, 7L)).willReturn(1);
|
||||
given(favoriteMapper.physicalDelete(1L, 8L)).willReturn(0);
|
||||
given(favoriteMapper.physicalDelete(1L, 9L)).willReturn(1);
|
||||
|
||||
favoriteService.removeBatch(1L, Arrays.asList(7L, 8L, 9L, null));
|
||||
|
||||
verify(dramaService).adjustFavoriteCount(7L, -1);
|
||||
verify(dramaService, never()).adjustFavoriteCount(8L, -1);
|
||||
verify(dramaService).adjustFavoriteCount(9L, -1);
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user