From 1be68d1e63da7ed5143a77e05e755d01c6014155 Mon Sep 17 00:00:00 2001 From: Nabeel S Date: Sat, 24 Oct 2020 15:11:08 -0400 Subject: [PATCH] Flight/Subfleet fares not returning in API #899 (#900) Make sure proper fares are returned from the API #899 --- app/Console/Commands/CreateDatabase.php | 5 +- app/Http/Controllers/Api/FlightController.php | 9 +- app/Http/Controllers/Api/UserController.php | 3 +- app/Http/Resources/Fare.php | 17 ++- app/Http/Resources/Flight.php | 1 + app/Providers/RouteServiceProvider.php | 1 + app/Services/BidService.php | 1 + app/Services/FareService.php | 4 +- app/Services/FlightService.php | 4 + tests/FinanceTest.php | 119 ++++++++++++++++++ tests/FlightTest.php | 48 +------ tests/SubfleetTest.php | 45 ++----- tests/TestData.php | 44 +++++++ 13 files changed, 206 insertions(+), 95 deletions(-) diff --git a/app/Console/Commands/CreateDatabase.php b/app/Console/Commands/CreateDatabase.php index 066ed3e8..6d4141a8 100644 --- a/app/Console/Commands/CreateDatabase.php +++ b/app/Console/Commands/CreateDatabase.php @@ -92,8 +92,9 @@ class CreateDatabase extends Command } if ($this->option('reset') === true) { - $cmd = ['rm', '-rf', config($dbkey.'database')]; - $this->runCommand($cmd); + if (file_exists($dbPath)) { + unlink(config($dbkey.'database')); + } } if (!file_exists($dbPath)) { diff --git a/app/Http/Controllers/Api/FlightController.php b/app/Http/Controllers/Api/FlightController.php index 7826ab0f..5e1928d9 100644 --- a/app/Http/Controllers/Api/FlightController.php +++ b/app/Http/Controllers/Api/FlightController.php @@ -54,9 +54,13 @@ class FlightController extends Controller */ public function get($id) { + /** @var \App\Models\User $user */ $user = Auth::user(); + + /** @var \App\Models\Flight $flight */ $flight = $this->flightRepo->with([ 'airline', + 'fares', 'subfleets', 'subfleets.aircraft', 'subfleets.fares', @@ -66,7 +70,7 @@ class FlightController extends Controller }, ])->find($id); - $this->flightSvc->filterSubfleets(Auth::user(), $flight); + $flight = $this->flightSvc->filterSubfleets($user, $flight); return new FlightResource($flight); } @@ -109,6 +113,7 @@ class FlightController extends Controller $flights = $this->flightRepo ->with([ 'airline', + 'fares', 'subfleets', 'subfleets.aircraft', 'subfleets.fares', @@ -124,7 +129,7 @@ class FlightController extends Controller // TODO: Remove any flights here that a user doesn't have permissions to foreach ($flights as $flight) { - $this->flightSvc->filterSubfleets(Auth::user(), $flight); + $this->flightSvc->filterSubfleets($user, $flight); } return FlightResource::collection($flights); diff --git a/app/Http/Controllers/Api/UserController.php b/app/Http/Controllers/Api/UserController.php index 16f87734..49cc1bb6 100644 --- a/app/Http/Controllers/Api/UserController.php +++ b/app/Http/Controllers/Api/UserController.php @@ -61,7 +61,8 @@ class UserController extends Controller */ protected function getUserId(Request $request) { - if ($request->get('id') === null) { + $id = $request->get('id'); + if ($id === null || $id === 'me') { return Auth::user()->id; } diff --git a/app/Http/Resources/Fare.php b/app/Http/Resources/Fare.php index a2f290f0..8189eaf6 100644 --- a/app/Http/Resources/Fare.php +++ b/app/Http/Resources/Fare.php @@ -3,6 +3,7 @@ namespace App\Http\Resources; use App\Contracts\Resource; +use App\Services\FareService; /** * @mixin \App\Models\Fare @@ -11,13 +12,17 @@ class Fare extends Resource { public function toArray($request) { + /** @var FareService $fareSvc */ + $fareSvc = app(FareService::class); + $fare = $fareSvc->getFares($this); + return [ - 'id' => $this->id, - 'code' => $this->code, - 'name' => $this->name, - 'price' => $this->price, - 'cost' => $this->cost, - 'capacity' => $this->capacity, + 'id' => $fare->id, + 'code' => $fare->code, + 'name' => $fare->name, + 'capacity' => $fare->capacity, + 'cost' => $fare->cost, + 'price' => $fare->price, 'type' => $this->type, 'notes' => $this->notes, 'active' => $this->active, diff --git a/app/Http/Resources/Flight.php b/app/Http/Resources/Flight.php index 06d17c6e..9a9d5752 100644 --- a/app/Http/Resources/Flight.php +++ b/app/Http/Resources/Flight.php @@ -58,6 +58,7 @@ class Flight extends Resource $res['airline'] = new Airline($this->airline); $res['subfleets'] = Subfleet::collection($this->whenLoaded('subfleets')); + $res['fares'] = Fare::collection($this->whenLoaded('fares')); $res['fields'] = $this->setFields(); // Simbrief info diff --git a/app/Providers/RouteServiceProvider.php b/app/Providers/RouteServiceProvider.php index 75363d22..6ba793d3 100755 --- a/app/Providers/RouteServiceProvider.php +++ b/app/Providers/RouteServiceProvider.php @@ -580,6 +580,7 @@ class RouteServiceProvider extends ServiceProvider Route::post('user/bids', 'UserController@bids'); Route::delete('user/bids', 'UserController@bids'); + Route::get('users/me', 'UserController@index'); Route::get('users/{id}', 'UserController@get'); Route::get('users/{id}/fleet', 'UserController@fleet'); Route::get('users/{id}/pireps', 'UserController@pireps'); diff --git a/app/Services/BidService.php b/app/Services/BidService.php index a06b522c..f30cd620 100644 --- a/app/Services/BidService.php +++ b/app/Services/BidService.php @@ -45,6 +45,7 @@ class BidService extends Service { $bids = Bid::with([ 'flight', + 'flight.fares', 'flight.simbrief', 'flight.subfleets', 'flight.subfleets.aircraft', diff --git a/app/Services/FareService.php b/app/Services/FareService.php index fdb1e13d..0436a56a 100644 --- a/app/Services/FareService.php +++ b/app/Services/FareService.php @@ -60,13 +60,13 @@ class FareService extends Service } /** - * Get fares + * Get a fare with the proper prices/costs populated in the pivot * * @param $fare * * @return mixed */ - protected function getFares($fare) + public function getFares($fare) { $pivot = $fare->pivot; if (filled($pivot->price)) { diff --git a/app/Services/FlightService.php b/app/Services/FlightService.php index c08b0e9e..5cf05a5f 100644 --- a/app/Services/FlightService.php +++ b/app/Services/FlightService.php @@ -16,6 +16,7 @@ use App\Support\Units\Time; class FlightService extends Service { private $airportSvc; + private $fareSvc; private $flightRepo; private $navDataRepo; private $userSvc; @@ -24,17 +25,20 @@ class FlightService extends Service * FlightService constructor. * * @param AirportService $airportSvc + * @param FareService $fareSvc * @param FlightRepository $flightRepo * @param NavdataRepository $navdataRepo * @param UserService $userSvc */ public function __construct( AirportService $airportSvc, + FareService $fareSvc, FlightRepository $flightRepo, NavdataRepository $navdataRepo, UserService $userSvc ) { $this->airportSvc = $airportSvc; + $this->fareSvc = $fareSvc; $this->flightRepo = $flightRepo; $this->navDataRepo = $navdataRepo; $this->userSvc = $userSvc; diff --git a/tests/FinanceTest.php b/tests/FinanceTest.php index a969a504..5904e81f 100644 --- a/tests/FinanceTest.php +++ b/tests/FinanceTest.php @@ -16,6 +16,7 @@ use App\Models\Subfleet; use App\Models\User; use App\Repositories\ExpenseRepository; use App\Repositories\JournalRepository; +use App\Services\BidService; use App\Services\FareService; use App\Services\Finance\PirepFinanceService; use App\Services\FleetService; @@ -235,12 +236,130 @@ class FinanceTest extends TestCase $this->assertEquals($fare->capacity, $subfleet_fares->get(0)->capacity); } + /** + * Make sure that the API is returning the fares properly for a subfleet on a flight + * https://github.com/nabeelio/phpvms/issues/899 + */ + public function testFlightFaresOverAPI() + { + $this->updateSetting('pireps.only_aircraft_at_dpt_airport', false); + $this->updateSetting('pireps.restrict_aircraft_to_rank', false); + + $this->user = factory(User::class)->create(); + + /** @var Flight $flight */ + $flight = factory(Flight::class)->create(); + + /** @var Subfleet $subfleet */ + $subfleet = factory(Subfleet::class)->create(); + $this->fleetSvc->addSubfleetToFlight($subfleet, $flight); + + /** @var Fare $fare */ + $fare = factory(Fare::class)->create(); + + $this->fareSvc->setForFlight($flight, $fare); + $flight_fares = $this->fareSvc->getForFlight($flight); + + $this->assertCount(1, $flight_fares); + $this->assertEquals($fare->price, $flight_fares->get(0)->price); + $this->assertEquals($fare->capacity, $flight_fares->get(0)->capacity); + + // + // set an override now (but on the flight) + // + $this->fareSvc->setForFlight($flight, $fare, ['price' => 50]); + + $req = $this->get('/api/flights/'.$flight->id); + $req->assertStatus(200); + + $body = $req->json()['data']; + $this->assertEquals($flight->id, $body['id']); + $this->assertCount(1, $body['subfleets']); + $this->assertEquals(50, $body['fares'][0]['price']); + $this->assertEquals($fare->capacity, $body['fares'][0]['capacity']); + } + + public function testFlightFaresOverAPIOnUserBids() + { + $this->updateSetting('pireps.only_aircraft_at_dpt_airport', false); + $this->updateSetting('pireps.restrict_aircraft_to_rank', false); + + /** @var BidService $bidSvc */ + $bidSvc = app(BidService::class); + + $this->user = factory(User::class)->create(); + + /** @var Flight $flight */ + $flight = factory(Flight::class)->create(); + + /** @var Subfleet $subfleet */ + $subfleet = factory(Subfleet::class)->create(); + $this->fleetSvc->addSubfleetToFlight($subfleet, $flight); + + /** @var Fare $fare */ + $fare = factory(Fare::class)->create(); + + $this->fareSvc->setForFlight($flight, $fare); + $flight_fares = $this->fareSvc->getForFlight($flight); + + $this->assertCount(1, $flight_fares); + $this->assertEquals($fare->price, $flight_fares->get(0)->price); + $this->assertEquals($fare->capacity, $flight_fares->get(0)->capacity); + + // + // set an override now (but on the flight) + // + $this->fareSvc->setForFlight($flight, $fare, ['price' => 50]); + $bid = $bidSvc->addBid($flight, $this->user); + + $req = $this->get('/api/user/bids'); + $req->assertStatus(200); + + $body = $req->json()['data']; + $this->assertEquals($flight->id, $body[0]['flight_id']); + $this->assertCount(1, $body[0]['flight']['subfleets']); + $this->assertEquals(50, $body[0]['flight']['fares'][0]['price']); + $this->assertEquals($fare->capacity, $body[0]['flight']['fares'][0]['capacity']); + } + + public function testSubfleetFaresOverAPI() + { + $this->updateSetting('pireps.only_aircraft_at_dpt_airport', false); + $this->updateSetting('pireps.restrict_aircraft_to_rank', false); + + /** + * Add a user and flights + */ + $this->user = factory(User::class)->create(); + $flight = $this->addFlight($this->user); + + /** @var FareService $fare_svc */ + $fare_svc = app(FareService::class); + + /** @var \App\Models\Fare $fare */ + $fare = factory(Fare::class)->create(); + $fare_svc->setForSubfleet($flight->subfleets[0], $fare, ['price' => 50]); + + // Get from API + $req = $this->get('/api/flights/'.$flight->id); + $req->assertStatus(200); + + $body = $req->json()['data']; + $this->assertEquals($flight->id, $body['id']); + $this->assertCount(1, $body['subfleets']); + $this->assertEquals(50, $body['subfleets'][0]['fares'][0]['price']); + $this->assertEquals($fare->capacity, $body['subfleets'][0]['fares'][0]['capacity']); + } + /** * Assign percentage values and make sure they're valid */ public function testFlightFareOverrideAsPercent() { + /** @var Flight $flight */ $flight = factory(Flight::class)->create(); + + /** @var \App\Models\Fare $fare */ $fare = factory(Fare::class)->create(); $percent_incr = '20%'; diff --git a/tests/FlightTest.php b/tests/FlightTest.php index f7f544b8..3bab4c2a 100644 --- a/tests/FlightTest.php +++ b/tests/FlightTest.php @@ -33,50 +33,6 @@ class FlightTest extends TestCase $this->settingsRepo = app(SettingRepository::class); } - /** - * Add a single flight - * - * @param $user - * @param array $flight_properties - * - * @return mixed - */ - public function addFlight($user, $flight_properties = []) - { - $opts = array_merge([ - 'airline_id' => $user->airline_id, - ], $flight_properties); - - $flight = factory(Flight::class)->create($opts); - - $flight->subfleets()->syncWithoutDetaching([ - factory(Subfleet::class)->create([ - 'airline_id' => $user->airline_id, - ])->id, - ]); - - return $flight; - } - - /** - * Add a given number of flights for a subfleet - * - * @param $subfleet - * @param $num_flights - * - * @return \App\Models\Flight[] - */ - public function addFlightsForSubfleet($subfleet, $num_flights) - { - return factory(Flight::class, $num_flights)->create([ - 'airline_id' => $subfleet->airline->id, - ])->each(function (Flight $f) use ($subfleet) { - $f->subfleets()->syncWithoutDetaching([ - $subfleet->id, - ]); - }); - } - /** * Test adding a flight and also if there are duplicates */ @@ -468,7 +424,11 @@ class FlightTest extends TestCase public function testFlightSearchApiDistance() { $total_flights = 10; + + /** @var \App\Models\User user */ $this->user = factory(User::class)->create(); + + /** @var \App\Models\Flight $flights */ $flights = factory(Flight::class, $total_flights)->create([ 'airline_id' => $this->user->airline_id, ]); diff --git a/tests/SubfleetTest.php b/tests/SubfleetTest.php index 84f39869..18cd111b 100644 --- a/tests/SubfleetTest.php +++ b/tests/SubfleetTest.php @@ -3,7 +3,6 @@ namespace Tests; use App\Models\Fare; -use App\Models\Subfleet; use App\Services\FareService; class SubfleetTest extends TestCase @@ -19,9 +18,15 @@ class SubfleetTest extends TestCase public function testSubfleetFaresNoOverride() { + /** @var FareService $fare_svc */ $fare_svc = app(FareService::class); - $subfleet = factory(Subfleet::class)->create(); + $subfleet_aircraft = $this->createSubfleetWithAircraft(1); + + /** @var \App\Models\Subfleet $subfleet */ + $subfleet = $subfleet_aircraft['subfleet']; + + /** @var \App\Models\Fare $fare */ $fare = factory(Fare::class)->create(); $fare_svc->setForSubfleet($subfleet, $fare); @@ -49,40 +54,4 @@ class SubfleetTest extends TestCase $fare_svc->delFareFromSubfleet($subfleet, $fare); $this->assertCount(0, $fare_svc->getForSubfleet($subfleet)); } - - public function testSubfleetFaresOverride() - { - $fare_svc = app(FareService::class); - - $subfleet = factory(Subfleet::class)->create(); - $fare = factory(Fare::class)->create(); - - $fare_svc->setForSubfleet($subfleet, $fare, [ - 'price' => 50, 'capacity' => 400, - ]); - - $ac_fares = $fare_svc->getForSubfleet($subfleet); - - $this->assertCount(1, $ac_fares); - $this->assertEquals(50, $ac_fares[0]->price); - $this->assertEquals(400, $ac_fares[0]->capacity); - - // - // update the override to a different amount and make sure it updates - // - - $fare_svc->setForSubfleet($subfleet, $fare, [ - 'price' => 150, 'capacity' => 50, - ]); - - $ac_fares = $fare_svc->getForSubfleet($subfleet); - - $this->assertCount(1, $ac_fares); - $this->assertEquals(150, $ac_fares[0]->price); - $this->assertEquals(50, $ac_fares[0]->capacity); - - // delete - $fare_svc->delFareFromSubfleet($subfleet, $fare); - $this->assertCount(0, $fare_svc->getForSubfleet($subfleet)); - } } diff --git a/tests/TestData.php b/tests/TestData.php index 1da1feca..f5522eea 100644 --- a/tests/TestData.php +++ b/tests/TestData.php @@ -3,6 +3,7 @@ namespace Tests; use App\Models\Aircraft; +use App\Models\Flight; use App\Models\Subfleet; use App\Models\User; use Exception; @@ -74,6 +75,49 @@ trait TestData return $rank; } + /** + * Add a single flight + * + * @param $user + * @param array $flight_properties + * + * @return mixed + */ + public function addFlight($user, $flight_properties = []) + { + $opts = array_merge([ + 'airline_id' => $user->airline_id, + ], $flight_properties); + + $flight = factory(Flight::class)->create($opts); + + $flight->subfleets()->syncWithoutDetaching([ + factory(Subfleet::class)->create([ + 'airline_id' => $user->airline_id, + ])->id, + ]); + + return $flight; + } + + /** + * Add a given number of flights for a subfleet + * + * @param $subfleet + * @param $num_flights + * + * @return \App\Models\Flight[] + */ + public function addFlightsForSubfleet($subfleet, $num_flights) + { + return factory(Flight::class, $num_flights)->create([ + 'airline_id' => $subfleet->airline->id, + ])->each(function (Flight $f) use ($subfleet) { + $f->subfleets()->syncWithoutDetaching([$subfleet->id]); + $f->refresh(); + }); + } + /** * Create a subfleet with a number of aircraft assigned *