// Copyright © 2015 HSL <https://www.hsl.fi> // This program is dual-licensed under the EUPL v1.2 and AGPLv3 licenses. package fi.hsl.parkandride.back; import com.google.common.collect.ImmutableSet; import fi.hsl.parkandride.core.back.HubRepository; import fi.hsl.parkandride.core.domain.*; import fi.hsl.parkandride.core.service.ValidationException; import org.geolatte.geom.Geometry; import org.geolatte.geom.Point; import org.junit.Test; import javax.inject.Inject; import java.util.List; import java.util.Set; import static fi.hsl.parkandride.core.domain.Sort.Dir.ASC; import static fi.hsl.parkandride.core.domain.Sort.Dir.DESC; import static fi.hsl.parkandride.core.domain.Spatial.fromWkt; import static org.assertj.core.api.Assertions.assertThat; import static org.junit.Assert.fail; public class HubDaoTest extends AbstractDaoTest { private static final MultilingualString NAME = new MultilingualString("malmi"); public static final Point LOCATION = (Point) fromWkt("POINT(25.010563 60.251022)"); public static final ImmutableSet<Long> FACILITY_IDS = ImmutableSet.of(1l, 2l, 3l); public static final String POSTAL_CODE = "00100"; public static final MultilingualString STREET_ADDRESS = new MultilingualString("street"); public static final MultilingualString CITY = new MultilingualString("city"); @Inject HubRepository hubRepository; @Test public void create_read_update() { // Insert Hub hub = createHub(); final long hubId = hubRepository.insertHub(hub); assertThat(hubId).isGreaterThan(0); // Get hub = hubRepository.getHub(hubId); assertDefaultHub(hub); // Update final Set<Long> newFacilityIds = ImmutableSet.of(5l, 6l); final Point newLocation = (Point) fromWkt("POINT(25.016392 60.254157)"); final MultilingualString newName = new MultilingualString("Malminkaari"); final MultilingualString newStreetAddress = new MultilingualString("new street"); final MultilingualString newCity = new MultilingualString("new city"); final String newPostalCode = "00200"; hub.name = newName; hub.address = new Address(newStreetAddress, newPostalCode, newCity); hub.location = newLocation; hub.facilityIds = newFacilityIds; hubRepository.updateHub(hubId, hub); // Find List<Hub> hubs = findByGeometry(fromWkt("POLYGON((" + "25.015955 60.254351, " + "25.0178 60.254649, " + "25.016395 60.253675, " + "25.015955 60.254351))")); assertThat(hubs.size()).isEqualTo(1); hub = hubs.get(0); assertThat(hub.name).isEqualTo(newName); assertThat(hub.address.streetAddress).isEqualTo(newStreetAddress); assertThat(hub.address.city).isEqualTo(newCity); assertThat(hub.address.postalCode).isEqualTo(newPostalCode); assertThat(hub.location).isEqualTo(newLocation); assertThat(hub.facilityIds).isEqualTo(newFacilityIds); hubs = findByGeometry(fromWkt("POLYGON((" + "25.015955 60.254351, " + "25.0178 60.254649, " + "25.01677 60.254548, " + "25.015955 60.254351))")); assertThat(hubs).isEmpty(); hubs = findByDistance(fromWkt("POINT(25.016390 60.254160)"), 1); assertThat(hubs).hasSize(1); assertThat(hubs.get(0).id).isEqualTo(hubId); hubs = findByDistance(fromWkt("POINT(23.016392 58.254157)"), 1); assertThat(hubs).isEmpty(); } private void assertDefaultHub(Hub hub) { assertThat(hub.name).isEqualTo(NAME); assertThat(hub.address.streetAddress).isEqualTo(STREET_ADDRESS); assertThat(hub.address.city).isEqualTo(CITY); assertThat(hub.address.postalCode).isEqualTo(POSTAL_CODE); assertThat(hub.location).isEqualTo(LOCATION); assertThat(hub.facilityIds).isEqualTo(FACILITY_IDS); } @Test public void search_exclusion_test() { final Hub hub1 = new Hub(); hub1.name = NAME; hub1.location = LOCATION; hub1.facilityIds = FACILITY_IDS; hub1.address = new Address(STREET_ADDRESS, POSTAL_CODE, CITY); final Hub hub2 = new Hub(); hub2.name = new MultilingualString("Nalmi"); hub2.location = (Point) fromWkt("POINT(24.010563 59.251022)"); hub2.facilityIds = ImmutableSet.of(3l, 4l, 5l); hub2.address = new Address(STREET_ADDRESS, POSTAL_CODE, CITY); final long hub1Id = hubRepository.insertHub(hub1); final long hub2Id = hubRepository.insertHub(hub2); // ids = hub1.id HubSearch search = new HubSearch(); search.setIds(ImmutableSet.of(hub1Id)); SearchResults<Hub> hubs = hubRepository.findHubs(search); assertThat(hubs.size()).isEqualTo(1); assertDefaultHub(hubs.get(0)); // ids = hub2.id search.setIds(ImmutableSet.of(hub2Id)); hubs = hubRepository.findHubs(search); assertThat(hubs.size()).isEqualTo(1); assertThat(hubs.get(0).id).isEqualTo(hub2Id); // ids = [hub1.id, hub2.id] search.setIds(ImmutableSet.of(hub1Id, hub2Id)); hubs = hubRepository.findHubs(search); assertThat(hubs.size()).isEqualTo(2); assertThat(hubs.get(0).facilityIds).isEqualTo(hub1.facilityIds); assertThat(hubs.get(1).facilityIds).isEqualTo(hub2.facilityIds); // facilityIds in hub1.facilityIds search.setIds(null); search.setFacilityIds(ImmutableSet.of(2l)); hubs = hubRepository.findHubs(search); assertThat(hubs.size()).isEqualTo(1); assertDefaultHub(hubs.get(0)); // facilityIds in both hub1.facilityIds and hub2.facilityIds, with limit search.setFacilityIds(ImmutableSet.of(3l)); search.setLimit(1); hubs = hubRepository.findHubs(search); assertThat(hubs.size()).isEqualTo(1); assertThat(hubs.hasMore).isEqualTo(true); assertDefaultHub(hubs.get(0)); // facilityIds in both hub1.facilityIds and hub2.facilityIds, with offset search.setOffset(1); hubs = hubRepository.findHubs(search); assertThat(hubs.size()).isEqualTo(1); assertThat(hubs.hasMore).isEqualTo(false); assertThat(hubs.get(0).id).isEqualTo(hub2Id); } @Test public void sorting() { Hub h1 = new Hub(); h1.name = new MultilingualString("a", "å", "C"); h1.location = LOCATION; h1.id = hubRepository.insertHub(h1); Hub h2 = new Hub(); h2.name = new MultilingualString("D", "Ä", "F"); h2.location = LOCATION; h2.id = hubRepository.insertHub(h2); // Default sort HubSearch search = new HubSearch(); assertResultOrder(hubRepository.findHubs(search), h1.id, h2.id); // name.fi desc search.setSort(new Sort("name.fi", DESC)); assertResultOrder(hubRepository.findHubs(search), h2.id, h1.id); // name.sv desc // NOTE: This doesn't work on mac/postgresql because it's fi-collation is broken search.setSort(new Sort("name.sv", DESC)); assertResultOrder(hubRepository.findHubs(search), h2.id, h1.id); // name.en asc search.setSort(new Sort("name.en", ASC)); assertResultOrder(hubRepository.findHubs(search), h1.id, h2.id); } @Test(expected = NotFoundException.class) public void get_throws_an_exception_if_not_found() { hubRepository.getHub(0); } @Test(expected = NotFoundException.class) public void update_throws_an_exception_if_not_found() { hubRepository.updateHub(0, createHub()); } @Test public void unique_name() { Hub hub = createHub(); hubRepository.insertHub(hub); verifyUniqueName(hub, "fi"); verifyUniqueName(hub, "sv"); verifyUniqueName(hub, "en"); } private void verifyUniqueName(Hub hub, String lang) { hub.name = new MultilingualString("something else"); try { hub.name.asMap().put(lang, NAME.asMap().get(lang)); hubRepository.insertHub(hub); fail("should not allow duplicate names"); } catch (ValidationException e) { assertThat(e.violations).hasSize(1); assertThat(e.violations.get(0).path).isEqualTo("name." + lang); } } private Hub createHub() { Hub hub = new Hub(); hub.name = NAME; hub.location = LOCATION; hub.facilityIds = FACILITY_IDS; hub.address = new Address(STREET_ADDRESS, POSTAL_CODE, CITY); return hub; } private void assertResultOrder(SearchResults<Hub> results, long id1, long id2) { assertThat(results.size()).isEqualTo(2); assertThat(results.get(0).id).isEqualTo(id1); assertThat(results.get(1).id).isEqualTo(id2); } private List<Hub> findByGeometry(Geometry geometry) { HubSearch search = new HubSearch(); search.setGeometry(geometry); return hubRepository.findHubs(search).results; } private List<Hub> findByDistance(Geometry geometry, double distance) { HubSearch search = new HubSearch(); search.setGeometry(geometry); search.setMaxDistance(distance); return hubRepository.findHubs(search).results; } }