Skip to content

Commit

Permalink
Merge pull request #5284 from HSLdevcom/DT-5946-missing-ticket-discla…
Browse files Browse the repository at this point in the history
…imer

Consider feed id in HSL fare service
  • Loading branch information
optionsome authored Sep 14, 2023
2 parents 80f58d1 + a9caa84 commit 260c581
Show file tree
Hide file tree
Showing 6 changed files with 305 additions and 17 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@
import static org.opentripplanner.ext.fares.impl.FareModelForTest.CITY_CENTER_A_STOP;
import static org.opentripplanner.ext.fares.impl.FareModelForTest.CITY_CENTER_B_STOP;
import static org.opentripplanner.ext.fares.impl.FareModelForTest.INSIDE_CITY_CENTER_SET;
import static org.opentripplanner.ext.fares.impl.FareModelForTest.OTHER_FEED_ATTRIBUTE;
import static org.opentripplanner.ext.fares.impl.FareModelForTest.OTHER_FEED_ROUTE;
import static org.opentripplanner.ext.fares.impl.FareModelForTest.OTHER_FEED_SET;
import static org.opentripplanner.ext.fares.impl.FareModelForTest.OTHER_FEED_STOP;
import static org.opentripplanner.ext.fares.impl.FareModelForTest.SUBURB_STOP;
import static org.opentripplanner.model.plan.TestItineraryBuilder.newItinerary;

Expand Down Expand Up @@ -98,4 +102,79 @@ void unknownLeg() {
var firstBusLeg = itin.firstTransitLeg().get();
assertEquals(List.of(firstBusLeg), component.legs());
}

@Test
void multipleFeeds() {
var service = new DefaultFareService();
service.addFareRules(FareType.regular, List.of(AIRPORT_TO_CITY_CENTER_SET, OTHER_FEED_SET));
var itin = newItinerary(Place.forStop(AIRPORT_STOP))
.bus(1, T11_00, T11_05, Place.forStop(CITY_CENTER_A_STOP))
.walk(10, Place.forStop(OTHER_FEED_STOP))
.bus(OTHER_FEED_ROUTE, 2, T11_20, T11_32, Place.forStop(OTHER_FEED_STOP))
.build();
var result = service.calculateFares(itin);

var resultComponents = result
.getComponents(FareType.regular)
.stream()
.map(r -> r.fareId())
.toList();

var resultPrice = result.getFare(FareType.regular);

assertEquals(
List.of(AIRPORT_TO_CITY_CENTER_SET.getFareAttribute().getId(), OTHER_FEED_ATTRIBUTE.getId()),
resultComponents
);

assertEquals(Money.usDollars(20), resultPrice);
}

@Test
void multipleFeedsWithTransfersWithinFeed() {
var service = new DefaultFareService();
service.addFareRules(FareType.regular, List.of(INSIDE_CITY_CENTER_SET, OTHER_FEED_SET));
var itin = newItinerary(Place.forStop(OTHER_FEED_STOP))
.bus(OTHER_FEED_ROUTE, 2, T11_00, T11_05, Place.forStop(OTHER_FEED_STOP))
.walk(10, Place.forStop(CITY_CENTER_A_STOP))
.bus(1, T11_00, T11_05, Place.forStop(CITY_CENTER_A_STOP))
.walk(10, Place.forStop(OTHER_FEED_STOP))
.bus(OTHER_FEED_ROUTE, 2, T11_20, T11_32, Place.forStop(OTHER_FEED_STOP))
.build();
var result = service.calculateFares(itin);

var resultComponents = result
.getComponents(FareType.regular)
.stream()
.map(r -> r.fareId())
.toList();

var resultPrice = result.getFare(FareType.regular);
assertEquals(
List.of(INSIDE_CITY_CENTER_SET.getFareAttribute().getId(), OTHER_FEED_ATTRIBUTE.getId()),
resultComponents
);

assertEquals(Money.usDollars(20), resultPrice);
}

