/* * Copyright (c) [2011-2017] "Pivotal Software, Inc." / "Neo Technology" / "Graph Aware Ltd." * * This product is licensed to you under the Apache License, Version 2.0 (the "License"). * You may not use this product except in compliance with the License. * * This product may include a number of subcomponents with * separate copyright notices and license terms. Your use of the source * code for these subcomponents is subject to the terms and * conditions of the subcomponent's license, as noted in the LICENSE file. * */ package org.springframework.data.neo4j.examples.galaxy; import static org.hamcrest.core.AnyOf.*; import static org.hamcrest.core.Is.*; import static org.hamcrest.core.StringContains.*; import static org.junit.Assert.*; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.List; import java.util.Optional; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.neo4j.ogm.cypher.query.Pagination; import org.neo4j.ogm.session.SessionFactory; import org.neo4j.ogm.testutil.MultiDriverTestClass; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Sort; import org.springframework.data.neo4j.examples.galaxy.domain.World; import org.springframework.data.neo4j.examples.galaxy.service.GalaxyService; import org.springframework.data.neo4j.repository.config.EnableNeo4jRepositories; import org.springframework.data.neo4j.transaction.Neo4jTransactionManager; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.transaction.PlatformTransactionManager; import org.springframework.transaction.annotation.EnableTransactionManagement; import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.support.TransactionTemplate; /** * @author Vince Bickers * @author Mark Paluch */ @ContextConfiguration(classes = {GalaxyServiceTests.GalaxyContext.class}) @RunWith(SpringJUnit4ClassRunner.class) @Transactional public class GalaxyServiceTests extends MultiDriverTestClass { @Autowired private GalaxyService galaxyService; @Before public void setUp() { galaxyService.deleteAll(); assertEquals(0, galaxyService.getNumberOfWorlds()); } @Test public void shouldAllowDirectWorldCreation() { World myWorld = galaxyService.createWorld("mine", 0); Collection<World> foundWorlds = (Collection<World>) galaxyService.getAllWorlds(); assertEquals(1, foundWorlds.size()); World mine = foundWorlds.iterator().next(); assertEquals(myWorld.getName(), mine.getName()); } @Test public void shouldHaveCorrectNumberOfWorlds() { galaxyService.makeSomeWorlds(); assertEquals(13, galaxyService.getNumberOfWorlds()); } @Test public void createAllWorldsAtOnce() { galaxyService.makeAllWorldsAtOnce(); assertEquals(13, galaxyService.getNumberOfWorlds()); World earth = galaxyService.findWorldByName("Earth"); World mars = galaxyService.findWorldByName("Mars"); assertTrue(mars.canBeReachedFrom(earth)); assertTrue(earth.canBeReachedFrom(mars)); } @Test public void shouldFindWorldsById() { galaxyService.makeSomeWorlds(); for (World world : galaxyService.getAllWorlds()) { Optional<World> foundWorld = galaxyService.findWorldById(world.getId()); assertTrue(foundWorld.isPresent()); } } @Test public void shouldFindWorldsByName() { galaxyService.makeSomeWorlds(); for (World world : galaxyService.getAllWorlds()) { World foundWorld = galaxyService.findWorldByName(world.getName()); assertNotNull(foundWorld); } } @Test public void shouldReachMarsFromEarth() { galaxyService.makeSomeWorlds(); World earth = galaxyService.findWorldByName("Earth"); World mars = galaxyService.findWorldByName("Mars"); assertTrue(mars.canBeReachedFrom(earth)); assertTrue(earth.canBeReachedFrom(mars)); } @Test public void shouldFindAllWorlds() { Collection<World> madeWorlds = galaxyService.makeSomeWorlds(); Iterable<World> foundWorlds = galaxyService.getAllWorlds(); int countOfFoundWorlds = 0; for (World foundWorld : foundWorlds) { assertTrue(madeWorlds.contains(foundWorld)); countOfFoundWorlds++; } assertEquals(madeWorlds.size(), countOfFoundWorlds); } @SuppressWarnings("unchecked") @Test public void shouldFindWorldsWith1Moon() { galaxyService.makeSomeWorlds(); for (World worldWithOneMoon : galaxyService.findAllByNumberOfMoons(1)) { assertThat( worldWithOneMoon.getName(), is(anyOf(containsString("Earth"), containsString("Midgard")))); } } @Test public void shouldNotFindKrypton() { galaxyService.makeSomeWorlds(); World krypton = galaxyService.findWorldByName("Krypton"); assertNull(krypton); } @Test public void shouldSupportPaging() { List<World> worlds = (List<World>) galaxyService.makeAllWorldsAtOnce(); int count = worlds.size(); int PAGE_SIZE = 3; int pages = count / PAGE_SIZE + 1; long n = 0; for (World world : worlds) { n += world.getId(); } for (int page = 0; page < pages; page++) { Iterable<World> paged = galaxyService.findAllWorlds(new Pagination(page, PAGE_SIZE)); for (World world : paged) { n -= world.getId(); } } assertEquals(0L, n); } @Test public void shouldDetectNotOnLastPage() { int count = galaxyService.makeAllWorldsAtOnce().size(); assertEquals(count, 13); Pageable pageable = new PageRequest(2, 3); Page<World> worlds = galaxyService.findAllWorlds(pageable); assertTrue(worlds.hasNext()); } @Test public void shouldDetectLastPage() { int count = galaxyService.makeAllWorldsAtOnce().size(); assertEquals(count, 13); Pageable pageable = new PageRequest(4, 3); Page<World> worlds = galaxyService.findAllWorlds(pageable); assertFalse(worlds.hasNext()); } @Test public void shouldPageAllWorlds() { long sum = 0; List<World> worlds = (List<World>) galaxyService.makeAllWorldsAtOnce(); for (World world : worlds) { sum += world.getId(); } // note: this doesn't work, because deleted node ids are not reclaimed // long sum = (size * size - size) / 2; // 0-based node ids Pageable pageable = new PageRequest(0, 3); for (; ; ) { Page<World> page = galaxyService.findAllWorlds(pageable); for (World world : page) { sum -= world.getId(); } if (!page.hasNext()) { break; } pageable = pageable.next(); } assertEquals(0, sum); } @Test public void shouldPageAllWorldsSorted() { List<World> worlds = (List<World>) galaxyService.makeAllWorldsAtOnce(); int count = worlds.size(); assertEquals(count, 13); String[] sortedNames = getNamesSorted(worlds); Pageable pageable = new PageRequest(0, 3, Sort.Direction.ASC, "name"); int i = 0; for (; ; ) { Page<World> page = galaxyService.findAllWorlds(pageable); for (World world : page) { assertEquals(sortedNames[i], world.getName()); count--; i++; } if (!page.hasNext()) { break; } pageable = pageable.next(); } assertEquals(0, count); } @Test public void shouldIterateAllWorldsSorted() { List<World> worlds = (List<World>) galaxyService.makeAllWorldsAtOnce(); int count = worlds.size(); assertEquals(count, 13); String[] sortedNames = getNamesSorted(worlds); Sort sort = new Sort(Sort.Direction.ASC, "name"); int i = 0; for (World world : galaxyService.findAllWorlds(sort)) { assertEquals(sortedNames[i], world.getName()); count--; i++; } assertEquals(0, count); } /** * @see DATAGRAPH-783 */ @Test public void shouldFindWorldWithRadius() { galaxyService.deleteAll(); World earth = new World("Earth", 1); earth.setRadius(6371.0f); galaxyService.create(earth); earth = galaxyService.findByName("Earth"); assertEquals(Float.valueOf(6371.0f), earth.getRadius()); } private String[] getNamesSorted(List<World> worlds) { List<String> names = new ArrayList(); for (World world : worlds) { names.add(world.getName()); } String[] sortedNames = names.toArray(new String[]{}); Arrays.sort(sortedNames); return sortedNames; } @Configuration @ComponentScan({"org.springframework.data.neo4j.examples.galaxy.service"}) @EnableNeo4jRepositories("org.springframework.data.neo4j.examples.galaxy.repo") @EnableTransactionManagement static class GalaxyContext { @Bean public PlatformTransactionManager transactionManager() { return new Neo4jTransactionManager(sessionFactory()); } @Bean public SessionFactory sessionFactory() { return new SessionFactory(getBaseConfiguration().build(), "org.springframework.data.neo4j.examples.galaxy.domain"); } @Bean public TransactionTemplate transactionTemplate() { return new TransactionTemplate(transactionManager()); } } }