/** * The contents of this file are subject to the OpenMRS Public License * Version 1.0 (the "License"); you may not use this file except in * compliance with the License. You may obtain a copy of the License at * http://license.openmrs.org * * Software distributed under the License is distributed on an "AS IS" * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the * License for the specific language governing rights and limitations * under the License. * * Copyright (C) OpenMRS, LLC. All Rights Reserved. */ package org.openmrs.module.sync.api.db.hibernate; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.dbunit.database.DatabaseConfig; import org.dbunit.database.DatabaseConnection; import org.dbunit.database.IDatabaseConnection; import org.dbunit.database.QueryDataSet; import org.dbunit.dataset.xml.FlatXmlDataSet; import org.dbunit.ext.hsqldb.HsqldbDataTypeFactory; import org.junit.After; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.openmrs.EncounterType; import org.openmrs.VisitType; import org.openmrs.api.context.Context; import org.openmrs.module.sync.TestUtil; import org.openmrs.module.sync.test.ExampleTransactionalService; import org.openmrs.test.BaseModuleContextSensitiveTest; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.annotation.NotTransactional; import org.springframework.test.annotation.Rollback; import org.springframework.test.context.transaction.AfterTransaction; import org.springframework.test.context.transaction.BeforeTransaction; import org.springframework.transaction.annotation.Transactional; import java.io.StringWriter; /** * Tests transaction handling of the HibernateSyncInterceptor */ public class HibernateSyncInterceptorTransactionTest extends BaseModuleContextSensitiveTest { protected final Log log = LogFactory.getLog(getClass()); private static final String ENCOUNTER_TYPE = "Test Encounter Type"; private static final String VISIT_TYPE = "Visit Type"; private static final String EXCEPTION_MESSAGE = "Test Exception"; @Autowired ExampleTransactionalService testService; @Before @Override public void baseSetupWithStandardDataAndAuthentication() throws Exception { } @After @Override public void deleteAllData() throws Exception { } @BeforeTransaction public void beforeTx() throws Exception { Context.openSession(); initializeInMemoryDatabase(); executeDataSet(EXAMPLE_XML_DATASET_PACKAGE_PATH); executeDataSet("org/openmrs/module/sync/include/" + new TestUtil().getTestDatasetFilename("syncCreateTest")); authenticate(); } @AfterTransaction public void afterTx() throws Exception { if (log.isDebugEnabled()) { log.debug("====== ENCOUNTER_TYPE ========="); log.debug(getTableContents("encounter_type")); log.debug("====== VISIT_TYPE ========="); log.debug(getTableContents("visit_type")); log.debug("====== SYNC_RECORD ========="); log.debug(getTableContents("sync_record")); } if (checkTableContains("encounter_type", ENCOUNTER_TYPE)) { Assert.assertTrue("Encounter Type saved, but Sync Record was not", checkTableContains("sync_record", ENCOUNTER_TYPE)); } else { Assert.assertFalse("Encounter Type not saved, but Sync Record was", checkTableContains("sync_record", ENCOUNTER_TYPE)); } if (checkTableContains("visit_type", VISIT_TYPE)) { Assert.assertTrue("Visit Type saved, but Sync Record was not", checkTableContains("sync_record", VISIT_TYPE)); } else { Assert.assertFalse("Visit Type not saved, but Sync Record was", checkTableContains("sync_record", VISIT_TYPE)); } super.deleteAllData(); } @Test @Transactional @Rollback(false) public void shouldTestAllInSameTx() throws Exception { { EncounterType encounterType = new EncounterType(); encounterType.setName(ENCOUNTER_TYPE); encounterType.setDescription("Encounter Type Description"); testService.saveObjectInTransaction(encounterType); } { VisitType visitType = new VisitType(); visitType.setName(VISIT_TYPE); visitType.setDescription("Visit Type Description"); testService.saveObjectInTransaction(visitType); } } @Test @Transactional @Rollback(false) public void shouldTestFirstInNewTx() throws Exception { { EncounterType encounterType = new EncounterType(); encounterType.setName(ENCOUNTER_TYPE); encounterType.setDescription("Encounter Type Description"); testService.saveObjectInNewTransaction(encounterType); } { VisitType visitType = new VisitType(); visitType.setName(VISIT_TYPE); visitType.setDescription("Visit Type Description"); testService.saveObjectInTransaction(visitType); } } @Test @Transactional @Rollback(false) public void shouldTestSecondInNewTx() throws Exception { { EncounterType encounterType = new EncounterType(); encounterType.setName(ENCOUNTER_TYPE); encounterType.setDescription("Encounter Type Description"); testService.saveObjectInTransaction(encounterType); } { VisitType visitType = new VisitType(); visitType.setName(VISIT_TYPE); visitType.setDescription("Visit Type Description"); testService.saveObjectInNewTransaction(visitType); } } @Test @Transactional @Rollback(false) public void shouldTestBothInNewTx() throws Exception { { EncounterType encounterType = new EncounterType(); encounterType.setName(ENCOUNTER_TYPE); encounterType.setDescription("Encounter Type Description"); testService.saveObjectInNewTransaction(encounterType); } { VisitType visitType = new VisitType(); visitType.setName(VISIT_TYPE); visitType.setDescription("Visit Type Description"); testService.saveObjectInNewTransaction(visitType); } } @Test @Transactional @Rollback(false) public void shouldTestFirstInNoTransaction() throws Exception { { EncounterType encounterType = new EncounterType(); encounterType.setName(ENCOUNTER_TYPE); encounterType.setDescription("Encounter Type Description"); testService.saveObjectNoTransaction(encounterType); } { VisitType visitType = new VisitType(); visitType.setName(VISIT_TYPE); visitType.setDescription("Visit Type Description"); testService.saveObjectInTransaction(visitType); } } @Test @NotTransactional public void shouldTestFirstThrowsException() throws Exception { beforeTx(); { EncounterType encounterType = new EncounterType(); encounterType.setName(ENCOUNTER_TYPE); encounterType.setDescription("Encounter Type Description"); String exceptionMessage = ""; try { testService.saveObjectInTransactionWithException(encounterType); } catch (IllegalArgumentException e) { exceptionMessage = e.getMessage(); } Assert.assertEquals(EXCEPTION_MESSAGE, exceptionMessage); } { VisitType visitType = new VisitType(); visitType.setName(VISIT_TYPE); visitType.setDescription("Visit Type Description"); testService.saveObjectInTransaction(visitType); } afterTx(); } @Test @NotTransactional public void shouldTestSecondThrowsException() throws Exception { beforeTx(); { EncounterType encounterType = new EncounterType(); encounterType.setName(ENCOUNTER_TYPE); encounterType.setDescription("Encounter Type Description"); testService.saveObjectInTransaction(encounterType); } { VisitType visitType = new VisitType(); visitType.setName(VISIT_TYPE); visitType.setDescription("Visit Type Description"); String exceptionMessage = ""; try { testService.saveObjectInTransactionWithException(visitType); } catch (IllegalArgumentException e) { exceptionMessage = e.getMessage(); } Assert.assertEquals(EXCEPTION_MESSAGE, exceptionMessage); } afterTx(); } public String getTableContents(String tableName) throws Exception { StringWriter writer = new StringWriter(); IDatabaseConnection connection = new DatabaseConnection(getConnection()); DatabaseConfig config = connection.getConfig(); config.setProperty(DatabaseConfig.PROPERTY_DATATYPE_FACTORY, new HsqldbDataTypeFactory()); QueryDataSet outputSet = new QueryDataSet(connection); outputSet.addTable(tableName); FlatXmlDataSet.write(outputSet, writer); return writer.toString(); } public boolean checkTableContains(String tableName, String testValue) throws Exception { return getTableContents(tableName).contains(testValue); } }