package jnpf.dmsBusinessOccupancy;
|
|
import com.baomidou.dynamic.datasource.tx.TransactionContext;
|
import org.apache.ibatis.mapping.Environment;
|
import org.apache.ibatis.session.Configuration;
|
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
|
import org.junit.jupiter.api.Test;
|
import org.mybatis.spring.SqlSessionTemplate;
|
import org.mybatis.spring.transaction.SpringManagedTransactionFactory;
|
import org.springframework.transaction.support.TransactionSynchronizationManager;
|
import javax.sql.DataSource;
|
import java.util.List;
|
import static org.junit.jupiter.api.Assertions.*;
|
import static org.mockito.Mockito.*;
|
import static jnpf.dmsBusinessOccupancy.BusinessOccupancyException.Reason.*;
|
|
class BusinessFileOccupancyCoordinatorTest {
|
private BusinessFileOccupancyCoordinator service(DataSource source) {
|
var config = new Configuration(new Environment("unit", new SpringManagedTransactionFactory(), source));
|
return new BusinessFileOccupancyCoordinator(new SqlSessionTemplate(new SqlSessionFactoryBuilder().build(config)));
|
}
|
|
@Test void refusesBatchExecutorBecauseOccupancyRequiresImmediateWriteResults() {
|
DataSource source = mock(DataSource.class);
|
var config = new Configuration(new Environment("unit", new SpringManagedTransactionFactory(), source));
|
var template = new SqlSessionTemplate(new SqlSessionFactoryBuilder().build(config),
|
org.apache.ibatis.session.ExecutorType.BATCH);
|
var error = assertThrows(BusinessOccupancyException.class, () -> new BusinessFileOccupancyCoordinator(template));
|
assertEquals(UNSUPPORTED_TRANSACTION, error.getReason());
|
verifyNoInteractions(source);
|
}
|
|
@Test void refusesExpiryWithoutTransactionBeforeAnyDatabaseAccess() {
|
DataSource source = mock(DataSource.class);
|
var service = service(source);
|
var error = assertThrows(BusinessOccupancyException.class,
|
() -> service.tryEnterExpiry("tenant", List.of("A")));
|
assertEquals(TRANSACTION_REQUIRED, error.getReason());
|
verifyNoInteractions(source);
|
}
|
|
@Test void readOnlyTransactionCannotBeMistakenForAdmissionTransaction() {
|
DataSource source = mock(DataSource.class);
|
var service = service(source);
|
TransactionSynchronizationManager.setActualTransactionActive(true);
|
TransactionSynchronizationManager.setCurrentTransactionReadOnly(true);
|
try {
|
var error = assertThrows(BusinessOccupancyException.class,
|
() -> service.tryEnterExpiry("tenant", List.of("A")));
|
assertEquals(READ_ONLY_TRANSACTION, error.getReason());
|
verifyNoInteractions(source);
|
} finally { TransactionSynchronizationManager.clear(); }
|
}
|
|
@Test void rejectsUnboundSourceBeforeObtainingAnyConnection() {
|
DataSource source = mock(DataSource.class);
|
var service = service(source);
|
TransactionSynchronizationManager.setActualTransactionActive(true);
|
try {
|
var error = assertThrows(BusinessOccupancyException.class,
|
() -> service.tryEnterExpiry("tenant", List.of("A")));
|
assertEquals(TRANSACTION_CONNECTION_MISMATCH, error.getReason());
|
verifyNoInteractions(source);
|
} finally { TransactionSynchronizationManager.clear(); }
|
}
|
|
@Test void refusesMixedTransactionManagersBeforeDatabaseAccess() {
|
DataSource source = mock(DataSource.class);
|
var service = service(source);
|
TransactionSynchronizationManager.setActualTransactionActive(true);
|
TransactionContext.bind("mixed");
|
try {
|
var error = assertThrows(BusinessOccupancyException.class,
|
() -> service.tryEnterExpiry("tenant", List.of("A")));
|
assertEquals(UNSUPPORTED_TRANSACTION, error.getReason());
|
verifyNoInteractions(source);
|
} finally { TransactionContext.remove(); TransactionSynchronizationManager.clear(); }
|
}
|
}
|