@Test
void multipleFeedsWithUnknownFareLegs() {
var service = new DefaultFareService();
service.addFareRules(FareType.regular, List.of(AIRPORT_TO_CITY_CENTER_SET, OTHER_FEED_SET));
var itin = newItinerary(Place.forStop(AIRPORT_STOP))
.bus(1, T11_00, T11_05, Place.forStop(OTHER_FEED_STOP))
.walk(10, Place.forStop(OTHER_FEED_STOP))
.bus(OTHER_FEED_ROUTE, 2, T11_20, T11_32, Place.forStop(OTHER_FEED_STOP))
.build();
var result = service.calculateFares(itin);
var resultComponents = result
.getComponents(FareType.regular)
.stream()
.map(r -> r.fareId())
.toList();
var resultPrice = result.getFare(FareType.regular);
assertEquals(List.of(OTHER_FEED_ATTRIBUTE.getId()), resultComponents);
assertEquals(Money.usDollars(-0.01f), resultPrice);
}
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
package org.opentripplanner.ext.fares.impl;

import static org.opentripplanner.transit.model._data.TransitModelForTest.FEED_ID;
import static org.opentripplanner.transit.model._data.TransitModelForTest.OTHER_AGENCY;
import static org.opentripplanner.transit.model._data.TransitModelForTest.OTHER_FEED_AGENCY;
import static org.opentripplanner.transit.model._data.TransitModelForTest.id;

import org.opentripplanner.ext.fares.model.FareAttribute;
import org.opentripplanner.ext.fares.model.FareRuleSet;
import org.opentripplanner.framework.geometry.WgsCoordinate;
import org.opentripplanner.framework.i18n.NonLocalizedString;
import org.opentripplanner.transit.model.basic.TransitMode;
import org.opentripplanner.transit.model.framework.FeedScopedId;
import org.opentripplanner.transit.model.network.Route;
import org.opentripplanner.transit.model.site.FareZone;
import org.opentripplanner.transit.model.site.RegularStop;

