package com.atlassian.stash.internal.spring;

import org.junit.After;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;
import org.springframework.transaction.support.TransactionSynchronization;
import org.springframework.transaction.support.TransactionSynchronizationManager;

import java.util.List;

import static org.junit.Assert.*;

@RunWith(MockitoJUnitRunner.class)
public class DefaultTransactionSynchronizerTest {

    private final DefaultTransactionSynchronizer synchronizer = new DefaultTransactionSynchronizer();

    @Mock
    private TransactionSynchronization synchronization;

    @After
    public void tearDown() throws Exception {
        if (TransactionSynchronizationManager.isSynchronizationActive()) {
            TransactionSynchronizationManager.clear();
        } else {
            TransactionSynchronizationManager.setActualTransactionActive(false);
        }
    }

    @Test
    public void testIsAvailable() throws Exception {
        assertFalse(synchronizer.isAvailable());

        //Without an actual transaction active, just having synchronization in place is not enough
        TransactionSynchronizationManager.initSynchronization();
        assertFalse(synchronizer.isAvailable());

        //With both a transaction active _and_ synchronization in place, the synchronizer should be available
        TransactionSynchronizationManager.setActualTransactionActive(true);
        assertTrue(synchronizer.isAvailable());
    }

    @Test
    public void testRegister() throws Exception {
        TransactionSynchronizationManager.initSynchronization();
        TransactionSynchronizationManager.setActualTransactionActive(true);

        assertTrue(synchronizer.register(synchronization));

        List<TransactionSynchronization> synchronizations = TransactionSynchronizationManager.getSynchronizations();
        assertEquals(1, synchronizations.size());
        assertSame(synchronization, synchronizations.get(0));
    }

    @Test
    public void testRegisterWithoutSynchronization() {
        TransactionSynchronizationManager.setActualTransactionActive(true);

        assertFalse(synchronizer.register(synchronization));
    }

    @Test
    public void testRegisterWithoutTransaction() {
        assertFalse(synchronizer.register(synchronization));
    }
}
