Skip to content

Fix ID generation hacks in GTFS mapping, improve FaresV2 spec conformance #6586

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

Open
wants to merge 20 commits into
base: dev-2.x
Choose a base branch
from
Open
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Add test for free transfer
leonardehrenfried committed Apr 11, 2025
commit ec253345d25f2cfbb37b71ca075845edb9490c0f
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
package org.opentripplanner.ext.fares.impl;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.opentripplanner.model.plan.TestItineraryBuilder.newItinerary;
import static org.opentripplanner.transit.model._data.TimetableRepositoryForTest.id;

import com.google.common.collect.Multimaps;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.junit.jupiter.api.Test;
import org.opentripplanner.ext.fares.model.FareLegRule;
import org.opentripplanner.ext.fares.model.FareTransferRule;
import org.opentripplanner.model.fare.FareProduct;
import org.opentripplanner.model.plan.Place;
import org.opentripplanner.model.plan.PlanTestConstants;
import org.opentripplanner.transit.model._data.TimetableRepositoryForTest;
import org.opentripplanner.transit.model.basic.Money;
import org.opentripplanner.transit.model.framework.FeedScopedId;

class FreeTransferTest implements PlanTestConstants {

private static final TimetableRepositoryForTest TEST_MODEL = TimetableRepositoryForTest.of();

FeedScopedId LEG_GROUP1 = id("leg-group1");
int ID = 100;

FareProduct freeTransfer = FareProduct.of(
id("free-transfer"),
"Free transfer",
Money.ZERO_USD
).build();

Place INNER_ZONE_STOP = Place.forStop(
TEST_MODEL.stop("inner city stop").withCoordinate(1, 1).build()
);
Place OUTER_ZONE_STOP = Place.forStop(
TEST_MODEL.stop("outer city stop").withCoordinate(2, 2).build()
);
String INNER_ZONE = "inner-zone";
String OUTER_ZONE = "outer-zone";

FareProduct regular = FareProduct.of(
id( "regular"),
"regular",
Money.euros(5)
).build();

GtfsFaresV2Service service = new GtfsFaresV2Service(
List.of(
FareLegRule.of(id("6"), regular)
.withLegGroupId(LEG_GROUP1)
.withFromAreaId(INNER_ZONE)
.withToAreaId(INNER_ZONE)
.build()
),
List.of(
new FareTransferRule(id("transfer"), LEG_GROUP1, LEG_GROUP1, -1, null, List.of(freeTransfer))
),
Multimaps.forMap(
Map.of(INNER_ZONE_STOP.stop.getId(), INNER_ZONE, OUTER_ZONE_STOP.stop.getId(), OUTER_ZONE)
)
);

@Test
void freeTransfer() {
var i1 = newItinerary(INNER_ZONE_STOP, 0).bus(ID, 0, 50, INNER_ZONE_STOP).build();
var result = service.getProducts(i1);
assertEquals(Set.of(regular), result.itineraryProducts());
}
}
Original file line number Diff line number Diff line change
@@ -11,5 +11,4 @@ class AgencyAndIdMapper {
public static FeedScopedId mapAgencyAndId(@Nullable AgencyAndId id) {
return id == null ? null : new FeedScopedId(id.getAgencyId(), id.getId());
}

}
Original file line number Diff line number Diff line change
@@ -15,7 +15,11 @@

public class FareTransferRuleMapper {

public static final FareProduct FREE_TRANSFER = FareProduct.of(new FeedScopedId("unknown", "free-transfer"), "Free transfer", Money.ZERO_USD).build();
public static final FareProduct FREE_TRANSFER = FareProduct.of(
new FeedScopedId("unknown", "free-transfer"),
"Free transfer",
Money.ZERO_USD
).build();
public final int MISSING_VALUE = -999;

private final DataImportIssueStore issueStore;
@@ -58,16 +62,16 @@ private FareTransferRule doMap(org.onebusaway.gtfs.model.FareTransferRule rhs) {

@Nullable
private Collection<FareProduct> getFareProducts(@Nullable FeedScopedId fareProductId, String id) {
if(fareProductId == null) {
if (fareProductId == null) {
return List.of(FREE_TRANSFER);
}
var products = fareProductMapper.getByFareProductId(fareProductId);
if (products.isEmpty()) {
issueStore.add(
"UnknownFareProductId",
"Fare product with id %s referenced by fare transfer rule with id %s not found.".formatted(
fareProductId,
id
fareProductId,
id
)
);
return null;