package jnpf.dmsIntegration.audit; import jnpf.audit.AuditConsts; import jnpf.audit.model.AuditEventDTO; import jnpf.audit.sdk.AuditEventPublisher; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.ObjectProvider; import org.springframework.transaction.support.TransactionSynchronization; import org.springframework.transaction.support.TransactionSynchronizationManager; import java.util.List; import static org.junit.jupiter.api.Assertions.*; import static org.mockito.ArgumentMatchers.argThat; import static org.mockito.Mockito.*; class DmsSystemAuditTest { @SuppressWarnings("unchecked") @Test void backgroundAuditKeepsSystemIdentityAndOnlyPublishesAfterCommit() { org.springframework.context.ApplicationContext previous = (org.springframework.context.ApplicationContext) org.springframework.test.util.ReflectionTestUtils.getField(jnpf.util.context.SpringContext.class, "applicationContext"); org.springframework.context.ApplicationContext context = mock(org.springframework.context.ApplicationContext.class); when(context.getBean(jnpf.util.RedisUtil.class)).thenReturn(mock(jnpf.util.RedisUtil.class)); when(context.getBean(jnpf.util.CacheKeyUtil.class)).thenReturn(mock(jnpf.util.CacheKeyUtil.class)); when(context.getBean(com.baomidou.lock.LockTemplate.class)).thenReturn(mock(com.baomidou.lock.LockTemplate.class)); jnpf.util.context.SpringContext.setApplicationContext(context); try { AuditEventPublisher publisher = mock(AuditEventPublisher.class); ObjectProvider provider = mock(ObjectProvider.class); when(provider.getObject()).thenReturn(publisher); DmsSystemAudit audit = new DmsSystemAudit(provider, true); AuditEventDTO event = AuditEventDTO.builder().eventType(AuditConsts.TYPE_BIZ_ACTION) .actionCode("RETRY").operatorId("0").tenantId("tenant-a").build(); TransactionSynchronizationManager.initSynchronization(); try { audit.record(event); verifyNoInteractions(publisher); List synchronizations = TransactionSynchronizationManager.getSynchronizations(); synchronizations.forEach(TransactionSynchronization::afterCommit); verify(publisher).publishAsync(argThat(events -> events.size() == 1 && "0".equals(events.get(0).getOperatorId()) && "tenant-a".equals(events.get(0).getTenantId()))); synchronizations.forEach(s -> s.afterCompletion(TransactionSynchronization.STATUS_COMMITTED)); } finally { TransactionSynchronizationManager.clearSynchronization(); } reset(publisher); TransactionSynchronizationManager.initSynchronization(); try { audit.record(event); TransactionSynchronizationManager.getSynchronizations() .forEach(s -> s.afterCompletion(TransactionSynchronization.STATUS_ROLLED_BACK)); verifyNoInteractions(publisher); } finally { TransactionSynchronizationManager.clearSynchronization(); } assertThrows(IllegalArgumentException.class, () -> audit.record(event.toBuilder().operatorId("user").build())); assertThrows(IllegalArgumentException.class, () -> audit.record(event.toBuilder().tenantId("").build())); } finally { jnpf.util.context.SpringContext.setApplicationContext(previous); } } }