/*
* Copyright 2014 - 2017 Blazebit.
*
* Licensed under the Apache License, Version 2.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://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.blazebit.persistence.impl.springdata;
import com.blazebit.persistence.impl.springdata.accessor.DocumentAccessor;
import com.blazebit.persistence.impl.springdata.accessor.DocumentAccessors;
import com.blazebit.persistence.impl.springdata.config.SystemPropertyBasedActiveProfilesResolver;
import com.blazebit.persistence.impl.springdata.entity.Document;
import com.blazebit.persistence.impl.springdata.entity.Person;
import com.blazebit.persistence.impl.springdata.repository.DocumentEntityRepository;
import com.blazebit.persistence.impl.springdata.repository.DocumentRepository;
import com.blazebit.persistence.impl.springdata.repository.DocumentViewRepository;
import com.blazebit.persistence.impl.springdata.repository.EntityViewRepositoryFactoryBean;
import com.blazebit.persistence.impl.springdata.tx.TransactionalWorkService;
import com.blazebit.persistence.impl.springdata.tx.TxWork;
import com.blazebit.persistence.view.impl.spring.EnableEntityViews;
import org.junit.Assume;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.ImportResource;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Slice;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.ContextConfiguration;
import javax.persistence.EntityManager;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import static org.junit.Assert.*;
/**
* @author Moritz Becker (moritz.becker@gmx.at)
* @since 1.2
*/
@RunWith(Parameterized.class)
@ContextConfiguration(classes = DocumentRepositoryTest.TestConfig.class)
@ActiveProfiles(resolver = SystemPropertyBasedActiveProfilesResolver.class)
@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD)
public class DocumentRepositoryTest extends AbstractSpringTest {
@Parameterized.Parameters
public static Iterable<?> createParameters() {
return Arrays.asList(DocumentViewRepository.class, DocumentEntityRepository.class);
}
private final Class<? extends DocumentRepository<?>> repositoryClass;
@Autowired
private AutowireCapableBeanFactory autowireCapableBeanFactory;
@Autowired
private TransactionalWorkService transactionalWorkService;
private DocumentRepository<?> documentRepository;
public DocumentRepositoryTest(Class<? extends DocumentRepository<?>> repositoryClass) {
this.repositoryClass = repositoryClass;
}
@Before
public void initRepository() {
documentRepository = autowireCapableBeanFactory.getBean(repositoryClass);
}
@Test
public void testFindOne() {
// Given
final Document d1 = createDocument("D1");
final Document d2 = createDocument("D2");
// When
DocumentAccessor result1 = DocumentAccessors.of(documentRepository.findOne(d1.getId()));
DocumentAccessor result2 = DocumentAccessors.of(documentRepository.findOne(d2.getId()));
// Then
assertEquals(d1.getId(), result1.getId());
assertNotNull(result1);
assertEquals(d2.getId(), result2.getId());
assertNotNull(result2);
}
@Test
public void testExists(){
// Given
final Document d1 = createDocument("D1");
// When
boolean existsP1 = documentRepository.exists(d1.getId());
// Then
assertTrue(existsP1);
}
@Test
public void testFindAll() {
// Given
final Person p1 = createPerson("P1");
final Document d1 = createDocument("D1", p1);
final Document d2 = createDocument("D2", p1);
// When
Iterable<DocumentAccessor> actual = DocumentAccessors.of(documentRepository.findAll());
List<Long> actualIds = getIdsFromViews(actual);
// Then
assertEquals(2, actualIds.size());
assertTrue(actualIds.contains(d1.getId()));
assertTrue(actualIds.contains(d2.getId()));
}
@Test
public void testFindAllByIds() {
// ignored with EclipseLink due to IN collection rendering bug
Assume.assumeFalse(isEntityRepository() && isEclipseLink());
// Given
final Document d1 = createDocument("D1");
final Document d2 = createDocument("D2");
// When
Iterable<DocumentAccessor> actual = DocumentAccessors.of(documentRepository.findAll(Arrays.asList(d1.getId(), d2.getId())));
List<Long> actualIds = getIdsFromViews(actual);
// Then
assertEquals(2, actualIds.size());
assertTrue(actualIds.contains(d1.getId()));
assertTrue(actualIds.contains(d2.getId()));
}
@Test
public void testCount() {
// Given
final Document d1 = createDocument("D1");
final Document d2 = createDocument("D2");
// When
long count = documentRepository.count();
// Then
assertEquals(2, count);
}
@Test
public void testFindByName() {
// Given
final Document d1 = createDocument("D1");
// When
List<DocumentAccessor> result = DocumentAccessors.of(documentRepository.findByName(d1.getName()));
// Then
assertEquals(1, result.size());
assertEquals(d1.getId(), result.get(0).getId());
}
@Test
public void testFindByNameAndAgeOrDescription() {
// Given
final String name = "D1";
final Document d1 = createDocument(name, "desc1", 12, null);
final Document d2 = createDocument(name, "desc2", 13, null);
final Document d3 = createDocument(name, "desc3", 14, null);
// When
List<DocumentAccessor> actual = DocumentAccessors.of(documentRepository.findByNameAndAgeOrDescription(name, 12, "desc2"));
List<Long> actualIds = getIdsFromViews(actual);
// Then
assertEquals(2, actual.size());
assertTrue(actualIds.contains(d1.getId()));
assertTrue(actualIds.contains(d2.getId()));
}
@Test
public void testFindByNameIn() {
// ignored with EclipseLink due to IN collection rendering bug
Assume.assumeFalse(isEntityRepository() && isEclipseLink());
// Given
final Document d1 = createDocument("d1");
final Document d2 = createDocument("d2");
final Document d3 = createDocument("d3");
// When
List<DocumentAccessor> actual = DocumentAccessors.of(documentRepository.findByNameIn(d2.getName(), d3.getName()));
List<Long> actualIds = getIdsFromViews(actual);
// Then
assertEquals(2, actual.size());
assertTrue(actualIds.contains(d2.getId()));
assertTrue(actualIds.contains(d3.getId()));
}
@Test
public void testFindByNameInPaginated() {
// ignored with EclipseLink due to IN collection rendering bug
Assume.assumeFalse(isEntityRepository() && isEclipseLink());
// Given
final Document d1 = createDocument("d1");
final Document d2 = createDocument("d2");
final Document d3 = createDocument("d3");
// When
Page<DocumentAccessor> actual = DocumentAccessors.of(documentRepository.findByNameInOrderById(new PageRequest(0, 1), d2.getName(), d3.getName()));
List<Long> actualIds = getIdsFromViews(actual);
// Then
assertEquals(2, actual.getTotalPages());
assertEquals(0, actual.getNumber());
assertEquals(1, actual.getNumberOfElements());
assertEquals(1, actual.getSize());
assertTrue(actualIds.contains(d2.getId()));
actual = DocumentAccessors.of(documentRepository.findByNameInOrderById(actual.nextPageable(), d2.getName(), d3.getName()));
actualIds = getIdsFromViews(actual);
assertEquals(2, actual.getTotalPages());
assertEquals(1, actual.getNumber());
assertEquals(1, actual.getNumberOfElements());
assertEquals(1, actual.getSize());
assertTrue(actualIds.contains(d3.getId()));
}
@Test
public void testFindByNameLikeOrderByAgeAsc() {
// Given
final Document d1 = createDocument("d1", null, 2l, null);
final Document d2 = createDocument("d2", null, 1l, null);
// When
List<DocumentAccessor> actual = DocumentAccessors.of(documentRepository.findByNameLikeOrderByAgeAsc("d%"));
// Then
assertEquals(2, actual.size());
assertEquals(d2.getId(), actual.get(0).getId());
assertEquals(d1.getId(), actual.get(1).getId());
}
@Test
public void testFindByOwnerName() {
// Given
final Person p1 = createPerson("p1");
final Person p2 = createPerson("p2");
final Document d1 = createDocument("d1", p1);
final Document d2 = createDocument("d2", p2);
final Document d3 = createDocument("d3", p2);
// When
List<DocumentAccessor> actual = DocumentAccessors.of(documentRepository.findByOwnerName(p2.getName()));
List<Long> actualIds = getIdsFromViews(actual);
// Then
assertEquals(2, actual.size());
assertTrue(actualIds.contains(d2.getId()));
assertTrue(actualIds.contains(d3.getId()));
}
@Test
public void testFindByAgeGreaterThanEqual() {
// Given
final Document d1 = createDocument("d1", null, 3l, null);
final Document d2 = createDocument("d2", null, 4l, null);
final Document d3 = createDocument("d3", null, 5l, null);
// When
List<DocumentAccessor> actual = DocumentAccessors.of(documentRepository.findByAgeGreaterThanEqual(4l));
List<Long> actualIds = getIdsFromViews(actual);
// Then
assertEquals(2, actual.size());
assertTrue(actualIds.contains(d2.getId()));
assertTrue(actualIds.contains(d3.getId()));
}
@Test
public void testFindSliceByAgeGreaterThanEqual() {
// Given
final Document d1 = createDocument("d1", null, 3l, null);
final Document d2 = createDocument("d2", null, 4l, null);
final Document d3 = createDocument("d3", null, 5l, null);
// When
Slice<DocumentAccessor> actual = DocumentAccessors.of(documentRepository.findSliceByAgeGreaterThanEqual(4l, new PageRequest(1, 1)));
List<Long> actualIds = getIdsFromViews(actual);
// Then
assertEquals(1, actual.getSize());
assertFalse(actual.hasNext());
assertTrue(actual.hasPrevious());
assertTrue(actualIds.contains(d3.getId()));
}
@Test
public void testFindFirstByOrderByNameAsc() {
// Given
final Document d3 = createDocument("d3");
final Document d2 = createDocument("d2");
final Document d1 = createDocument("d1");
// When
DocumentAccessor actual = DocumentAccessors.of(documentRepository.findFirstByOrderByNameAsc());
// Then
assertEquals(d1.getId(), actual.getId());
}
@Test
public void testFindByAgeIn() {
// ignored with EclipseLink due to IN collection rendering bug
Assume.assumeFalse(isEclipseLink());
// Given
final Document d3 = createDocument("d3");
final Document d2 = createDocument("d2");
final Document d1 = createDocument("d1");
// When
List<DocumentAccessor> actual1 = DocumentAccessors.of(documentRepository.findByNameIn(new HashSet<String>(0)));
List<DocumentAccessor> actual2 = DocumentAccessors.of(documentRepository.findByAgeIn(new Long[0]));
// Then
assertEquals(0, actual1.size());
assertEquals(0, actual2.size());
}
@Test
public void testFindOneBySpec() {
// Given
final Document d3 = createDocument("d3", null, 3L, null);
final Document d2 = createDocument("d2", null, 2L, null);
final Document d1 = createDocument("d1", null, 1L, null);
// When
DocumentAccessor actual = DocumentAccessors.of(((DocumentRepository) documentRepository).findOne(new Specification<Document>() {
@Override
public Predicate toPredicate(Root<Document> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
return criteriaBuilder.equal(root.<String>get("name"), "d2");
}
}));
// Then
assertTrue(actual.getId().equals(d2.getId()));
}
@Test
public void testFindAllBySpec() {
// Given
final Document d3 = createDocument("d3", null, 3L, null);
final Document d2 = createDocument("d2", null, 2L, null);
final Document d1 = createDocument("d1", null, 1L, null);
// When
List<DocumentAccessor> actual = DocumentAccessors.of(((DocumentRepository) documentRepository).findAll(new Specification<Document>() {
@Override
public Predicate toPredicate(Root<Document> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
return criteriaBuilder.ge(root.<Long>get("age"), 2L);
}
}));
List<Long> actualIds = getIdsFromViews(actual);
// Then
assertEquals(2, actual.size());
assertTrue(actualIds.contains(d2.getId()));
assertTrue(actualIds.contains(d3.getId()));
}
@Test
public void testFindAllBySpecPageable() {
// Given
final Document d4 = createDocument("d4", null, 2L, null);
final Document d3 = createDocument("d3", null, 3L, null);
final Document d2 = createDocument("d2", null, 2L, null);
final Document d1 = createDocument("d1", null, 1L, null);
// When
Page<DocumentAccessor> actual = DocumentAccessors.of(((DocumentRepository) documentRepository).findAll(new Specification<Document>() {
@Override
public Predicate toPredicate(Root<Document> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
return criteriaBuilder.gt(root.<Long>get("age"), 1L);
}
}, new PageRequest(1, 2, Sort.Direction.ASC, "name", "id")));
List<Long> actualIds = getIdsFromViews(actual);
// Then
assertEquals(1, actual.getNumberOfElements());
assertTrue(actualIds.contains(d4.getId()));
}
@Test
public void testFindAllBySpecSorted() {
// Given
final Document d3 = createDocument("d3", null, 3L, null);
final Document d2 = createDocument("d2", null, 2L, null);
final Document d1 = createDocument("d1", null, 1L, null);
// When
List<DocumentAccessor> actual = DocumentAccessors.of(((DocumentRepository) documentRepository).findAll(new Specification<Document>() {
@Override
public Predicate toPredicate(Root<Document> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
return criteriaBuilder.ge(root.<Long>get("age"), 2L);
}
}, new Sort(Sort.Direction.ASC, "name")));
// Then
assertEquals(2, actual.size());
assertTrue(actual.get(0).getId().equals(d2.getId()));
assertTrue(actual.get(1).getId().equals(d3.getId()));
}
private List<Long> getIdsFromViews(Iterable<DocumentAccessor> views) {
List<Long> ids = new ArrayList<>();
for (DocumentAccessor view : views) {
ids.add(view.getId());
}
return ids;
}
private Document createDocument(String name) {
return createDocument(name, null);
}
private Document createDocument(final String name, final Person owner) {
return createDocument(name, null, 0l, owner);
}
private Document createDocument(final String name, final String description, final long age, final Person owner) {
return transactionalWorkService.doTxWork(new TxWork<Document>() {
@Override
public Document work(EntityManager em) {
Document d = new Document(name);
d.setDescription(description);
d.setAge(age);
d.setOwner(owner);
em.persist(d);
return d;
}
});
}
private Person createPerson(final String name) {
return transactionalWorkService.doTxWork(new TxWork<Person>() {
@Override
public Person work(EntityManager em) {
Person p = new Person(name);
em.persist(p);
return p;
}
});
}
private boolean isEntityRepository() {
return repositoryClass == DocumentEntityRepository.class;
}
private boolean isEclipseLink() {
return Arrays.asList(new SystemPropertyBasedActiveProfilesResolver().resolve(DocumentRepositoryTest.class)).contains("eclipselink");
}
@Configuration
@ComponentScan
@ImportResource("classpath:/com/blazebit/persistence/impl/springdata/application-config.xml")
@EnableEntityViews(basePackages = {"org.springframework.data.jpa.repository.support", "com.blazebit.persistence.impl.springdata.view"})
@EnableJpaRepositories(
basePackages = "com.blazebit.persistence.impl.springdata.repository",
entityManagerFactoryRef = "myEmf",
repositoryFactoryBeanClass = EntityViewRepositoryFactoryBean.class)
static class TestConfig {
}
}