refactor(audit): drop @DirtiesContext, add @BeforeEach, use existsByKind in wait conditions
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -5,4 +5,5 @@ import org.springframework.data.jpa.repository.JpaRepository;
|
|||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
public interface AuditLogRepository extends JpaRepository<AuditLog, UUID> {
|
public interface AuditLogRepository extends JpaRepository<AuditLog, UUID> {
|
||||||
|
boolean existsByKind(AuditKind kind);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package org.raddatz.familienarchiv.audit;
|
package org.raddatz.familienarchiv.audit;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.raddatz.familienarchiv.PostgresContainerConfig;
|
import org.raddatz.familienarchiv.PostgresContainerConfig;
|
||||||
import org.raddatz.familienarchiv.dto.CreateUserRequest;
|
import org.raddatz.familienarchiv.dto.CreateUserRequest;
|
||||||
@@ -9,7 +10,6 @@ import org.raddatz.familienarchiv.service.UserService;
|
|||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.boot.test.context.SpringBootTest;
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
import org.springframework.context.annotation.Import;
|
import org.springframework.context.annotation.Import;
|
||||||
import org.springframework.test.annotation.DirtiesContext;
|
|
||||||
import org.springframework.test.context.ActiveProfiles;
|
import org.springframework.test.context.ActiveProfiles;
|
||||||
import org.springframework.test.context.bean.override.mockito.MockitoBean;
|
import org.springframework.test.context.bean.override.mockito.MockitoBean;
|
||||||
import org.springframework.transaction.support.TransactionTemplate;
|
import org.springframework.transaction.support.TransactionTemplate;
|
||||||
@@ -25,7 +25,6 @@ import static org.awaitility.Awaitility.await;
|
|||||||
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE)
|
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE)
|
||||||
@ActiveProfiles("test")
|
@ActiveProfiles("test")
|
||||||
@Import(PostgresContainerConfig.class)
|
@Import(PostgresContainerConfig.class)
|
||||||
@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD)
|
|
||||||
class UserManagementAuditIntegrationTest {
|
class UserManagementAuditIntegrationTest {
|
||||||
|
|
||||||
@MockitoBean S3Client s3Client;
|
@MockitoBean S3Client s3Client;
|
||||||
@@ -35,6 +34,11 @@ class UserManagementAuditIntegrationTest {
|
|||||||
@Autowired AuditLogQueryService auditLogQueryService;
|
@Autowired AuditLogQueryService auditLogQueryService;
|
||||||
@Autowired TransactionTemplate transactionTemplate;
|
@Autowired TransactionTemplate transactionTemplate;
|
||||||
|
|
||||||
|
@BeforeEach
|
||||||
|
void clearAuditLog() {
|
||||||
|
transactionTemplate.execute(status -> { auditLogRepository.deleteAll(); return null; });
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void createAndDeleteUser_producesOrderedAuditEntries() {
|
void createAndDeleteUser_producesOrderedAuditEntries() {
|
||||||
// Create the actor (admin) user directly — bypasses audit logging so no FK issue
|
// Create the actor (admin) user directly — bypasses audit logging so no FK issue
|
||||||
@@ -46,7 +50,7 @@ class UserManagementAuditIntegrationTest {
|
|||||||
UUID actorId = actor.getId();
|
UUID actorId = actor.getId();
|
||||||
|
|
||||||
// The admin creation is logged with null actorId — clear to start with a clean slate
|
// The admin creation is logged with null actorId — clear to start with a clean slate
|
||||||
await().atMost(5, SECONDS).until(() -> auditLogRepository.count() > 0);
|
await().atMost(5, SECONDS).until(() -> auditLogRepository.existsByKind(AuditKind.USER_CREATED));
|
||||||
transactionTemplate.execute(status -> { auditLogRepository.deleteAll(); return null; });
|
transactionTemplate.execute(status -> { auditLogRepository.deleteAll(); return null; });
|
||||||
|
|
||||||
// Create the target user — should emit USER_CREATED
|
// Create the target user — should emit USER_CREATED
|
||||||
@@ -57,7 +61,7 @@ class UserManagementAuditIntegrationTest {
|
|||||||
userService.createUserOrUpdate(actorId, req);
|
userService.createUserOrUpdate(actorId, req);
|
||||||
return null;
|
return null;
|
||||||
});
|
});
|
||||||
await().atMost(5, SECONDS).until(() -> auditLogRepository.count() > 0);
|
await().atMost(5, SECONDS).until(() -> auditLogRepository.existsByKind(AuditKind.USER_CREATED));
|
||||||
|
|
||||||
// Delete the target user — should emit USER_DELETED
|
// Delete the target user — should emit USER_DELETED
|
||||||
AppUser created = userRepository.findByEmail("audit-test@example.com").orElseThrow();
|
AppUser created = userRepository.findByEmail("audit-test@example.com").orElseThrow();
|
||||||
@@ -65,7 +69,7 @@ class UserManagementAuditIntegrationTest {
|
|||||||
userService.deleteUser(actorId, created.getId());
|
userService.deleteUser(actorId, created.getId());
|
||||||
return null;
|
return null;
|
||||||
});
|
});
|
||||||
await().atMost(5, SECONDS).until(() -> auditLogRepository.count() >= 2);
|
await().atMost(5, SECONDS).until(() -> auditLogRepository.existsByKind(AuditKind.USER_DELETED));
|
||||||
|
|
||||||
List<AuditLog> events = auditLogQueryService.findRecentUserManagementEvents(10);
|
List<AuditLog> events = auditLogQueryService.findRecentUserManagementEvents(10);
|
||||||
assertThat(events).hasSize(2);
|
assertThat(events).hasSize(2);
|
||||||
|
|||||||
Reference in New Issue
Block a user