package org.springframework.roo.addon.jpa.addon;
import static org.junit.Assert.assertEquals;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.util.Properties;
import org.apache.commons.io.IOUtils;
import org.junit.Before;
import org.junit.Test;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.powermock.api.support.membermodification.MemberModifier;
import org.springframework.roo.addon.propfiles.PropFileOperations;
import org.springframework.roo.process.manager.FileManager;
import org.springframework.roo.project.Path;
import org.springframework.roo.project.PathResolver;
import org.springframework.roo.project.ProjectOperations;
/**
* Unit test of {@link JpaOperationsImpl}
*
* @author Andrew Swan
* @since 1.2.0
*/
public class JpaOperationsImplTest {
private static final String APP_CONTEXT = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
+ "<beans>" + "</beans>";
private static final String APPLICATION_CONTEXT_PATH = "/path/to/the/app/context";
private static final String DB_DIALECT = "dbDialect";
private static final String DB_HOST_NAME = "myDbHost";
private static final String DB_JNDI_NAME = "myDataSource";
private static final String DB_NAME = "myDbName";
private static final String DB_PASSWORD = "myDbPassword";
private static final String DB_USER_NAME = "myDbUserName";
private static final String EXPECTED_APPLICATION_CONTEXT =
"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n"
+ "<beans>\n"
+ " <bean class=\"org.apache.commons.dbcp.BasicDataSource\" destroy-method=\"close\" id=\"dataSource\">\n"
+ " <property name=\"driverClassName\" value=\"${database.driverClassName}\"/>\n"
+ " <property name=\"url\" value=\"${database.url}\"/>\n"
+ " <property name=\"username\" value=\"${database.username}\"/>\n"
+ " <property name=\"password\" value=\"${database.password}\"/>\n"
+ " <property name=\"testOnBorrow\" value=\"true\"/>\n"
+ " <property name=\"testOnReturn\" value=\"true\"/>\n"
+ " <property name=\"testWhileIdle\" value=\"true\"/>\n"
+ " <property name=\"timeBetweenEvictionRunsMillis\" value=\"1800000\"/>\n"
+ " <property name=\"numTestsPerEvictionRun\" value=\"3\"/>\n"
+ " <property name=\"minEvictableIdleTimeMillis\" value=\"1800000\"/>\n"
+ " </bean>\n"
+ " <bean class=\"org.springframework.orm.jpa.JpaTransactionManager\" id=\"myTransactionManager\">\n"
+ " <property name=\"entityManagerFactory\" ref=\"entityManagerFactory\"/>\n"
+ " </bean>\n"
+ " <tx:annotation-driven mode=\"aspectj\" transaction-manager=\"myTransactionManager\"/>\n"
+ " <bean class=\"org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean\" id=\"entityManagerFactory\">\n"
+ " <property name=\"persistenceUnitName\" value=\"myPersistenceUnit\"/>\n"
+ " <property name=\"dataSource\" ref=\"dataSource\"/>\n" + " </bean>\n"
+ "</beans>\n";
private static final String EXPECTED_JNDI_APPLICATION_CONTEXT =
"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n"
+ "<beans>\n"
+ " <jee:jndi-lookup id=\"dataSource\" jndi-name=\"myDataSource\"/>\n"
+ " <bean class=\"org.springframework.orm.jpa.JpaTransactionManager\" id=\"myTransactionManager\">\n"
+ " <property name=\"entityManagerFactory\" ref=\"entityManagerFactory\"/>\n"
+ " </bean>\n"
+ " <tx:annotation-driven mode=\"aspectj\" transaction-manager=\"myTransactionManager\"/>\n"
+ " <bean class=\"org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean\" id=\"entityManagerFactory\">\n"
+ " <property name=\"persistenceUnitName\" value=\"myPersistenceUnit\"/>\n"
+ " <property name=\"dataSource\" ref=\"dataSource\"/>\n" + " </bean>\n"
+ "</beans>\n";
private static final String EXPECTED_PERSISTENCE_XML_FOR_H2_IN_MEMORY_AND_HIBERNATE =
"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n"
+ "<persistence xmlns=\"http://java.sun.com/xml/ns/persistence\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" version=\"2.0\" xsi:schemaLocation=\"http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd\">\n"
+ "<persistence-unit name=\"myPersistenceUnit\" transaction-type=\"RESOURCE_LOCAL\">\n"
+ " <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>\n"
+ " <properties>\n"
+ " <property name=\"hibernate.dialect\" value=\"dbDialect\"/>\n"
+ " <!-- value=\"create\" to build a new database on each run; value=\"update\" to modify an existing database; value=\"create-drop\" means the same as \"create\" but also drops tables when Hibernate closes; value=\"validate\" makes no changes to the database -->\n"
+ " <property name=\"hibernate.hbm2ddl.auto\" value=\"create\"/>\n"
+ " <property name=\"hibernate.ejb.naming_strategy\" value=\"org.hibernate.cfg.ImprovedNamingStrategy\"/>\n"
+ " <property name=\"hibernate.connection.charSet\" value=\"UTF-8\"/>\n"
+ " <!-- Uncomment the following two properties for JBoss only -->\n"
+ " <!-- property name=\"hibernate.validator.apply_to_ddl\" value=\"false\" /-->\n"
+ " <!-- property name=\"hibernate.validator.autoregister_listeners\" value=\"false\" /-->\n"
+ " </properties>\n" + " </persistence-unit>\n" + "</persistence>\n";
private static final String PERSISTENCE_PATH = "/path/to/persistence";
private static final String PERSISTENCE_UNIT = "myPersistenceUnit";
private static final String POM = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + "<project>"
+ " <build>" + " <plugins>" + " <plugin>"
+ " <groupId>org.apache.maven.plugins</groupId>"
+ " <artifactId>maven-eclipse-plugin</artifactId>"
+ " <version>2.7</version>" + " <configuration>"
+ " <additionalBuildcommands></additionalBuildcommands>"
+ " <additionalProjectnatures></additionalProjectnatures>"
+ " </configuration>" + " </plugin>" + " </plugins>"
+ " </build>" + "</project>";
private static final String POM_PATH = "/path/to/the/pom";
private static final String TRANSACTION_MANAGER = "myTransactionManager";
private Properties dialects;
// Fixture
private JpaOperationsImpl jpaOperations;
@Mock
private FileManager mockFileManager;
@Mock
private PathResolver mockPathResolver;
@Mock
private ProjectOperations mockProjectOperations;
@Mock
private PropFileOperations mockPropFileOperations;
/**
* Creates a new {@link InputStream} each time we need to read from the
* Spring application context
*
* @param pom the application context XML as a String (required)
* @return a fresh stream
*/
private InputStream getAppContextInputStream(final String appContext) {
return new ByteArrayInputStream(appContext.getBytes());
}
/**
* Creates a new {@link InputStream} each time we need to read from the POM
*
* @param pom the POM XML as a String (required)
* @return a fresh stream
*/
private ByteArrayInputStream getPomInputStream(final String pom) {
return new ByteArrayInputStream(pom.getBytes());
}
@Before
public void setUp() throws IllegalArgumentException, IllegalAccessException {
MockitoAnnotations.initMocks(this);
// Mocks
/*when(mockProjectOperations.getPathResolver()).thenReturn(mockPathResolver);
when(mockPathResolver.getFocusedIdentifier(Path.ROOT, JpaOperationsImpl.POM_XML)).thenReturn(
POM_PATH);
// Object under test
jpaOperations = new JpaOperationsImpl();
// Setting pathResolver
MemberModifier.field(JpaOperationsImpl.class, "pathResolver").set(jpaOperations,
mockPathResolver);
// Setting fileManager
MemberModifier.field(JpaOperationsImpl.class, "fileManager")
.set(jpaOperations, mockFileManager);
// Setting projectOperations
MemberModifier.field(JpaOperationsImpl.class, "projectOperations").set(jpaOperations,
mockProjectOperations);
// Things that are too hard or ugly to mock
dialects = new Properties();*/
}
@Test
public void testConfigureJpaForH2InMemoryAndHibernateAndJndiForNewProject() {
// Set up
/* when(mockFileManager.getInputStream(POM_PATH)).thenReturn(
getPomInputStream(POM), getPomInputStream(POM));
when(mockFileManager.getInputStream(APPLICATION_CONTEXT_PATH))
.thenReturn(getAppContextInputStream(APP_CONTEXT));
// i.e. no existing persistence.xml
when(mockFileManager.exists(PERSISTENCE_PATH)).thenReturn(false);
final OrmProvider ormProvider = HIBERNATE;
final JdbcDatabase jdbcDatabase = H2_IN_MEMORY;
dialects.put(ormProvider.name() + "." + jdbcDatabase.name(), DB_DIALECT);
// Invoke
jpaOperations.configureJpa(ormProvider, jdbcDatabase, DB_JNDI_NAME,
null, DB_HOST_NAME, DB_NAME, DB_USER_NAME, DB_PASSWORD,
TRANSACTION_MANAGER, PERSISTENCE_UNIT, "");
// Check
verifyFileUpdate(EXPECTED_JNDI_APPLICATION_CONTEXT,
APPLICATION_CONTEXT_PATH);
verifyFileUpdate(
EXPECTED_PERSISTENCE_XML_FOR_H2_IN_MEMORY_AND_HIBERNATE,
PERSISTENCE_PATH);*/
}
@Test
public void testConfigureJpaForH2InMemoryAndHibernateForNewProject() {
// Set up
/*when(mockFileManager.getInputStream(POM_PATH)).thenReturn(
getPomInputStream(POM), getPomInputStream(POM));
when(mockFileManager.getInputStream(APPLICATION_CONTEXT_PATH))
.thenReturn(getAppContextInputStream(APP_CONTEXT));
// i.e. no existing persistence.xml
when(mockFileManager.exists(PERSISTENCE_PATH)).thenReturn(false);
final OrmProvider ormProvider = HIBERNATE;
final JdbcDatabase jdbcDatabase = H2_IN_MEMORY;
dialects.put(ormProvider.name() + "." + jdbcDatabase.name(), DB_DIALECT);
// Invoke
jpaOperations.configureJpa(ormProvider, jdbcDatabase, null, null,
DB_HOST_NAME, DB_NAME, DB_USER_NAME, DB_PASSWORD,
TRANSACTION_MANAGER, PERSISTENCE_UNIT, "");
// Check
verifyFileUpdate(EXPECTED_APPLICATION_CONTEXT, APPLICATION_CONTEXT_PATH);
verifyFileUpdate(
EXPECTED_PERSISTENCE_XML_FOR_H2_IN_MEMORY_AND_HIBERNATE,
PERSISTENCE_PATH);*/
}
/**
* Verifies that the mock {@link FileManager} was asked to write the given
* contents to the given file
*
* @param expectedContents the contents we expect to be written
* @param filename the file we expect to be written to
*/
private void verifyFileUpdate(final String expectedContents, final String filename) {
final ArgumentCaptor<String> textCaptor = ArgumentCaptor.forClass(String.class);
verify(mockFileManager).createOrUpdateTextFileIfRequired(eq(filename), textCaptor.capture(),
eq(false));
// Replace the dummy line terminator with the platform-specific one that
// will be applied by XmlUtils.nodeToString.
final String normalisedContents = expectedContents.replace("\n", IOUtils.LINE_SEPARATOR);
assertEquals(normalisedContents, textCaptor.getValue());
}
}