package com.vincent.rsf.server.system.controller;
|
|
import com.baomidou.mybatisplus.core.conditions.Wrapper;
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
import com.vincent.rsf.framework.common.R;
|
import com.vincent.rsf.server.common.domain.BaseParam;
|
import com.vincent.rsf.server.common.service.ListExportService;
|
import com.vincent.rsf.server.system.entity.Role;
|
import com.vincent.rsf.server.system.service.RoleMenuService;
|
import com.vincent.rsf.server.system.service.RoleService;
|
import jakarta.servlet.ServletOutputStream;
|
import jakarta.servlet.http.HttpServletResponse;
|
import org.apache.poi.ss.usermodel.Sheet;
|
import org.apache.poi.ss.usermodel.Workbook;
|
import org.apache.poi.ss.usermodel.WorkbookFactory;
|
import org.junit.jupiter.api.BeforeEach;
|
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.extension.ExtendWith;
|
import org.mockito.Mock;
|
import org.mockito.junit.jupiter.MockitoExtension;
|
import org.springframework.test.util.ReflectionTestUtils;
|
|
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayInputStream;
|
import java.util.HashMap;
|
import java.util.List;
|
import java.util.Map;
|
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertAll;
|
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
import static org.mockito.ArgumentMatchers.any;
|
import static org.mockito.Mockito.never;
|
import static org.mockito.Mockito.lenient;
|
import static org.mockito.Mockito.verify;
|
import static org.mockito.Mockito.when;
|
import static org.mockito.Mockito.doReturn;
|
|
@ExtendWith(MockitoExtension.class)
|
class RoleControllerTest {
|
|
@Mock
|
private RoleService roleService;
|
@Mock
|
private RoleMenuService roleMenuService;
|
@Mock
|
private HttpServletResponse response;
|
|
private RoleController roleController;
|
private ListExportService listExportService;
|
private ByteArrayOutputStream exportBuffer;
|
|
@BeforeEach
|
void setUp() throws Exception {
|
roleController = new TestableRoleController();
|
ReflectionTestUtils.setField(roleController, "roleService", roleService);
|
ReflectionTestUtils.setField(roleController, "roleMenuService", roleMenuService);
|
listExportService = new ListExportService();
|
ReflectionTestUtils.setField(roleController, "listExportService", listExportService);
|
exportBuffer = new ByteArrayOutputStream();
|
lenient().doReturn(new ServletOutputStream() {
|
@Override
|
public void write(int b) {
|
exportBuffer.write(b);
|
}
|
|
@Override
|
public boolean isReady() {
|
return true;
|
}
|
|
@Override
|
public void setWriteListener(jakarta.servlet.WriteListener writeListener) {
|
}
|
}).when(response).getOutputStream();
|
}
|
|
@Test
|
void exportPrefersSelectedIdsEvenWhenFiltersArePresent() throws Exception {
|
|
Role role = role(1L, "管理员", "ADMIN", 1, "系统角色");
|
Map<String, Object> body = new HashMap<>();
|
body.put("ids", List.of(1L, 2L));
|
body.put("name", "管理员");
|
body.put("current", 1);
|
body.put("pageSize", 20);
|
body.put("meta", Map.of(
|
"reportTitle", "角色管理报表",
|
"columns", List.of(
|
Map.of("source", "name", "label", "角色名称"),
|
Map.of("source", "statusText", "label", "状态"),
|
Map.of("source", "memo", "label", "备注")
|
)
|
));
|
|
when(roleService.listByIds(List.of(1L, 2L))).thenReturn(List.of(role));
|
|
roleController.export(body, response);
|
|
verify(roleService).listByIds(List.of(1L, 2L));
|
verify(roleService, never()).list(anyWrapper());
|
assertExportSheet(
|
exportBuffer.toByteArray(),
|
List.of("序号", "角色名称", "状态", "备注"),
|
List.of("1", "管理员", "正常", "系统角色")
|
);
|
}
|
|
@Test
|
void pageStillAcceptsFlatPrintQueryWithoutFilterFields() {
|
Map<String, Object> body = new HashMap<>();
|
body.put("current", 1);
|
body.put("pageSize", 200);
|
|
when(roleService.page(any(), any())).thenReturn(new Page<>());
|
|
R result = roleController.page(body);
|
|
assertNotNull(result);
|
verify(roleService).page(any(), any());
|
}
|
|
@Test
|
void exportUsesFilteredRoleListWhenIdsMissing() throws Exception {
|
|
Role role = role(1L, "管理员", "ADMIN", 1, "系统角色");
|
Map<String, Object> body = new HashMap<>();
|
body.put("name", "管理员");
|
body.put("current", 1);
|
body.put("pageSize", 200);
|
body.put("meta", Map.of(
|
"reportTitle", "角色管理报表",
|
"columns", List.of(
|
Map.of("source", "name", "label", "角色名称"),
|
Map.of("source", "statusText", "label", "状态")
|
)
|
));
|
|
when(roleService.list(anyWrapper())).thenReturn(List.of(role));
|
|
roleController.export(body, response);
|
|
verify(roleService).list(anyWrapper());
|
verify(roleService, never()).listByIds(any());
|
}
|
|
@Test
|
void exportInsertsSequenceHeaderFromReportStyleWhenSequenceColumnIsNotRequested() throws Exception {
|
Role role = role(1L, "管理员", "ADMIN", 1, "系统角色");
|
List<Map<String, Object>> requestedColumns = List.of(
|
Map.of("source", "name", "label", "角色名称"),
|
Map.of("source", "statusText", "label", "状态")
|
);
|
Map<String, Object> body = new HashMap<>();
|
body.put("ids", List.of(1L));
|
body.put("meta", Map.of(
|
"reportTitle", "角色管理报表",
|
"reportDate", "2026-03-29",
|
"columns", requestedColumns,
|
"reportStyle", Map.of(
|
"showSequence", true
|
)
|
));
|
|
when(roleService.listByIds(List.of(1L))).thenReturn(List.of(role));
|
|
roleController.export(body, response);
|
|
try (Workbook workbook = WorkbookFactory.create(new ByteArrayInputStream(exportBuffer.toByteArray()))) {
|
Sheet sheet = workbook.getSheetAt(0);
|
assertEquals("角色管理报表", sheet.getRow(0).getCell(0).getStringCellValue());
|
assertTrue(sheet.getRow(1).getCell(0).getStringCellValue().startsWith("报表日期:"));
|
assertAll("showSequence generated column",
|
() -> assertEquals("序号", sheet.getRow(3).getCell(0).getStringCellValue(),
|
"showSequence=true should prepend a generated 序号 column even when request columns omit it."),
|
() -> assertEquals("1", sheet.getRow(4).getCell(0).getStringCellValue(),
|
"showSequence=true should generate the first sequence cell as 1 in the exported data row.")
|
);
|
assertEquals("角色名称", sheet.getRow(3).getCell(1).getStringCellValue(),
|
"Generated 序号 column should shift requested columns to the right.");
|
}
|
}
|
|
private void assertExportSheet(byte[] workbookBytes, List<String> expectedHeaders, List<String> expectedFirstRow) throws Exception {
|
try (Workbook workbook = WorkbookFactory.create(new ByteArrayInputStream(workbookBytes))) {
|
Sheet sheet = workbook.getSheetAt(0);
|
for (int index = 0; index < expectedHeaders.size(); index++) {
|
assertEquals(expectedHeaders.get(index), sheet.getRow(3).getCell(index).getStringCellValue());
|
assertEquals(expectedFirstRow.get(index), sheet.getRow(4).getCell(index).getStringCellValue());
|
}
|
}
|
}
|
|
private Role role(Long id, String name, String code, Integer status, String memo) {
|
Role role = new Role();
|
role.setId(id);
|
role.setName(name);
|
role.setCode(code);
|
role.setStatus(status);
|
role.setMemo(memo);
|
return role;
|
}
|
|
@SuppressWarnings("unchecked")
|
private Wrapper<Role> anyWrapper() {
|
return any(Wrapper.class);
|
}
|
|
private static final class TestableRoleController extends RoleController {
|
@Override
|
public <T extends BaseParam> T buildParam(Map<String, Object> map, Class<T> clz) {
|
try {
|
T param = clz.getDeclaredConstructor().newInstance();
|
Map<String, Object> copy = new HashMap<>(map);
|
Object metaObject = copy.remove("meta");
|
if (metaObject instanceof Map<?, ?> metaMap) {
|
metaMap.forEach((key, value) -> copy.put(String.valueOf(key), value));
|
}
|
BaseParam baseParam = param;
|
baseParam.setCurrent(asInteger(copy.remove("current")));
|
baseParam.setPageSize(asInteger(copy.remove("pageSize")));
|
baseParam.setOrderBy(asString(copy.remove("orderBy")));
|
baseParam.setCondition(asString(copy.remove("condition")));
|
baseParam.setMap(copy);
|
return param;
|
} catch (Exception error) {
|
throw new RuntimeException(error);
|
}
|
}
|
|
private Integer asInteger(Object value) {
|
return value == null ? null : Integer.valueOf(String.valueOf(value));
|
}
|
|
private String asString(Object value) {
|
return value == null ? null : String.valueOf(value);
|
}
|
}
|
}
|