feat: complete review workflow support
This commit is contained in:
@@ -1,7 +1,9 @@
|
||||
package com.guo.learningprogresstracker;
|
||||
|
||||
import cn.dev33.satoken.stp.StpUtil;
|
||||
import com.guo.learningprogresstracker.entity.TestTableEntity;
|
||||
import com.guo.learningprogresstracker.service.impl.TestTableServiceImpl;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
@@ -19,6 +21,11 @@ public class DataSourceTest {
|
||||
@Autowired
|
||||
TestTableServiceImpl testTableService;
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
StpUtil.login("1", "test_driver");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAdd(){
|
||||
TestTableEntity testTableEntity = new TestTableEntity();
|
||||
@@ -30,8 +37,12 @@ public class DataSourceTest {
|
||||
|
||||
@Test
|
||||
public void testDelete(){
|
||||
TestTableEntity testTableEntity = new TestTableEntity();
|
||||
testTableEntity.setIdName("guo_test_delete");
|
||||
testTableService.save(testTableEntity);
|
||||
|
||||
HashMap<String, Object> stringStringHashMap = new HashMap<>();
|
||||
stringStringHashMap.put("id_name", "guo_test");
|
||||
stringStringHashMap.put("id_name", "guo_test_delete");
|
||||
boolean delete = testTableService.removeByMap(stringStringHashMap);
|
||||
|
||||
assertTrue(delete,"删除idName为guo_test的数据失败");
|
||||
|
||||
@@ -18,8 +18,6 @@ import org.springframework.test.web.servlet.MockMvc;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete;
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
|
||||
@@ -45,12 +43,12 @@ class TaskControllerTest {
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
StpUtil.login("测试用户-创建任务", "test_driver");
|
||||
StpUtil.login("1", "test_driver");
|
||||
}
|
||||
|
||||
@Test
|
||||
void addTask() throws Exception {
|
||||
TaskRequest taskRequest = getTaskRequest();
|
||||
TaskRequest taskRequest = getTaskRequest("测试任务名称-" + System.nanoTime());
|
||||
log.info("testInfo");
|
||||
String s = jacksonObjectMapper.writeValueAsString(taskRequest);
|
||||
System.out.println("Token Value: " + StpUtil.getTokenValue());
|
||||
@@ -63,30 +61,16 @@ class TaskControllerTest {
|
||||
|
||||
}
|
||||
|
||||
private static TaskRequest getTaskRequest() {
|
||||
TaskRequest taskRequest = mock(TaskRequest.class);
|
||||
|
||||
when(taskRequest.getId()).thenReturn(null);
|
||||
// 设置学习任务的名称
|
||||
when(taskRequest.getTaskName()).thenReturn("测试任务名称");
|
||||
|
||||
// 设置学习材料的存储URL
|
||||
when(taskRequest.getMaterialUrl()).thenReturn("http://example.com/material");
|
||||
|
||||
// 设置用户设置的任务紧急性
|
||||
when(taskRequest.getUrgency()).thenReturn(5);
|
||||
|
||||
// 设置用户设置的任务重要性
|
||||
when(taskRequest.getImportance()).thenReturn(3);
|
||||
|
||||
// 设置任务的内容难度
|
||||
when(taskRequest.getContentDifficulty()).thenReturn(4);
|
||||
|
||||
// 设置任务的未来价值
|
||||
when(taskRequest.getFutureValue()).thenReturn(4);
|
||||
|
||||
// 设置用户对任务的主观优先级
|
||||
when(taskRequest.getSubjectivePriority()).thenReturn(1);
|
||||
private static TaskRequest getTaskRequest(String taskName) {
|
||||
TaskRequest taskRequest = new TaskRequest();
|
||||
taskRequest.setTaskName(taskName);
|
||||
taskRequest.setTaskDescription("测试任务描述");
|
||||
taskRequest.setMaterialUrl("http://example.com/material");
|
||||
taskRequest.setUrgency(5);
|
||||
taskRequest.setImportance(3);
|
||||
taskRequest.setContentDifficulty(4);
|
||||
taskRequest.setFutureValue(4);
|
||||
taskRequest.setSubjectivePriority(1);
|
||||
return taskRequest;
|
||||
}
|
||||
|
||||
@@ -108,10 +92,8 @@ class TaskControllerTest {
|
||||
@Test
|
||||
void updateTask() throws Exception {
|
||||
|
||||
TaskRequest taskRequest = mock(TaskRequest.class);
|
||||
when(taskRequest.getTaskName()).thenReturn("测试数据名称");
|
||||
when(taskRequest.getMaterialUrl()).thenReturn("http://example.com/material");
|
||||
when(taskRequest.getId()).thenReturn(1);
|
||||
TaskRequest taskRequest = getTaskRequest("测试数据名称");
|
||||
taskRequest.setId(1);
|
||||
String s = jacksonObjectMapper.writeValueAsString(taskRequest);
|
||||
|
||||
mockMvc.perform(put("/tasks/"+taskRequest.getId())
|
||||
@@ -126,9 +108,9 @@ class TaskControllerTest {
|
||||
|
||||
@Test
|
||||
void deleteTask() throws Exception {
|
||||
CommonResult commonResult = taskController.addTask(getTaskRequest());
|
||||
CommonResult commonResult = taskController.addTask(getTaskRequest("待删除任务-" + System.nanoTime()));
|
||||
assertEquals(commonResult.getCode(),200);
|
||||
TaskEntity taskEntity = tasksServiceImpl.getOne(Wrappers.<TaskEntity>lambdaQuery().eq(TaskEntity::getTaskNum, commonResult.getMessage()));
|
||||
TaskEntity taskEntity = tasksServiceImpl.getOne(Wrappers.<TaskEntity>lambdaQuery().eq(TaskEntity::getTaskNum, commonResult.getData()));
|
||||
assertNotNull(taskEntity,"未能找到新创建的任务实体");
|
||||
mockMvc.perform(delete("/tasks/"+taskEntity.getId())
|
||||
.header("satoken",StpUtil.getTokenValue()))
|
||||
@@ -145,4 +127,4 @@ class TaskControllerTest {
|
||||
.andExpect(jsonPath("$.code").value(200))
|
||||
.andExpect(jsonPath("$.data").exists());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+175
@@ -0,0 +1,175 @@
|
||||
package com.guo.learningprogresstracker.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.core.MybatisConfiguration;
|
||||
import com.baomidou.mybatisplus.core.metadata.TableInfoHelper;
|
||||
import com.guo.learningprogresstracker.dto.ReviewFeedItem;
|
||||
import com.guo.learningprogresstracker.dto.request.CreateReviewApplicationRequest;
|
||||
import com.guo.learningprogresstracker.dto.request.UpsertReviewMindMapRequest;
|
||||
import com.guo.learningprogresstracker.entity.ReviewApplicationEntity;
|
||||
import com.guo.learningprogresstracker.entity.ReviewMindMapEntity;
|
||||
import com.guo.learningprogresstracker.entity.StudyReportFragmentsEntity;
|
||||
import com.guo.learningprogresstracker.entity.StudyReportsEntity;
|
||||
import com.guo.learningprogresstracker.entity.StudySessionsEntity;
|
||||
import com.guo.learningprogresstracker.entity.TaskEntity;
|
||||
import com.guo.learningprogresstracker.enums.ReviewApplicationStatusEnum;
|
||||
import com.guo.learningprogresstracker.mapper.ReviewApplicationMapper;
|
||||
import com.guo.learningprogresstracker.mapper.ReviewMindMapMapper;
|
||||
import com.guo.learningprogresstracker.mapper.StudyReportFragmentsMapper;
|
||||
import com.guo.learningprogresstracker.mapper.StudyReportsMapper;
|
||||
import com.guo.learningprogresstracker.mapper.StudySessionsMapper;
|
||||
import com.guo.learningprogresstracker.mapper.TasksMapper;
|
||||
import org.apache.ibatis.builder.MapperBuilderAssistant;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
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.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
class ReviewServiceImplTest {
|
||||
|
||||
@BeforeAll
|
||||
static void initTableInfo() {
|
||||
MybatisConfiguration configuration = new MybatisConfiguration();
|
||||
TableInfoHelper.initTableInfo(new MapperBuilderAssistant(configuration, ""), StudyReportsEntity.class);
|
||||
TableInfoHelper.initTableInfo(new MapperBuilderAssistant(configuration, ""), StudyReportFragmentsEntity.class);
|
||||
TableInfoHelper.initTableInfo(new MapperBuilderAssistant(configuration, ""), StudySessionsEntity.class);
|
||||
TableInfoHelper.initTableInfo(new MapperBuilderAssistant(configuration, ""), TaskEntity.class);
|
||||
TableInfoHelper.initTableInfo(new MapperBuilderAssistant(configuration, ""), ReviewApplicationEntity.class);
|
||||
TableInfoHelper.initTableInfo(new MapperBuilderAssistant(configuration, ""), ReviewMindMapEntity.class);
|
||||
}
|
||||
|
||||
@InjectMocks
|
||||
private ReviewServiceImpl reviewService;
|
||||
|
||||
@Mock
|
||||
private StudyReportsMapper studyReportsMapper;
|
||||
|
||||
@Mock
|
||||
private StudyReportFragmentsMapper studyReportFragmentsMapper;
|
||||
|
||||
@Mock
|
||||
private StudySessionsMapper studySessionsMapper;
|
||||
|
||||
@Mock
|
||||
private TasksMapper tasksMapper;
|
||||
|
||||
@Mock
|
||||
private ReviewApplicationMapper reviewApplicationMapper;
|
||||
|
||||
@Mock
|
||||
private ReviewMindMapMapper reviewMindMapMapper;
|
||||
|
||||
@Test
|
||||
void getReviewFeed_shouldApplyFinalLimitAfterMerge() {
|
||||
StudyReportsEntity report = new StudyReportsEntity();
|
||||
report.setId(1);
|
||||
report.setSessionNum("S1");
|
||||
report.setContent("report");
|
||||
report.setCreatedTime(LocalDateTime.now());
|
||||
|
||||
StudyReportFragmentsEntity fragment = new StudyReportFragmentsEntity();
|
||||
fragment.setId(2);
|
||||
fragment.setSessionNum("S1");
|
||||
fragment.setContent("fragment");
|
||||
fragment.setCreatedTime(LocalDateTime.now().minusMinutes(1));
|
||||
|
||||
StudySessionsEntity session = new StudySessionsEntity();
|
||||
session.setSessionNum("S1");
|
||||
session.setTaskNum("T1");
|
||||
|
||||
TaskEntity task = new TaskEntity();
|
||||
task.setTaskNum("T1");
|
||||
task.setTaskName("Task");
|
||||
|
||||
when(studyReportsMapper.selectList(any())).thenReturn(List.of(report));
|
||||
when(studyReportFragmentsMapper.selectList(any())).thenReturn(List.of(fragment));
|
||||
when(studySessionsMapper.selectList(any())).thenReturn(List.of(session));
|
||||
when(tasksMapper.selectList(any())).thenReturn(List.of(task));
|
||||
|
||||
List<ReviewFeedItem> items = reviewService.getReviewFeed(1, "recent");
|
||||
|
||||
assertEquals(1, items.size());
|
||||
assertEquals("REPORT", items.get(0).getSourceType());
|
||||
assertEquals("Task", items.get(0).getTaskName());
|
||||
}
|
||||
|
||||
@Test
|
||||
void createApplication_shouldUseDefaultStatusWhenStatusInvalid() throws Exception {
|
||||
when(tasksMapper.exists(any())).thenReturn(true);
|
||||
when(reviewApplicationMapper.insert(any())).thenAnswer(invocation -> {
|
||||
ReviewApplicationEntity entity = invocation.getArgument(0);
|
||||
entity.setId(7);
|
||||
return 1;
|
||||
});
|
||||
|
||||
CreateReviewApplicationRequest request = new CreateReviewApplicationRequest();
|
||||
request.setTaskNum("T1");
|
||||
request.setTitle("Build a demo");
|
||||
request.setStatus("invalid");
|
||||
|
||||
ReviewApplicationEntity entity = reviewService.createApplication(request);
|
||||
|
||||
assertEquals(7, entity.getId());
|
||||
assertEquals(ReviewApplicationStatusEnum.TODO.getCode(), entity.getStatus());
|
||||
verify(reviewApplicationMapper).insert(any(ReviewApplicationEntity.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void upsertMindMap_shouldCreateWhenMissing() throws Exception {
|
||||
when(tasksMapper.exists(any())).thenReturn(true);
|
||||
when(reviewMindMapMapper.selectOne(any())).thenReturn(null);
|
||||
when(reviewMindMapMapper.insert(any())).thenAnswer(invocation -> {
|
||||
ReviewMindMapEntity entity = invocation.getArgument(0);
|
||||
entity.setId(3);
|
||||
return 1;
|
||||
});
|
||||
|
||||
UpsertReviewMindMapRequest request = new UpsertReviewMindMapRequest();
|
||||
request.setTitle("Map");
|
||||
request.setContent("root");
|
||||
request.setContentFormat("mermaid");
|
||||
|
||||
ReviewMindMapEntity entity = reviewService.upsertMindMap("T1", request);
|
||||
|
||||
assertNotNull(entity.getId());
|
||||
assertEquals("T1", entity.getTaskNum());
|
||||
assertEquals("MERMAID", entity.getContentFormat());
|
||||
verify(reviewMindMapMapper).insert(any(ReviewMindMapEntity.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void upsertMindMap_shouldUpdateExisting() throws Exception {
|
||||
ReviewMindMapEntity existing = new ReviewMindMapEntity();
|
||||
existing.setId(5);
|
||||
existing.setTaskNum("T1");
|
||||
existing.setTitle("Old");
|
||||
existing.setContent("old");
|
||||
existing.setContentFormat("TEXT");
|
||||
|
||||
when(tasksMapper.exists(any())).thenReturn(true);
|
||||
when(reviewMindMapMapper.selectOne(any())).thenReturn(existing);
|
||||
|
||||
UpsertReviewMindMapRequest request = new UpsertReviewMindMapRequest();
|
||||
request.setTitle("New");
|
||||
request.setContent("new");
|
||||
request.setContentFormat("json");
|
||||
|
||||
ReviewMindMapEntity entity = reviewService.upsertMindMap("T1", request);
|
||||
|
||||
assertEquals(5, entity.getId());
|
||||
assertEquals("New", entity.getTitle());
|
||||
assertEquals("JSON", entity.getContentFormat());
|
||||
verify(reviewMindMapMapper).updateById(existing);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
spring:
|
||||
datasource:
|
||||
driver-class-name: org.h2.Driver
|
||||
url: jdbc:h2:mem:lpt_test;MODE=MySQL;DATABASE_TO_LOWER=TRUE;CASE_INSENSITIVE_IDENTIFIERS=TRUE;NON_KEYWORDS=USER;DB_CLOSE_DELAY=-1
|
||||
username: sa
|
||||
password:
|
||||
flyway:
|
||||
enabled: true
|
||||
locations: classpath:db/migration
|
||||
baseline-on-migrate: true
|
||||
jackson:
|
||||
time-zone: UTC
|
||||
date-format: yyyy-MM-dd'T'HH:mm:ss'Z'
|
||||
|
||||
mybatis-plus:
|
||||
configuration:
|
||||
log-impl: org.apache.ibatis.logging.nologging.NoLoggingImpl
|
||||
|
||||
sa-token:
|
||||
token-name: satoken
|
||||
timeout: 2592000
|
||||
active-timeout: -1
|
||||
is-concurrent: true
|
||||
is-share: true
|
||||
token-style: uuid
|
||||
is-log: false
|
||||
@@ -0,0 +1,37 @@
|
||||
insert into user (id, user_name, user_password, created_time, deleted)
|
||||
values ('1', 'admin', '$2a$10$skdiSwut4R9pAvt2ZK5ct.6QNualPyJGiaxngFObdLrpAxRnzehBS', now(), 0);
|
||||
|
||||
insert into tasks (
|
||||
id,
|
||||
task_num,
|
||||
task_name,
|
||||
task_description,
|
||||
urgency,
|
||||
importance,
|
||||
content_difficulty,
|
||||
future_value,
|
||||
subjective_priority,
|
||||
calculated_priority,
|
||||
material_url,
|
||||
last_learning_status,
|
||||
created_by,
|
||||
created_time,
|
||||
deleted
|
||||
)
|
||||
values (
|
||||
1,
|
||||
'TASK_TEST',
|
||||
'测试任务名称',
|
||||
'测试任务描述',
|
||||
3,
|
||||
3,
|
||||
3,
|
||||
3,
|
||||
3,
|
||||
3,
|
||||
'http://example.com/material',
|
||||
'未开始',
|
||||
'1',
|
||||
now(),
|
||||
0
|
||||
);
|
||||
@@ -0,0 +1 @@
|
||||
mock-maker-subclass
|
||||
Reference in New Issue
Block a user