Skip to content

Commit

Permalink
Check for departure airport restrictions #221
Browse files Browse the repository at this point in the history
  • Loading branch information
nabeelio committed Mar 30, 2018
1 parent 35fb6f0 commit bd30b1f
Show file tree
Hide file tree
Showing 12 changed files with 189 additions and 29 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ public function up()
'description' => 'Aircraft that can be flown are restricted to a user\'s rank',
]);

$this->addSetting('pireps.only_aircraft_at_dep_airport', [
$this->addSetting('pireps.only_aircraft_at_dpt_airport', [
'name' => 'Restrict Aircraft At Departure',
'group' => 'pireps',
'value' => false,
Expand Down
13 changes: 13 additions & 0 deletions app/Exceptions/AircraftNotAtAirport.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?php

namespace App\Exceptions;

/**
* Class AircraftNotAtAirport
* @package App\Exceptions
*/
class AircraftNotAtAirport extends InternalError
{
public const FIELD = 'aircraft_id';
public const MESSAGE = 'The aircraft is not at the departure airport';
}
18 changes: 3 additions & 15 deletions app/Exceptions/AircraftPermissionDenied.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,12 @@

namespace App\Exceptions;

use Symfony\Component\HttpKernel\Exception\HttpException;

/**
* Class AircraftPermissionDenied
* @package App\Exceptions
*/
class AircraftPermissionDenied extends HttpException
class AircraftPermissionDenied extends InternalError
{
public function __construct(
string $message = null,
\Exception $previous = null,
int $code = 0,
array $headers = []
) {
parent::__construct(
400,
'User is not allowed to fly this aircraft',
$previous, $headers, $code
);
}
public const FIELD = 'aircraft_id';
public const MESSAGE = 'User is not allowed to fly this aircraft';
}
9 changes: 6 additions & 3 deletions app/Exceptions/InternalError.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,18 +14,21 @@
*/
class InternalError extends ValidationException
{
protected const FLASH_FIELD_NAME = 'internal_error_message';
public const FIELD = 'internal_error_message';
public const MESSAGE = '';

/**
* InternalError constructor.
* @param string|null $message
* @param null $field
*/
final public function __construct(string $message = null, $field = null)
public function __construct(string $message = null, $field = null)
{
Log::error($message);
$validator = Validator::make([], []);
$validator->errors()->add($field ?? static::FLASH_FIELD_NAME, $message);
$validator->errors()->add(
$field ?? static::FIELD,
$message ?? static::MESSAGE);

parent::__construct($validator);
}
Expand Down
14 changes: 14 additions & 0 deletions app/Exceptions/UserNotAtAirport.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?php

namespace App\Exceptions;


/**
* Class UserNotAtAirport
* @package App\Exceptions
*/
class UserNotAtAirport extends InternalError
{
public const FIELD = 'dpt_airport_id';
public const MESSAGE = 'Pilot is not at the departure airport';
}
27 changes: 22 additions & 5 deletions app/Http/Controllers/Api/PirepController.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@

namespace App\Http\Controllers\Api;

use App\Exceptions\AircraftNotAtAirport;
use App\Exceptions\AircraftPermissionDenied;
use App\Exceptions\PirepCancelled;
use App\Exceptions\UserNotAtAirport;
use App\Http\Requests\Acars\CommentRequest;
use App\Http\Requests\Acars\EventRequest;
use App\Http\Requests\Acars\FileRequest;
Expand Down Expand Up @@ -155,6 +157,8 @@ protected function updateFares($pirep, Request $request)
*
* @param PrefileRequest $request
* @return PirepResource
* @throws \App\Exceptions\AircraftNotAtAirport
* @throws \App\Exceptions\UserNotAtAirport
* @throws \App\Exceptions\PirepCancelled
* @throws \App\Exceptions\AircraftPermissionDenied
* @throws \Exception
Expand All @@ -173,12 +177,25 @@ public function prefile(PrefileRequest $request)

$pirep = new Pirep($attrs);

# See if this user is at the current airport
if (setting('pilots.only_flights_from_current')
&& $user->current_airport_id !== $pirep->dpt_airport_id)
{
throw new UserNotAtAirport();
}

# 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 AircraftPermissionDenied();
}
if (setting('pireps.restrict_aircraft_to_rank', false)
&& !$this->userSvc->aircraftAllowed($user, $pirep->aircraft_id))
{
throw new AircraftPermissionDenied();
}

# See if this aircraft is at the departure airport
if (setting('pireps.only_aircraft_at_dpt_airport')
&& $pirep->aircraft_id !== $pirep->dpt_airport_id)
{
throw new AircraftNotAtAirport();
}

# Find if there's a duplicate, if so, let's work on that
Expand Down
35 changes: 32 additions & 3 deletions app/Http/Controllers/Frontend/PirepController.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace App\Http\Controllers\Frontend;

use App\Exceptions\UserNotAtAirport;
use App\Facades\Utils;
use App\Http\Requests\CreatePirepRequest;
use App\Http\Requests\UpdatePirepRequest;
Expand Down Expand Up @@ -241,12 +242,40 @@ public function store(CreatePirepRequest $request)
$pirep = new Pirep($request->post());
$pirep->user_id = Auth::user()->id;

# Are they allowed at this airport?
if (setting('pilots.only_flights_from_current')
&& Auth::user()->current_airport_id !== $pirep->dpt_airport_id) {
return $this->flashError(
'You are currently not at the departure airport!',
'frontend.pireps.create'
);
}

# Can they fly this aircraft?
if (setting('pireps.restrict_aircraft_to_rank', false)
&& !$this->userSvc->aircraftAllowed(Auth::user(), $pirep->aircraft_id)) {
return $this->flashError(
'You are not allowed to fly this aircraft!',
'frontend.pireps.create'
);
}

# is the aircraft in the right place?
if (setting('pireps.only_aircraft_at_dpt_airport')
&& $pirep->aircraft_id !== $pirep->dpt_airport_id) {
return $this->flashError(
'This aircraft is not positioned at the departure airport!',
'frontend.pireps.create'
);
}

# Make sure this isn't a duplicate
$dupe_pirep = $this->pirepSvc->findDuplicate($pirep);
if ($dupe_pirep !== false) {
flash()->error('This PIREP has already been filed.');

return redirect(route('frontend.pireps.create'))->withInput();
return $this->flashError(
'This PIREP has already been filed.',
'frontend.pireps.create'
);
}

// Any special fields
Expand Down
12 changes: 12 additions & 0 deletions app/Interfaces/Controller.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,18 @@ abstract class Controller extends \Illuminate\Routing\Controller
{
use AuthorizesRequests, DispatchesJobs, ValidatesRequests;

/**
* Write a error to the flash and redirect the user to a route
* @param $message
* @param $route
* @return mixed
*/
public function flashError($message, $route)
{
flash()->error($message);
return redirect(route($route))->withInput();
}

/**
* Shortcut function to get the attributes from a request while running the validations
* @param Request $request
Expand Down
5 changes: 4 additions & 1 deletion app/Models/Pirep.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,13 @@
* @property string route_leg
* @property integer airline_id
* @property integer user_id
* @property integer aircraft_id
* @property Aircraft aircraft
* @property Airline airline
* @property Airport arr_airport
* @property Airport dep_airport
* @property string arr_airport_id
* @property Airport dpt_airport
* @property string dpt_airport_id
* @property integer block_time
* @property integer flight_time In minutes
* @property User user
Expand Down
2 changes: 2 additions & 0 deletions app/Models/User.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
* @property string $email
* @property string $password
* @property string $api_key
* @property string current_airport_id
* @property string home_airport_id
* @property Flight[] $flights
* @property string $flight_time
* @property string $remember_token
Expand Down
2 changes: 1 addition & 1 deletion app/Services/FlightService.php
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ public function filterSubfleets($user, $flight)
/**
* Only allow aircraft that are at the current departure airport
*/
if (setting('pireps.only_aircraft_at_dep_airport', false)) {
if (setting('pireps.only_aircraft_at_dpt_airport', false)) {
foreach ($subfleets as $subfleet) {
$subfleet->aircraft = $subfleet->aircraft->filter(
function ($aircraft, $i) use ($flight) {
Expand Down
79 changes: 79 additions & 0 deletions tests/AcarsTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,85 @@ public function testPrefileErrors()

}

/**
* Make sure an error is thrown if the pilot is not at the current airport
*/
public function testPilotNotAtAirport(): void
{
$this->settingsRepo->store('pilots.only_flights_from_current', true);
$this->settingsRepo->store('pireps.restrict_aircraft_to_rank', false);

$this->user = factory(App\Models\User::class)->create([
'curr_airport_id' => 'KJFK',
]);

$airport = factory(App\Models\Airport::class)->create();
$airline = factory(App\Models\Airline::class)->create();
$aircraft = factory(App\Models\Aircraft::class)->create();

/**
* INVALID AIRLINE_ID FIELD
*/
$uri = '/api/pireps/prefile';
$pirep = [
'airline_id' => $airline->id,
'aircraft_id' => $aircraft->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' => 'phpunit',
];

$response = $this->post($uri, $pirep);
$response->assertStatus(400);
$body = $response->json();
$this->assertEquals(\App\Exceptions\UserNotAtAirport::MESSAGE, $body['error']['message']);
}

/**
* Make sure an error is thrown if the pilot is not at the current airport
*/
public function testAircraftNotAtAirport(): void
{
$this->settingsRepo->store('pireps.only_aircraft_at_dpt_airport', true);
$this->settingsRepo->store('pireps.restrict_aircraft_to_rank', false);
$this->settingsRepo->store('pireps.restrict_aircraft_to_rank', false);

$this->user = factory(App\Models\User::class)->create([
'curr_airport_id' => 'KJFK',
]);

$airport = factory(App\Models\Airport::class)->create();
$airline = factory(App\Models\Airline::class)->create();
$aircraft = factory(App\Models\Aircraft::class)->create([
'airport_id' => 'KAUS'
]);

/**
* INVALID AIRLINE_ID FIELD
*/
$uri = '/api/pireps/prefile';
$pirep = [
'airline_id' => $airline->id,
'aircraft_id' => $aircraft->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' => 'phpunit',
];

$response = $this->post($uri, $pirep);
$response->assertStatus(400);
$body = $response->json();
$this->assertEquals(\App\Exceptions\AircraftNotAtAirport::MESSAGE, $body['error']['message']);
}

/**
* Post a PIREP into a PREFILE state and post ACARS
*/
Expand Down

0 comments on commit bd30b1f

Please sign in to comment.