/* * Copyright 2016-2017 the original author or authors. * * 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 org.springframework.data.mongodb.repository; import static org.hamcrest.Matchers.*; import static org.junit.Assert.*; import lombok.Data; import lombok.NoArgsConstructor; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; import reactor.test.StepVerifier; import java.util.Arrays; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.BeansException; import org.springframework.beans.factory.BeanClassLoaderAware; import org.springframework.beans.factory.BeanFactory; import org.springframework.beans.factory.BeanFactoryAware; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.annotation.Id; import org.springframework.data.domain.Sort; import org.springframework.data.domain.Sort.Direction; import org.springframework.data.domain.Sort.Order; import org.springframework.data.mongodb.core.ReactiveMongoTemplate; import org.springframework.data.mongodb.repository.support.ReactiveMongoRepositoryFactory; import org.springframework.data.mongodb.repository.support.SimpleReactiveMongoRepository; import org.springframework.data.repository.query.DefaultEvaluationContextProvider; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.util.ClassUtils; /** * Test for {@link ReactiveMongoRepository}. * * @author Mark Paluch */ @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration("classpath:reactive-infrastructure.xml") public class SimpleReactiveMongoRepositoryTests implements BeanClassLoaderAware, BeanFactoryAware { @Autowired private ReactiveMongoTemplate template; ReactiveMongoRepositoryFactory factory; ClassLoader classLoader; BeanFactory beanFactory; ReactivePersonRepostitory repository; private ReactivePerson dave, oliver, carter, boyd, stefan, leroi, alicia; @Override public void setBeanClassLoader(ClassLoader classLoader) { this.classLoader = classLoader == null ? ClassUtils.getDefaultClassLoader() : classLoader; } @Override public void setBeanFactory(BeanFactory beanFactory) throws BeansException { this.beanFactory = beanFactory; } @Before public void setUp() { factory = new ReactiveMongoRepositoryFactory(template); factory.setRepositoryBaseClass(SimpleReactiveMongoRepository.class); factory.setBeanClassLoader(classLoader); factory.setBeanFactory(beanFactory); factory.setEvaluationContextProvider(DefaultEvaluationContextProvider.INSTANCE); repository = factory.getRepository(ReactivePersonRepostitory.class); StepVerifier.create(repository.deleteAll()).verifyComplete(); dave = new ReactivePerson("Dave", "Matthews", 42); oliver = new ReactivePerson("Oliver August", "Matthews", 4); carter = new ReactivePerson("Carter", "Beauford", 49); boyd = new ReactivePerson("Boyd", "Tinsley", 45); stefan = new ReactivePerson("Stefan", "Lessard", 34); leroi = new ReactivePerson("Leroi", "Moore", 41); alicia = new ReactivePerson("Alicia", "Keys", 30); StepVerifier.create(repository.saveAll(Arrays.asList(oliver, dave, carter, boyd, stefan, leroi, alicia))) // .expectNextCount(7) // .verifyComplete(); } @Test // DATAMONGO-1444 public void existsByIdShouldReturnTrueForExistingObject() { StepVerifier.create(repository.existsById(dave.id)).expectNext(true).verifyComplete(); } @Test // DATAMONGO-1444 public void existsByIdShouldReturnFalseForAbsentObject() { StepVerifier.create(repository.existsById("unknown")).expectNext(false).verifyComplete(); } @Test // DATAMONGO-1444 public void existsByMonoOfIdShouldReturnTrueForExistingObject() { StepVerifier.create(repository.existsById(Mono.just(dave.id))).expectNext(true).verifyComplete(); } @Test // DATAMONGO-1444 public void existsByEmptyMonoOfIdShouldReturnEmptyMono() { StepVerifier.create(repository.existsById(Mono.empty())).verifyComplete(); } @Test // DATAMONGO-1444 public void findOneShouldReturnObject() { StepVerifier.create(repository.findById(dave.id)).expectNext(dave).verifyComplete(); } @Test // DATAMONGO-1444 public void findOneShouldCompleteWithoutValueForAbsentObject() { StepVerifier.create(repository.findById("unknown")).verifyComplete(); } @Test // DATAMONGO-1444 public void findOneByMonoOfIdShouldReturnTrueForExistingObject() { StepVerifier.create(repository.findById(Mono.just(dave.id))).expectNext(dave).verifyComplete(); } @Test // DATAMONGO-1444 public void findOneByEmptyMonoOfIdShouldReturnEmptyMono() { StepVerifier.create(repository.findById(Mono.empty())).verifyComplete(); } @Test // DATAMONGO-1444 public void findAllShouldReturnAllResults() { StepVerifier.create(repository.findAll()).expectNextCount(7).verifyComplete(); } @Test // DATAMONGO-1444 public void findAllByIterableOfIdShouldReturnResults() { StepVerifier.create(repository.findAllById(Arrays.asList(dave.id, boyd.id))).expectNextCount(2).verifyComplete(); } @Test // DATAMONGO-1444 public void findAllByPublisherOfIdShouldReturnResults() { StepVerifier.create(repository.findAllById(Flux.just(dave.id, boyd.id))).expectNextCount(2).verifyComplete(); } @Test // DATAMONGO-1444 public void findAllByEmptyPublisherOfIdShouldReturnResults() { StepVerifier.create(repository.findAllById(Flux.empty())).verifyComplete(); } @Test // DATAMONGO-1444 public void findAllWithSortShouldReturnResults() { StepVerifier.create(repository.findAll(Sort.by(new Order(Direction.ASC, "age")))) // .expectNextCount(7) // .verifyComplete(); } @Test // DATAMONGO-1444 public void countShouldReturnNumberOfRecords() { StepVerifier.create(repository.count()).expectNext(7L).verifyComplete(); } @Test // DATAMONGO-1444 public void insertEntityShouldInsertEntity() { StepVerifier.create(repository.deleteAll()).verifyComplete(); ReactivePerson person = new ReactivePerson("Homer", "Simpson", 36); StepVerifier.create(repository.insert(person)).expectNext(person).verifyComplete(); assertThat(person.getId(), is(notNullValue())); } @Test // DATAMONGO-1444 public void insertShouldDeferredWrite() { ReactivePerson person = new ReactivePerson("Homer", "Simpson", 36); repository.insert(person); assertThat(person.getId(), is(nullValue())); } @Test // DATAMONGO-1444 public void insertIterableOfEntitiesShouldInsertEntity() { StepVerifier.create(repository.deleteAll()).verifyComplete(); dave.setId(null); oliver.setId(null); boyd.setId(null); StepVerifier.create(repository.insert(Arrays.asList(dave, oliver, boyd))) // .expectNext(dave, oliver, boyd) // .verifyComplete(); assertThat(dave.getId(), is(notNullValue())); assertThat(oliver.getId(), is(notNullValue())); assertThat(boyd.getId(), is(notNullValue())); } @Test // DATAMONGO-1444 public void insertPublisherOfEntitiesShouldInsertEntity() { StepVerifier.create(repository.deleteAll()).verifyComplete(); dave.setId(null); oliver.setId(null); boyd.setId(null); StepVerifier.create(repository.insert(Flux.just(dave, oliver, boyd))).expectNextCount(3).verifyComplete(); assertThat(dave.getId(), is(notNullValue())); assertThat(oliver.getId(), is(notNullValue())); assertThat(boyd.getId(), is(notNullValue())); } @Test // DATAMONGO-1444 public void saveEntityShouldUpdateExistingEntity() { dave.setFirstname("Hello, Dave"); dave.setLastname("Bowman"); StepVerifier.create(repository.save(dave)).expectNext(dave).verifyComplete(); StepVerifier.create(repository.findByLastname("Matthews")).expectNext(oliver).verifyComplete(); StepVerifier.create(repository.findById(dave.id)).consumeNextWith(actual -> { assertThat(actual.getFirstname(), is(equalTo(dave.getFirstname()))); assertThat(actual.getLastname(), is(equalTo(dave.getLastname()))); }).verifyComplete(); } @Test // DATAMONGO-1444 public void saveEntityShouldInsertNewEntity() { ReactivePerson person = new ReactivePerson("Homer", "Simpson", 36); StepVerifier.create(repository.save(person)).expectNext(person).verifyComplete(); StepVerifier.create(repository.findById(person.id)).consumeNextWith(actual -> { assertThat(actual.getFirstname(), is(equalTo(person.getFirstname()))); assertThat(actual.getLastname(), is(equalTo(person.getLastname()))); }).verifyComplete(); } @Test // DATAMONGO-1444 public void saveIterableOfNewEntitiesShouldInsertEntity() { StepVerifier.create(repository.deleteAll()).verifyComplete(); dave.setId(null); oliver.setId(null); boyd.setId(null); StepVerifier.create(repository.saveAll(Arrays.asList(dave, oliver, boyd))).expectNextCount(3).verifyComplete(); assertThat(dave.getId(), is(notNullValue())); assertThat(oliver.getId(), is(notNullValue())); assertThat(boyd.getId(), is(notNullValue())); } @Test // DATAMONGO-1444 public void saveIterableOfMixedEntitiesShouldInsertEntity() { ReactivePerson person = new ReactivePerson("Homer", "Simpson", 36); dave.setFirstname("Hello, Dave"); dave.setLastname("Bowman"); StepVerifier.create(repository.saveAll(Arrays.asList(person, dave))).expectNextCount(2).verifyComplete(); StepVerifier.create(repository.findById(dave.id)).expectNext(dave).verifyComplete(); assertThat(person.id, is(notNullValue())); StepVerifier.create(repository.findById(person.id)).expectNext(person).verifyComplete(); } @Test // DATAMONGO-1444 public void savePublisherOfEntitiesShouldInsertEntity() { StepVerifier.create(repository.deleteAll()).verifyComplete(); dave.setId(null); oliver.setId(null); boyd.setId(null); StepVerifier.create(repository.saveAll(Flux.just(dave, oliver, boyd))).expectNextCount(3).verifyComplete(); assertThat(dave.getId(), is(notNullValue())); assertThat(oliver.getId(), is(notNullValue())); assertThat(boyd.getId(), is(notNullValue())); } @Test // DATAMONGO-1444 public void deleteAllShouldRemoveEntities() { StepVerifier.create(repository.deleteAll()).verifyComplete(); StepVerifier.create(repository.findAll()).verifyComplete(); } @Test // DATAMONGO-1444 public void deleteByIdShouldRemoveEntity() { StepVerifier.create(repository.deleteById(dave.id)).verifyComplete(); StepVerifier.create(repository.findById(dave.id)).verifyComplete(); } @Test // DATAMONGO-1444 public void deleteShouldRemoveEntity() { StepVerifier.create(repository.delete(dave)).verifyComplete(); StepVerifier.create(repository.findById(dave.id)).verifyComplete(); } @Test // DATAMONGO-1444 public void deleteIterableOfEntitiesShouldRemoveEntities() { StepVerifier.create(repository.deleteAll(Arrays.asList(dave, boyd))).verifyComplete(); StepVerifier.create(repository.findById(boyd.id)).verifyComplete(); StepVerifier.create(repository.findByLastname("Matthews")).expectNext(oliver).verifyComplete(); } @Test // DATAMONGO-1444 public void deletePublisherOfEntitiesShouldRemoveEntities() { StepVerifier.create(repository.deleteAll(Flux.just(dave, boyd))).verifyComplete(); StepVerifier.create(repository.findById(boyd.id)).verifyComplete(); StepVerifier.create(repository.findByLastname("Matthews")).expectNext(oliver).verifyComplete(); } interface ReactivePersonRepostitory extends ReactiveMongoRepository<ReactivePerson, String> { Flux<ReactivePerson> findByLastname(String lastname); } @Data @NoArgsConstructor static class ReactivePerson { @Id String id; String firstname; String lastname; int age; public ReactivePerson(String firstname, String lastname, int age) { this.firstname = firstname; this.lastname = lastname; this.age = age; } } }