chore: 清理旧迁移脚本并添加本地开发配置

- 删除旧的V10和V11迁移脚本(已被V12和V13替代)
- 更新BaseDomain和自动配置文件
- 删除旧的测试文件
- 添加本地开发配置文件
- 添加简化版应用启动类
This commit was merged in pull request #3.
This commit is contained in:
张翔
2026-04-15 23:39:02 +08:00
parent 648851df92
commit 2954e8cd2c
16 changed files with 1184 additions and 263 deletions
@@ -0,0 +1,220 @@
package cn.novalon.manage.sys.audit.controller;
import cn.novalon.manage.sys.audit.domain.AuditLog;
import cn.novalon.manage.sys.audit.dto.AuditLogQueryRequest;
import cn.novalon.manage.sys.audit.dto.AuditLogStatistics;
import cn.novalon.manage.sys.audit.service.IAuditLogService;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
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.web.reactive.server.WebTestClient;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import java.time.LocalDateTime;
import static org.mockito.ArgumentMatchers.*;
import static org.mockito.Mockito.when;
import static org.junit.jupiter.api.Assertions.*;
/**
* AuditLogController 单元测试
*
* @author 张翔
* @date 2026-04-14
*/
@ExtendWith(MockitoExtension.class)
class AuditLogControllerTest {
@Mock
private IAuditLogService auditLogService;
private WebTestClient webTestClient;
private AuditLogController auditLogController;
@BeforeEach
void setUp() {
auditLogController = new AuditLogController(auditLogService);
webTestClient = WebTestClient.bindToController(auditLogController).build();
}
@Test
@DisplayName("根据ID查询审计日志 - 成功")
void findById_whenExists_shouldReturnAuditLog() {
AuditLog auditLog = createTestAuditLog(1L);
when(auditLogService.findById(1L)).thenReturn(Mono.just(auditLog));
webTestClient.get()
.uri("/api/audit-logs/1")
.exchange()
.expectStatus().isOk()
.expectBody(AuditLog.class)
.isEqualTo(auditLog);
}
@Test
@DisplayName("根据ID查询审计日志 - 不存在")
void findById_whenNotExists_shouldReturnNotFound() {
when(auditLogService.findById(999L)).thenReturn(Mono.empty());
webTestClient.get()
.uri("/api/audit-logs/999")
.exchange()
.expectStatus().isOk()
.expectBody().isEmpty();
}
@Test
@DisplayName("按实体类型查询审计日志")
void findByEntityType_shouldReturnAuditLogs() {
AuditLog auditLog1 = createTestAuditLog(1L);
AuditLog auditLog2 = createTestAuditLog(2L);
when(auditLogService.findByEntityType("User")).thenReturn(Flux.just(auditLog1, auditLog2));
webTestClient.get()
.uri("/api/audit-logs/entity-type/User")
.exchange()
.expectStatus().isOk()
.expectBodyList(AuditLog.class)
.hasSize(2)
.contains(auditLog1, auditLog2);
}
@Test
@DisplayName("按实体ID查询审计日志")
void findByEntityId_shouldReturnAuditLogs() {
AuditLog auditLog = createTestAuditLog(1L);
when(auditLogService.findByEntityId(100L)).thenReturn(Flux.just(auditLog));
webTestClient.get()
.uri("/api/audit-logs/entity/100")
.exchange()
.expectStatus().isOk()
.expectBodyList(AuditLog.class)
.hasSize(1)
.contains(auditLog);
}
@Test
@DisplayName("按操作人查询审计日志")
void findByOperator_shouldReturnAuditLogs() {
AuditLog auditLog = createTestAuditLog(1L);
when(auditLogService.findByOperator("admin")).thenReturn(Flux.just(auditLog));
webTestClient.get()
.uri("/api/audit-logs/operator/admin")
.exchange()
.expectStatus().isOk()
.expectBodyList(AuditLog.class)
.hasSize(1)
.contains(auditLog);
}
@Test
@DisplayName("按操作类型查询审计日志")
void findByOperationType_shouldReturnAuditLogs() {
AuditLog auditLog = createTestAuditLog(1L);
when(auditLogService.findByOperationType("CREATE")).thenReturn(Flux.just(auditLog));
webTestClient.get()
.uri("/api/audit-logs/operation-type/CREATE")
.exchange()
.expectStatus().isOk()
.expectBodyList(AuditLog.class)
.hasSize(1)
.contains(auditLog);
}
@Test
@DisplayName("按时间范围查询审计日志")
void findByTimeRange_shouldReturnAuditLogs() {
LocalDateTime startTime = LocalDateTime.now().minusDays(1);
LocalDateTime endTime = LocalDateTime.now();
AuditLog auditLog = createTestAuditLog(1L);
when(auditLogService.findByOperationTimeBetween(startTime, endTime))
.thenReturn(Flux.just(auditLog));
webTestClient.get()
.uri(uriBuilder -> uriBuilder
.path("/api/audit-logs/time-range")
.queryParam("startTime", startTime)
.queryParam("endTime", endTime)
.build())
.exchange()
.expectStatus().isOk()
.expectBodyList(AuditLog.class)
.hasSize(1)
.contains(auditLog);
}
@Test
@DisplayName("获取审计日志统计信息")
void getStatistics_shouldReturnStatistics() {
webTestClient.get()
.uri("/api/audit-logs/statistics")
.exchange()
.expectStatus().isOk()
.expectBody(AuditLogStatistics.class)
.value(returnedStatistics -> {
assertNotNull(returnedStatistics);
assertNull(returnedStatistics.getTotalCount());
});
}
@Test
@DisplayName("按实体类型统计数量")
void countByEntityType_shouldReturnCount() {
when(auditLogService.countByEntityType("User")).thenReturn(Mono.just(10L));
webTestClient.get()
.uri("/api/audit-logs/count/entity-type/User")
.exchange()
.expectStatus().isOk()
.expectBody(Long.class)
.isEqualTo(10L);
}
@Test
@DisplayName("按操作人统计数量")
void countByOperator_shouldReturnCount() {
when(auditLogService.countByOperator("admin")).thenReturn(Mono.just(5L));
webTestClient.get()
.uri("/api/audit-logs/count/operator/admin")
.exchange()
.expectStatus().isOk()
.expectBody(Long.class)
.isEqualTo(5L);
}
@Test
@DisplayName("按操作类型统计数量")
void countByOperationType_shouldReturnCount() {
when(auditLogService.countByOperationType("CREATE")).thenReturn(Mono.just(3L));
webTestClient.get()
.uri("/api/audit-logs/count/operation-type/CREATE")
.exchange()
.expectStatus().isOk()
.expectBody(Long.class)
.isEqualTo(3L);
}
private AuditLog createTestAuditLog(Long id) {
AuditLog auditLog = new AuditLog();
auditLog.setId(id);
auditLog.setEntityType("User");
auditLog.setEntityId(100L);
auditLog.setOperator("admin");
auditLog.setOperationType("CREATE");
auditLog.setOperationTime(LocalDateTime.now());
auditLog.setDescription("创建用户");
auditLog.setIpAddress("192.168.1.1");
auditLog.setUserAgent("Mozilla/5.0");
return auditLog;
}
}
@@ -0,0 +1,224 @@
package cn.novalon.manage.sys.audit.domain;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import java.time.LocalDateTime;
import static org.junit.jupiter.api.Assertions.*;
/**
* AuditLog 单元测试
*
* @author 张翔
* @date 2026-04-14
*/
class AuditLogTest {
@Test
@DisplayName("创建默认审计日志")
void createDefaultAuditLog_shouldHaveNullFields() {
AuditLog auditLog = new AuditLog();
assertNull(auditLog.getId());
assertNull(auditLog.getEntityType());
assertNull(auditLog.getEntityId());
assertNull(auditLog.getOperator());
assertNull(auditLog.getOperationType());
assertNull(auditLog.getOperationTime());
assertNull(auditLog.getDescription());
assertNull(auditLog.getIpAddress());
assertNull(auditLog.getUserAgent());
assertNull(auditLog.getDeletedAt());
}
@Test
@DisplayName("设置和获取ID")
void setAndGetId_shouldWorkCorrectly() {
AuditLog auditLog = new AuditLog();
auditLog.setId(1L);
assertEquals(1L, auditLog.getId());
}
@Test
@DisplayName("设置和获取实体类型")
void setAndGetEntityType_shouldWorkCorrectly() {
AuditLog auditLog = new AuditLog();
auditLog.setEntityType("User");
assertEquals("User", auditLog.getEntityType());
}
@Test
@DisplayName("设置和获取实体ID")
void setAndGetEntityId_shouldWorkCorrectly() {
AuditLog auditLog = new AuditLog();
auditLog.setEntityId(100L);
assertEquals(100L, auditLog.getEntityId());
}
@Test
@DisplayName("设置和获取操作人")
void setAndGetOperator_shouldWorkCorrectly() {
AuditLog auditLog = new AuditLog();
auditLog.setOperator("admin");
assertEquals("admin", auditLog.getOperator());
}
@Test
@DisplayName("设置和获取操作类型")
void setAndGetOperationType_shouldWorkCorrectly() {
AuditLog auditLog = new AuditLog();
auditLog.setOperationType("CREATE");
assertEquals("CREATE", auditLog.getOperationType());
}
@Test
@DisplayName("设置和获取操作时间")
void setAndGetOperationTime_shouldWorkCorrectly() {
LocalDateTime operationTime = LocalDateTime.now();
AuditLog auditLog = new AuditLog();
auditLog.setOperationTime(operationTime);
assertEquals(operationTime, auditLog.getOperationTime());
}
@Test
@DisplayName("设置和获取描述")
void setAndGetDescription_shouldWorkCorrectly() {
AuditLog auditLog = new AuditLog();
auditLog.setDescription("创建用户");
assertEquals("创建用户", auditLog.getDescription());
}
@Test
@DisplayName("设置和获取IP地址")
void setAndGetIpAddress_shouldWorkCorrectly() {
AuditLog auditLog = new AuditLog();
auditLog.setIpAddress("192.168.1.1");
assertEquals("192.168.1.1", auditLog.getIpAddress());
}
@Test
@DisplayName("设置和获取用户代理")
void setAndGetUserAgent_shouldWorkCorrectly() {
AuditLog auditLog = new AuditLog();
auditLog.setUserAgent("Mozilla/5.0");
assertEquals("Mozilla/5.0", auditLog.getUserAgent());
}
@Test
@DisplayName("设置和获取删除时间")
void setAndGetDeletedAt_shouldWorkCorrectly() {
LocalDateTime deletedAt = LocalDateTime.now();
AuditLog auditLog = new AuditLog();
auditLog.setDeletedAt(deletedAt);
assertEquals(deletedAt, auditLog.getDeletedAt());
}
@Test
@DisplayName("toString方法应包含所有字段")
void toString_shouldContainAllFields() {
LocalDateTime operationTime = LocalDateTime.now();
AuditLog auditLog = new AuditLog();
auditLog.setId(1L);
auditLog.setEntityType("User");
auditLog.setEntityId(100L);
auditLog.setOperator("admin");
auditLog.setOperationType("CREATE");
auditLog.setOperationTime(operationTime);
auditLog.setDescription("创建用户");
auditLog.setIpAddress("192.168.1.1");
auditLog.setUserAgent("Mozilla/5.0");
String toString = auditLog.toString();
assertTrue(toString.contains("1"));
assertTrue(toString.contains("User"));
assertTrue(toString.contains("100"));
assertTrue(toString.contains("admin"));
assertTrue(toString.contains("CREATE"));
assertTrue(toString.contains("创建用户"));
assertTrue(toString.contains("192.168.1.1"));
assertTrue(toString.contains("Mozilla/5.0"));
}
@Test
@DisplayName("equals和hashCode方法应基于字段值")
void equalsAndHashCode_shouldBeBasedOnFieldValues() {
LocalDateTime operationTime = LocalDateTime.now();
AuditLog auditLog1 = new AuditLog();
auditLog1.setId(1L);
auditLog1.setEntityType("User");
auditLog1.setEntityId(100L);
auditLog1.setOperator("admin");
auditLog1.setOperationType("CREATE");
auditLog1.setOperationTime(operationTime);
auditLog1.setDescription("创建用户");
auditLog1.setIpAddress("192.168.1.1");
auditLog1.setUserAgent("Mozilla/5.0");
AuditLog auditLog2 = new AuditLog();
auditLog2.setId(1L);
auditLog2.setEntityType("User");
auditLog2.setEntityId(100L);
auditLog2.setOperator("admin");
auditLog2.setOperationType("CREATE");
auditLog2.setOperationTime(operationTime);
auditLog2.setDescription("创建用户");
auditLog2.setIpAddress("192.168.1.1");
auditLog2.setUserAgent("Mozilla/5.0");
assertEquals(auditLog1, auditLog2);
assertEquals(auditLog1.hashCode(), auditLog2.hashCode());
}
@Test
@DisplayName("不同ID的对象应不相等")
void differentIds_shouldNotBeEqual() {
AuditLog auditLog1 = new AuditLog();
auditLog1.setId(1L);
AuditLog auditLog2 = new AuditLog();
auditLog2.setId(2L);
assertNotEquals(auditLog1, auditLog2);
}
@Test
@DisplayName("null对象应不相等")
void nullObject_shouldNotBeEqual() {
AuditLog auditLog = new AuditLog();
auditLog.setId(1L);
assertNotEquals(auditLog, null);
}
@Test
@DisplayName("不同类型对象应不相等")
void differentTypeObject_shouldNotBeEqual() {
AuditLog auditLog = new AuditLog();
auditLog.setId(1L);
assertNotEquals(auditLog, "not an audit log");
}
@Test
@DisplayName("相同对象引用应相等")
void sameObjectReference_shouldBeEqual() {
AuditLog auditLog = new AuditLog();
auditLog.setId(1L);
assertEquals(auditLog, auditLog);
}
}
@@ -0,0 +1,146 @@
package cn.novalon.manage.sys.audit.dto;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import java.time.LocalDateTime;
import static org.junit.jupiter.api.Assertions.*;
/**
* AuditLogQueryRequest 单元测试
*
* @author 张翔
* @date 2026-04-14
*/
class AuditLogQueryRequestTest {
@Test
@DisplayName("创建默认查询请求")
void createDefaultRequest_shouldHaveNullFields() {
AuditLogQueryRequest request = new AuditLogQueryRequest();
assertNull(request.getEntityType());
assertNull(request.getEntityId());
assertNull(request.getOperator());
assertNull(request.getOperationType());
assertNull(request.getStartTime());
assertNull(request.getEndTime());
}
@Test
@DisplayName("设置和获取实体类型")
void setAndGetEntityType_shouldWorkCorrectly() {
AuditLogQueryRequest request = new AuditLogQueryRequest();
request.setEntityType("User");
assertEquals("User", request.getEntityType());
}
@Test
@DisplayName("设置和获取实体ID")
void setAndGetEntityId_shouldWorkCorrectly() {
AuditLogQueryRequest request = new AuditLogQueryRequest();
request.setEntityId(100L);
assertEquals(100L, request.getEntityId());
}
@Test
@DisplayName("设置和获取操作人")
void setAndGetOperator_shouldWorkCorrectly() {
AuditLogQueryRequest request = new AuditLogQueryRequest();
request.setOperator("admin");
assertEquals("admin", request.getOperator());
}
@Test
@DisplayName("设置和获取操作类型")
void setAndGetOperationType_shouldWorkCorrectly() {
AuditLogQueryRequest request = new AuditLogQueryRequest();
request.setOperationType("CREATE");
assertEquals("CREATE", request.getOperationType());
}
@Test
@DisplayName("设置和获取开始时间")
void setAndGetStartTime_shouldWorkCorrectly() {
LocalDateTime startTime = LocalDateTime.now().minusDays(1);
AuditLogQueryRequest request = new AuditLogQueryRequest();
request.setStartTime(startTime);
assertEquals(startTime, request.getStartTime());
}
@Test
@DisplayName("设置和获取结束时间")
void setAndGetEndTime_shouldWorkCorrectly() {
LocalDateTime endTime = LocalDateTime.now();
AuditLogQueryRequest request = new AuditLogQueryRequest();
request.setEndTime(endTime);
assertEquals(endTime, request.getEndTime());
}
@Test
@DisplayName("toString方法应包含所有字段")
void toString_shouldContainAllFields() {
LocalDateTime startTime = LocalDateTime.now().minusDays(1);
LocalDateTime endTime = LocalDateTime.now();
AuditLogQueryRequest request = new AuditLogQueryRequest();
request.setEntityType("User");
request.setEntityId(100L);
request.setOperator("admin");
request.setOperationType("CREATE");
request.setStartTime(startTime);
request.setEndTime(endTime);
String toString = request.toString();
assertTrue(toString.contains("User"));
assertTrue(toString.contains("100"));
assertTrue(toString.contains("admin"));
assertTrue(toString.contains("CREATE"));
}
@Test
@DisplayName("equals和hashCode方法应基于字段值")
void equalsAndHashCode_shouldBeBasedOnFieldValues() {
LocalDateTime startTime = LocalDateTime.now().minusDays(1);
LocalDateTime endTime = LocalDateTime.now();
AuditLogQueryRequest request1 = new AuditLogQueryRequest();
request1.setEntityType("User");
request1.setEntityId(100L);
request1.setOperator("admin");
request1.setOperationType("CREATE");
request1.setStartTime(startTime);
request1.setEndTime(endTime);
AuditLogQueryRequest request2 = new AuditLogQueryRequest();
request2.setEntityType("User");
request2.setEntityId(100L);
request2.setOperator("admin");
request2.setOperationType("CREATE");
request2.setStartTime(startTime);
request2.setEndTime(endTime);
assertEquals(request1, request2);
assertEquals(request1.hashCode(), request2.hashCode());
}
@Test
@DisplayName("不同字段值的对象应不相等")
void differentFieldValues_shouldNotBeEqual() {
AuditLogQueryRequest request1 = new AuditLogQueryRequest();
request1.setEntityType("User");
AuditLogQueryRequest request2 = new AuditLogQueryRequest();
request2.setEntityType("Role");
assertNotEquals(request1, request2);
}
}
@@ -0,0 +1,350 @@
package cn.novalon.manage.sys.audit.service.impl;
import cn.novalon.manage.sys.audit.domain.AuditLog;
import cn.novalon.manage.sys.audit.repository.IAuditLogRepository;
import cn.novalon.manage.common.dto.PageRequest;
import cn.novalon.manage.common.dto.PageResponse;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import reactor.test.StepVerifier;
import java.time.LocalDateTime;
import java.util.List;
import java.util.concurrent.Executor;
import static org.mockito.ArgumentMatchers.*;
import static org.mockito.Mockito.*;
/**
* AuditLogService 单元测试
*
* @author 张翔
* @date 2026-04-14
*/
@ExtendWith(MockitoExtension.class)
class AuditLogServiceTest {
@Mock
private IAuditLogRepository auditLogRepository;
@Mock
private Executor auditLogExecutor;
private AuditLogService auditLogService;
@BeforeEach
void setUp() {
auditLogService = new AuditLogService(auditLogRepository, auditLogExecutor);
}
@Test
@DisplayName("根据ID查询审计日志 - 成功")
void findById_whenExists_shouldReturnAuditLog() {
AuditLog auditLog = createTestAuditLog(1L);
when(auditLogRepository.findById(1L)).thenReturn(Mono.just(auditLog));
StepVerifier.create(auditLogService.findById(1L))
.expectNext(auditLog)
.verifyComplete();
}
@Test
@DisplayName("根据ID查询审计日志 - 不存在")
void findById_whenNotExists_shouldReturnEmpty() {
when(auditLogRepository.findById(999L)).thenReturn(Mono.empty());
StepVerifier.create(auditLogService.findById(999L))
.verifyComplete();
}
@Test
@DisplayName("查询所有审计日志")
void findAll_shouldReturnAllAuditLogs() {
AuditLog auditLog1 = createTestAuditLog(1L);
AuditLog auditLog2 = createTestAuditLog(2L);
when(auditLogRepository.findAll()).thenReturn(Flux.just(auditLog1, auditLog2));
StepVerifier.create(auditLogService.findAll())
.expectNext(auditLog1)
.expectNext(auditLog2)
.verifyComplete();
}
@Test
@DisplayName("分页查询审计日志")
void findAuditLogsByPage_shouldReturnPageResponse() {
AuditLog auditLog1 = createTestAuditLog(1L);
AuditLog auditLog2 = createTestAuditLog(2L);
AuditLog auditLog3 = createTestAuditLog(3L);
when(auditLogRepository.findAll()).thenReturn(Flux.just(auditLog1, auditLog2, auditLog3));
PageRequest pageRequest = new PageRequest();
pageRequest.setPage(0);
pageRequest.setSize(2);
StepVerifier.create(auditLogService.findAuditLogsByPage(pageRequest))
.expectNextMatches(pageResponse ->
pageResponse.getContent().size() == 2 &&
pageResponse.getTotalPages() == 2 &&
pageResponse.getTotalElements() == 3)
.verifyComplete();
}
@Test
@DisplayName("统计审计日志总数")
void count_shouldReturnTotalCount() {
when(auditLogRepository.findAll()).thenReturn(Flux.just(
createTestAuditLog(1L),
createTestAuditLog(2L),
createTestAuditLog(3L)
));
StepVerifier.create(auditLogService.count())
.expectNext(3L)
.verifyComplete();
}
@Test
@DisplayName("按实体类型查询审计日志")
void findByEntityType_shouldReturnAuditLogs() {
AuditLog auditLog = createTestAuditLog(1L);
when(auditLogRepository.findByEntityType("User")).thenReturn(Flux.just(auditLog));
StepVerifier.create(auditLogService.findByEntityType("User"))
.expectNext(auditLog)
.verifyComplete();
}
@Test
@DisplayName("按实体ID查询审计日志")
void findByEntityId_shouldReturnAuditLogs() {
AuditLog auditLog = createTestAuditLog(1L);
when(auditLogRepository.findByEntityId(100L)).thenReturn(Flux.just(auditLog));
StepVerifier.create(auditLogService.findByEntityId(100L))
.expectNext(auditLog)
.verifyComplete();
}
@Test
@DisplayName("按实体类型和实体ID查询审计日志")
void findByEntityTypeAndEntityId_shouldReturnAuditLogs() {
AuditLog auditLog = createTestAuditLog(1L);
when(auditLogRepository.findByEntityTypeAndEntityId("User", 100L))
.thenReturn(Flux.just(auditLog));
StepVerifier.create(auditLogService.findByEntityTypeAndEntityId("User", 100L))
.expectNext(auditLog)
.verifyComplete();
}
@Test
@DisplayName("按操作人查询审计日志")
void findByOperator_shouldReturnAuditLogs() {
AuditLog auditLog = createTestAuditLog(1L);
when(auditLogRepository.findByOperator("admin")).thenReturn(Flux.just(auditLog));
StepVerifier.create(auditLogService.findByOperator("admin"))
.expectNext(auditLog)
.verifyComplete();
}
@Test
@DisplayName("按操作类型查询审计日志")
void findByOperationType_shouldReturnAuditLogs() {
AuditLog auditLog = createTestAuditLog(1L);
when(auditLogRepository.findByOperationType("CREATE")).thenReturn(Flux.just(auditLog));
StepVerifier.create(auditLogService.findByOperationType("CREATE"))
.expectNext(auditLog)
.verifyComplete();
}
@Test
@DisplayName("按时间范围查询审计日志")
void findByOperationTimeBetween_shouldReturnAuditLogs() {
LocalDateTime startTime = LocalDateTime.now().minusDays(1);
LocalDateTime endTime = LocalDateTime.now();
AuditLog auditLog = createTestAuditLog(1L);
when(auditLogRepository.findByOperationTimeBetween(startTime, endTime))
.thenReturn(Flux.just(auditLog));
StepVerifier.create(auditLogService.findByOperationTimeBetween(startTime, endTime))
.expectNext(auditLog)
.verifyComplete();
}
@Test
@DisplayName("按实体类型和时间范围查询审计日志")
void findByEntityTypeAndOperationTimeBetween_shouldReturnAuditLogs() {
LocalDateTime startTime = LocalDateTime.now().minusDays(1);
LocalDateTime endTime = LocalDateTime.now();
AuditLog auditLog = createTestAuditLog(1L);
when(auditLogRepository.findByEntityTypeAndOperationTimeBetween("User", startTime, endTime))
.thenReturn(Flux.just(auditLog));
StepVerifier.create(auditLogService.findByEntityTypeAndOperationTimeBetween("User", startTime, endTime))
.expectNext(auditLog)
.verifyComplete();
}
@Test
@DisplayName("按操作人和时间范围查询审计日志")
void findByOperatorAndOperationTimeBetween_shouldReturnAuditLogs() {
LocalDateTime startTime = LocalDateTime.now().minusDays(1);
LocalDateTime endTime = LocalDateTime.now();
AuditLog auditLog = createTestAuditLog(1L);
when(auditLogRepository.findByOperatorAndOperationTimeBetween("admin", startTime, endTime))
.thenReturn(Flux.just(auditLog));
StepVerifier.create(auditLogService.findByOperatorAndOperationTimeBetween("admin", startTime, endTime))
.expectNext(auditLog)
.verifyComplete();
}
@Test
@DisplayName("按实体类型统计数量")
void countByEntityType_shouldReturnCount() {
when(auditLogRepository.countByEntityType("User")).thenReturn(Mono.just(5L));
StepVerifier.create(auditLogService.countByEntityType("User"))
.expectNext(5L)
.verifyComplete();
}
@Test
@DisplayName("按操作类型统计数量")
void countByOperationType_shouldReturnCount() {
when(auditLogRepository.countByOperationType("CREATE")).thenReturn(Mono.just(3L));
StepVerifier.create(auditLogService.countByOperationType("CREATE"))
.expectNext(3L)
.verifyComplete();
}
@Test
@DisplayName("按操作人统计数量")
void countByOperator_shouldReturnCount() {
when(auditLogRepository.countByOperator("admin")).thenReturn(Mono.just(2L));
StepVerifier.create(auditLogService.countByOperator("admin"))
.expectNext(2L)
.verifyComplete();
}
@Test
@DisplayName("按时间范围统计数量")
void countByOperationTimeBetween_shouldReturnCount() {
LocalDateTime startTime = LocalDateTime.now().minusDays(1);
LocalDateTime endTime = LocalDateTime.now();
when(auditLogRepository.countByOperationTimeBetween(startTime, endTime))
.thenReturn(Mono.just(10L));
StepVerifier.create(auditLogService.countByOperationTimeBetween(startTime, endTime))
.expectNext(10L)
.verifyComplete();
}
@Test
@DisplayName("保存审计日志")
void save_shouldReturnSavedAuditLog() {
AuditLog auditLog = createTestAuditLog(null);
AuditLog savedAuditLog = createTestAuditLog(1L);
when(auditLogRepository.save(auditLog)).thenReturn(Mono.just(savedAuditLog));
StepVerifier.create(auditLogService.save(auditLog))
.expectNext(savedAuditLog)
.verifyComplete();
}
@Test
@DisplayName("异步保存审计日志")
void saveAsync_shouldReturnSavedAuditLog() {
AuditLog auditLog = createTestAuditLog(null);
AuditLog savedAuditLog = createTestAuditLog(1L);
when(auditLogRepository.save(auditLog)).thenReturn(Mono.just(savedAuditLog));
StepVerifier.create(auditLogService.saveAsync(auditLog))
.expectNext(savedAuditLog)
.verifyComplete();
}
@Test
@DisplayName("根据ID删除审计日志")
void deleteById_shouldDeleteAuditLog() {
when(auditLogRepository.deleteById(1L)).thenReturn(Mono.empty());
StepVerifier.create(auditLogService.deleteById(1L))
.verifyComplete();
}
@Test
@DisplayName("逻辑删除审计日志")
void logicalDeleteById_shouldSetDeletedAt() {
AuditLog auditLog = createTestAuditLog(1L);
AuditLog deletedAuditLog = createTestAuditLog(1L);
deletedAuditLog.setDeletedAt(LocalDateTime.now());
when(auditLogRepository.findById(1L)).thenReturn(Mono.just(auditLog));
when(auditLogRepository.save(auditLog)).thenReturn(Mono.just(deletedAuditLog));
StepVerifier.create(auditLogService.logicalDeleteById(1L))
.verifyComplete();
}
@Test
@DisplayName("批量逻辑删除审计日志")
void logicalDeleteByIds_shouldDeleteMultipleAuditLogs() {
AuditLog auditLog1 = createTestAuditLog(1L);
AuditLog auditLog2 = createTestAuditLog(2L);
when(auditLogRepository.findById(1L)).thenReturn(Mono.just(auditLog1));
when(auditLogRepository.findById(2L)).thenReturn(Mono.just(auditLog2));
when(auditLogRepository.save(any(AuditLog.class))).thenReturn(Mono.just(auditLog1));
StepVerifier.create(auditLogService.logicalDeleteByIds(List.of(1L, 2L)))
.verifyComplete();
}
@Test
@DisplayName("恢复逻辑删除的审计日志")
void restoreById_shouldClearDeletedAt() {
AuditLog auditLog = createTestAuditLog(1L);
auditLog.setDeletedAt(LocalDateTime.now());
AuditLog restoredAuditLog = createTestAuditLog(1L);
restoredAuditLog.setDeletedAt(null);
when(auditLogRepository.findById(1L)).thenReturn(Mono.just(auditLog));
when(auditLogRepository.save(auditLog)).thenReturn(Mono.just(restoredAuditLog));
StepVerifier.create(auditLogService.restoreById(1L))
.verifyComplete();
}
private AuditLog createTestAuditLog(Long id) {
AuditLog auditLog = new AuditLog();
auditLog.setId(id);
auditLog.setEntityType("User");
auditLog.setEntityId(100L);
auditLog.setOperator("admin");
auditLog.setOperationType("CREATE");
auditLog.setOperationTime(LocalDateTime.now());
auditLog.setDescription("创建用户");
auditLog.setIpAddress("192.168.1.1");
auditLog.setUserAgent("Mozilla/5.0");
return auditLog;
}
}
@@ -1,44 +0,0 @@
package cn.novalon.manage.sys.config;
import cn.novalon.manage.common.handler.ExceptionLogService;
import cn.novalon.manage.sys.handler.ExceptionLogServiceImpl;
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 static org.assertj.core.api.Assertions.assertThat;
@ExtendWith(MockitoExtension.class)
class ExceptionLogConfigTest {
@Mock
private ExceptionLogServiceImpl exceptionLogServiceImpl;
private ExceptionLogConfig exceptionLogConfig;
@BeforeEach
void setUp() {
exceptionLogConfig = new ExceptionLogConfig();
}
@Test
void testExceptionLogService() {
ExceptionLogService exceptionLogService = exceptionLogConfig.exceptionLogService(exceptionLogServiceImpl);
assertThat(exceptionLogService).isNotNull();
assertThat(exceptionLogService).isSameAs(exceptionLogServiceImpl);
}
@Test
void testExceptionLogService_DifferentInstance() {
ExceptionLogService exceptionLogService1 = exceptionLogConfig.exceptionLogService(exceptionLogServiceImpl);
ExceptionLogService exceptionLogService2 = exceptionLogConfig.exceptionLogService(exceptionLogServiceImpl);
assertThat(exceptionLogService1).isNotNull();
assertThat(exceptionLogService2).isNotNull();
assertThat(exceptionLogService1).isSameAs(exceptionLogServiceImpl);
assertThat(exceptionLogService2).isSameAs(exceptionLogServiceImpl);
}
}
@@ -1,120 +0,0 @@
package cn.novalon.manage.sys.handler;
import cn.novalon.manage.sys.core.domain.SysExceptionLog;
import cn.novalon.manage.sys.core.service.ISysExceptionLogService;
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 reactor.core.publisher.Mono;
import reactor.test.StepVerifier;
import java.time.LocalDateTime;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@ExtendWith(MockitoExtension.class)
class ExceptionLogServiceImplTest {
@Mock
private ISysExceptionLogService exceptionLogService;
private ExceptionLogServiceImpl exceptionLogServiceImpl;
@BeforeEach
void setUp() {
exceptionLogServiceImpl = new ExceptionLogServiceImpl(exceptionLogService);
}
@Test
void testLogException() {
SysExceptionLog savedLog = new SysExceptionLog();
savedLog.setId(1L);
savedLog.setTitle("测试异常");
savedLog.setExceptionName("TestException");
savedLog.setExceptionMsg("测试异常消息");
savedLog.setMethodName("testMethod");
savedLog.setIp("127.0.0.1");
savedLog.setExceptionStack("测试堆栈信息");
savedLog.setCreateTime(LocalDateTime.now());
when(exceptionLogService.save(any(SysExceptionLog.class))).thenReturn(Mono.just(savedLog));
StepVerifier.create(exceptionLogServiceImpl.logException(
"测试异常",
"TestException",
"测试异常消息",
"testMethod",
"127.0.0.1",
"测试堆栈信息"
))
.verifyComplete();
verify(exceptionLogService).save(any(SysExceptionLog.class));
}
@Test
void testLogException_WithEmptyFields() {
SysExceptionLog savedLog = new SysExceptionLog();
savedLog.setId(1L);
when(exceptionLogService.save(any(SysExceptionLog.class))).thenReturn(Mono.just(savedLog));
StepVerifier.create(exceptionLogServiceImpl.logException(
"",
"",
"",
"",
"",
""
))
.verifyComplete();
verify(exceptionLogService).save(any(SysExceptionLog.class));
}
@Test
void testLogException_WithNullFields() {
SysExceptionLog savedLog = new SysExceptionLog();
savedLog.setId(1L);
when(exceptionLogService.save(any(SysExceptionLog.class))).thenReturn(Mono.just(savedLog));
StepVerifier.create(exceptionLogServiceImpl.logException(
null,
null,
null,
null,
null,
null
))
.verifyComplete();
verify(exceptionLogService).save(any(SysExceptionLog.class));
}
@Test
void testLogException_WithLongStackTrace() {
String longStackTrace = "a".repeat(10000);
SysExceptionLog savedLog = new SysExceptionLog();
savedLog.setId(1L);
when(exceptionLogService.save(any(SysExceptionLog.class))).thenReturn(Mono.just(savedLog));
StepVerifier.create(exceptionLogServiceImpl.logException(
"测试异常",
"TestException",
"测试异常消息",
"testMethod",
"127.0.0.1",
longStackTrace
))
.verifyComplete();
verify(exceptionLogService).save(any(SysExceptionLog.class));
}
}