package org.croudtrip.trips;
import com.google.common.base.Optional;
import com.google.common.collect.Lists;
import junit.framework.TestCase;
import org.croudtrip.api.account.User;
import org.croudtrip.api.account.Vehicle;
import org.croudtrip.api.directions.NavigationResult;
import org.croudtrip.api.directions.Route;
import org.croudtrip.api.directions.RouteDistanceDuration;
import org.croudtrip.api.directions.RouteLocation;
import org.croudtrip.api.trips.SuperTripReservation;
import org.croudtrip.api.trips.TripOffer;
import org.croudtrip.api.trips.TripOfferStatus;
import org.croudtrip.api.trips.TripQuery;
import org.croudtrip.api.trips.UserWayPoint;
import org.croudtrip.closestpair.ClosestPair;
import org.croudtrip.closestpair.ClosestPairResult;
import org.croudtrip.db.JoinTripRequestDAO;
import org.croudtrip.db.TripOfferDAO;
import org.croudtrip.directions.DirectionsManager;
import org.croudtrip.logs.LogManager;
import org.croudtrip.places.PlacesManager;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import java.util.List;
import mockit.Expectations;
import mockit.Injectable;
import mockit.Mocked;
import mockit.Tested;
import mockit.integration.junit4.JMockit;
@RunWith(JMockit.class)
public class SuperTripsMatcherTest extends TestCase {
/*
What those annotations do:
@Mocked: mock all methods of SimpleTripsMatcher
@Tested: have JMockit call the constructor of SimpleTripsMatcher with parameters that are annotated with @Injectable
(if not those fields will be null causing NPEs in SuperTripsMatcher).
==> SuperTripsMatcher can be tested while all super methods are mocked.
*/
@Tested @Mocked SimpleTripsMatcher simpleTripsMatcher;
private SuperTripsMatcher superTripsMatcher;
@Injectable @Mocked JoinTripRequestDAO joinTripRequestDAO;
@Injectable @Mocked TripOfferDAO tripOfferDAO;
@Injectable @Mocked TripsNavigationManager tripsNavigationManager;
@Injectable @Mocked DirectionsManager directionsManager;
@Injectable @Mocked TripsUtils tripsUtils;
@Injectable @Mocked LogManager logManager;
@Injectable @Mocked PlacesManager placesManager;
@Mocked ClosestPair closestPair;
@Before
public void setupMatcher() {
superTripsMatcher = new SuperTripsMatcher(joinTripRequestDAO, tripOfferDAO, tripsNavigationManager, directionsManager,
tripsUtils, closestPair, placesManager, logManager);
}
@Test
public void testSimpleTrips() {
final List<SuperTripReservation> reservations = Lists.newArrayList(new SuperTripReservation());
new Expectations() {{
simpleTripsMatcher.findPotentialTrips(null, null);
result = reservations;
}};
List<SuperTripReservation> resultReservations = superTripsMatcher.findPotentialTrips(null, null);
Assert.assertEquals(reservations, resultReservations);
}
@Test
@SuppressWarnings("unchecked")
public void testSimpleTwoOffersTrip() throws Exception {
final User passenger = new User.Builder().build();
final TripQuery query = createQuery(passenger);
final TripOffer offer1 = createOffer(42);
final TripOffer offer2 = createOffer(43);
new Expectations() {{
simpleTripsMatcher.findPotentialTrips((List<TripOffer>) any, (TripQuery) any); result = Lists.newArrayList();
simpleTripsMatcher.assertJoinRequestNotDeclined((TripOffer) any, query); result = true;
tripsUtils.getActivePassengerCountForOffer((TripOffer) any); result = 2;
simpleTripsMatcher.assertWithinAirDistance(offer1, (TripQuery) any); result = true;
simpleTripsMatcher.assertWithinAirDistance(offer2, (TripQuery) any); result = true;
tripsNavigationManager.getNavigationResultForOffer((TripOffer) any, (TripQuery) any);
result = new NavigationResult.Builder()
.addUserWayPoint(new UserWayPoint.Builder().setDistanceToDriverInMeters(0).build())
.addUserWayPoint(new UserWayPoint.Builder().setDistanceToDriverInMeters(0).build())
.build();
simpleTripsMatcher.assertRouteWithinPassengerMaxWaitingTime((TripOffer) any, (TripQuery) any, (List<UserWayPoint>) any);
result = true;
closestPair.findClosestPair((User) any, (NavigationResult) any, (NavigationResult) any);
result = new ClosestPairResult(new RouteLocation(0, 0), new RouteLocation(0, 0));
simpleTripsMatcher.isPotentialMatch((TripOffer) any, (TripQuery) any);
result = Optional.of(new TripsMatcher.PotentialMatch(
offer1,
query,
new NavigationResult.Builder()
.addUserWayPoint(new UserWayPoint.Builder().setUser(passenger).build())
.addUserWayPoint(new UserWayPoint.Builder().setUser(passenger).build())
.build()));
directionsManager.getDistanceAndDurationForDirection( (RouteLocation) any, (RouteLocation) any );
result = new RouteDistanceDuration( 100, 200 );
}};
List<SuperTripReservation> reservations = superTripsMatcher.findPotentialTrips(Lists.newArrayList(offer1, offer2), query);
Assert.assertEquals(1, reservations.size());
}
@Test
public void testIsRoughPotentialSuperTripMatchForOneWaypointSuccess() {
final TripOffer offer = createOffer(42);
final TripQuery query = createQuery(new User.Builder().setId(42).build());
new Expectations() {{
simpleTripsMatcher.assertJoinRequestNotDeclined(offer, query); result = true;
tripsUtils.getActivePassengerCountForOffer(offer); result = 2;
simpleTripsMatcher.assertWithinAirDistance(offer, (TripQuery) any); result = true;
}};
boolean isMatch = superTripsMatcher.isRoughPotentialSuperTripMatchForOneWaypoint(offer, query, true);
Assert.assertEquals(true, isMatch);
}
@Test
public void testIsRoughPotentialSuperTripMatchForOneWaypointFailure() {
final TripOffer offer = createOffer(42);
final TripQuery query = createQuery(new User.Builder().setId(42).build());
new Expectations() {{
simpleTripsMatcher.assertJoinRequestNotDeclined(offer, query); result = true;
tripsUtils.getActivePassengerCountForOffer(offer); result = 2;
simpleTripsMatcher.assertWithinAirDistance(offer, (TripQuery) any); result = false;
}};
boolean isMatch = superTripsMatcher.isRoughPotentialSuperTripMatchForOneWaypoint(offer, query, true);
Assert.assertEquals(false, isMatch);
}
private TripOffer createOffer(long id) {
return new TripOffer.Builder()
.setId(id)
.setStatus(TripOfferStatus.ACTIVE)
.setVehicle(new Vehicle.Builder().setCapacity(4).build())
.setMaxDiversionInMeters(1000)
.setDriverRoute(new Route.Builder().distanceInMeters(1000).build())
.build();
}
private TripQuery createQuery(User passenger) {
return new TripQuery.Builder()
.setPassenger(passenger)
.setStartLocation(new RouteLocation(42, 42))
.setStartLocation(new RouteLocation(43, 43))
.build();
}
}