Expand All @@ -14,6 +20,10 @@ public class FareModelForTest {
public static final FareZone AIRPORT_ZONE = FareZone.of(id("airport-zone")).build();
public static final FareZone CITY_CENTER_ZONE = FareZone.of(id("city-center")).build();

public static final FareZone OTHER_FEED_ZONE = FareZone
.of(FeedScopedId.ofNullable("F2", "other-feed-zone"))
.build();

static RegularStop AIRPORT_STOP = RegularStop
.of(id("airport"))
.withCoordinate(new WgsCoordinate(1, 1))
Expand All @@ -39,16 +49,33 @@ public class FareModelForTest {
.withName(new NonLocalizedString("Suburb"))
.build();

static RegularStop OTHER_FEED_STOP = RegularStop
.of(FeedScopedId.ofNullable("F2", "other-feed-stop"))
.withCoordinate(new WgsCoordinate(1, 5))
.withName(new NonLocalizedString("Other feed stop"))
.addFareZones(OTHER_FEED_ZONE)
.build();
static FareAttribute TEN_DOLLARS = FareAttribute
.of(id("airport-to-city-center"))
.setCurrencyType("USD")
.setPrice(10)
.setTransfers(0)
.build();

static FareAttribute OTHER_FEED_ATTRIBUTE = FareAttribute
.of(FeedScopedId.ofNullable("F2", "other-feed-attribute"))
.setCurrencyType("USD")
.setPrice(10)
.setTransfers(1)
.setAgency(OTHER_FEED_AGENCY.getId())
.build();

// Fare rule sets
static FareRuleSet AIRPORT_TO_CITY_CENTER_SET = new FareRuleSet(TEN_DOLLARS);
static FareRuleSet INSIDE_CITY_CENTER_SET = new FareRuleSet(TEN_DOLLARS);

static FareRuleSet OTHER_FEED_SET = new FareRuleSet(OTHER_FEED_ATTRIBUTE);

static {
AIRPORT_TO_CITY_CENTER_SET.addOriginDestination(
AIRPORT_ZONE.getId().getId(),
Expand All @@ -58,5 +85,16 @@ public class FareModelForTest {
CITY_CENTER_ZONE.getId().getId(),
CITY_CENTER_ZONE.getId().getId()
);
OTHER_FEED_SET.addOriginDestination(
OTHER_FEED_ZONE.getId().getId(),
OTHER_FEED_ZONE.getId().getId()
);
}

static Route OTHER_FEED_ROUTE = Route
.of(new FeedScopedId("F2", "other-feed-route"))
.withAgency(OTHER_FEED_AGENCY)
.withLongName(new NonLocalizedString("other-feed-route"))
.withMode(TransitMode.BUS)
.build();
}
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,12 @@ private static List<Arguments> createTestCases() {
.withTimezone("Europe/Helsinki")
.build();

Agency agency3 = Agency
.of(new FeedScopedId("FEED2", "AG3"))
.withName("Agency 3")
.withTimezone("Europe/Helsinki")
.build();

FareZone A = FareZone.of(new FeedScopedId(FEED_ID, "A")).build();
FareZone B = FareZone.of(new FeedScopedId(FEED_ID, "B")).build();
FareZone C = FareZone.of(new FeedScopedId(FEED_ID, "C")).build();
Expand Down Expand Up @@ -147,6 +153,12 @@ private static List<Arguments> createTestCases() {
.setAgency(agency2.getId())
.build();

FareAttribute fareAttributeAgency3 = FareAttribute
.of(new FeedScopedId("FEED2", "attribute"))
.setCurrencyType("EUR")
.setAgency(agency3.getId())
.build();

// Fare rule sets
FareRuleSet ruleSetAB = new FareRuleSet(fareAttributeAB);
ruleSetAB.addContains("A");
Expand Down Expand Up @@ -183,6 +195,9 @@ private static List<Arguments> createTestCases() {
ruleSetD2.addContains("D");
ruleSetD2.setAgency(agency2.getId());

FareRuleSet ruleSetAgency3 = new FareRuleSet(fareAttributeAgency3);
ruleSetAgency3.addContains("B");

hslFareService.addFareRules(
FareType.regular,
List.of(
Expand All @@ -193,7 +208,8 @@ private static List<Arguments> createTestCases() {
ruleSetBCD,
ruleSetABCD,
ruleSetD,
ruleSetD2
ruleSetD2,
ruleSetAgency3
)
);

Expand All @@ -211,6 +227,13 @@ private static List<Arguments> createTestCases() {
.withMode(TransitMode.BUS)
.build();

Route routeAgency3 = Route
.of(new FeedScopedId("FEED2", "R3"))
.withAgency(agency3)
.withLongName(new NonLocalizedString("Route agency 3"))
.withMode(TransitMode.BUS)
.build();

// Itineraries within zone A
Itinerary A1_A2 = newItinerary(A1, T11_06).bus(1, T11_06, T11_12, A2).build();

Expand Down Expand Up @@ -366,6 +389,49 @@ private static List<Arguments> createTestCases() {
)
);

// Multifeed case
Itinerary A1_A2_2 = newItinerary(A1, T11_06)
.bus(routeAgency3, 1, T11_06, T11_14, A2)
.bus(routeAgency1, 2, T11_30, T11_50, A1)
.build();

args.add(
Arguments.of(
"Bus ride within zone A with two legs using different agencies from different feeds ",
hslFareService,
A1_A2_2,
List.of(fareAttributeAB.getId())
)
);

Itinerary i = newItinerary(D1, T11_06)
.bus(routeAgency1, 1, T11_06, T11_10, D2)
.walk(10, D1)
.bus(routeAgency2, 2, T11_20, T11_30, D2)
.build();

args.add(
Arguments.of(
"Multi-agency itinerary",
hslFareService,
i,
List.of(fareAttributeD.getId(), fareAttributeD2.getId())
)
);

Itinerary i2 = newItinerary(B1)
.bus(routeAgency1, 1, T11_06, T11_12, B1)
.bus(routeAgency3, 1, T11_14, T11_15, B2)
.build();

args.add(
Arguments.of(
"",
hslFareService,
i2,
List.of(fareAttributeAB.getId(), fareAttributeAgency3.getId())
)
);
return args;
}

Expand Down
Loading

0 comments on commit 260c581

Please sign in to comment.