Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix IBI fare calculators #5397

Merged
Merged
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
public class FaresFilterTest implements PlanTestConstants {

@Test
public void shouldAddFare() {
void shouldAddFare() {
final int ID = 1;

Itinerary i1 = newItinerary(A, 0)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package org.opentripplanner.ext.fares.impl;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.opentripplanner.ext.fares.impl.AtlantaFareService.COBB_AGENCY_ID;
import static org.opentripplanner.ext.fares.impl.AtlantaFareService.GCT_AGENCY_ID;
import static org.opentripplanner.ext.fares.impl.AtlantaFareService.MARTA_AGENCY_ID;
Expand All @@ -10,7 +13,6 @@
import static org.opentripplanner.transit.model.basic.Money.usDollars;

import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.junit.jupiter.api.BeforeAll;
Expand All @@ -20,6 +22,7 @@
import org.opentripplanner.framework.geometry.WgsCoordinate;
import org.opentripplanner.framework.i18n.NonLocalizedString;
import org.opentripplanner.model.fare.ItineraryFares;
import org.opentripplanner.model.plan.Itinerary;
import org.opentripplanner.model.plan.Leg;
import org.opentripplanner.model.plan.Place;
import org.opentripplanner.model.plan.PlanTestConstants;
Expand All @@ -34,16 +37,20 @@
public class AtlantaFareServiceTest implements PlanTestConstants {

public static final Money DEFAULT_TEST_RIDE_PRICE = usDollars(3.49f);
private static final String FEED_ID = "A";
private static AtlantaFareService atlFareService;

@BeforeAll
public static void setUpClass() {
Map<FeedScopedId, FareRuleSet> regularFareRules = new HashMap<>();
Map<FeedScopedId, FareRuleSet> regularFareRules = Map.of(
new FeedScopedId(FEED_ID, "regular"),
FareModelForTest.INSIDE_CITY_CENTER_SET
);
atlFareService = new TestAtlantaFareService(regularFareRules.values());
}

@Test
public void fromMartaTransfers() {
void fromMartaTransfers() {
List<Leg> rides = List.of(getLeg(MARTA_AGENCY_ID, 0), getLeg(XPRESS_AGENCY_ID, 1));
calculateFare(rides, DEFAULT_TEST_RIDE_PRICE);

Expand All @@ -69,7 +76,7 @@ void nullShortName() {
}

@Test
public void fromCobbTransfers() {
void fromCobbTransfers() {
List<Leg> rides = List.of(getLeg(COBB_AGENCY_ID, 0), getLeg(MARTA_AGENCY_ID, 1));
calculateFare(rides, DEFAULT_TEST_RIDE_PRICE);

Expand Down Expand Up @@ -98,13 +105,13 @@ public void fromCobbTransfers() {
}

@Test
public void fromGctTransfers() {
void fromGctTransfers() {
List<Leg> rides = List.of(getLeg(GCT_AGENCY_ID, 0), getLeg(MARTA_AGENCY_ID, 1));
calculateFare(rides, DEFAULT_TEST_RIDE_PRICE);
}

@Test
public void tooManyLegs() {
void tooManyLegs() {
List<Leg> rides = List.of(
getLeg(MARTA_AGENCY_ID, 0),
getLeg(MARTA_AGENCY_ID, 1),
Expand Down Expand Up @@ -158,7 +165,7 @@ public void tooManyLegs() {
}

@Test
public void expiredTransfer() {
void expiredTransfer() {
List<Leg> rides = List.of(
getLeg(MARTA_AGENCY_ID, 0),
getLeg(MARTA_AGENCY_ID, 1),
Expand All @@ -179,7 +186,7 @@ public void expiredTransfer() {
}

@Test
public void useStreetcar() {
void useStreetcar() {
var STREETCAR_PRICE = DEFAULT_TEST_RIDE_PRICE.minus(usDollars(1));
List<Leg> rides = List.of(
getLeg(MARTA_AGENCY_ID, 0),
Expand All @@ -199,6 +206,18 @@ public void useStreetcar() {
calculateFare(rides, DEFAULT_TEST_RIDE_PRICE.plus(usDollars(1)).plus(STREETCAR_PRICE));
}

@Test
void fullItinerary() {
var itin = createItinerary(MARTA_AGENCY_ID, "1", 0);
var fares = atlFareService.calculateFares(itin);
assertNotNull(fares);
assertTrue(fares.getLegProducts().isEmpty());
var itineraryProducts = fares.getItineraryProducts();
assertFalse(itineraryProducts.isEmpty());
var fp = itineraryProducts.stream().filter(p -> p.name().equals("regular")).findAny().get();
assertEquals(Money.usDollars(3.49f), fp.price());
}

/**
* These tests are designed to specifically validate ATL fares. Since these fares are hard-coded,
* it is acceptable to make direct calls to the ATL fare service with predefined routes. Where the
Expand Down Expand Up @@ -230,25 +249,30 @@ private static Leg getLeg(String agencyId, String shortName, long startTimeMins)
}

private static Leg createLeg(String agencyId, String shortName, long startTimeMins) {
final var itin = createItinerary(agencyId, shortName, startTimeMins);
return itin.getLegs().get(0);
}

private static Itinerary createItinerary(String agencyId, String shortName, long startTimeMins) {
Agency agency = Agency
.of(new FeedScopedId("A", agencyId))
.of(new FeedScopedId(FEED_ID, agencyId))
.withName(agencyId)
.withTimezone(ZoneIds.NEW_YORK.getId())
.build();

// Set up stops
RegularStop firstStop = RegularStop
.of(new FeedScopedId("A", "1"))
.of(new FeedScopedId(FEED_ID, "1"))
.withCoordinate(new WgsCoordinate(1, 1))
.withName(new NonLocalizedString("first stop"))
.build();
RegularStop lastStop = RegularStop
.of(new FeedScopedId("A", "2"))
.of(new FeedScopedId(FEED_ID, "2"))
.withCoordinate(new WgsCoordinate(1, 2))
.withName(new NonLocalizedString("last stop"))
.build();

FeedScopedId routeFeedScopeId = new FeedScopedId("A", "123");
FeedScopedId routeFeedScopeId = new FeedScopedId(FEED_ID, "123");
Route route = Route
.of(routeFeedScopeId)
.withAgency(agency)
Expand All @@ -261,8 +285,7 @@ private static Leg createLeg(String agencyId, String shortName, long startTimeMi
var itin = newItinerary(Place.forStop(firstStop), start)
.bus(route, 1, start, T11_12, Place.forStop(lastStop))
.build();

return itin.getLegs().get(0);
return itin;
}

private static class TestAtlantaFareService extends AtlantaFareService {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.opentripplanner.ext.fares.impl.FareModelForTest.AIRPORT_STOP;
import static org.opentripplanner.ext.fares.impl.FareModelForTest.AIRPORT_TO_CITY_CENTER_SET;
import static org.opentripplanner.ext.fares.impl.FareModelForTest.CITY_CENTER_A_STOP;
Expand All @@ -25,6 +26,9 @@

class DefaultFareServiceTest implements PlanTestConstants {

private static final Money TEN_DOLLARS = Money.usDollars(10);
private static final Money TWENTY_DOLLARS = Money.usDollars(20);

@Test
void noRules() {
var service = new DefaultFareService();
Expand All @@ -46,7 +50,19 @@ void simpleZoneBasedFare() {

var price = fare.getFare(FareType.regular);

assertEquals(Money.usDollars(10), price);
assertEquals(TEN_DOLLARS, price);

var fp = fare.getItineraryProducts().get(0);
assertEquals(TEN_DOLLARS, fp.price());
assertEquals("F:regular", fp.id().toString());

var lp = fare.legProductsFromComponents();
assertEquals(1, lp.size());
var product = lp.values().iterator().next().product();
assertEquals(TEN_DOLLARS, product.price());

// the leg products from the components and the "true" leg products are different collections
assertTrue(fare.getLegProducts().isEmpty());
}

@Test
Expand All @@ -73,7 +89,23 @@ void shouldNotCombineInterlinedLegs() {

var price = fare.getFare(FareType.regular);

assertEquals(Money.usDollars(20), price);
assertEquals(TWENTY_DOLLARS, price);

assertTrue(fare.getLegProducts().isEmpty());

var legProductsFromComponents = fare.legProductsFromComponents();

var firstLeg = itin.getLegs().get(0);
var products = List.copyOf(legProductsFromComponents.get(firstLeg));

assertEquals(TEN_DOLLARS, products.get(0).product().price());

var secondLeg = itin.getLegs().get(1);
products = List.copyOf(legProductsFromComponents.get(secondLeg));
assertEquals(TEN_DOLLARS, products.get(0).product().price());

assertEquals(1, fare.getItineraryProducts().size());
assertEquals(TWENTY_DOLLARS, fare.getItineraryProducts().get(0).price());
}

@Test
Expand All @@ -97,10 +129,13 @@ void unknownLeg() {

var component = components.get(0);
assertEquals(AIRPORT_TO_CITY_CENTER_SET.getFareAttribute().getId(), component.fareId());
assertEquals(Money.usDollars(10), component.price());
assertEquals(TEN_DOLLARS, component.price());

var firstBusLeg = itin.firstTransitLeg().get();
assertEquals(List.of(firstBusLeg), component.legs());

var legProductsFromComponent = fare.legProductsFromComponents();
assertEquals(1, legProductsFromComponent.size());
}

@Test
Expand All @@ -127,7 +162,7 @@ void multipleFeeds() {
resultComponents
);

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

@Test
Expand Down Expand Up @@ -155,7 +190,7 @@ void multipleFeedsWithTransfersWithinFeed() {
resultComponents
);

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

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ private static List<Arguments> createTestCases() {
float ABCD_PRICE = 5.70f;
float D_PRICE = 2.80f;

HSLFareServiceImpl hslFareService = new HSLFareServiceImpl();
HSLFareService hslFareService = new HSLFareService();
int fiveMinutes = 60 * 5;

// Fare attributes
Expand Down Expand Up @@ -446,7 +446,7 @@ void unknownFare() {

FareRuleSet ruleSetAB = new FareRuleSet(fareAttributeAB);

var service = new HSLFareServiceImpl();
var service = new HSLFareService();
service.addFareRules(FareType.regular, List.of(ruleSetAB));

// outside HSL's fare zones, should return null
Expand Down
Loading