phpvms/tests/Feature/AcarsTest.php
Arthur Parienté 7490e72523
[8.x] refactor: use native php enum instead of class (#2210)
* wip

* refactor: update enum handling and improve type hints across models

* refactor: deprecate labels and select methods in HasSelect trait for better separation of concerns

* copilot suggestions
2026-05-12 16:29:41 -05:00

1001 lines
30 KiB
PHP

<?php
use App\Enums\PirepState;
use App\Enums\PirepStatus;
use App\Exceptions\AircraftNotAtAirport;
use App\Exceptions\UserNotAtAirport;
use App\Models\Acars;
use App\Models\Aircraft;
use App\Models\Airline;
use App\Models\Airport;
use App\Models\Fare;
use App\Models\Navdata;
use App\Models\PirepFare;
use App\Models\PirepFieldValue;
use App\Models\Rank;
use App\Models\Subfleet;
use App\Models\User;
use App\Services\FareService;
use App\Support\Utils;
function allPointsInRoute(array $route, array $points, array $addtl_fields = []): void
{
if ($addtl_fields === []) {
$addtl_fields = [];
}
$fields = array_merge(
[
'name',
'order',
'lat',
'lon',
],
$addtl_fields
);
expect($points)->toHaveCount(count($route));
foreach ($route as $idx => $point) {
expect($points[$idx])->toHaveKeys($fields);
foreach ($fields as $f) {
if ($f === 'lat') {
continue;
}
if ($f === 'lon') {
continue;
}
expect($points[$idx][$f])->toEqual($point[$f]);
}
}
}
function getPirepFromApi(string $pirep_id): array
{
$resp = test()->get('/api/pireps/'.$pirep_id);
$resp->assertStatus(200);
return $resp->json()['data'];
}
it('should return a prefile error', function (): void {
$user = User::factory()->create();
apiAs($user);
$airport = Airport::factory()->create();
$airline = Airline::factory()->create();
$aircraft = Aircraft::factory()->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',
];
$response = $this->post($uri, $pirep);
$response->assertStatus(400);
});
it('should not start pirep if the aircraft is not at the departure airport', function (): void {
updateSetting('pilots.only_flights_from_current', false);
updateSetting('pireps.restrict_aircraft_to_rank', false);
updateSetting('pireps.only_aircraft_at_dpt_airport', true);
$user = User::factory()->create();
apiAs($user);
$airport = Airport::factory()->create();
$aircraft_airport = Airport::factory()->create();
$airline = Airline::factory()->create();
$aircraft = Aircraft::factory()->create(['airport_id' => $aircraft_airport->id]);
$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' => 'Tests',
];
$response = $this->post($uri, $pirep);
$response->assertStatus(400);
expect($response->json('title'))->toEqual('The aircraft is not at the departure airport')
->and($response->json('error.message'))->toEqual(AircraftNotAtAirport::MESSAGE);
});
it('should not start pirep without airports', function (): void {
$user = User::factory()->create();
apiAs($user);
$airline = Airline::factory()->create();
$aircraft = Aircraft::factory()->create();
$uri = '/api/pireps/prefile';
$pirep = [
'airline_id' => $airline->id,
'aircraft_id' => $aircraft->id,
'dpt_airport_id' => null,
'arr_airport_id' => null,
'flight_number' => '6000',
'level' => 38000,
'planned_flight_time' => 120,
'source_name' => 'ACARSTESTS',
'route' => 'POINTA POINTB',
];
$response = $this->post($uri, $pirep);
$response->assertStatus(400);
expect($response->json('details'))->toEqual('A departure airport is required, An arrival airport is required');
});
it('should not start pirep if the pilot is not at the departure airport', function (): void {
updateSetting('pilots.only_flights_from_current', true);
updateSetting('pireps.restrict_aircraft_to_rank', false);
$user = User::factory()->create([
'curr_airport_id' => 'KJFK',
]);
apiAs($user);
$airport = Airport::factory()->create();
$airline = Airline::factory()->create();
$aircraft = Aircraft::factory()->create();
$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();
expect($body['error']['message'])->toEqual(UserNotAtAirport::MESSAGE);
});
it('can prefile and update a pirep', function (): void {
$subfleet = Subfleet::factory()->hasAircraft(2)->create();
$rank = Rank::factory()->hasAttached($subfleet)->create();
$fare = Fare::factory()->create();
$user = User::factory()->create(
[
'rank_id' => $rank->id,
]
);
apiAs($user);
$airport = Airport::factory()->create();
$airline = Airline::factory()->create();
$aircraft = $subfleet['aircraft']->random();
app(FareService::class)->setForSubfleet($subfleet, $fare);
$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_distance' => 400,
'planned_flight_time' => 120,
'route' => 'POINTA POINTB',
'source_name' => 'UnitTest',
'fields' => [
'custom_field' => 'custom_value',
],
'fares' => [
[
'id' => $fare->id,
'count' => $fare->capacity,
],
],
];
$response = $this->post($uri, $pirep);
$response->assertStatus(200);
$pirep = $response->json('data');
expect($pirep['planned_distance']['nmi'])->toEqual(400)
->and($pirep['planned_distance']['mi'])->toEqual(460.31)
->and($pirep['planned_distance']['km'])->toEqual(740.8)
->and($pirep['planned_distance']['m'])->toEqual(740800)
->and(str_ends_with((string) $pirep['submitted_at'], 'Z'))->toBeTrue();
// Are date times in UTC?
// See that the fields and fares were set
$fares = PirepFare::where('pirep_id', $pirep['id'])->get();
expect($fares)->toHaveCount(1);
$saved_fare = $fares->first();
// $this->assertEquals($fare->id, $saved_fare['fare_id']);
expect($saved_fare['count'])->toEqual($fare->capacity)
->and($saved_fare['cost'])->toEqual($fare->cost)
->and($saved_fare['price'])->toEqual($fare->price);
// Check saved fields
$saved_fields = PirepFieldValue::where('pirep_id', $pirep['id'])->get();
expect($saved_fields)->toHaveCount(1);
$field = $saved_fields->first();
expect($field['name'])->toEqual('custom_field')
->and($field['value'])->toEqual('custom_value');
/**
* Try to update fields
*/
$uri = '/api/pireps/'.$pirep['id'].'/update';
$update = [
'fares' => [
[
'id' => $fare->id,
'count' => $fare->capacity,
],
],
];
$response = $this->post($uri, $update);
$response->assertOk();
// Make sure there are no duplicates
$fares = PirepFare::where('pirep_id', $pirep['id'])->get();
expect($fares)->toHaveCount(1);
$saved_fare = $fares->first();
// $this->assertEquals($fare->id, $saved_fare['fare_id']);
expect($saved_fare['count'])->toEqual($fare->capacity);
/*
* Try cancelling the PIREP now
*/
$uri = '/api/pireps/'.$pirep['id'].'/cancel';
$response = $this->put($uri, []);
$response->assertOk();
// Read it
$uri = '/api/pireps/'.$pirep['id'];
$response = $this->get($uri);
$response->assertOk();
$body = $response->json('data');
expect(PirepState::CANCELLED->value)->toEqual($body['state']);
});
it('should validate updates', function (): void {
$subfleet = Subfleet::factory()->hasAircraft(2)->create();
$rank = Rank::factory()->hasAttached($subfleet)->create();
$user = User::factory()->create([
'rank_id' => $rank->id,
]);
apiAs($user);
$airport = Airport::factory()->create();
$airline = Airline::factory()->create();
$aircraft = $subfleet->aircraft->random();
$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_distance' => 400,
'planned_flight_time' => 120,
'route' => 'POINTA POINTB',
'source_name' => 'UnitTest',
];
$response = $this->post($uri, $pirep);
$response->assertStatus(200);
$pirep = $response->json('data');
/**
* Try to update fields
*/
$uri = '/api/pireps/'.$pirep['id'].'/update';
$update = [
'dpt_airport_id' => '',
];
$response = $this->post($uri, $update);
$response->assertStatus(400);
$detail = $response->json('details');
expect($detail)->toEqual('A departure airport is required');
});
it('can receive acars updates', function (): void {
$subfleet = Subfleet::factory()->hasAircraft(2)->create();
$rank = Rank::factory()->hasAttached($subfleet)->create();
$user = User::factory()->create([
'rank_id' => $rank->id,
]);
apiAs($user);
$airport = Airport::factory()->create();
$airline = Airline::factory()->create();
$aircraft = $subfleet->aircraft->random();
$uri = '/api/pireps/prefile';
$pirep_create = [
'airline_id' => $airline->id,
'aircraft_id' => $aircraft->id,
'dpt_airport_id' => $airport->icao,
'arr_airport_id' => $airport->icao,
'flight_number' => '6000',
'level' => 38000,
'planned_distance' => 400,
'planned_flight_time' => 120,
'status' => PirepStatus::BOARDING->value,
'route' => 'POINTA POINTB',
'source_name' => 'AcarsTest::testAcarsUpdates',
'fields' => [
'custom_field' => 'custom_value',
],
];
$response = $this->post($uri, $pirep_create);
$response->assertStatus(200);
// Get the PIREP ID
$body = $response->json();
$pirep_id = $body['data']['id'];
expect($body['data'])->toHaveKeys(['airline', 'arr_airport', 'dpt_airport'])
->and($pirep_id)->not->toBeNull()
->and($user->id)->toEqual($body['data']['user_id']);
// Check the PIREP state and status
$pirep = getPirepFromApi($pirep_id);
expect(PirepState::from($pirep['state']))->toEqual(PirepState::IN_PROGRESS)
->and(PirepStatus::from($pirep['status']))->toEqual(PirepStatus::INITIATED)
->and($pirep)->toHaveKey('fields')
->and($pirep['fields']['custom_field'])->toEqual('custom_value')
->and($pirep['planned_distance']['nmi'])->toEqual($pirep_create['planned_distance'])
->and($pirep['planned_distance'])->toHaveKeys(['mi', 'nmi', 'km']);
/*
* Check the fields
*/
/**
* Update the custom field
*/
$uri = '/api/pireps/'.$pirep_id.'/update';
$this->post($uri, [
'flight_time' => 60,
'distance' => 20,
'status' => PirepStatus::AIRBORNE->value,
'fields' => [
'custom_field' => 'custom_value_changed',
],
]);
$pirep = getPirepFromApi($pirep_id);
expect($pirep['fields']['custom_field'])->toEqual('custom_value_changed');
/**
* Add some position updates
*/
$uri = '/api/pireps/'.$pirep_id.'/acars/position';
// Test missing positions field
// Post an ACARS update
$update = [];
$response = $this->post($uri, $update);
$response->assertStatus(400);
// Post an ACARS update
$acars = Acars::factory()->make(['pirep_id' => $pirep_id])->toArray();
$acars = transformData($acars);
$update = ['positions' => [$acars]];
$response = $this->post($uri, $update);
$response->assertStatus(200)->assertJson(['count' => 1]);
// Read that if the ACARS record posted
$response = $this->get($uri);
$acars_data = $response->json('data')[0];
expect(round($acars_data['lat'], 2))->toEqual(round($acars['lat'], 2))
->and(round($acars_data['lon'], 2))->toEqual(round($acars['lon'], 2))
->and($acars_data['log'])->toEqual($acars['log']);
// Make sure PIREP state moved into ENROUTE
$pirep = getPirepFromApi($pirep_id);
expect(PirepState::from($pirep['state']))->toEqual(PirepState::IN_PROGRESS)
->and(PirepStatus::from($pirep['status']))->toEqual(PirepStatus::AIRBORNE);
$response = $this->get($uri);
$response->assertStatus(200);
$body = $response->json()['data'];
expect($body)->not->toBeNull()
->and($body)->toHaveCount(1)
->and(round($body[0]['lat'], 2))->toEqual(round($acars['lat'], 2))
->and(round($body[0]['lon'], 2))->toEqual(round($acars['lon'], 2));
// Update fields standalone
$uri = '/api/pireps/'.$pirep_id.'/fields';
$response = $this->post($uri, [
'fields' => [
'Departure Gate' => 'G26',
],
]);
$response->assertStatus(200);
$body = $response->json('data');
expect($body['Departure Gate'])->toEqual('G26');
/*
* Get the live flights and make sure all the fields we want are there
*/
$uri = '/api/acars';
$response = $this->get($uri);
$response->assertStatus(200);
$body = collect($response->json('data'));
$body = $body->firstWhere('id', $pirep['id']);
expect($body['user']['name'])->not->toBeEmpty()
->and($body['user']['avatar'])->not->toBeEmpty();
/*
* File the PIREP
*/
$uri = '/api/pireps/'.$pirep_id.'/file';
$response = $this->post($uri, []);
$response->assertStatus(400);
// missing field
$response = $this->post($uri, ['flight_time' => '1:30']);
$response->assertStatus(400);
// invalid flight time
$response = $this->post($uri, [
'flight_time' => 130,
'fuel_used' => 8000.19,
'distance' => 400,
]);
$response->assertStatus(200);
$body = $response->json();
// Add a comment
$uri = '/api/pireps/'.$pirep_id.'/comments';
$response = $this->post($uri, ['comment' => 'A comment']);
$response->assertStatus(201);
$response = $this->get($uri);
$response->assertStatus(200);
$comments = $response->json();
expect($comments)->toHaveCount(1);
});
test('multiple altitudes', function (): void {
$subfleet = Subfleet::factory()->hasAircraft(2)->create();
$rank = Rank::factory()->hasAttached($subfleet)->create();
$user = User::factory()->create([
'rank_id' => $rank->id,
]);
apiAs($user);
$airport = Airport::factory()->create();
$airline = Airline::factory()->create();
$aircraft = $subfleet->aircraft->random();
$uri = '/api/pireps/prefile';
$pirep_create = [
'airline_id' => $airline->id,
'aircraft_id' => $aircraft->id,
'dpt_airport_id' => $airport->icao,
'arr_airport_id' => $airport->icao,
'flight_number' => '6000',
'level' => 38000,
'planned_distance' => 400,
'planned_flight_time' => 120,
'status' => PirepStatus::BOARDING->value,
'route' => 'POINTA POINTB',
'source_name' => 'AcarsTest::testAcarsUpdates',
'fields' => [
'custom_field' => 'custom_value',
],
];
$response = $this->post($uri, $pirep_create);
$response->assertStatus(200);
// Get the PIREP ID
$body = $response->json();
$pirep_id = $body['data']['id'];
$dt = new DateTime('now');
// Post an ACARS update
$acars = Acars::factory()->make(['pirep_id' => $pirep_id])->toArray();
$acars['sim_time'] = $dt->format(DateTime::ATOM);
unset($acars['altitude_agl']);
unset($acars['altitude_msl']);
$acars['altitude'] = 1000;
$acars = transformData($acars);
// $acars = $this->transformData($acars);
$inst = new Acars($acars);
expect($inst->altitude_agl)->toEqual($acars['altitude'])
->and($inst->altitude_msl)->toEqual($acars['altitude']);
$uri = '/api/pireps/'.$pirep_id.'/acars/position';
$response = $this->post($uri, ['positions' => [$acars]]);
$response->assertStatus(200)->assertJson(['count' => 1]);
// Read that if the ACARS record posted
$response = $this->get($uri);
$acars_data = $response->json('data')[0];
expect($acars_data['altitude_agl'])->toEqual($acars['altitude'])
->and($acars_data['altitude_msl'])->toEqual($acars['altitude']);
/**
* Now push the new fields without the old one
*/
$acars2 = Acars::factory()->make(['pirep_id' => $pirep_id])->toArray();
$acars2['sim_time'] = $dt
->add(DateInterval::createFromDateString('30 seconds'))
->format(DateTimeInterface::ATOM);
$acars2 = transformData($acars2);
// send it in
$response = $this->post($uri, ['positions' => [$acars2]]);
$response->assertStatus(200)->assertJson(['count' => 1]);
// Read that if the ACARS record posted
$response = $this->get($uri);
$acars_data = $response->json('data')[1];
expect($acars_data['altitude_agl'])->toEqualWithDelta($acars2['altitude_agl'], 0.1)
->and($acars_data['altitude_msl'])->toEqualWithDelta($acars2['altitude_msl'], 0.1);
});
test('acars data instantitaion', function (): void {
$acars = Acars::factory()->make(['pirep_id' => 'abc'])->toArray();
$acars['altitude'] = 5000;
$acars = transformData($acars);
// Set this to the model first
$inst = new Acars($acars);
expect($inst->altitude_agl)->toEqual($acars['altitude_agl'])
->and($inst->altitude_msl)->toEqual($acars['altitude_msl']);
// Now delete the agl/msl and recreate the instance
unset($acars['altitude_agl']);
unset($acars['altitude_msl']);
$inst = new Acars($acars);
expect($inst->altitude_agl)->toEqual($acars['altitude'])
->and($inst->altitude_msl)->toEqual($acars['altitude']);
});
it('can file a pirep via api', function (): void {
$subfleet = Subfleet::factory()->hasAircraft(2)->create();
$rank = Rank::factory()->hasAttached($subfleet)->create();
$user = User::factory()->create([
'rank_id' => $rank->id,
]);
apiAs($user);
$airport = Airport::factory()->create();
$airline = Airline::factory()->create();
$aircraft = $subfleet->aircraft->random();
$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,
'source_name' => 'AcarsTest::testFilePirepApi',
];
$response = $this->post($uri, $pirep);
$response->assertStatus(200);
// Get the PIREP ID
$body = $response->json();
$pirep_id = $body['data']['id'];
// File the PIREP now
$uri = '/api/pireps/'.$pirep_id.'/file';
$response = $this->post($uri, [
'flight_time' => 130,
'fuel_used' => 8000.19,
'distance' => 400,
]);
$response->assertStatus(200);
// Check the block_off_time and block_on_time being set
$body = $this->get('/api/pireps/'.$pirep_id)->json('data');
expect(PirepState::from($body['state']))->toEqual(PirepState::PENDING)
->and($body['block_off_time'])->not->toBeNull()
->and($body['block_on_time'])->not->toBeNull();
// Try to refile, should be blocked
$response = $this->post($uri, [
'flight_time' => 130,
'fuel_used' => 8000.19,
'distance' => 400,
]);
$response->assertStatus(400);
});
it('should check if the aircraft is allowed for flight', function (): void {
updateSetting('pireps.restrict_aircraft_to_rank', true);
$airport = Airport::factory()->create();
$airline = Airline::factory()->create();
// Add subfleets and aircraft, but also add another set of subfleets
$subfleetA = Subfleet::factory()->hasAircraft(1)->create();
// User not allowed aircraft from this subfleet
$subfleetB = Subfleet::factory()->hasAircraft(1)->create();
$rank = Rank::factory()->hasAttached($subfleetA)->create();
$user = User::factory()->create(
[
'rank_id' => $rank->id,
]
);
apiAs($user);
$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(200);
});
it('should ignore aircraft allowed', function (): void {
updateSetting('pireps.restrict_aircraft_to_rank', false);
$airport = Airport::factory()->create();
$airline = Airline::factory()->create();
// Add subfleets and aircraft, but also add another set of subfleets
$subfleetA = Subfleet::factory()->hasAircraft(1)->create();
// User not allowed aircraft from this subfleet
$subfleetB = Subfleet::factory()->hasAircraft(1)->create();
$rank = Rank::factory()->hasAttached($subfleetA)->create();
$user = User::factory()->create(
[
'rank_id' => $rank->id,
]
);
apiAs($user);
$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(200);
});
it('can receive multiple acars position updates', function (): void {
$pirep = createPirep();
apiAs($pirep->user);
$pirep = $pirep->toArray();
$pirep = transformData($pirep);
$uri = '/api/pireps/prefile';
$response = $this->post($uri, $pirep);
$response->assertStatus(200);
$pirep_id = $response->json()['data']['id'];
$uri = '/api/pireps/'.$pirep_id.'/acars/position';
// Post an ACARS update
$acars_count = random_int(5, 10);
$acars = Acars::factory()->count($acars_count)->make(['id' => ''])
->map(function (Acars $point): Acars {
$point->id = Utils::generateNewId();
return $point;
})
->toArray();
$acars = transformData($acars);
$update = ['positions' => $acars];
$response = $this->post($uri, $update);
$response->assertStatus(200)->assertJson(['count' => $acars_count]);
// Try posting again, should be ignored/not throw any sql errors
$response = $this->post($uri, $update);
$response->assertStatus(200)->assertJson(['count' => $acars_count]);
$response = $this->get($uri);
$response->assertStatus(200)->assertJsonCount($acars_count, 'data');
});
it('should return a 404 on a non existent pirep get', function (): void {
$user = User::factory()->create();
apiAs($user);
$uri = '/api/pireps/DOESNTEXIST/acars';
$response = $this->get($uri);
$response->assertStatus(404);
});
it('should return a 404 on a non existent pirep store', function (): void {
$user = User::factory()->create();
apiAs($user);
$uri = '/api/pireps/DOESNTEXIST/acars/position';
$acars = Acars::factory()->make()->toArray();
$response = $this->post($uri, $acars);
$response->assertStatus(404);
});
it('should use acars iso date', function (): void {
$pirep = createPirep();
apiAs($pirep->user);
$pirep = $pirep->toArray();
$pirep = transformData($pirep);
$uri = '/api/pireps/prefile';
$response = $this->post($uri, $pirep);
$response->assertStatus(200);
$pirep_id = $response->json()['data']['id'];
$dt = date('c');
$uri = '/api/pireps/'.$pirep_id.'/acars/position';
$acars = Acars::factory()->make([
'sim_time' => $dt,
])->toArray();
$acars = transformData($acars);
$update = ['positions' => [$acars]];
$response = $this->post($uri, $update);
$response->assertStatus(200);
});
it('refuses invalid route post', function (): void {
$pirep = createPirep();
apiAs($pirep->user);
$pirep = $pirep->toArray();
$pirep = transformData($pirep);
$uri = '/api/pireps/prefile';
$response = $this->post($uri, $pirep);
$pirep_id = $response->json()['data']['id'];
// Missing lat/lon
$post_route = ['order' => 1, 'name' => 'NAVPOINT'];
$uri = '/api/pireps/'.$pirep_id.'/route';
$response = $this->post($uri, $post_route);
$response->assertStatus(400);
$post_route = [
[
'id' => 'NAVPOINT',
'order' => 1,
'name' => 'NAVPOINT',
'lat' => 'notanumber',
'lon' => 34.11,
],
];
$uri = '/api/pireps/'.$pirep_id.'/route';
$response = $this->post($uri, $post_route);
$response->assertStatus(400);
});
it('can receive acars log', function (): void {
$pirep = createPirep();
apiAs($pirep->user);
$pirep = $pirep->toArray();
$pirep = transformData($pirep);
$uri = '/api/pireps/prefile';
$response = $this->post($uri, $pirep);
$pirep_id = $response->json()['data']['id'];
$acars = Acars::factory()->make();
$post_log = [
'logs' => [
['log' => $acars->log],
],
];
$uri = '/api/pireps/'.$pirep_id.'/acars/logs';
$response = $this->post($uri, $post_log);
$response->assertStatus(200);
$body = $response->json();
expect($body['count'])->toEqual(1);
$acars = Acars::factory()->make();
$post_log = [
'events' => [
['event' => $acars->log],
],
];
$uri = '/api/pireps/'.$pirep_id.'/acars/events';
$response = $this->post($uri, $post_log);
$response->assertStatus(200);
$body = $response->json();
expect($body['count'])->toEqual(1);
});
it('can receive acars route', function (): void {
$pirep = createPirep();
apiAs($pirep->user);
$pirep = $pirep->toArray();
$pirep = transformData($pirep);
$uri = '/api/pireps/prefile';
$response = $this->post($uri, $pirep);
$pirep_id = $response->json()['data']['id'];
$order = 1;
$post_route = [];
$route_count = random_int(2, 10);
$route = Navdata::factory()->count($route_count)->create();
foreach ($route as $position) {
$post_route[] = [
'order' => $order,
'id' => $position->id,
'name' => $position->id,
'lat' => $position->lat,
'lon' => $position->lon,
];
$order++;
}
$uri = '/api/pireps/'.$pirep_id.'/route';
$response = $this->post($uri, ['route' => $post_route]);
$response->assertStatus(200)->assertJson(['count' => $route_count]);
// Try double post to ignore SQL update
$response = $this->post($uri, ['route' => $post_route]);
$response->assertStatus(200)->assertJson(['count' => $route_count]);
/**
* Get
*/
$uri = '/api/pireps/'.$pirep_id.'/route';
$response = $this->get($uri);
$response->assertStatus(200)->assertJsonCount($route_count, 'data');
$body = $response->json()['data'];
allPointsInRoute($post_route, $body);
/**
* Delete and then recheck
*/
$uri = '/api/pireps/'.$pirep_id.'/route';
$response = $this->delete($uri);
$response->assertStatus(200);
$uri = '/api/pireps/'.$pirep_id.'/route';
$response = $this->get($uri);
$response->assertStatus(200)->assertJsonCount(0, 'data');
});
it('handles duplicate pirep', function (): void {
$pirep = createPirep();
apiAs($pirep->user);
$pirep = $pirep->toArray();
$pirep = transformData($pirep);
$uri = '/api/pireps/prefile';
$response = $this->post($uri, $pirep);
$response->assertStatus(200);
$pirep_id = $response->json()['data']['id'];
// try readding
$response = $this->post($uri, $pirep);
$response->assertStatus(200);
$dupe_pirep_id = $response->json()['data']['id'];
expect($dupe_pirep_id)->toEqual($pirep_id);
});