package org.sculptor.examples.library.person.domain; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import static org.sculptor.examples.library.person.domain.PersonName.personName; import static org.sculptor.examples.library.person.domain.PersonProperties.name; import static org.sculptor.examples.library.person.domain.PersonProperties.sex; import static org.sculptor.examples.library.person.domain.PersonProperties.ssn; import static org.sculptor.examples.library.person.domain.Ssn.ssn; import static org.sculptor.framework.accessapi.ConditionalCriteriaBuilder.criteriaFor; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import org.apache.commons.lang.time.DateUtils; import org.junit.After; import org.junit.Before; import org.junit.Ignore; import org.junit.Test; import org.junit.runner.RunWith; import org.sculptor.examples.library.person.exception.PersonNotFoundException; import org.sculptor.framework.accessapi.ConditionalCriteria; import org.sculptor.framework.accessimpl.mongodb.DbManager; import org.sculptor.framework.domain.PagedResult; import org.sculptor.framework.domain.PagingParameter; import org.sculptor.framework.errorhandling.UnexpectedRuntimeException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.AbstractJUnit4SpringContextTests; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = { "classpath:applicationContext-test.xml" }) public class PersonRepositoryTest extends AbstractJUnit4SpringContextTests { private static final String[] DATE_PATTERNS = { "yyyy-MM-dd" }; @Autowired private PersonRepository personRepository; @Autowired private DbManager dbManager; @Before public void initialData() throws Exception { Person p1 = new Person(Gender.MALE, ssn("123456", Country.DENMARK)); p1.setBirthDate(DateUtils.parseDate("1963-01-01", DATE_PATTERNS)); p1.setName(personName("Aaaa", "Bbbb")); p1 = personRepository.save(p1); Person p2 = new Person(Gender.FEMALE, ssn("123456", Country.SWEDEN)); p2.setBirthDate(DateUtils.parseDate("1964-01-01", DATE_PATTERNS)); p2.setName(personName("Xxxx", "Yyyy")); p2 = personRepository.save(p2); Person p3 = new Person(Gender.FEMALE, ssn("987654", Country.DENMARK)); p3.setBirthDate(DateUtils.parseDate("1965-01-01", DATE_PATTERNS)); p3.setName(personName("Cccc", "Dddd")); p3 = personRepository.save(p3); createInitiaData("999999", "Zzzz1"); createInitiaData("999998", "Zzzz2"); createInitiaData("999997", "Zzzz3"); createInitiaData("999996", "Zzzz4"); createInitiaData("999995", "Zzzz5"); createInitiaData("999994", "Zzzz6"); createInitiaData("999993", "Zzzz7"); } private void createInitiaData(String ssnNumber, String firstName) throws Exception { Person p = new Person(Gender.MALE, ssn(ssnNumber, Country.NORWAY)); p.setBirthDate(DateUtils.parseDate("1966-01-01", DATE_PATTERNS)); p.setName(personName(firstName, "Zzzz")); p = personRepository.save(p); } @After public void dropDatabase() { Set<String> names = dbManager.getDB().getCollectionNames(); for (String each : names) { if (!each.startsWith("system")) { dbManager.getDB().getCollection(each).drop(); } } // dbManager.getDB().dropDatabase(); } @Test public void shouldFindBySimplePropertyCondition() throws Exception { List<ConditionalCriteria> conditionalCriteria = criteriaFor(Person.class).withProperty(sex()).eq(Gender.FEMALE) .build(); List<Person> persons = personRepository.findByCondition(conditionalCriteria); assertEquals(2, persons.size()); } @Test public void shouldFindByNestedPropertyCondition() throws Exception { List<ConditionalCriteria> conditionalCriteria = criteriaFor(Person.class).withProperty(ssn().country()) .eq(Country.SWEDEN).orderBy(name().last()).build(); List<Person> persons = personRepository.findByCondition(conditionalCriteria); assertEquals(1, persons.size()); assertEquals(Country.SWEDEN, persons.get(0).getSsn().getCountry()); } @Test(expected = UnexpectedRuntimeException.class) public void shouldFindByOrCondition() throws Exception { List<ConditionalCriteria> conditionalCriteria = criteriaFor(Person.class).withProperty(name().first()) .eq("Aaaa").or().withProperty(name().last()).eq("Dddd").orderBy(name().last()).build(); personRepository.findByCondition(conditionalCriteria); } @Test public void shouldFindByGroupedCondition() throws Exception { List<ConditionalCriteria> conditionalCriteria = criteriaFor(Person.class).withProperty(sex()).eq(Gender.FEMALE) .and().lbrace().withProperty(name().first()).eq("Xxxx").and().withProperty(name().last()).eq("Yyyy") .rbrace().orderBy(name().last()).build(); List<Person> persons = personRepository.findByCondition(conditionalCriteria); assertEquals(1, persons.size()); assertEquals("123456", persons.get(0).getSsn().getNumber()); assertEquals(Country.SWEDEN, persons.get(0).getSsn().getCountry()); } @Test public void shouldFindByNotCondition() throws Exception { List<ConditionalCriteria> conditionalCriteria = criteriaFor(Person.class).not().withProperty(sex()) .eq(Gender.MALE).build(); List<Person> persons = personRepository.findByCondition(conditionalCriteria); assertEquals(2, persons.size()); } @Test public void shouldFindByGroupedNotCondition() throws Exception { List<ConditionalCriteria> conditionalCriteria = criteriaFor(Person.class).withProperty(sex()).eq(Gender.MALE) .and().not().lbrace().withProperty(ssn().country()).eq(Country.NORWAY).and() .withProperty(name().last()).eq("Dddd").rbrace().orderBy(name().last()).build(); List<Person> persons = personRepository.findByCondition(conditionalCriteria); assertEquals(1, persons.size()); assertEquals("123456", persons.get(0).getSsn().getNumber()); assertEquals(Country.DENMARK, persons.get(0).getSsn().getCountry()); } @Test public void shouldOrderByCondition() throws Exception { List<ConditionalCriteria> conditionalCriteria = criteriaFor(Person.class).withProperty(ssn().country()) .eq(Country.NORWAY).orderBy(name().first()).build(); List<Person> persons = personRepository.findByCondition(conditionalCriteria); String previous = null; for (Person each : persons) { if (previous != null) { assertTrue("Expected " + each.getName().getFirst() + " >= " + previous, each.getName().getFirst() .compareTo(previous) >= 0); } previous = each.getName().getFirst(); } } @Test public void shouldFindByInCondition() throws Exception { List<ConditionalCriteria> conditionalCriteria = criteriaFor(Person.class).withProperty(name().first()) .in("Zzzz1", "Zzzz3", "Zzzz5").build(); List<Person> persons = personRepository.findByCondition(conditionalCriteria); assertEquals(3, persons.size()); } @Test public void shouldFindByKey() throws Exception { Person found = personRepository.findByKey(ssn("123456", Country.DENMARK)); assertNotNull(found); assertEquals(Country.DENMARK, found.getSsn().getCountry()); } @Test(expected = PersonNotFoundException.class) public void shouldNotFindByKey() throws Exception { personRepository.findByKey(ssn("123456", Country.NORWAY)); } @Test public void shouldFindByNaturalKeys() throws Exception { Set<Ssn> keys = new HashSet<Ssn>(); Ssn ssn1 = new Ssn("123456", Country.DENMARK); keys.add(ssn1); Ssn ssn2 = new Ssn("987654", Country.DENMARK); keys.add(ssn2); Ssn ssn3 = new Ssn("999999", Country.SWEDEN); keys.add(ssn3); Map<Ssn, Person> persons = personRepository.findByNaturalKeys(keys); assertEquals(2, persons.size()); assertNull(persons.get(ssn3)); assertEquals("Aaaa", persons.get(ssn1).getName().getFirst()); assertEquals(Gender.MALE, persons.get(ssn1).getSex()); assertEquals("Cccc", persons.get(ssn2).getName().getFirst()); assertEquals(Gender.FEMALE, persons.get(ssn2).getSex()); } @Test public void shouldFindAllFirstPage() throws Exception { // thera are 10 persons PagingParameter pagingParameter = PagingParameter.pageAccess(3, 1, true); PagedResult<Person> pagedResult = personRepository.findAll(pagingParameter); assertEquals(1, pagedResult.getPage()); assertEquals(3, pagedResult.getPageSize()); assertEquals(3, pagedResult.getValues().size()); assertTrue(pagedResult.isTotalCounted()); assertEquals(4, pagedResult.getTotalPages()); assertEquals(10, pagedResult.getTotalRows()); } @Test public void shouldFindAllSecondPage() throws Exception { PagingParameter pagingParameter = PagingParameter.pageAccess(3, 2); PagedResult<Person> pagedResult = personRepository.findAll(pagingParameter); assertEquals(2, pagedResult.getPage()); assertEquals(3, pagedResult.getPageSize()); assertEquals(3, pagedResult.getValues().size()); assertFalse(pagedResult.isTotalCounted()); } @Test public void shouldFindAllThirdPage() throws Exception { PagingParameter pagingParameter = PagingParameter.pageAccess(3, 3); PagedResult<Person> pagedResult = personRepository.findAll(pagingParameter); assertEquals(3, pagedResult.getPage()); assertEquals(3, pagedResult.getPageSize()); assertEquals(3, pagedResult.getValues().size()); assertFalse(pagedResult.isTotalCounted()); } @Test public void shouldFindAllLastPage() throws Exception { PagingParameter pagingParameter = PagingParameter.pageAccess(3, 4); PagedResult<Person> pagedResult = personRepository.findAll(pagingParameter); assertEquals(4, pagedResult.getPage()); assertEquals(3, pagedResult.getPageSize()); assertEquals(1, pagedResult.getValues().size()); // when end reached last page we get the total, even though we didn't // ask for it assertTrue(pagedResult.isTotalCounted()); assertEquals(4, pagedResult.getTotalPages()); assertEquals(10, pagedResult.getTotalRows()); } @Test public void shouldNotFindAllWhenPageNumberTooBig() throws Exception { PagingParameter pagingParameter = PagingParameter.pageAccess(3, 17); PagedResult<Person> pagedResult = personRepository.findAll(pagingParameter); assertEquals(17, pagedResult.getPage()); assertEquals(3, pagedResult.getPageSize()); assertEquals(0, pagedResult.getValues().size()); // when end reached last page we get the total, even though we didn't // ask for it // but only if it's really last page (some rows was fetched) assertFalse(pagedResult.isTotalCounted()); } @Test public void shouldFindAllFillAddionalResultRows() throws Exception { PagingParameter pagingParameter = PagingParameter.rowAccess(4, 6, 3); PagedResult<Person> pagedResult = personRepository.findAll(pagingParameter); assertEquals(-1, pagedResult.getPage()); assertEquals(-1, pagedResult.getPageSize()); assertEquals(2, pagedResult.getValues().size()); assertFalse(pagedResult.isTotalCounted()); assertEquals(-1, pagedResult.getTotalPages()); assertEquals(-1, pagedResult.getTotalRows()); assertTrue(pagedResult.isAddionalResultCounted()); assertEquals(-1, pagedResult.getAdditionalResultPages()); assertEquals(3, pagedResult.getAdditionalResultRows()); } @Test public void shouldFindAllFillAddionalResultPage2() throws Exception { PagingParameter pagingParameter = PagingParameter.pageAccess(3, 2, 2); PagedResult<Person> pagedResult = personRepository.findAll(pagingParameter); assertEquals(2, pagedResult.getPage()); assertEquals(3, pagedResult.getPageSize()); assertEquals(3, pagedResult.getValues().size()); assertFalse(pagedResult.isTotalCounted()); assertEquals(-1, pagedResult.getTotalPages()); assertEquals(-1, pagedResult.getTotalRows()); assertTrue(pagedResult.isAddionalResultCounted()); assertEquals(2, pagedResult.getAdditionalResultPages()); assertEquals(4, pagedResult.getAdditionalResultRows()); } @Test public void shouldFindAllFillCountPage3() throws Exception { PagingParameter pagingParameter = PagingParameter.pageAccess(3, 3, 2); PagedResult<Person> pagedResult = personRepository.findAll(pagingParameter); assertEquals(3, pagedResult.getPage()); assertEquals(3, pagedResult.getPageSize()); assertEquals(3, pagedResult.getValues().size()); // when end reached last page we get the total, even though we didn't // ask for it assertTrue(pagedResult.isTotalCounted()); assertEquals(4, pagedResult.getTotalPages()); assertEquals(10, pagedResult.getTotalRows()); assertTrue(pagedResult.isAddionalResultCounted()); assertEquals(1, pagedResult.getAdditionalResultPages()); assertEquals(1, pagedResult.getAdditionalResultRows()); } @Test public void shouldFindAllFillCountPage4() throws Exception { PagingParameter pagingParameter = PagingParameter.pageAccess(3, 4, 2); PagedResult<Person> pagedResult = personRepository.findAll(pagingParameter); assertEquals(4, pagedResult.getPage()); assertEquals(3, pagedResult.getPageSize()); assertEquals(1, pagedResult.getValues().size()); // when end reached last page we get the total, even though we didn't // ask for it assertTrue(pagedResult.isTotalCounted()); assertEquals(4, pagedResult.getTotalPages()); assertEquals(10, pagedResult.getTotalRows()); assertTrue(pagedResult.isAddionalResultCounted()); assertEquals(0, pagedResult.getAdditionalResultPages()); assertEquals(0, pagedResult.getAdditionalResultRows()); } @Test public void shouldCalculateMaxPagesWhenSmallPageSize() throws Exception { PagingParameter pagingParameter = PagingParameter.pageAccess(3, 1, true); PagedResult<Person> pagedResult = personRepository.findAll(pagingParameter); assertEquals(4, pagedResult.getTotalPages()); } @Test public void shouldCalculateMaxPagesWhenPageSizeEqualToCount() throws Exception { PagingParameter pagingParameter = PagingParameter.pageAccess(10, 1, true); PagedResult<Person> pagedResult = personRepository.findAll(pagingParameter); assertEquals(1, pagedResult.getTotalPages()); } @Test public void shouldCalculateMaxPagesWhenHalfPageSizeToCount() throws Exception { PagingParameter pagingParameter = PagingParameter.pageAccess(5, 1, true); PagedResult<Person> pagedResult = personRepository.findAll(pagingParameter); assertEquals(2, pagedResult.getTotalPages()); } @Test public void shouldCalculateMaxPagesWhenLargePageSize() throws Exception { PagingParameter pagingParameter = PagingParameter.pageAccess(100, 1, true); PagedResult<Person> pagedResult = personRepository.findAll(pagingParameter); assertEquals(1, pagedResult.getTotalPages()); } @Test public void shouldFetchAllWithRowAccess() throws Exception { Set<Person> all = new HashSet<Person>(); int row = 0; while (row < 20) { PagingParameter pagingParameter = PagingParameter.rowAccess(row, row + 3, 1); PagedResult<Person> result = personRepository.findAll(pagingParameter); all.addAll(result.getValues()); if (result.getAdditionalResultRows() <= 0) { break; } row = result.getEndRow(); } assertEquals(10, all.size()); } @Test public void shouldFetchAllWithPageAccess() throws Exception { Set<Person> all = new HashSet<Person>(); for (int page = 1; page < 20; page++) { PagingParameter pagingParameter = PagingParameter.pageAccess(3, page, 1); PagedResult<Person> result = personRepository.findAll(pagingParameter); all.addAll(result.getValues()); if (result.getAdditionalResultPages() <= 0) { break; } } assertEquals(10, all.size()); } @Test @Ignore // not implemented yet public void shouldFetchAllWithNextPageAccess() throws Exception { Set<Person> all = new HashSet<Person>(); PagedResult<Person> result = null; while (true) { PagingParameter pagingParameter; if (result == null) { pagingParameter = PagingParameter.pageAccess(3, 1); } else { pagingParameter = PagingParameter.getNextPage(result); } result = personRepository.findAll(pagingParameter); if (result.getValues().isEmpty()) { break; } all.addAll(result.getValues()); } assertEquals(10, all.size()); } }