package com.atlassian.stash.internal.liquibase;

import com.atlassian.bitbucket.annotation.Dao;
import com.atlassian.bitbucket.annotation.DataSet;
import com.atlassian.stash.internal.AbstractDaoTest;
import com.atlassian.stash.internal.DataSets;
import com.atlassian.stash.internal.project.HibernateProjectDao;
import com.atlassian.stash.internal.project.ProjectDao;
import liquibase.database.Database;
import liquibase.database.DatabaseFactory;
import liquibase.database.jvm.JdbcConnection;
import org.junit.Ignore;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;

import javax.sql.DataSource;

/**
 * Tests that {@link PopulatePersonalProjectsChange} correctly populates the {@code sta_personal_project} table when
 * personal projects are detected.
 * <p>
 * {@code populate_personal_projects.xml} contains <i>invalid</i> data which is inserted by DbUnit. That data creates
 * several {@link com.atlassian.stash.internal.project.InternalPersonalProject personal projects} without adding their
 * rows in {@code sta_personal_project}, simulating the process of upgrading a customer instance with existing data.
 * <p>
 * After the change is run, Hibernate is used to retrieve the personal projects. If the rows have not been written into
 * {@code sta_personal_project} correctly one of two things will happen (and either will fail the test):
 * <ul>
 *     <li>{@link ProjectDao#getByOwner(int)} will return {@code null} when it shouldn't, or</li>
 *     <li>Hibernate will throw an exception because half of the mapping data is missing</li>
 * </ul>
 */
@DataSet(DataSets.PREFIX + "liquibase/populate_personal_projects" + DataSets.SUFFIX)
@Ignore("This test can't be run at present as it expects to be run after a certain set of Liquibase changesets " +
        "have been executed but is actually run after all have been executed and the schema, especially the " +
        "user tables, has advanced too far.")
@SuppressWarnings("ConstantConditions")
public class PopulatePersonalProjectsChangeTest extends AbstractDaoTest {

    @Autowired
    private DataSource dataSource;
    @Dao(HibernateProjectDao.class)
    private ProjectDao projectDao;

    @Test
    public void testExecute() throws Exception {
        JdbcConnection connection = new JdbcConnection(dataSource.getConnection());
        Database database = DatabaseFactory.getInstance().findCorrectDatabaseImplementation(connection);

        PopulatePersonalProjectsChange change = new PopulatePersonalProjectsChange();
        change.execute(database);
        assertEquals("Populated 3 personal projects", change.getConfirmationMessage());

        //Retrieving these verifies that they were populated into the sta_personal_projects table correctly
        assertEquals(1, projectDao.getByOwner(1).getId());
        assertEquals(3, projectDao.getByOwner(2).getId());
        assertEquals(5, projectDao.getByOwner(3).getId());
    }
}
