From 80aa17cc5dd0b5d47bb879123343ad647e25a1fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=20Erik=20St=C3=B8wer?= Date: Thu, 19 Dec 2024 11:22:42 +0100 Subject: [PATCH 1/4] Replace graphql kickstart project with spring graphql --- pom.xml | 12 +- .../controller/GraphQLQueryController.java | 309 ------------------ .../controller/BaseGraphQLController.java | 119 +++++++ .../FeedProviderGraphQLController.java | 28 ++ .../GeofencingZonesGraphQLController.java | 34 ++ .../controller/StationGraphQLController.java | 102 ++++++ .../controller/VehicleGraphQLController.java | 105 ++++++ .../service/BoundingBoxQueryParameters.java | 12 + .../lamassu/service/FilterParameters.java | 14 +- .../lamassu/service/RangeQueryParameters.java | 8 + .../service/StationFilterParameters.java | 13 + .../service/VehicleFilterParameters.java | 17 + 12 files changed, 453 insertions(+), 320 deletions(-) delete mode 100644 src/main/java/org/entur/lamassu/controller/GraphQLQueryController.java create mode 100644 src/main/java/org/entur/lamassu/graphql/controller/BaseGraphQLController.java create mode 100644 src/main/java/org/entur/lamassu/graphql/controller/FeedProviderGraphQLController.java create mode 100644 src/main/java/org/entur/lamassu/graphql/controller/GeofencingZonesGraphQLController.java create mode 100644 src/main/java/org/entur/lamassu/graphql/controller/StationGraphQLController.java create mode 100644 src/main/java/org/entur/lamassu/graphql/controller/VehicleGraphQLController.java diff --git a/pom.xml b/pom.xml index 7c7947af..d89b0822 100644 --- a/pom.xml +++ b/pom.xml @@ -20,7 +20,6 @@ 21 - 15.1.0 1.101 3.40.2 0.9.1 @@ -127,9 +126,8 @@ ${jackson.version} - com.graphql-java-kickstart - graphql-spring-boot-starter - ${graphql-starter.version} + org.springframework.boot + spring-boot-starter-graphql net.logstash.logback @@ -172,12 +170,6 @@ ${okhttp.version} test - - com.graphql-java-kickstart - graphql-spring-boot-starter-test - ${graphql-starter.version} - test - org.wiremock wiremock diff --git a/src/main/java/org/entur/lamassu/controller/GraphQLQueryController.java b/src/main/java/org/entur/lamassu/controller/GraphQLQueryController.java deleted file mode 100644 index fc3f43fa..00000000 --- a/src/main/java/org/entur/lamassu/controller/GraphQLQueryController.java +++ /dev/null @@ -1,309 +0,0 @@ -package org.entur.lamassu.controller; - -import graphql.GraphqlErrorException; -import graphql.kickstart.tools.GraphQLQueryResolver; -import java.util.Collection; -import java.util.HashSet; -import java.util.List; -import java.util.Set; -import java.util.function.Predicate; -import java.util.stream.Collectors; -import org.entur.lamassu.cache.GeofencingZonesCache; -import org.entur.lamassu.cache.StationCache; -import org.entur.lamassu.cache.VehicleCache; -import org.entur.lamassu.model.entities.FormFactor; -import org.entur.lamassu.model.entities.GeofencingZones; -import org.entur.lamassu.model.entities.Operator; -import org.entur.lamassu.model.entities.PropulsionType; -import org.entur.lamassu.model.entities.Station; -import org.entur.lamassu.model.entities.Vehicle; -import org.entur.lamassu.model.provider.FeedProvider; -import org.entur.lamassu.service.BoundingBoxQueryParameters; -import org.entur.lamassu.service.FeedProviderService; -import org.entur.lamassu.service.GeoSearchService; -import org.entur.lamassu.service.RangeQueryParameters; -import org.entur.lamassu.service.StationFilterParameters; -import org.entur.lamassu.service.VehicleFilterParameters; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; - -@Component -public class GraphQLQueryController implements GraphQLQueryResolver { - - private final Logger logger = LoggerFactory.getLogger(this.getClass()); - - private final GeoSearchService geoSearchService; - private final FeedProviderService feedProviderService; - private final VehicleCache vehicleCache; - private final StationCache stationCache; - private final GeofencingZonesCache geofencingZonesCache; - - @Autowired - public GraphQLQueryController( - GeoSearchService geoSearchService, - FeedProviderService feedProviderService, - VehicleCache vehicleCache, - StationCache stationCache, - GeofencingZonesCache geofencingZonesCache - ) { - this.geoSearchService = geoSearchService; - this.feedProviderService = feedProviderService; - this.vehicleCache = vehicleCache; - this.stationCache = stationCache; - this.geofencingZonesCache = geofencingZonesCache; - } - - public Collection getCodespaces() { - return feedProviderService - .getFeedProviders() - .stream() - .map(FeedProvider::getCodespace) - .collect(Collectors.toSet()); - } - - public Collection getOperators() { - return feedProviderService.getOperators(); - } - - public Collection getVehicles( - Set ids, - Double lat, - Double lon, - Double range, - Double minimumLatitude, - Double minimumLongitude, - Double maximumLatitude, - Double maximumLongitude, - Integer count, - List codespaces, - List systems, - List operators, - List formFactors, - List propulsionTypes, - boolean includeReserved, - boolean includeDisabled - ) { - if (ids != null) { - return vehicleCache.getAll(ids); - } - - validateCount(count); - validateCodespaces(codespaces); - validateSystems(systems); - - var filterParams = new VehicleFilterParameters(); - filterParams.setCodespaces(codespaces); - filterParams.setSystems(systems); - filterParams.setOperators(operators); - filterParams.setFormFactors(formFactors); - filterParams.setPropulsionTypes(propulsionTypes); - filterParams.setIncludeReserved(includeReserved); - filterParams.setIncludeDisabled(includeDisabled); - filterParams.setCount(count); - - if ( - isBoundingBoxSearch( - minimumLatitude, - minimumLongitude, - maximumLatitude, - maximumLongitude - ) - ) { - var boundingBoxQueryParameters = new BoundingBoxQueryParameters(); - boundingBoxQueryParameters.setMinimumLatitude(minimumLatitude); - boundingBoxQueryParameters.setMinimumLongitude(minimumLongitude); - boundingBoxQueryParameters.setMaximumLatitude(maximumLatitude); - boundingBoxQueryParameters.setMaximumLongitude(maximumLongitude); - - logger.debug( - "getVehicles called boundingBoxQueryParameters={} filter={}", - boundingBoxQueryParameters, - filterParams - ); - - return geoSearchService.getVehiclesInBoundingBox( - boundingBoxQueryParameters, - filterParams - ); - } else if (isRangeSearch(range, lat, lon)) { - validateRange(range); - - var rangeQueryParameters = new RangeQueryParameters(); - rangeQueryParameters.setLat(lat); - rangeQueryParameters.setLon(lon); - rangeQueryParameters.setRange(range); - - logger.debug( - "getVehicles called rangeQueryParameters={} filter={}", - rangeQueryParameters, - filterParams - ); - - return geoSearchService.getVehiclesWithinRange(rangeQueryParameters, filterParams); - } else { - throw new GraphqlErrorException.Builder() - .message( - "You must either specify lat, lon and range OR minimumLatitude, minimumLongitude, maximumLatitude and maximumLongitude" - ) - .build(); - } - } - - public Vehicle getVehicle(String id) { - return vehicleCache.get(id); - } - - public Collection getStations( - Set ids, - Double lat, - Double lon, - Double range, - Double minimumLatitude, - Double minimumLongitude, - Double maximumLatitude, - Double maximumLongitude, - Integer count, - List codespaces, - List systems, - List operators, - List availableFormFactors, - List availablePropulsionTypes - ) { - if (ids != null) { - return stationCache.getAll(ids); - } - - validateCount(count); - validateCodespaces(codespaces); - validateSystems(systems); - - var filterParams = new StationFilterParameters(); - filterParams.setCodespaces(codespaces); - filterParams.setSystems(systems); - filterParams.setOperators(operators); - filterParams.setAvailableFormFactors(availableFormFactors); - filterParams.setAvailablePropulsionTypes(availablePropulsionTypes); - filterParams.setCount(count); - - if ( - isBoundingBoxSearch( - minimumLatitude, - minimumLongitude, - maximumLatitude, - maximumLongitude - ) - ) { - var boundingBoxQueryParameters = new BoundingBoxQueryParameters(); - boundingBoxQueryParameters.setMinimumLatitude(minimumLatitude); - boundingBoxQueryParameters.setMinimumLongitude(minimumLongitude); - boundingBoxQueryParameters.setMaximumLatitude(maximumLatitude); - boundingBoxQueryParameters.setMaximumLongitude(maximumLongitude); - logger.debug( - "getStations called boundingBoxQueryParameters={} filter={}", - boundingBoxQueryParameters, - filterParams - ); - return geoSearchService.getStationsInBoundingBox( - boundingBoxQueryParameters, - filterParams - ); - } else if (isRangeSearch(range, lat, lon)) { - validateRange(range); - var rangeQueryParameters = new RangeQueryParameters(); - rangeQueryParameters.setLat(lat); - rangeQueryParameters.setLon(lon); - rangeQueryParameters.setRange(range); - logger.debug( - "getStations called rangeQueryParameters={} filter={}", - rangeQueryParameters, - filterParams - ); - return geoSearchService.getStationsWithinRange(rangeQueryParameters, filterParams); - } else { - throw new GraphqlErrorException.Builder() - .message( - "You must either specify lat, lon and range OR minimumLatitude, minimumLongitude, maximumLatitude and maximumLongitude" - ) - .build(); - } - } - - private boolean isRangeSearch(Double range, Double lat, Double lon) { - return range != null && lat != null && lon != null; - } - - private boolean isBoundingBoxSearch( - Double minimumLatitude, - Double minimumLongitude, - Double maximumLatitude, - Double maximumLongitude - ) { - return ( - minimumLatitude != null && - minimumLongitude != null && - maximumLatitude != null && - maximumLongitude != null - ); - } - - public Station getStation(String id) { - return stationCache.get(id); - } - - public Collection getStationsById(List ids) { - logger.debug("getStationsByIds called ids={}", ids); - return stationCache.getAll(new HashSet<>(ids)); - } - - public Collection geofencingZones(List systemIds) { - logger.debug("geofencingZones called systemIds={}", systemIds); - - validateSystems(systemIds); - - if (systemIds == null || systemIds.isEmpty()) { - return geofencingZonesCache.getAll(); - } else { - return geofencingZonesCache.getAll(new HashSet<>(systemIds)); - } - } - - private void validateCount(Integer count) { - if (count != null) { - validate(p -> p > 0, count, "Count must be positive"); - } - } - - private void validateRange(Double range) { - validate(p -> p > -1, range, "Range must be non-negative"); - } - - private void validateCodespaces(List codespaces) { - if (codespaces != null) { - var validCodespaces = getCodespaces(); - validate(validCodespaces::containsAll, codespaces, "Unknown codespace(s)"); - } - } - - private void validateSystems(List systems) { - if (systems != null) { - var validSystems = getSystems(); - validate(validSystems::containsAll, systems, "Unknown system(s)"); - } - } - - private Collection getSystems() { - return feedProviderService - .getFeedProviders() - .stream() - .map(FeedProvider::getSystemId) - .collect(Collectors.toSet()); - } - - private void validate(Predicate predicate, T value, String message) { - if (predicate.negate().test(value)) { - throw new GraphqlErrorException.Builder().message(message).build(); - } - } -} diff --git a/src/main/java/org/entur/lamassu/graphql/controller/BaseGraphQLController.java b/src/main/java/org/entur/lamassu/graphql/controller/BaseGraphQLController.java new file mode 100644 index 00000000..aa8a1c08 --- /dev/null +++ b/src/main/java/org/entur/lamassu/graphql/controller/BaseGraphQLController.java @@ -0,0 +1,119 @@ +package org.entur.lamassu.graphql.controller; + +import graphql.ErrorType; +import graphql.GraphQLError; +import graphql.GraphqlErrorException; +import java.util.Collection; +import java.util.List; +import java.util.function.Predicate; +import java.util.stream.Collectors; +import org.entur.lamassu.model.provider.FeedProvider; +import org.entur.lamassu.service.FeedProviderService; +import org.springframework.graphql.data.method.annotation.GraphQlExceptionHandler; + +public abstract class BaseGraphQLController { + + private final FeedProviderService feedProviderService; + + protected BaseGraphQLController(FeedProviderService feedProviderService) { + this.feedProviderService = feedProviderService; + } + + @GraphQlExceptionHandler(IllegalArgumentException.class) + protected GraphQLError handleIllegalArgumentException(IllegalArgumentException ex) { + return GraphQLError + .newError() + .errorType(ErrorType.ValidationError) + .message(ex.getMessage()) + .build(); + } + + protected void validateCount(Integer count) { + if (count != null) { + validate(p -> p > 0, count, "Count must be positive"); + } + } + + protected void validateRange(Double range) { + validate(p -> p > -1, range, "Range must be non-negative"); + } + + protected void validateCodespaces(List codespaces) { + if (codespaces != null) { + var validCodespaces = getCodespaces(); + validate(validCodespaces::containsAll, codespaces, "Unknown codespace(s)"); + } + } + + protected void validateSystems(List systems) { + if (systems != null) { + var validSystems = getSystems(); + validate(validSystems::containsAll, systems, "Unknown system(s)"); + } + } + + protected void validateQueryParameters( + Double lat, + Double lon, + Double range, + Double minimumLatitude, + Double minimumLongitude, + Double maximumLatitude, + Double maximumLongitude + ) { + if (isRangeSearch(range, lat, lon)) { + validateRange(range); + } else if ( + !isBoundingBoxSearch( + minimumLatitude, + minimumLongitude, + maximumLatitude, + maximumLongitude + ) + ) { + throw new IllegalArgumentException( + "At least one of minimumLatitude, minimumLongitude, maximumLatitude and maximumLongitude must be specified" + ); + } + } + + protected Collection getSystems() { + return feedProviderService + .getFeedProviders() + .stream() + .map(FeedProvider::getSystemId) + .collect(Collectors.toSet()); + } + + protected Collection getCodespaces() { + return feedProviderService + .getFeedProviders() + .stream() + .map(FeedProvider::getCodespace) + .collect(Collectors.toSet()); + } + + protected void validate(Predicate predicate, T value, String message) { + if (predicate.negate().test(value)) { + throw new GraphqlErrorException.Builder().message(message).build(); + } + } + + protected boolean isRangeSearch(Double range, Double lat, Double lon) { + return range != null && lat != null && lon != null; + } + + protected boolean isBoundingBoxSearch( + Double minimumLatitude, + Double minimumLongitude, + Double maximumLatitude, + Double maximumLongitude + ) { + return ( + minimumLatitude != null && + minimumLongitude != null && + maximumLatitude != null && + maximumLongitude != null + ); + } +} diff --git a/src/main/java/org/entur/lamassu/graphql/controller/FeedProviderGraphQLController.java b/src/main/java/org/entur/lamassu/graphql/controller/FeedProviderGraphQLController.java new file mode 100644 index 00000000..dc56dc56 --- /dev/null +++ b/src/main/java/org/entur/lamassu/graphql/controller/FeedProviderGraphQLController.java @@ -0,0 +1,28 @@ +package org.entur.lamassu.graphql.controller; + +import java.util.Collection; +import org.entur.lamassu.model.entities.Operator; +import org.entur.lamassu.service.FeedProviderService; +import org.springframework.graphql.data.method.annotation.QueryMapping; +import org.springframework.stereotype.Controller; + +@Controller +public class FeedProviderGraphQLController extends BaseGraphQLController { + + private final FeedProviderService feedProviderService; + + public FeedProviderGraphQLController(FeedProviderService feedProviderService) { + super(feedProviderService); + this.feedProviderService = feedProviderService; + } + + @QueryMapping + public Collection codespaces() { + return getCodespaces(); + } + + @QueryMapping + public Collection operators() { + return feedProviderService.getOperators(); + } +} diff --git a/src/main/java/org/entur/lamassu/graphql/controller/GeofencingZonesGraphQLController.java b/src/main/java/org/entur/lamassu/graphql/controller/GeofencingZonesGraphQLController.java new file mode 100644 index 00000000..5eda7507 --- /dev/null +++ b/src/main/java/org/entur/lamassu/graphql/controller/GeofencingZonesGraphQLController.java @@ -0,0 +1,34 @@ +package org.entur.lamassu.graphql.controller; + +import java.util.Collection; +import java.util.List; +import java.util.Set; +import org.entur.lamassu.cache.GeofencingZonesCache; +import org.entur.lamassu.model.entities.GeofencingZones; +import org.entur.lamassu.service.FeedProviderService; +import org.springframework.graphql.data.method.annotation.Argument; +import org.springframework.graphql.data.method.annotation.QueryMapping; +import org.springframework.stereotype.Controller; + +@Controller +public class GeofencingZonesGraphQLController extends BaseGraphQLController { + + private final GeofencingZonesCache geofencingZonesCache; + + public GeofencingZonesGraphQLController( + FeedProviderService feedProviderService, + GeofencingZonesCache geofencingZonesCache + ) { + super(feedProviderService); + this.geofencingZonesCache = geofencingZonesCache; + } + + @QueryMapping + public Collection geofencingZones(@Argument List systemIds) { + validateSystems(systemIds); + if (systemIds != null && !systemIds.isEmpty()) { + return geofencingZonesCache.getAll(Set.copyOf(systemIds)); + } + return geofencingZonesCache.getAll(); + } +} diff --git a/src/main/java/org/entur/lamassu/graphql/controller/StationGraphQLController.java b/src/main/java/org/entur/lamassu/graphql/controller/StationGraphQLController.java new file mode 100644 index 00000000..4e172343 --- /dev/null +++ b/src/main/java/org/entur/lamassu/graphql/controller/StationGraphQLController.java @@ -0,0 +1,102 @@ +package org.entur.lamassu.graphql.controller; + +import java.util.Collection; +import java.util.List; +import java.util.Set; +import org.entur.lamassu.cache.StationCache; +import org.entur.lamassu.model.entities.FormFactor; +import org.entur.lamassu.model.entities.PropulsionType; +import org.entur.lamassu.model.entities.Station; +import org.entur.lamassu.service.*; +import org.springframework.graphql.data.method.annotation.Argument; +import org.springframework.graphql.data.method.annotation.QueryMapping; +import org.springframework.stereotype.Controller; + +@Controller +public class StationGraphQLController extends BaseGraphQLController { + + private final GeoSearchService geoSearchService; + private final StationCache stationCache; + + public StationGraphQLController( + GeoSearchService geoSearchService, + FeedProviderService feedProviderService, + StationCache stationCache + ) { + super(feedProviderService); + this.geoSearchService = geoSearchService; + this.stationCache = stationCache; + } + + @QueryMapping + public Station station(@Argument String id) { + return stationCache.get(id); + } + + @QueryMapping + public Collection stations( + @Argument List ids, + @Argument Double lat, + @Argument Double lon, + @Argument Double range, + @Argument Double minimumLatitude, + @Argument Double minimumLongitude, + @Argument Double maximumLatitude, + @Argument Double maximumLongitude, + @Argument Integer count, + @Argument List codespaces, + @Argument List systems, + @Argument List operators, + @Argument List availableFormFactors, + @Argument List availablePropulsionTypes + ) { + if (ids != null && !ids.isEmpty()) { + return stationCache.getAll(Set.copyOf(ids)); + } + + validateCount(count); + validateCodespaces(codespaces); + validateSystems(systems); + + var filterParams = new StationFilterParameters( + codespaces, + systems, + operators, + count, + availableFormFactors, + availablePropulsionTypes + ); + + Collection stations; + + validateQueryParameters( + lat, + lon, + range, + minimumLatitude, + minimumLongitude, + maximumLatitude, + maximumLongitude + ); + + if (isRangeSearch(range, maximumLatitude, maximumLongitude)) { + var queryParams = new RangeQueryParameters(lat, lon, range); + stations = geoSearchService.getStationsWithinRange(queryParams, filterParams); + } else { + var queryParams = new BoundingBoxQueryParameters( + minimumLatitude, + minimumLongitude, + maximumLatitude, + maximumLongitude + ); + stations = geoSearchService.getStationsInBoundingBox(queryParams, filterParams); + } + + return stations; + } + + @QueryMapping + public Collection stationsById(@Argument List ids) { + return stationCache.getAll(Set.copyOf(ids)); + } +} diff --git a/src/main/java/org/entur/lamassu/graphql/controller/VehicleGraphQLController.java b/src/main/java/org/entur/lamassu/graphql/controller/VehicleGraphQLController.java new file mode 100644 index 00000000..e7351a53 --- /dev/null +++ b/src/main/java/org/entur/lamassu/graphql/controller/VehicleGraphQLController.java @@ -0,0 +1,105 @@ +package org.entur.lamassu.graphql.controller; + +import java.util.Collection; +import java.util.List; +import java.util.Set; +import org.entur.lamassu.cache.VehicleCache; +import org.entur.lamassu.model.entities.FormFactor; +import org.entur.lamassu.model.entities.PropulsionType; +import org.entur.lamassu.model.entities.Vehicle; +import org.entur.lamassu.service.BoundingBoxQueryParameters; +import org.entur.lamassu.service.FeedProviderService; +import org.entur.lamassu.service.GeoSearchService; +import org.entur.lamassu.service.RangeQueryParameters; +import org.entur.lamassu.service.VehicleFilterParameters; +import org.springframework.graphql.data.method.annotation.Argument; +import org.springframework.graphql.data.method.annotation.QueryMapping; +import org.springframework.stereotype.Controller; + +@Controller +public class VehicleGraphQLController extends BaseGraphQLController { + + private final GeoSearchService geoSearchService; + private final VehicleCache vehicleCache; + + public VehicleGraphQLController( + GeoSearchService geoSearchService, + FeedProviderService feedProviderService, + VehicleCache vehicleCache + ) { + super(feedProviderService); + this.geoSearchService = geoSearchService; + this.vehicleCache = vehicleCache; + } + + @QueryMapping + public Vehicle vehicle(@Argument String id) { + return vehicleCache.get(id); + } + + @QueryMapping + public Collection vehicles( + @Argument List ids, + @Argument Double lat, + @Argument Double lon, + @Argument Double range, + @Argument Double minimumLatitude, + @Argument Double minimumLongitude, + @Argument Double maximumLatitude, + @Argument Double maximumLongitude, + @Argument Integer count, + @Argument List codespaces, + @Argument List systems, + @Argument List operators, + @Argument List formFactors, + @Argument List propulsionTypes, + @Argument Boolean includeReserved, + @Argument Boolean includeDisabled + ) { + if (ids != null && !ids.isEmpty()) { + return vehicleCache.getAll(Set.copyOf(ids)); + } + + validateCount(count); + validateCodespaces(codespaces); + validateSystems(systems); + + var filterParams = new VehicleFilterParameters( + codespaces, + systems, + operators, + count, + formFactors, + propulsionTypes, + includeReserved, + includeDisabled + ); + + Collection vehicles; + + validateQueryParameters( + lat, + lon, + range, + minimumLatitude, + minimumLongitude, + maximumLatitude, + maximumLongitude + ); + + if (isRangeSearch(range, lat, lon)) { + var queryParams = new RangeQueryParameters(lat, lon, range); + vehicles = geoSearchService.getVehiclesWithinRange(queryParams, filterParams); + } else { + var queryParams = new BoundingBoxQueryParameters( + minimumLatitude, + minimumLongitude, + maximumLatitude, + maximumLongitude + ); + vehicles = geoSearchService.getVehiclesInBoundingBox(queryParams, filterParams); + } + + return vehicles; + } +} diff --git a/src/main/java/org/entur/lamassu/service/BoundingBoxQueryParameters.java b/src/main/java/org/entur/lamassu/service/BoundingBoxQueryParameters.java index b4163cb5..c82acba1 100644 --- a/src/main/java/org/entur/lamassu/service/BoundingBoxQueryParameters.java +++ b/src/main/java/org/entur/lamassu/service/BoundingBoxQueryParameters.java @@ -25,6 +25,18 @@ public class BoundingBoxQueryParameters { private Double maximumLatitude; private Double maximumLongitude; + public BoundingBoxQueryParameters( + Double minimumLatitude, + Double minimumLongitude, + Double maximumLatitude, + Double maximumLongitude + ) { + this.minimumLatitude = minimumLatitude; + this.minimumLongitude = minimumLongitude; + this.maximumLatitude = maximumLatitude; + this.maximumLongitude = maximumLongitude; + } + public Double getMinimumLatitude() { return minimumLatitude; } diff --git a/src/main/java/org/entur/lamassu/service/FilterParameters.java b/src/main/java/org/entur/lamassu/service/FilterParameters.java index a006a6bd..bed65c31 100644 --- a/src/main/java/org/entur/lamassu/service/FilterParameters.java +++ b/src/main/java/org/entur/lamassu/service/FilterParameters.java @@ -20,13 +20,25 @@ import java.util.List; -public class FilterParameters { +public abstract class FilterParameters { private List codespaces; private List systems; private List operators; private Integer count; + public FilterParameters( + List codespaces, + List systems, + List operators, + Integer count + ) { + this.codespaces = codespaces; + this.systems = systems; + this.operators = operators; + this.count = count; + } + public List getCodespaces() { return codespaces; } diff --git a/src/main/java/org/entur/lamassu/service/RangeQueryParameters.java b/src/main/java/org/entur/lamassu/service/RangeQueryParameters.java index 70aa914e..73a43cd3 100644 --- a/src/main/java/org/entur/lamassu/service/RangeQueryParameters.java +++ b/src/main/java/org/entur/lamassu/service/RangeQueryParameters.java @@ -6,6 +6,14 @@ public class RangeQueryParameters { private Double lon; private Double range; + public RangeQueryParameters() {} + + public RangeQueryParameters(Double lat, Double lon, Double range) { + this.lat = lat; + this.lon = lon; + this.range = range; + } + public Double getLat() { return lat; } diff --git a/src/main/java/org/entur/lamassu/service/StationFilterParameters.java b/src/main/java/org/entur/lamassu/service/StationFilterParameters.java index 903fa7be..88684b32 100644 --- a/src/main/java/org/entur/lamassu/service/StationFilterParameters.java +++ b/src/main/java/org/entur/lamassu/service/StationFilterParameters.java @@ -27,6 +27,19 @@ public class StationFilterParameters extends FilterParameters { private List availableFormFactors; private List availablePropulsionTypes; + public StationFilterParameters( + List codespaces, + List systems, + List operators, + Integer count, + List availableFormFactors, + List availablePropulsionTypes + ) { + super(codespaces, systems, operators, count); + this.availableFormFactors = availableFormFactors; + this.availablePropulsionTypes = availablePropulsionTypes; + } + public List getAvailableFormFactors() { return availableFormFactors; } diff --git a/src/main/java/org/entur/lamassu/service/VehicleFilterParameters.java b/src/main/java/org/entur/lamassu/service/VehicleFilterParameters.java index eefe3f48..71138b0c 100644 --- a/src/main/java/org/entur/lamassu/service/VehicleFilterParameters.java +++ b/src/main/java/org/entur/lamassu/service/VehicleFilterParameters.java @@ -11,6 +11,23 @@ public class VehicleFilterParameters extends FilterParameters { private boolean includeReserved; private boolean includeDisabled; + public VehicleFilterParameters( + List codespaces, + List systems, + List operators, + Integer count, + List formFactors, + List propulsionTypes, + boolean includeReserved, + boolean includeDisabled + ) { + super(codespaces, systems, operators, count); + this.formFactors = formFactors; + this.propulsionTypes = propulsionTypes; + this.includeReserved = includeReserved; + this.includeDisabled = includeDisabled; + } + public List getFormFactors() { return formFactors; } From 4ee93a7c22cfd7aef740f6a86c704354630ecc67 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=20Erik=20St=C3=B8wer?= Date: Thu, 19 Dec 2024 14:18:29 +0100 Subject: [PATCH 2/4] Fix conditional --- .../lamassu/graphql/controller/StationGraphQLController.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/entur/lamassu/graphql/controller/StationGraphQLController.java b/src/main/java/org/entur/lamassu/graphql/controller/StationGraphQLController.java index 4e172343..0df5e380 100644 --- a/src/main/java/org/entur/lamassu/graphql/controller/StationGraphQLController.java +++ b/src/main/java/org/entur/lamassu/graphql/controller/StationGraphQLController.java @@ -79,7 +79,7 @@ public Collection stations( maximumLongitude ); - if (isRangeSearch(range, maximumLatitude, maximumLongitude)) { + if (isRangeSearch(range, lat, lon)) { var queryParams = new RangeQueryParameters(lat, lon, range); stations = geoSearchService.getStationsWithinRange(queryParams, filterParams); } else { From 2bfc0bf95ec6ebf48a51705713036ef444f38b8e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=20Erik=20St=C3=B8wer?= Date: Thu, 19 Dec 2024 14:18:47 +0100 Subject: [PATCH 3/4] Update tests --- pom.xml | 5 + .../AbstractIntegrationTestBase.java | 18 +- .../integration/GBFSRestIntegrationTest.java | 38 +-- .../GBFSV3RestIntegrationTest.java | 34 +- .../integration/GraphQLIntegrationTest.java | 303 ++++++++---------- .../util/SpatialIndexIdFilterTest.java | 24 +- .../geofencing_zones_query.graphql | 0 ...lyline_encoded_multi_polygon_query.graphql | 0 .../station_by_id_query.graphql | 0 .../stations_bbox_query.graphql | 0 .../stations_by_id_query.graphql | 0 ...lyline_encoded_multi_polygon_query.graphql | 0 .../{ => graphql-test}/stations_query.graphql | 0 .../stations_query_unknown_operator.graphql | 0 .../vehicle_by_id_query.graphql | 0 .../vehicles_bbox_query.graphql | 0 .../vehicles_by_id_query.graphql | 0 .../vehicles_query_with_disabled.graphql | 0 .../vehicles_query_without_disabled.graphql | 0 19 files changed, 189 insertions(+), 233 deletions(-) rename src/test/resources/{ => graphql-test}/geofencing_zones_query.graphql (100%) rename src/test/resources/{ => graphql-test}/polyline_encoded_multi_polygon_query.graphql (100%) rename src/test/resources/{ => graphql-test}/station_by_id_query.graphql (100%) rename src/test/resources/{ => graphql-test}/stations_bbox_query.graphql (100%) rename src/test/resources/{ => graphql-test}/stations_by_id_query.graphql (100%) rename src/test/resources/{ => graphql-test}/stations_polyline_encoded_multi_polygon_query.graphql (100%) rename src/test/resources/{ => graphql-test}/stations_query.graphql (100%) rename src/test/resources/{ => graphql-test}/stations_query_unknown_operator.graphql (100%) rename src/test/resources/{ => graphql-test}/vehicle_by_id_query.graphql (100%) rename src/test/resources/{ => graphql-test}/vehicles_bbox_query.graphql (100%) rename src/test/resources/{ => graphql-test}/vehicles_by_id_query.graphql (100%) rename src/test/resources/{ => graphql-test}/vehicles_query_with_disabled.graphql (100%) rename src/test/resources/{ => graphql-test}/vehicles_query_without_disabled.graphql (100%) diff --git a/pom.xml b/pom.xml index d89b0822..25bc1fa3 100644 --- a/pom.xml +++ b/pom.xml @@ -152,6 +152,11 @@ spring-boot-starter-test test + + org.springframework.graphql + spring-graphql-test + test + org.signal embedded-redis diff --git a/src/test/java/org/entur/lamassu/integration/AbstractIntegrationTestBase.java b/src/test/java/org/entur/lamassu/integration/AbstractIntegrationTestBase.java index 1f52adb1..f4f3ca63 100644 --- a/src/test/java/org/entur/lamassu/integration/AbstractIntegrationTestBase.java +++ b/src/test/java/org/entur/lamassu/integration/AbstractIntegrationTestBase.java @@ -12,19 +12,19 @@ import org.entur.lamassu.TestLamassuApplication; import org.entur.lamassu.leader.LeaderSingletonService; import org.jetbrains.annotations.NotNull; -import org.junit.AfterClass; -import org.junit.Before; -import org.junit.BeforeClass; -import org.junit.runner.RunWith; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.extension.ExtendWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.context.ActiveProfiles; -import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.test.context.junit.jupiter.SpringExtension; @ActiveProfiles({ "test", "leader" }) @DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS) -@RunWith(SpringRunner.class) +@ExtendWith(SpringExtension.class) @SpringBootTest( classes = TestLamassuApplication.class, properties = "scheduling.enabled=false", @@ -37,7 +37,7 @@ public abstract class AbstractIntegrationTestBase { private static MockWebServer mockWebServer; - @BeforeClass + @BeforeAll public static void setUp() throws IOException { mockWebServer = new MockWebServer(); @@ -112,13 +112,13 @@ private static MockResponse getMockResponse(String file) { .setBody(getFileFromResource(file)); } - @AfterClass + @AfterAll public static void tearDown() throws IOException { mockWebServer.shutdown(); mockWebServer = null; } - @Before + @BeforeEach public void heartbeat() throws InterruptedException { Thread.sleep(1000); leaderSingletonService.update(); diff --git a/src/test/java/org/entur/lamassu/integration/GBFSRestIntegrationTest.java b/src/test/java/org/entur/lamassu/integration/GBFSRestIntegrationTest.java index b4401151..fc9f4d72 100644 --- a/src/test/java/org/entur/lamassu/integration/GBFSRestIntegrationTest.java +++ b/src/test/java/org/entur/lamassu/integration/GBFSRestIntegrationTest.java @@ -4,8 +4,8 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; -import org.junit.Ignore; -import org.junit.Test; +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; import org.springframework.test.web.servlet.MockMvc; @@ -17,7 +17,7 @@ public class GBFSRestIntegrationTest extends AbstractIntegrationTestBase { private MockMvc mockMvc; @Test - public void testFeedProviderDiscovery() throws Exception { + void testFeedProviderDiscovery() throws Exception { mockMvc .perform(get("/gbfs/v2").contentType("application/json")) .andExpect(status().isOk()) @@ -25,7 +25,7 @@ public void testFeedProviderDiscovery() throws Exception { } @Test - public void testGBFS() throws Exception { + void testGBFS() throws Exception { mockMvc .perform(get("/gbfs/v2/testatlantis/gbfs").contentType("application/json")) .andExpect(status().isOk()) @@ -33,8 +33,8 @@ public void testGBFS() throws Exception { } @Test - @Ignore("gbfs_versions intentionally not mapped") - public void testGBFSVersions() throws Exception { + @Disabled("gbfs_versions intentionally not mapped") + void testGBFSVersions() throws Exception { mockMvc .perform(get("/gbfs/v2/testatlantis/gbfs_versions").contentType("application/json")) .andExpect(status().isOk()) @@ -42,7 +42,7 @@ public void testGBFSVersions() throws Exception { } @Test - public void testSystemInformation() throws Exception { + void testSystemInformation() throws Exception { mockMvc .perform( get("/gbfs/v2/testatlantis/system_information").contentType("application/json") @@ -52,7 +52,7 @@ public void testSystemInformation() throws Exception { } @Test - public void testVehicleTypes() throws Exception { + void testVehicleTypes() throws Exception { mockMvc .perform(get("/gbfs/v2/testatlantis/vehicle_types").contentType("application/json")) .andExpect(status().isOk()) @@ -63,7 +63,7 @@ public void testVehicleTypes() throws Exception { } @Test - public void testFreeBikeStatus() throws Exception { + void testFreeBikeStatus() throws Exception { mockMvc .perform( get("/gbfs/v2/testatlantis/free_bike_status").contentType("application/json") @@ -79,7 +79,7 @@ public void testFreeBikeStatus() throws Exception { } @Test - public void testSystemRegions() throws Exception { + void testSystemRegions() throws Exception { mockMvc .perform( get("/gbfs/v2/testatlantis/system_regions").contentType("application/json") @@ -89,7 +89,7 @@ public void testSystemRegions() throws Exception { } @Test - public void testSystemPricingPlans() throws Exception { + void testSystemPricingPlans() throws Exception { mockMvc .perform( get("/gbfs/v2/testatlantis/system_pricing_plans").contentType("application/json") @@ -99,7 +99,7 @@ public void testSystemPricingPlans() throws Exception { } @Test - public void testStationInformation() throws Exception { + void testStationInformation() throws Exception { mockMvc .perform( get("/gbfs/v2/testatlantis/station_information").contentType("application/json") @@ -109,7 +109,7 @@ public void testStationInformation() throws Exception { } @Test - public void testStationStatus() throws Exception { + void testStationStatus() throws Exception { mockMvc .perform( get("/gbfs/v2/testatlantis/station_status").contentType("application/json") @@ -119,7 +119,7 @@ public void testStationStatus() throws Exception { } @Test - public void testSystemHours() throws Exception { + void testSystemHours() throws Exception { mockMvc .perform(get("/gbfs/v2/testatlantis/system_hours").contentType("application/json")) .andExpect(status().isOk()) @@ -127,7 +127,7 @@ public void testSystemHours() throws Exception { } @Test - public void testSystemCalendar() throws Exception { + void testSystemCalendar() throws Exception { mockMvc .perform( get("/gbfs/v2/testatlantis/system_calendar").contentType("application/json") @@ -137,7 +137,7 @@ public void testSystemCalendar() throws Exception { } @Test - public void testSystemAlerts() throws Exception { + void testSystemAlerts() throws Exception { mockMvc .perform(get("/gbfs/v2/testatlantis/system_alerts").contentType("application/json")) .andExpect(status().isOk()) @@ -147,7 +147,7 @@ public void testSystemAlerts() throws Exception { } @Test - public void testGeofencingZones() throws Exception { + void testGeofencingZones() throws Exception { mockMvc .perform( get("/gbfs/v2/testatlantis/geofencing_zones").contentType("application/json") @@ -159,14 +159,14 @@ public void testGeofencingZones() throws Exception { } @Test - public void testUnknownProviderResponds404() throws Exception { + void testUnknownProviderResponds404() throws Exception { mockMvc .perform(get("/gbfs/v2/foobar/gbfs").contentType("application/json")) .andExpect(status().isNotFound()); } @Test - public void testUnsupportedFeedResponds400() throws Exception { + void testUnsupportedFeedResponds400() throws Exception { mockMvc .perform(get("/gbfs/v2/testatlantis/foobar").contentType("application/json")) .andExpect(status().isBadRequest()); diff --git a/src/test/java/org/entur/lamassu/integration/GBFSV3RestIntegrationTest.java b/src/test/java/org/entur/lamassu/integration/GBFSV3RestIntegrationTest.java index cbd16f52..46c3b861 100644 --- a/src/test/java/org/entur/lamassu/integration/GBFSV3RestIntegrationTest.java +++ b/src/test/java/org/entur/lamassu/integration/GBFSV3RestIntegrationTest.java @@ -4,8 +4,8 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; -import org.junit.Ignore; -import org.junit.Test; +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; import org.springframework.test.web.servlet.MockMvc; @@ -17,7 +17,7 @@ public class GBFSV3RestIntegrationTest extends AbstractIntegrationTestBase { private MockMvc mockMvc; @Test - public void testFeedProviderDiscovery() throws Exception { + void testFeedProviderDiscovery() throws Exception { mockMvc .perform(get("/gbfs/v3/manifest.json").contentType("application/json")) .andExpect(status().isOk()) @@ -25,7 +25,7 @@ public void testFeedProviderDiscovery() throws Exception { } @Test - public void testGBFS() throws Exception { + void testGBFS() throws Exception { mockMvc .perform(get("/gbfs/v3/testozon/gbfs").contentType("application/json")) .andExpect(status().isOk()) @@ -33,8 +33,8 @@ public void testGBFS() throws Exception { } @Test - @Ignore("gbfs_versions intentionally not mapped") - public void testGBFSVersions() throws Exception { + @Disabled("gbfs_versions intentionally not mapped") + void testGBFSVersions() throws Exception { mockMvc .perform(get("/gbfs/v3/testozon/gbfs_versions").contentType("application/json")) .andExpect(status().isOk()) @@ -42,7 +42,7 @@ public void testGBFSVersions() throws Exception { } @Test - public void testSystemInformation() throws Exception { + void testSystemInformation() throws Exception { mockMvc .perform( get("/gbfs/v3/testozon/system_information").contentType("application/json") @@ -52,7 +52,7 @@ public void testSystemInformation() throws Exception { } @Test - public void testVehicleTypes() throws Exception { + void testVehicleTypes() throws Exception { mockMvc .perform(get("/gbfs/v3/testozon/vehicle_types").contentType("application/json")) .andExpect(status().isOk()) @@ -63,7 +63,7 @@ public void testVehicleTypes() throws Exception { } @Test - public void testVehicleStatus() throws Exception { + void testVehicleStatus() throws Exception { mockMvc .perform(get("/gbfs/v3/testozon/vehicle_status").contentType("application/json")) .andExpect(status().isOk()) @@ -77,7 +77,7 @@ public void testVehicleStatus() throws Exception { } @Test - public void testSystemRegions() throws Exception { + void testSystemRegions() throws Exception { mockMvc .perform(get("/gbfs/v3/testozon/system_regions").contentType("application/json")) .andExpect(status().isOk()) @@ -85,7 +85,7 @@ public void testSystemRegions() throws Exception { } @Test - public void testSystemPricingPlans() throws Exception { + void testSystemPricingPlans() throws Exception { mockMvc .perform( get("/gbfs/v3/testozon/system_pricing_plans").contentType("application/json") @@ -97,7 +97,7 @@ public void testSystemPricingPlans() throws Exception { } @Test - public void testStationInformation() throws Exception { + void testStationInformation() throws Exception { mockMvc .perform( get("/gbfs/v3/testozon/station_information").contentType("application/json") @@ -107,7 +107,7 @@ public void testStationInformation() throws Exception { } @Test - public void testStationStatus() throws Exception { + void testStationStatus() throws Exception { mockMvc .perform(get("/gbfs/v3/testozon/station_status").contentType("application/json")) .andExpect(status().isOk()) @@ -115,7 +115,7 @@ public void testStationStatus() throws Exception { } @Test - public void testSystemAlerts() throws Exception { + void testSystemAlerts() throws Exception { mockMvc .perform(get("/gbfs/v3/testozon/system_alerts").contentType("application/json")) .andExpect(status().isOk()) @@ -124,7 +124,7 @@ public void testSystemAlerts() throws Exception { } @Test - public void testGeofencingZones() throws Exception { + void testGeofencingZones() throws Exception { mockMvc .perform(get("/gbfs/v3/testozon/geofencing_zones").contentType("application/json")) .andExpect(status().isOk()) @@ -135,14 +135,14 @@ public void testGeofencingZones() throws Exception { } @Test - public void testUnknownProviderResponds404() throws Exception { + void testUnknownProviderResponds404() throws Exception { mockMvc .perform(get("/gbfs/v3/foobar/gbfs").contentType("application/json")) .andExpect(status().isNotFound()); } @Test - public void testUnsupportedFeedResponds400() throws Exception { + void testUnsupportedFeedResponds400() throws Exception { mockMvc .perform(get("/gbfs/v3/testozon/foobar").contentType("application/json")) .andExpect(status().isBadRequest()); diff --git a/src/test/java/org/entur/lamassu/integration/GraphQLIntegrationTest.java b/src/test/java/org/entur/lamassu/integration/GraphQLIntegrationTest.java index 924de438..bc59fb79 100644 --- a/src/test/java/org/entur/lamassu/integration/GraphQLIntegrationTest.java +++ b/src/test/java/org/entur/lamassu/integration/GraphQLIntegrationTest.java @@ -1,225 +1,172 @@ package org.entur.lamassu.integration; -import static org.junit.Assert.assertTrue; -import static org.junit.jupiter.api.Assertions.assertEquals; - -import com.graphql.spring.boot.test.GraphQLResponse; -import com.graphql.spring.boot.test.GraphQLTestTemplate; -import com.jayway.jsonpath.JsonPath; -import java.io.IOException; -import java.util.List; -import org.junit.Test; +import static org.springframework.graphql.test.tester.GraphQlTester.Response; + +import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.http.HttpStatus; +import org.springframework.graphql.test.tester.WebGraphQlTester; -public class GraphQLIntegrationTest extends AbstractIntegrationTestBase { +class GraphQLIntegrationTest extends AbstractIntegrationTestBase { @Autowired - private GraphQLTestTemplate graphQLTestTemplate; + private WebGraphQlTester graphQlTester; @Test - public void testVehiclesQuery() throws IOException { - GraphQLResponse response = graphQLTestTemplate.postForResource( - "vehicles_query_with_disabled.graphql" - ); - assertEquals(HttpStatus.OK, response.getStatusCode()); - - // TODO: investigate why this started failing - //assertEquals(2, response.get("$.data.vehicles", List.class).size()); - assertEquals( - 2, - JsonPath - .parse(response.getRawResponse().getBody()) - .read("$.data.vehicles", List.class) - .size() - ); - - assertEquals("TST:Vehicle:1234", response.get("$.data.vehicles[0].id")); - assertEquals( - "Test", - response.get("$.data.vehicles[0].system.name.translation[0].value") - ); + void testVehiclesQuery() { + Response response = graphQlTester + .documentName("vehicles_query_with_disabled") + .execute(); + + response.path("vehicles").entityList(Object.class).hasSize(2); + + response.path("vehicles[0].id").entity(String.class).isEqualTo("TST:Vehicle:1234"); + + response + .path("vehicles[0].system.name.translation[0].value") + .entity(String.class) + .isEqualTo("Test"); } @Test - public void testVehicleByIdQuery() throws IOException { - GraphQLResponse response = graphQLTestTemplate.postForResource( - "vehicle_by_id_query.graphql" - ); - assertEquals(HttpStatus.OK, response.getStatusCode()); - assertEquals("TST:Vehicle:1235", response.get("$.data.vehicle.id")); + void testVehicleByIdQuery() { + Response response = graphQlTester.documentName("vehicle_by_id_query").execute(); + + response.path("vehicle.id").entity(String.class).isEqualTo("TST:Vehicle:1235"); } @Test - public void testVehiclesByIdQuery() throws IOException, InterruptedException { - GraphQLResponse response = graphQLTestTemplate.postForResource( - "vehicles_by_id_query.graphql" - ); - assertEquals(HttpStatus.OK, response.getStatusCode()); - assertEquals( - "OZO:Vehicle:973a5c94-c288-4a2b-afa6-de8aeb6ae2e5", - response.get("$.data.vehicles[0].id") - ); - assertEquals("TST:Vehicle:1235", response.get("$.data.vehicles[1].id")); - assertEquals( - "Another company", - response.get( - "$.data.vehicles[0].system.attributionOrganizationName.translation[0].value" - ) - ); + void testVehiclesByIdQuery() { + Response response = graphQlTester.documentName("vehicles_by_id_query").execute(); + + response + .path("vehicles[*].id") + .entityList(String.class) + .hasSize(2) + .contains("TST:Vehicle:1235", "OZO:Vehicle:973a5c94-c288-4a2b-afa6-de8aeb6ae2e5"); } @Test - public void testVehicleQueryWithoutDisabled() throws IOException { - GraphQLResponse response = graphQLTestTemplate.postForResource( - "vehicles_query_without_disabled.graphql" - ); - assertEquals(HttpStatus.OK, response.getStatusCode()); - - // TODO: investigate why this started failing - //assertEquals(1, response.get("$.data.vehicles", List.class).size()); - assertEquals( - 1, - JsonPath - .parse(response.getRawResponse().getBody()) - .read("$.data.vehicles", List.class) - .size() - ); + void testVehicleQueryWithoutDisabled() { + Response response = graphQlTester + .documentName("vehicles_query_without_disabled") + .execute(); + + response.path("vehicles").entityList(Object.class).hasSize(1); } @Test - public void testStationsQuery() throws IOException { - GraphQLResponse response = graphQLTestTemplate.postForResource( - "stations_query.graphql" - ); - assertEquals(HttpStatus.OK, response.getStatusCode()); - assertEquals("TST:Station:2", response.get("$.data.stations[0].id")); - assertEquals( - "Cooler bikes", - response.get("$.data.stations[0].name.translation[0].value") - ); - assertEquals( - "https://rentmybikes.com", - response.get("$.data.stations[0].rentalUris.web") - ); + void testStationsQuery() { + Response response = graphQlTester.documentName("stations_query").execute(); + + response.path("stations[0].id").entity(String.class).isEqualTo("TST:Station:2"); + + response + .path("stations[0].name.translation[0].value") + .entity(String.class) + .isEqualTo("Cooler bikes"); + + response + .path("stations[0].rentalUris.web") + .entity(String.class) + .isEqualTo("https://rentmybikes.com"); } @Test - public void testStationAreaPolylineEncodedMultiPolygon() throws IOException { - GraphQLResponse response = graphQLTestTemplate.postForResource( - "stations_polyline_encoded_multi_polygon_query.graphql" - ); - - assertEquals(HttpStatus.OK, response.getStatusCode()); - assertEquals( - "gxk~wBiiiyRdBM@oHaBLEnH", - response.get("$.data.stations[0].stationAreaPolylineEncodedMultiPolygon[0][0]") - ); + void testStationAreaPolylineEncodedMultiPolygon() { + Response response = graphQlTester + .documentName("stations_polyline_encoded_multi_polygon_query") + .execute(); + + response + .path("stations[0].stationAreaPolylineEncodedMultiPolygon[0][0]") + .entity(String.class) + .isEqualTo("gxk~wBiiiyRdBM@oHaBLEnH"); } @Test - public void testStationByIdQuery() throws IOException { - GraphQLResponse response = graphQLTestTemplate.postForResource( - "station_by_id_query.graphql" - ); - assertEquals(HttpStatus.OK, response.getStatusCode()); - assertEquals("TST:Station:1", response.get("$.data.station.id")); - assertEquals("2", response.get("$.data.station.vehicleDocksAvailable[0].count")); - assertEquals("1", response.get("$.data.station.numVehiclesAvailable")); - assertEquals("2", response.get("$.data.station.numVehiclesDisabled")); + void testStationByIdQuery() { + Response response = graphQlTester.documentName("station_by_id_query").execute(); + + response.path("station.id").entity(String.class).isEqualTo("TST:Station:1"); + + response + .path("station.vehicleDocksAvailable[0].count") + .entity(String.class) + .isEqualTo("2"); + + response.path("station.numVehiclesAvailable").entity(String.class).isEqualTo("1"); + + response.path("station.numVehiclesDisabled").entity(String.class).isEqualTo("2"); } @Test - public void testStationsByIdQuery() throws IOException { - GraphQLResponse response = graphQLTestTemplate.postForResource( - "stations_by_id_query.graphql" - ); - assertEquals(HttpStatus.OK, response.getStatusCode()); - assertEquals("TST:Station:1", response.get("$.data.stations[0].id")); - assertEquals("2", response.get("$.data.stations[0].vehicleDocksAvailable[0].count")); + void testStationsByIdQuery() { + Response response = graphQlTester.documentName("stations_by_id_query").execute(); + + response.path("stations[0].id").entity(String.class).isEqualTo("TST:Station:1"); + + response + .path("stations[0].vehicleDocksAvailable[0].count") + .entity(String.class) + .isEqualTo("2"); } @Test - public void testGeofencingZones() throws IOException { - GraphQLResponse response = graphQLTestTemplate.postForResource( - "geofencing_zones_query.graphql" - ); - assertEquals(HttpStatus.OK, response.getStatusCode()); - assertEquals("testatlantis", response.get("$.data.geofencingZones[0].systemId")); - assertEquals( - "true", - response.get( - "$.data.geofencingZones[0].geojson.features[0].properties.rules[0].rideStartAllowed" - ) - ); - assertEquals( - "true", - response.get( - "$.data.geofencingZones[0].geojson.features[0].properties.rules[0].rideEndAllowed" - ) - ); + void testGeofencingZones() { + Response response = graphQlTester.documentName("geofencing_zones_query").execute(); + + response + .path("geofencingZones[0].systemId") + .entity(String.class) + .isEqualTo("testatlantis"); + + response + .path("geofencingZones[0].geojson.features[0].properties.rules[0].rideStartAllowed") + .entity(String.class) + .isEqualTo("true"); + + response + .path("geofencingZones[0].geojson.features[0].properties.rules[0].rideEndAllowed") + .entity(String.class) + .isEqualTo("true"); } @Test - public void testPolylineEncodedMultiPolygon() throws IOException { - GraphQLResponse response = graphQLTestTemplate.postForResource( - "polyline_encoded_multi_polygon_query.graphql" - ); - - assertEquals(HttpStatus.OK, response.getStatusCode()); - assertEquals( - "qznuqBsgw~TnwAepEpsFglSveIexThp[{cVj}DvcE|yA|`AvlJjjFnBj_@vRhM`PrdD`JlJxfJddoBpnl@bcx@hmOtzDzfFyvSb`\\pfQpkW|{{@~aDpkpAmjDndH|rCf_Zr{IdjSwwN|ml@q~@|{_@mf^jhVoxXrdc@ohPahUyvJqyc@ee^bcMud\\sz\\{me@tc@g_Swv\\unAv~f@{zIzsCeqCtA}w@`QeWlsDgiAtGgu@ux@mzAea@}iFy{F}wGsv@keN|i@utTdxSaoD~ud@aoMc`EitJkvf@idCe_@klAn`G{~Gp_B}~CxtAynI|kKsyAp}SovPz`I~{JxhWc|dAvmq@qg^ogfBrhNegNqxH{gZlCui^niU_djAfm^e{~@lh^wn_@yoCkhHc}l@lj]iiZq{^g}m@rxo@kle@edGc_g@_ku@h}h@ephCnmgAk|fDz|j@~yCrhOz_[pq}@~_@r}BprChbC}m@~@duChb@n`@~d@z|Ah`BjrBr}@k{@to_@~j_@rhKofGcsEcdLl~M{g]`tKo~Al}XxxaA`pVhnm@", - response.get( - "$.data.geofencingZones[0].geojson.features[0].properties.polylineEncodedMultiPolygon[0][0]" + void testPolylineEncodedMultiPolygon() { + Response response = graphQlTester + .documentName("polyline_encoded_multi_polygon_query") + .execute(); + + response + .path( + "geofencingZones[0].geojson.features[0].properties.polylineEncodedMultiPolygon[0][0]" ) - ); + .entity(String.class) + .isEqualTo( + "qznuqBsgw~TnwAepEpsFglSveIexThp[{cVj}DvcE|yA|`AvlJjjFnBj_@vRhM`PrdD`JlJxfJddoBpnl@bcx@hmOtzDzfFyvSb`\\pfQpkW|{{@~aDpkpAmjDndH|rCf_Zr{IdjSwwN|ml@q~@|{_@mf^jhVoxXrdc@ohPahUyvJqyc@ee^bcMud\\sz\\{me@tc@g_Swv\\unAv~f@{zIzsCeqCtA}w@`QeWlsDgiAtGgu@ux@mzAea@}iFy{F}wGsv@keN|i@utTdxSaoD~ud@aoMc`EitJkvf@idCe_@klAn`G{~Gp_B}~CxtAynI|kKsyAp}SovPz`I~{JxhWc|dAvmq@qg^ogfBrhNegNqxH{gZlCui^niU_djAfm^e{~@lh^wn_@yoCkhHc}l@lj]iiZq{^g}m@rxo@kle@edGc_g@_ku@h}h@ephCnmgAk|fDz|j@~yCrhOz_[pq}@~_@r}BprChbC}m@~@duChb@n`@~d@z|Ah`BjrBr}@k{@to_@~j_@rhKofGcsEcdLl~M{g]`tKo~Al}XxxaA`pVhnm@" + ); } @Test - public void testUnknownOperatorDoesNotThrow() throws IOException { - GraphQLResponse response = graphQLTestTemplate.postForResource( - "stations_query_unknown_operator.graphql" - ); - assertEquals(HttpStatus.OK, response.getStatusCode()); - - // TODO: investigate why this started failing - //assertTrue(response.get("$.data.stations", List.class).isEmpty()); - assertTrue( - JsonPath - .parse(response.getRawResponse().getBody()) - .read("$.data.stations", List.class) - .isEmpty() - ); + void testUnknownOperatorDoesNotThrow() { + Response response = graphQlTester + .documentName("stations_query_unknown_operator") + .execute(); + + response.path("stations").entityList(Object.class).hasSize(0); } @Test - public void testVehiclesBoundingBoxQuery() throws IOException { - GraphQLResponse response = graphQLTestTemplate.postForResource( - "vehicles_bbox_query.graphql" - ); - assertEquals(HttpStatus.OK, response.getStatusCode()); - - assertEquals( - 2, - JsonPath - .parse(response.getRawResponse().getBody()) - .read("$.data.vehicles", List.class) - .size() - ); + void testVehiclesBoundingBoxQuery() { + Response response = graphQlTester.documentName("vehicles_bbox_query").execute(); + + response.path("vehicles").entityList(Object.class).hasSize(2); } @Test - public void testStationsBoundingBoxQuery() throws IOException { - GraphQLResponse response = graphQLTestTemplate.postForResource( - "stations_bbox_query.graphql" - ); - assertEquals(HttpStatus.OK, response.getStatusCode()); - assertEquals( - 1, - JsonPath - .parse(response.getRawResponse().getBody()) - .read("$.data.stations", List.class) - .size() - ); + void testStationsBoundingBoxQuery() { + Response response = graphQlTester.documentName("stations_bbox_query").execute(); + + response.path("stations").entityList(Object.class).hasSize(1); } } diff --git a/src/test/java/org/entur/lamassu/util/SpatialIndexIdFilterTest.java b/src/test/java/org/entur/lamassu/util/SpatialIndexIdFilterTest.java index 5c1fb36e..5483583d 100644 --- a/src/test/java/org/entur/lamassu/util/SpatialIndexIdFilterTest.java +++ b/src/test/java/org/entur/lamassu/util/SpatialIndexIdFilterTest.java @@ -123,10 +123,14 @@ public void testIncludeDisabledFilter() { @Test public void testVehicleTypesAvailableFilter() { var testId = aStationId(); - var params = new StationFilterParameters(); - - params.setAvailableFormFactors(List.of(FormFactor.SCOOTER)); - params.setAvailablePropulsionTypes(List.of(PropulsionType.ELECTRIC)); + var params = new StationFilterParameters( + emptyList(), + emptyList(), + emptyList(), + null, + List.of(FormFactor.SCOOTER), + List.of(PropulsionType.ELECTRIC) + ); Assert.assertTrue(SpatialIndexIdFilter.filterStation(testId, params)); @@ -145,6 +149,10 @@ private VehicleSpatialIndexId aVehicleId() { return SpatialIndexIdUtil.createVehicleSpatialIndexId(aVehicle(), aProvider()); } + private List emptyList() { + return List.of(); + } + private StationSpatialIndexId aStationId() { return SpatialIndexIdUtil.createStationSpatialIndexId(aStation(), aProvider()); } @@ -204,14 +212,10 @@ private FeedProvider aProvider() { } private VehicleFilterParameters aVehicleFilterParams() { - var params = new VehicleFilterParameters(); - params.setIncludeReserved(false); - params.setIncludeDisabled(false); - return params; + return new VehicleFilterParameters(null, null, null, null, null, null, false, false); } private StationFilterParameters aStationFilterParams() { - var params = new StationFilterParameters(); - return params; + return new StationFilterParameters(null, null, null, null, null, null); } } diff --git a/src/test/resources/geofencing_zones_query.graphql b/src/test/resources/graphql-test/geofencing_zones_query.graphql similarity index 100% rename from src/test/resources/geofencing_zones_query.graphql rename to src/test/resources/graphql-test/geofencing_zones_query.graphql diff --git a/src/test/resources/polyline_encoded_multi_polygon_query.graphql b/src/test/resources/graphql-test/polyline_encoded_multi_polygon_query.graphql similarity index 100% rename from src/test/resources/polyline_encoded_multi_polygon_query.graphql rename to src/test/resources/graphql-test/polyline_encoded_multi_polygon_query.graphql diff --git a/src/test/resources/station_by_id_query.graphql b/src/test/resources/graphql-test/station_by_id_query.graphql similarity index 100% rename from src/test/resources/station_by_id_query.graphql rename to src/test/resources/graphql-test/station_by_id_query.graphql diff --git a/src/test/resources/stations_bbox_query.graphql b/src/test/resources/graphql-test/stations_bbox_query.graphql similarity index 100% rename from src/test/resources/stations_bbox_query.graphql rename to src/test/resources/graphql-test/stations_bbox_query.graphql diff --git a/src/test/resources/stations_by_id_query.graphql b/src/test/resources/graphql-test/stations_by_id_query.graphql similarity index 100% rename from src/test/resources/stations_by_id_query.graphql rename to src/test/resources/graphql-test/stations_by_id_query.graphql diff --git a/src/test/resources/stations_polyline_encoded_multi_polygon_query.graphql b/src/test/resources/graphql-test/stations_polyline_encoded_multi_polygon_query.graphql similarity index 100% rename from src/test/resources/stations_polyline_encoded_multi_polygon_query.graphql rename to src/test/resources/graphql-test/stations_polyline_encoded_multi_polygon_query.graphql diff --git a/src/test/resources/stations_query.graphql b/src/test/resources/graphql-test/stations_query.graphql similarity index 100% rename from src/test/resources/stations_query.graphql rename to src/test/resources/graphql-test/stations_query.graphql diff --git a/src/test/resources/stations_query_unknown_operator.graphql b/src/test/resources/graphql-test/stations_query_unknown_operator.graphql similarity index 100% rename from src/test/resources/stations_query_unknown_operator.graphql rename to src/test/resources/graphql-test/stations_query_unknown_operator.graphql diff --git a/src/test/resources/vehicle_by_id_query.graphql b/src/test/resources/graphql-test/vehicle_by_id_query.graphql similarity index 100% rename from src/test/resources/vehicle_by_id_query.graphql rename to src/test/resources/graphql-test/vehicle_by_id_query.graphql diff --git a/src/test/resources/vehicles_bbox_query.graphql b/src/test/resources/graphql-test/vehicles_bbox_query.graphql similarity index 100% rename from src/test/resources/vehicles_bbox_query.graphql rename to src/test/resources/graphql-test/vehicles_bbox_query.graphql diff --git a/src/test/resources/vehicles_by_id_query.graphql b/src/test/resources/graphql-test/vehicles_by_id_query.graphql similarity index 100% rename from src/test/resources/vehicles_by_id_query.graphql rename to src/test/resources/graphql-test/vehicles_by_id_query.graphql diff --git a/src/test/resources/vehicles_query_with_disabled.graphql b/src/test/resources/graphql-test/vehicles_query_with_disabled.graphql similarity index 100% rename from src/test/resources/vehicles_query_with_disabled.graphql rename to src/test/resources/graphql-test/vehicles_query_with_disabled.graphql diff --git a/src/test/resources/vehicles_query_without_disabled.graphql b/src/test/resources/graphql-test/vehicles_query_without_disabled.graphql similarity index 100% rename from src/test/resources/vehicles_query_without_disabled.graphql rename to src/test/resources/graphql-test/vehicles_query_without_disabled.graphql From abde0deea8d671f2b4f282caeffce92a87323165 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=20Erik=20St=C3=B8wer?= Date: Thu, 19 Dec 2024 14:30:39 +0100 Subject: [PATCH 4/4] Fix test --- .../org/entur/lamassu/util/SpatialIndexIdFilterTest.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/test/java/org/entur/lamassu/util/SpatialIndexIdFilterTest.java b/src/test/java/org/entur/lamassu/util/SpatialIndexIdFilterTest.java index 5483583d..08c29791 100644 --- a/src/test/java/org/entur/lamassu/util/SpatialIndexIdFilterTest.java +++ b/src/test/java/org/entur/lamassu/util/SpatialIndexIdFilterTest.java @@ -124,9 +124,9 @@ public void testIncludeDisabledFilter() { public void testVehicleTypesAvailableFilter() { var testId = aStationId(); var params = new StationFilterParameters( - emptyList(), - emptyList(), - emptyList(), + null, + null, + null, null, List.of(FormFactor.SCOOTER), List.of(PropulsionType.ELECTRIC)