package org.multibit.mbm.db.dao.hibernate; import com.google.common.base.Optional; import com.xeiam.xchange.currency.MoneyUtils; import org.junit.Test; import org.multibit.mbm.core.model.*; import org.multibit.mbm.db.dao.ItemDao; import org.multibit.mbm.test.BaseIntegrationTests; import org.springframework.test.context.ContextConfiguration; import javax.annotation.Resource; import java.util.List; import static org.hamcrest.CoreMatchers.equalTo; import static org.junit.Assert.assertThat; /** * Integration test to verify the Hibernate annotations of the DTOs against a generated schema */ @ContextConfiguration(locations = {"/spring/test-mbm-context.xml"}) public class HibernateItemDaoIntegrationTest extends BaseIntegrationTests { @Resource(name= "hibernateItemDao") ItemDao testObject; /** * Simple inserts and updates (includes price persistence check) */ @Test public void testPersistAndFindBySKU() { String sku="abc123"; String gtin="def456"; Item expected = ItemBuilder .newInstance() .withSKU(sku) .withGTIN(gtin) .withLocalPrice(MoneyUtils.parseBitcoin("BTC 1.2345678")) .build(); // Persist with insert int originalItemRows = countRowsInTable("items"); int originalItemFieldDetailRows = countRowsInTable("item_field_details"); int originalItemFieldDetailSecondaryRows = countRowsInTable("item_field_secondary_details"); testObject.saveOrUpdate(expected); testObject.flush(); // Session flush: Expect an insert in items only int updatedItemRows = countRowsInTable("items"); int updatedItemFieldDetailRows = countRowsInTable("item_field_details"); int updatedItemFieldDetailSecondaryRows = countRowsInTable("item_field_secondary_details"); assertThat("Expected session flush for first insert", updatedItemRows, equalTo(originalItemRows+1)); assertThat("Unexpected data in contact_method_details", updatedItemFieldDetailRows, equalTo(originalItemFieldDetailRows)); assertThat("Unexpected data in contact_method_secondary_details", updatedItemFieldDetailSecondaryRows, equalTo(originalItemFieldDetailSecondaryRows)); // Perform an update to the Item that cascades to an insert in ItemField (but not secondary) ItemFieldDetail summary = new ItemFieldDetail(); LocalisedText summary_en = new LocalisedText(); summary_en.setLocaleKey("en"); summary_en.setContent("test Summary_en"); summary.setPrimaryDetail(summary_en); summary.setItemField(ItemField.SUMMARY); expected.setItemFieldDetail(ItemField.SUMMARY, summary); expected=testObject.saveOrUpdate(expected); testObject.flush(); // Session flush: Expect no change to items, insert into item_field_details // Note that itemFieldDetail is now a different instance from the persistent one updatedItemRows = countRowsInTable("items"); updatedItemFieldDetailRows = countRowsInTable("item_field_details"); updatedItemFieldDetailSecondaryRows = countRowsInTable("item_field_secondary_details"); assertThat("Unexpected data in items", updatedItemRows, equalTo(originalItemRows+1)); assertThat("Expected data in item_field_details", updatedItemFieldDetailRows, equalTo(originalItemFieldDetailRows+1)); assertThat("Unexpected data in item_field_secondary_details", updatedItemFieldDetailSecondaryRows, equalTo(originalItemFieldDetailSecondaryRows)); // Perform an update to the Item that cascades to an insert in secondary ItemField // due to an addition to the linked reference summary = expected.getItemFieldDetail(ItemField.SUMMARY); LocalisedText summary_fr = new LocalisedText(); summary_fr.setLocaleKey("fr"); summary_fr.setContent("test Summary_fr"); summary.getSecondaryDetails().add(summary_fr); expected=testObject.saveOrUpdate(expected); testObject.flush(); // Session flush: Expect no change to items, item_field_details, insert into item_field_secondary_details updatedItemRows = countRowsInTable("items"); updatedItemFieldDetailRows = countRowsInTable("item_field_details"); updatedItemFieldDetailSecondaryRows = countRowsInTable("item_field_secondary_details"); assertThat("Unexpected data in items", updatedItemRows, equalTo(originalItemRows+1)); assertThat("Unexpected data in item_field_details", updatedItemFieldDetailRows, equalTo(originalItemFieldDetailRows+1)); assertThat("Unexpected data in item_field_secondary_details", updatedItemFieldDetailSecondaryRows, equalTo(originalItemFieldDetailSecondaryRows+1)); // Query against the SKU Optional<Item> actual=testObject.getBySKU("abc123"); // Session flush: Expect no change to items, contact_method_details, contact_method_secondary_details updatedItemRows = countRowsInTable("items"); updatedItemFieldDetailRows = countRowsInTable("item_field_details"); updatedItemFieldDetailSecondaryRows = countRowsInTable("item_field_secondary_details"); assertThat("Unexpected data in items",updatedItemRows, equalTo(originalItemRows+1)); assertThat("Unexpected data in item_field_details",updatedItemFieldDetailRows, equalTo(originalItemFieldDetailRows+1)); assertThat("Unexpected data in item_field_secondary_details", updatedItemFieldDetailSecondaryRows, equalTo(originalItemFieldDetailSecondaryRows+1)); assertThat(actual.get(),equalTo(expected)); assertThat(actual.get().getGTIN(),equalTo("def456")); assertThat(actual.get().getLocalPrice().getCurrencyUnit().getCurrencyCode(),equalTo("BTC")); assertThat(actual.get().getLocalPrice().getAmount().toPlainString(),equalTo("1.234567800000")); } /** * Verifies that a populated database can be searched and paged */ @Test public void testGetAllByPage() { // All items (check against inefficient joins) final List<Item> allItems = testObject.getAllByPage(5,0); assertThat("Unexpected size in Item page 1", allItems.size(), equalTo(5)); assertThat("Unexpected data ordering in Item [0,1]", allItems.get(0).getId(), equalTo(1L)); assertThat("Unexpected data ordering in Item [1,1]", allItems.get(1).getId(), equalTo(2L)); assertThat("Unexpected data ordering in Item [2,1]", allItems.get(2).getId(), equalTo(3L)); assertThat("Unexpected data ordering in Item [3,1]", allItems.get(3).getId(), equalTo(4L)); assertThat("Unexpected data ordering in Item [4,1]", allItems.get(4).getId(), equalTo(5L)); // Page 1 final List<Item> page1 = testObject.getAllByPage(2,0); assertThat("Unexpected size in Item page 1", page1.size(), equalTo(2)); assertThat("Unexpected data ordering in Item [0,1]", page1.get(0).getId(), equalTo(1L)); assertThat("Unexpected data ordering in Item [1,1]", page1.get(1).getId(), equalTo(2L)); // Page 2 final List<Item> page2 = testObject.getAllByPage(2,1); assertThat("Unexpected size in Item page 2", page2.size(), equalTo(2)); assertThat("Unexpected data ordering in Item [0,2]", page2.get(0).getId(), equalTo(3L)); assertThat("Unexpected data ordering in Item [1,2]", page2.get(1).getId(), equalTo(4L)); // Page 3 final List<Item> page3 = testObject.getAllByPage(2,2); assertThat("Unexpected size in Item page 3", page3.size(), equalTo(1)); assertThat("Unexpected data ordering in Item [0,3]", page3.get(0).getId(), equalTo(5L)); // Predicated searches } /** * Verifies that a populated database can be searched and paged */ @Test public void testGetByExampleByPage() { // Search in the primary TITLE field Item example = ItemBuilder .newInstance() .withPrimaryFieldDetail(ItemField.TITLE, "Central Heating", "en") .build(); final List<Item> byTitle = testObject.getByExampleByPage(5,0,example); assertThat("Unexpected size in Item page 1 (title)", byTitle.size(), equalTo(1)); assertThat("Unexpected data ordering in Item (title) [0,1]", byTitle.get(0).getId(), equalTo(3L)); // Search in both primary TITLE and SUMMARY field (only SUMMARY will succeed) example = ItemBuilder .newInstance() .withPrimaryFieldDetail(ItemField.TITLE, "aardvark", "en") .withPrimaryFieldDetail(ItemField.SUMMARY, "trust me", "en") .build(); final List<Item> byTitleAndSummary = testObject.getByExampleByPage(5,0,example); assertThat("Unexpected size in Item page 1 (summary)", byTitleAndSummary.size(), equalTo(1)); assertThat("Unexpected data ordering in Item (summary) [0,1]", byTitleAndSummary.get(0).getId(), equalTo(1L)); } }