mirror of
https://codeup.aliyun.com/67c68d4e484ca2f0a13ac3c1/ydc/jsowell-charger-web.git
synced 2026-07-18 21:18:01 +08:00
新增当前用户待办接口和权限测试
This commit is contained in:
@@ -0,0 +1,118 @@
|
||||
package com.jsowell.web.controller.system;
|
||||
|
||||
import com.jsowell.common.annotation.Log;
|
||||
import com.jsowell.common.core.controller.BaseController;
|
||||
import com.jsowell.common.core.domain.AjaxResult;
|
||||
import com.jsowell.common.core.page.TableDataInfo;
|
||||
import com.jsowell.common.enums.BusinessType;
|
||||
import com.jsowell.system.domain.SysTodoTask;
|
||||
import com.jsowell.system.domain.dto.TodoTaskCancelRequest;
|
||||
import com.jsowell.system.domain.dto.TodoTaskQuery;
|
||||
import com.jsowell.system.service.TodoTaskService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PutMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 当前登录用户待办任务接口。
|
||||
*
|
||||
* @author jsowell
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/system/todo")
|
||||
public class SysTodoTaskController extends BaseController {
|
||||
@Autowired
|
||||
private TodoTaskService todoTaskService;
|
||||
|
||||
/**
|
||||
* 获取当前用户待办数量。
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('system:todo:list')")
|
||||
@GetMapping("/unreadCount")
|
||||
public AjaxResult unreadCount() {
|
||||
Long userId = getUserId();
|
||||
Map<String, Integer> counts = new HashMap<>(2);
|
||||
counts.put("activeCount", todoTaskService.countActive(userId));
|
||||
counts.put("unreadCount", todoTaskService.countUnread(userId));
|
||||
return AjaxResult.success(counts);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取首页最近待办。
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('system:todo:list')")
|
||||
@GetMapping("/homeList")
|
||||
public AjaxResult homeList(@RequestParam(required = false) Integer limit) {
|
||||
return AjaxResult.success(todoTaskService.homeList(getUserId(), limit));
|
||||
}
|
||||
|
||||
/**
|
||||
* 分页查询当前用户待办。
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('system:todo:list')")
|
||||
@GetMapping("/list")
|
||||
public TableDataInfo list(TodoTaskQuery query) {
|
||||
startPage();
|
||||
List<SysTodoTask> list = todoTaskService.listForAssignee(query, getUserId());
|
||||
return getDataTable(list);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询当前用户待办详情。
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('system:todo:query')")
|
||||
@GetMapping("/{todoId}")
|
||||
public AjaxResult getInfo(@PathVariable Long todoId) {
|
||||
return AjaxResult.success(todoTaskService.getForAssignee(todoId, getUserId()));
|
||||
}
|
||||
|
||||
/**
|
||||
* 标记当前用户的一条待办为已读。
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('system:todo:read')")
|
||||
@PutMapping("/{todoId}/read")
|
||||
public AjaxResult markRead(@PathVariable Long todoId) {
|
||||
return toAjax(todoTaskService.markRead(todoId, getUserId(), getUsername()));
|
||||
}
|
||||
|
||||
/**
|
||||
* 标记当前用户全部待办为已读。
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('system:todo:read')")
|
||||
@PutMapping("/readAll")
|
||||
public AjaxResult markAllRead() {
|
||||
return AjaxResult.success(todoTaskService.markAllRead(getUserId(), getUsername()));
|
||||
}
|
||||
|
||||
/**
|
||||
* 完成当前用户待办。
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('system:todo:complete')")
|
||||
@Log(title = "待办任务", businessType = BusinessType.UPDATE)
|
||||
@PutMapping("/{todoId}/complete")
|
||||
public AjaxResult complete(@PathVariable Long todoId) {
|
||||
return toAjax(todoTaskService.complete(todoId, getUserId(), getUsername()));
|
||||
}
|
||||
|
||||
/**
|
||||
* 取消当前用户待办。
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('system:todo:cancel')")
|
||||
@Log(title = "待办任务", businessType = BusinessType.UPDATE)
|
||||
@PutMapping("/{todoId}/cancel")
|
||||
public AjaxResult cancel(@PathVariable Long todoId,
|
||||
@Validated @RequestBody TodoTaskCancelRequest request) {
|
||||
return toAjax(todoTaskService.cancelForAssignee(todoId, getUserId(), getUsername(), request.getReason()));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,149 @@
|
||||
package com.jsowell.system.service;
|
||||
|
||||
import com.jsowell.common.exception.ServiceException;
|
||||
import com.jsowell.system.constant.TodoTaskConstants;
|
||||
import com.jsowell.system.domain.SysTodoTask;
|
||||
import com.jsowell.system.domain.dto.TodoTaskCreateCommand;
|
||||
import com.jsowell.system.domain.dto.TodoTaskQuery;
|
||||
import com.jsowell.system.mapper.SysTodoTaskMapper;
|
||||
import com.jsowell.system.service.impl.TodoTaskServiceImpl;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.springframework.dao.DuplicateKeyException;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.Collections;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertSame;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.doAnswer;
|
||||
import static org.mockito.Mockito.doThrow;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
class TodoTaskServiceImplTest {
|
||||
@Test
|
||||
void createTask_shouldSetDefaultsAndInsert() {
|
||||
SysTodoTaskMapper mapper = mock(SysTodoTaskMapper.class);
|
||||
TodoTaskServiceImpl service = newService(mapper);
|
||||
TodoTaskCreateCommand command = createCommand();
|
||||
when(mapper.selectActiveByIdempotentKey("INVOICE:100:8")).thenReturn(null);
|
||||
doAnswer(invocation -> {
|
||||
SysTodoTask task = invocation.getArgument(0);
|
||||
task.setTodoId(11L);
|
||||
return 1;
|
||||
}).when(mapper).insertTodoTask(any(SysTodoTask.class));
|
||||
|
||||
SysTodoTask result = service.createTask(command);
|
||||
|
||||
ArgumentCaptor<SysTodoTask> captor = ArgumentCaptor.forClass(SysTodoTask.class);
|
||||
verify(mapper).insertTodoTask(captor.capture());
|
||||
SysTodoTask inserted = captor.getValue();
|
||||
assertEquals(11L, result.getTodoId());
|
||||
assertEquals(TodoTaskConstants.PRIORITY_NORMAL, inserted.getPriority());
|
||||
assertEquals(TodoTaskConstants.STATUS_PENDING, inserted.getTaskStatus());
|
||||
assertEquals(TodoTaskConstants.READ_UNREAD, inserted.getReadStatus());
|
||||
assertEquals(inserted.getIdempotentKey(), inserted.getActiveIdempotentKey());
|
||||
}
|
||||
|
||||
@Test
|
||||
void createTask_shouldReturnExistingTask() {
|
||||
SysTodoTaskMapper mapper = mock(SysTodoTaskMapper.class);
|
||||
TodoTaskServiceImpl service = newService(mapper);
|
||||
SysTodoTask existing = new SysTodoTask();
|
||||
existing.setTodoId(12L);
|
||||
when(mapper.selectActiveByIdempotentKey("INVOICE:100:8")).thenReturn(existing);
|
||||
|
||||
SysTodoTask result = service.createTask(createCommand());
|
||||
|
||||
assertSame(existing, result);
|
||||
verify(mapper, never()).insertTodoTask(any(SysTodoTask.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void createTask_shouldRecoverFromConcurrentDuplicate() {
|
||||
SysTodoTaskMapper mapper = mock(SysTodoTaskMapper.class);
|
||||
TodoTaskServiceImpl service = newService(mapper);
|
||||
SysTodoTask existing = new SysTodoTask();
|
||||
existing.setTodoId(13L);
|
||||
when(mapper.selectActiveByIdempotentKey("INVOICE:100:8")).thenReturn(null, existing);
|
||||
doThrow(new DuplicateKeyException("duplicate"))
|
||||
.when(mapper).insertTodoTask(any(SysTodoTask.class));
|
||||
|
||||
SysTodoTask result = service.createTask(createCommand());
|
||||
|
||||
assertSame(existing, result);
|
||||
}
|
||||
|
||||
@Test
|
||||
void listForAssignee_shouldOverrideRequestedUser() {
|
||||
SysTodoTaskMapper mapper = mock(SysTodoTaskMapper.class);
|
||||
TodoTaskServiceImpl service = newService(mapper);
|
||||
TodoTaskQuery query = new TodoTaskQuery();
|
||||
query.setAssigneeUserId(999L);
|
||||
when(mapper.selectTodoList(query)).thenReturn(Collections.emptyList());
|
||||
|
||||
service.listForAssignee(query, 8L);
|
||||
|
||||
assertEquals(8L, query.getAssigneeUserId());
|
||||
verify(mapper).selectTodoList(query);
|
||||
}
|
||||
|
||||
@Test
|
||||
void complete_shouldBeIdempotentWhenAlreadyCompleted() {
|
||||
SysTodoTaskMapper mapper = mock(SysTodoTaskMapper.class);
|
||||
TodoTaskServiceImpl service = newService(mapper);
|
||||
SysTodoTask completed = new SysTodoTask();
|
||||
completed.setTaskStatus(TodoTaskConstants.STATUS_COMPLETED);
|
||||
when(mapper.completeTodoForAssignee(20L, 8L, 8L, "tester")).thenReturn(0);
|
||||
when(mapper.selectTodoByIdForAssignee(20L, 8L)).thenReturn(completed);
|
||||
|
||||
assertTrue(service.complete(20L, 8L, "tester"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void complete_shouldRejectCancelledTask() {
|
||||
SysTodoTaskMapper mapper = mock(SysTodoTaskMapper.class);
|
||||
TodoTaskServiceImpl service = newService(mapper);
|
||||
SysTodoTask cancelled = new SysTodoTask();
|
||||
cancelled.setTaskStatus(TodoTaskConstants.STATUS_CANCELLED);
|
||||
when(mapper.completeTodoForAssignee(20L, 8L, 8L, "tester")).thenReturn(0);
|
||||
when(mapper.selectTodoByIdForAssignee(20L, 8L)).thenReturn(cancelled);
|
||||
|
||||
assertThrows(ServiceException.class, () -> service.complete(20L, 8L, "tester"));
|
||||
}
|
||||
|
||||
private static TodoTaskCreateCommand createCommand() {
|
||||
return TodoTaskCreateCommand.builder()
|
||||
.taskType("INVOICE_REVIEW")
|
||||
.title("司机开票申请")
|
||||
.businessType("INVOICE_APPLY")
|
||||
.businessId("100")
|
||||
.routeName("InvoiceApplyDetail")
|
||||
.assigneeUserId(8L)
|
||||
.idempotentKey("INVOICE:100:8")
|
||||
.createBy("tester")
|
||||
.build();
|
||||
}
|
||||
|
||||
private static TodoTaskServiceImpl newService(SysTodoTaskMapper mapper) {
|
||||
TodoTaskServiceImpl service = new TodoTaskServiceImpl();
|
||||
setField(service, "todoTaskMapper", mapper);
|
||||
return service;
|
||||
}
|
||||
|
||||
private static void setField(Object target, String fieldName, Object value) {
|
||||
try {
|
||||
Field field = target.getClass().getDeclaredField(fieldName);
|
||||
field.setAccessible(true);
|
||||
field.set(target, value);
|
||||
} catch (Exception exception) {
|
||||
throw new RuntimeException(exception);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
package com.jsowell.web.controller.system;
|
||||
|
||||
import com.jsowell.common.core.domain.AjaxResult;
|
||||
import com.jsowell.system.domain.SysTodoTask;
|
||||
import com.jsowell.system.service.TodoTaskService;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertSame;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
class SysTodoTaskControllerTest {
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
void unreadCount_shouldUseCurrentLoginUser() {
|
||||
TodoTaskService service = mock(TodoTaskService.class);
|
||||
TestController controller = newController(service, 8L, "tester");
|
||||
when(service.countActive(8L)).thenReturn(5);
|
||||
when(service.countUnread(8L)).thenReturn(3);
|
||||
|
||||
AjaxResult result = controller.unreadCount();
|
||||
|
||||
Map<String, Integer> data = (Map<String, Integer>) result.get(AjaxResult.DATA_TAG);
|
||||
assertEquals(5, data.get("activeCount"));
|
||||
assertEquals(3, data.get("unreadCount"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void getInfo_shouldNotAcceptAnotherAssignee() {
|
||||
TodoTaskService service = mock(TodoTaskService.class);
|
||||
TestController controller = newController(service, 8L, "tester");
|
||||
SysTodoTask task = new SysTodoTask();
|
||||
task.setTodoId(20L);
|
||||
when(service.getForAssignee(20L, 8L)).thenReturn(task);
|
||||
|
||||
AjaxResult result = controller.getInfo(20L);
|
||||
|
||||
assertSame(task, result.get(AjaxResult.DATA_TAG));
|
||||
verify(service).getForAssignee(20L, 8L);
|
||||
}
|
||||
|
||||
@Test
|
||||
void complete_shouldPassCurrentUserAndOperator() {
|
||||
TodoTaskService service = mock(TodoTaskService.class);
|
||||
TestController controller = newController(service, 8L, "tester");
|
||||
when(service.complete(20L, 8L, "tester")).thenReturn(true);
|
||||
|
||||
controller.complete(20L);
|
||||
|
||||
verify(service).complete(20L, 8L, "tester");
|
||||
}
|
||||
|
||||
private static TestController newController(TodoTaskService service, Long userId, String username) {
|
||||
TestController controller = new TestController(userId, username);
|
||||
setField(controller, "todoTaskService", service);
|
||||
return controller;
|
||||
}
|
||||
|
||||
private static void setField(Object target, String fieldName, Object value) {
|
||||
try {
|
||||
Field field = SysTodoTaskController.class.getDeclaredField(fieldName);
|
||||
field.setAccessible(true);
|
||||
field.set(target, value);
|
||||
} catch (Exception exception) {
|
||||
throw new RuntimeException(exception);
|
||||
}
|
||||
}
|
||||
|
||||
private static class TestController extends SysTodoTaskController {
|
||||
private final Long userId;
|
||||
private final String username;
|
||||
|
||||
private TestController(Long userId, String username) {
|
||||
this.userId = userId;
|
||||
this.username = username;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long getUserId() {
|
||||
return userId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUsername() {
|
||||
return username;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user