Refuse pirep prefile is user not allowed to use aircraft #170

This commit is contained in:
Nabeel Shahzad 2018-02-20 12:59:49 -06:00
parent 8393ae2851
commit 4e43223f3a
8 changed files with 137 additions and 42 deletions

View File

@ -5,6 +5,7 @@ namespace App\Http\Controllers\Api;
use App\Http\Requests\Acars\EventRequest; use App\Http\Requests\Acars\EventRequest;
use App\Http\Requests\Acars\UpdateRequest; use App\Http\Requests\Acars\UpdateRequest;
use App\Models\Enums\PirepSource; use App\Models\Enums\PirepSource;
use App\Services\UserService;
use Auth; use Auth;
use Log; use Log;
use Illuminate\Http\Request; use Illuminate\Http\Request;
@ -40,7 +41,8 @@ class PirepController extends RestController
protected $acarsRepo, protected $acarsRepo,
$geoSvc, $geoSvc,
$pirepRepo, $pirepRepo,
$pirepSvc; $pirepSvc,
$userSvc;
/** /**
* PirepController constructor. * PirepController constructor.
@ -53,12 +55,14 @@ class PirepController extends RestController
AcarsRepository $acarsRepo, AcarsRepository $acarsRepo,
GeoService $geoSvc, GeoService $geoSvc,
PirepRepository $pirepRepo, PirepRepository $pirepRepo,
PIREPService $pirepSvc PIREPService $pirepSvc,
UserService $userSvc
) { ) {
$this->acarsRepo = $acarsRepo; $this->acarsRepo = $acarsRepo;
$this->geoSvc = $geoSvc; $this->geoSvc = $geoSvc;
$this->pirepRepo = $pirepRepo; $this->pirepRepo = $pirepRepo;
$this->pirepSvc = $pirepSvc; $this->pirepSvc = $pirepSvc;
$this->userSvc = $userSvc;
} }
/** /**
@ -111,19 +115,30 @@ class PirepController extends RestController
* *
* @param PrefileRequest $request * @param PrefileRequest $request
* @return PirepResource * @return PirepResource
* @throws \Symfony\Component\HttpKernel\Exception\BadRequestHttpException
*/ */
public function prefile(PrefileRequest $request) public function prefile(PrefileRequest $request)
{ {
Log::info('PIREP Prefile, user '.Auth::id(), $request->post()); Log::info('PIREP Prefile, user '.Auth::id(), $request->post());
$user = Auth::user();
$attrs = $request->post(); $attrs = $request->post();
$attrs['user_id'] = Auth::id(); $attrs['user_id'] = $user->id;
$attrs['source'] = PirepSource::ACARS; $attrs['source'] = PirepSource::ACARS;
$attrs['state'] = PirepState::IN_PROGRESS; $attrs['state'] = PirepState::IN_PROGRESS;
$attrs['status'] = PirepStatus::PREFILE; $attrs['status'] = PirepStatus::PREFILE;
$pirep = new Pirep($attrs); $pirep = new Pirep($attrs);
# See if this user is allowed to fly this aircraft
if(setting('pireps.restrict_aircraft_to_rank', false)) {
$can_use_ac = $this->userSvc->aircraftAllowed($user, $pirep->aircraft_id);
if (!$can_use_ac) {
throw new BadRequestHttpException('User is not allowed to fly this aircraft');
}
}
# Find if there's a duplicate, if so, let's work on that # Find if there's a duplicate, if so, let's work on that
$dupe_pirep = $this->pirepSvc->findDuplicate($pirep); $dupe_pirep = $this->pirepSvc->findDuplicate($pirep);
if($dupe_pirep !== false) { if($dupe_pirep !== false) {

View File

@ -25,6 +25,7 @@ class Aircraft extends BaseModel
* @var array * @var array
*/ */
protected $casts = [ protected $casts = [
'subfleet_id' => 'integer',
'zfw' => 'float', 'zfw' => 'float',
'active' => 'boolean', 'active' => 'boolean',
]; ];

View File

@ -2,6 +2,7 @@
namespace App\Services; namespace App\Services;
use App\Repositories\AircraftRepository;
use App\Repositories\SubfleetRepository; use App\Repositories\SubfleetRepository;
use Illuminate\Support\Collection; use Illuminate\Support\Collection;
use Log; use Log;
@ -16,15 +17,17 @@ use App\Models\Enums\UserState;
class UserService extends BaseService class UserService extends BaseService
{ {
protected $subfleetRepo; protected $aircraftRepo, $subfleetRepo;
/** /**
* UserService constructor. * UserService constructor.
* @param SubfleetRepository $subfleetRepo * @param SubfleetRepository $subfleetRepo
*/ */
public function __construct( public function __construct(
AircraftRepository $aircraftRepo,
SubfleetRepository $subfleetRepo SubfleetRepository $subfleetRepo
) { ) {
$this->aircraftRepo = $aircraftRepo;
$this->subfleetRepo = $subfleetRepo; $this->subfleetRepo = $subfleetRepo;
} }
@ -83,6 +86,21 @@ class UserService extends BaseService
return $subfleets->with('aircraft')->get(); return $subfleets->with('aircraft')->get();
} }
/**
* Return a bool if a user is allowed to fly the current aircraft
* @param $user
* @param $aircraft_id
* @return bool
*/
public function aircraftAllowed($user, $aircraft_id)
{
$aircraft = $this->aircraftRepo->find($aircraft_id, ['subfleet_id']);
$subfleets = $this->getAllowableSubfleets($user);
$subfleet_ids = $subfleets->pluck('id')->toArray();
return \in_array($aircraft->subfleet_id, $subfleet_ids, true);
}
/** /**
* Change the user's state. PENDING to ACCEPTED, etc * Change the user's state. PENDING to ACCEPTED, etc
* Send out an email * Send out an email

View File

@ -2,6 +2,7 @@
use App\Models\Enums\PirepState; use App\Models\Enums\PirepState;
use App\Models\Enums\PirepStatus; use App\Models\Enums\PirepStatus;
use Tests\TestData;
/** /**
* Test API calls and authentication, etc * Test API calls and authentication, etc
@ -88,11 +89,16 @@ class AcarsTest extends TestCase
*/ */
public function testAcarsUpdates() public function testAcarsUpdates()
{ {
$this->user = factory(App\Models\User::class)->create(); $subfleet = $this->createSubfleetWithAircraft(2);
$rank = $this->createRank(10, [$subfleet['subfleet']->id]);
$this->user = factory(App\Models\User::class)->create([
'rank_id' => $rank->id
]);
$airport = factory(App\Models\Airport::class)->create(); $airport = factory(App\Models\Airport::class)->create();
$airline = factory(App\Models\Airline::class)->create(); $airline = factory(App\Models\Airline::class)->create();
$aircraft = factory(App\Models\Aircraft::class)->create(); $aircraft = $subfleet['aircraft']->random();
$uri = '/api/pireps/prefile'; $uri = '/api/pireps/prefile';
$pirep = [ $pirep = [
@ -217,13 +223,56 @@ class AcarsTest extends TestCase
$this->assertCount(1, $comments); $this->assertCount(1, $comments);
} }
/**
* Test aircraft is allowed
*/
public function testAircraftAllowed()
{
$this->settingsRepo->store('pireps.restrict_aircraft_to_rank', true);
$airport = factory(App\Models\Airport::class)->create();
$airline = factory(App\Models\Airline::class)->create();
# Add subfleets and aircraft, but also add another set of subfleets
$subfleetA = $this->createSubfleetWithAircraft(1);
// User not allowed aircraft from this subfleet
$subfleetB = $this->createSubfleetWithAircraft(1);
$rank = $this->createRank(10, [$subfleetA['subfleet']->id]);
$this->user = factory(App\Models\User::class)->create([
'rank_id' => $rank->id,
]);
$uri = '/api/pireps/prefile';
$pirep = [
'airline_id' => $airline->id,
'aircraft_id' => $subfleetB['aircraft']->random()->id,
'dpt_airport_id' => $airport->icao,
'arr_airport_id' => $airport->icao,
'flight_number' => '6000',
'level' => 38000,
'planned_flight_time' => 120,
'route' => 'POINTA POINTB',
'source_name' => 'Unit test'
];
$response = $this->post($uri, $pirep);
$response->assertStatus(400);
// Try refiling with a valid aircraft
$pirep['aircraft_id'] = $subfleetA['aircraft']->random()->id;
$response = $this->post($uri, $pirep);
$response->assertStatus(201);
}
/** /**
* Test publishing multiple, batched updates * Test publishing multiple, batched updates
*/ */
public function testMultipleAcarsPositionUpdates() public function testMultipleAcarsPositionUpdates()
{ {
$this->user = factory(App\Models\User::class)->create(); $pirep = $this->createPirep()->toArray();
$pirep = factory(App\Models\Pirep::class)->make()->toArray();
$uri = '/api/pireps/prefile'; $uri = '/api/pireps/prefile';
$response = $this->post($uri, $pirep); $response = $this->post($uri, $pirep);
@ -275,8 +324,7 @@ class AcarsTest extends TestCase
*/ */
public function testAcarsIsoDate() public function testAcarsIsoDate()
{ {
$this->user = factory(App\Models\User::class)->create(); $pirep = $this->createPirep()->toArray();
$pirep = factory(App\Models\Pirep::class)->make()->toArray();
$uri = '/api/pireps/prefile'; $uri = '/api/pireps/prefile';
$response = $this->post($uri, $pirep); $response = $this->post($uri, $pirep);
@ -298,8 +346,7 @@ class AcarsTest extends TestCase
*/ */
public function testAcarsInvalidRoutePost() public function testAcarsInvalidRoutePost()
{ {
$this->user = factory(App\Models\User::class)->create(); $pirep = $this->createPirep()->toArray();
$pirep = factory(App\Models\Pirep::class)->make()->toArray();
$uri = '/api/pireps/prefile'; $uri = '/api/pireps/prefile';
$response = $this->post($uri, $pirep); $response = $this->post($uri, $pirep);
@ -321,8 +368,7 @@ class AcarsTest extends TestCase
public function testAcarsLogPost() public function testAcarsLogPost()
{ {
$this->user = factory(App\Models\User::class)->create(); $pirep = $this->createPirep()->toArray();
$pirep = factory(App\Models\Pirep::class)->make()->toArray();
$uri = '/api/pireps/prefile'; $uri = '/api/pireps/prefile';
$response = $this->post($uri, $pirep); $response = $this->post($uri, $pirep);
@ -362,8 +408,7 @@ class AcarsTest extends TestCase
*/ */
public function testAcarsRoutePost() public function testAcarsRoutePost()
{ {
$this->user = factory(App\Models\User::class)->create(); $pirep = $this->createPirep()->toArray();
$pirep = factory(App\Models\Pirep::class)->make()->toArray();
$uri = '/api/pireps/prefile'; $uri = '/api/pireps/prefile';
$response = $this->post($uri, $pirep); $response = $this->post($uri, $pirep);
@ -418,16 +463,9 @@ class AcarsTest extends TestCase
*/ */
public function testDuplicatePirep() public function testDuplicatePirep()
{ {
$this->user = factory(App\Models\User::class)->create(); $pirep = $this->createPirep()->toArray();
$uri = '/api/pireps/prefile'; $uri = '/api/pireps/prefile';
$this->user = factory(App\Models\User::class)->create();
$pirep = factory(App\Models\Pirep::class)->make([
'airline_id' => $this->user->airline_id,
'user_id' => $this->user->id,
])->toArray();
$response = $this->post($uri, $pirep); $response = $this->post($uri, $pirep);
$response->assertStatus(201); $response->assertStatus(201);
$pirep_id = $response->json()['data']['id']; $pirep_id = $response->json()['data']['id'];

View File

@ -10,13 +10,15 @@ use App\Models\Enums\PirepState;
class PIREPTest extends TestCase class PIREPTest extends TestCase
{ {
protected $pirepSvc; protected $pirepSvc, $settingsRepo;
public function setUp() public function setUp()
{ {
parent::setUp(); // TODO: Change the autogenerated stub parent::setUp(); // TODO: Change the autogenerated stub
$this->addData('base'); $this->addData('base');
$this->pirepSvc = app('App\Services\PIREPService'); $this->pirepSvc = app('App\Services\PIREPService');
$this->settingsRepo = app(SettingRepository::class);
} }
protected function createNewRoute() protected function createNewRoute()
@ -246,8 +248,7 @@ class PIREPTest extends TestCase
*/ */
public function testCancelViaAPI() public function testCancelViaAPI()
{ {
$this->user = factory(App\Models\User::class)->create(); $pirep = $this->createPirep()->toArray();
$pirep = factory(App\Models\Pirep::class)->make(['id'=>''])->toArray();
$uri = '/api/pireps/prefile'; $uri = '/api/pireps/prefile';
$response = $this->post($uri, $pirep); $response = $this->post($uri, $pirep);

View File

@ -1,13 +1,15 @@
<?php <?php
use App\Services\DatabaseService; use App\Services\DatabaseService;
use Tests\TestData;
/** /**
* Class TestCase * Class TestCase
*/ */
class TestCase extends Illuminate\Foundation\Testing\TestCase class TestCase extends Illuminate\Foundation\Testing\TestCase
{ {
use TestData;
/** /**
* The base URL to use while testing the application. * The base URL to use while testing the application.
* *

View File

@ -5,15 +5,34 @@
namespace Tests; namespace Tests;
class TestData trait TestData
{ {
/**
* Create a new PIREP with a proper subfleet/rank/user and an
* aircraft that the user is allowed to fly
* @return \App\Models\Pirep
*/
protected function createPirep()
{
$subfleet = $this->createSubfleetWithAircraft(2);
$rank = $this->createRank(10, [$subfleet['subfleet']->id]);
$this->user = factory(\App\Models\User::class)->create([
'rank_id' => $rank->id
]);
// Return a Pirep model
return factory(\App\Models\Pirep::class)->make([
'aircraft_id' => $subfleet['aircraft']->random()->id
]);
}
/** /**
* Create a rank and associate the given subfleet IDs with it * Create a rank and associate the given subfleet IDs with it
* @param int $hours * @param int $hours
* @param array $subfleet_ids * @param array $subfleet_ids
* @return mixed * @return mixed
*/ */
public static function createRank($hours=0, $subfleet_ids=[]) public function createRank($hours=0, array $subfleet_ids)
{ {
$attrs = []; $attrs = [];
@ -32,9 +51,10 @@ class TestData
/** /**
* Create a subfleet with a number of aircraft assigned * Create a subfleet with a number of aircraft assigned
* @param null $aircraft_count * @param null $aircraft_count
* @param null $airport_id
* @return mixed * @return mixed
*/ */
public static function createSubfleetWithAircraft($aircraft_count = null, $airport_id=null) public function createSubfleetWithAircraft($aircraft_count = null, $airport_id=null)
{ {
$subfleet = factory(\App\Models\Subfleet::class)->create(); $subfleet = factory(\App\Models\Subfleet::class)->create();

View File

@ -25,10 +25,10 @@ class UserTest extends TestCase
{ {
# Add subfleets and aircraft, but also add another # Add subfleets and aircraft, but also add another
# set of subfleets # set of subfleets
$subfleetA = TestData::createSubfleetWithAircraft(); $subfleetA = $this->createSubfleetWithAircraft();
TestData::createSubfleetWithAircraft(); $this->createSubfleetWithAircraft();
$rank = TestData::createRank(10, [$subfleetA['subfleet']->id]); $rank = $this->createRank(10, [$subfleetA['subfleet']->id]);
$user = factory(App\Models\User::class)->create([ $user = factory(App\Models\User::class)->create([
'rank_id' => $rank->id, 'rank_id' => $rank->id,
@ -81,15 +81,15 @@ class UserTest extends TestCase
{ {
# Add subfleets and aircraft, but also add another # Add subfleets and aircraft, but also add another
# set of subfleets # set of subfleets
$subfleetA = TestData::createSubfleetWithAircraft(); $subfleetA = $this->createSubfleetWithAircraft();
$subfleetB = TestData::createSubfleetWithAircraft(); $subfleetB = $this->createSubfleetWithAircraft();
$added_aircraft = array_merge( $added_aircraft = array_merge(
$subfleetA['aircraft']->pluck('id')->toArray(), $subfleetA['aircraft']->pluck('id')->toArray(),
$subfleetB['aircraft']->pluck('id')->toArray() $subfleetB['aircraft']->pluck('id')->toArray()
); );
$rank = TestData::createRank(10, [$subfleetA['subfleet']->id]); $rank = $this->createRank(10, [$subfleetA['subfleet']->id]);
$user = factory(App\Models\User::class)->create([ $user = factory(App\Models\User::class)->create([
'rank_id' => $rank->id, 'rank_id' => $rank->id,
@ -134,10 +134,10 @@ class UserTest extends TestCase
# Add subfleets and aircraft, but also add another # Add subfleets and aircraft, but also add another
# set of subfleets # set of subfleets
$airport = factory(App\Models\Airport::class)->create(); $airport = factory(App\Models\Airport::class)->create();
$subfleetA = TestData::createSubfleetWithAircraft(2, $airport->id); $subfleetA = $this->createSubfleetWithAircraft(2, $airport->id);
$subfleetB = TestData::createSubfleetWithAircraft(2); $subfleetB = $this->createSubfleetWithAircraft(2);
$rank = TestData::createRank(10, [$subfleetA['subfleet']->id]); $rank = $this->createRank(10, [$subfleetA['subfleet']->id]);
$user = factory(App\Models\User::class)->create([ $user = factory(App\Models\User::class)->create([
'curr_airport_id' => $airport->id, 'curr_airport_id' => $airport->id,
'rank_id' => $rank->id, 'rank_id' => $rank->id,