package com.baiyue.audit.service; import com.baiyue.audit.dto.AuditLogQuery; import com.baiyue.audit.dto.AuditLogResponses; import com.baiyue.audit.entity.AuditLogEntity; import com.baiyue.audit.repository.AuditEventRepository; import com.baiyue.common.core.api.PageResult; import com.baiyue.common.core.exception.BizException; import jakarta.annotation.Resource; import org.junit.jupiter.api.Test; import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.test.context.junit.jupiter.SpringJUnitConfig; import java.time.Instant; import java.time.LocalDateTime; import java.util.List; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.mockito.Mockito.when; @SpringJUnitConfig(AuditLogQueryService.class) class AuditLogQueryServiceTest { @MockBean private AuditEventRepository repository; @Resource private AuditLogQueryService service; @Test void pageDoesNotExposeSnapshots() { AuditLogQuery query = new AuditLogQuery(10001L, 7L, "ROLE_UPDATE", "ROLE", "9", true, null, null, "管理员"); when(repository.page(query, 1, 20)).thenReturn(new PageResult<>(List.of(log(8L)), 1, 20, 1, 1)); PageResult result = service.page(query, 1, 20); assertThat(result.records()).singleElement().satisfies(item -> { assertThat(item.id()).isEqualTo(8L); assertThat(item.accountId()).isEqualTo(10001L); assertThat(item.eventType()).isEqualTo("ROLE_UPDATE"); }); assertThat(AuditLogResponses.ListItem.class.getRecordComponents()) .extracting(component -> component.getName()) .doesNotContain("beforeData", "afterData"); } @Test void pagePreservesTotalAndPagesForCustomerLogPagination() { AuditLogQuery query = new AuditLogQuery(10001L, null, null, "TENANT", null, null, null, null, null); when(repository.page(query, 1, 20)).thenReturn(new PageResult<>(List.of(log(8L)), 1, 20, 13, 1)); PageResult result = service.page(query, 1, 20); assertThat(result.records()).hasSize(1); assertThat(result.total()).isEqualTo(13); assertThat(result.pages()).isEqualTo(1); } @Test void detailReturnsSanitizedSnapshots() { when(repository.findById(8L)).thenReturn(log(8L)); AuditLogResponses.Detail detail = service.detail(8L); assertThat(detail.beforeData()).isEqualTo("{\"name\":\"旧角色\"}"); assertThat(detail.afterData()).isEqualTo("{\"name\":\"新角色\"}"); } @Test void missingLogIsReportedAsNotFound() { when(repository.findById(8L)).thenReturn(null); assertThatThrownBy(() -> service.detail(8L)).isInstanceOf(BizException.class) .hasMessage("操作日志不存在"); } private static AuditLogEntity log(Long id) { AuditLogEntity entity = new AuditLogEntity(); entity.setId(id); entity.setEventId("audit-8"); entity.setEventType("ROLE_UPDATE"); entity.setResourceType("ROLE"); entity.setResourceId("9"); entity.setDescription("管理员修改角色权限"); entity.setTenantId(10001L); entity.setOperatorTenantId(0L); entity.setUserId(7L); entity.setUsername("管理员"); entity.setAppCode("PLATFORM"); entity.setClientType("WEB"); entity.setRequestId("request-8"); entity.setTraceId("trace-8"); entity.setSuccess(true); entity.setBeforeData("{\"name\":\"旧角色\"}"); entity.setAfterData("{\"name\":\"新角色\"}"); entity.setServiceName("iam-service"); entity.setOccurredAt(Instant.parse("2026-08-05T10:00:00Z")); entity.setCreatedAt(LocalDateTime.of(2026, 8, 5, 18, 0)); return entity; } }