Skip to content

Commit

Permalink
feat: easier to use date picker for request a stand
Browse files Browse the repository at this point in the history
  • Loading branch information
AndyTWF committed Jun 30, 2023
1 parent a106802 commit 95611b0
Show file tree
Hide file tree
Showing 2 changed files with 128 additions and 22 deletions.
79 changes: 65 additions & 14 deletions app/Http/Livewire/RequestAStandForm.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,18 @@
namespace App\Http\Livewire;

use App\Filament\Helpers\DisplaysStandStatus;
use App\Filament\Helpers\SelectOptions;
use App\Models\Aircraft\Aircraft;
use App\Models\Airfield\Airfield;
use App\Models\Stand\Stand;
use App\Models\Stand\StandRequest;
use App\Models\Stand\StandRequestHistory;
use App\Models\Vatsim\NetworkAircraft;
use Carbon\Carbon;
use Filament\Forms\Components\DateTimePicker;
use Closure;
use Exception;
use Filament\Forms\Components\Placeholder;
use Filament\Forms\Components\Select;
use Filament\Forms\Components\TextInput;
use Filament\Forms\Components\View;
use Filament\Forms\Concerns\InteractsWithForms;
use Filament\Forms\Contracts\HasForms;
Expand All @@ -34,7 +35,7 @@ class RequestAStandForm extends Component implements HasForms

protected $messages = [
'requestedStand' => 'You must select a valid stand.',
'requestedTime' => 'You must select a valid time.',
'requestedTime' => 'Please enter a valid time.',
];

public function mount(): void
Expand All @@ -55,13 +56,17 @@ public function mount(): void
->notClosed()
->sizeAppropriate($this->userAircraftType)
->get()
->mapWithKeys(fn (Stand $stand): array => [$stand->id => $stand->airfieldIdentifier])
->mapWithKeys(fn(Stand $stand): array => [$stand->id => $stand->airfieldIdentifier])
->toArray()
: [];
}

public function getFormSchema(): array
{
$requestedTime = $this->requestedTimeValid()
? $this->getRequestedTime()
: $this->getMinimumRequestableTime();

return [
Placeholder::make('')
->content($this->getFirstPlaceholderText()),
Expand All @@ -81,7 +86,7 @@ public function getFormSchema(): array
->searchable()
->required(),
View::make('livewire.stand-status')
->hidden(fn () => $this->requestedStand === null)
->hidden(fn() => $this->requestedStand === null)
->viewData(
[
'standStatus' => $this->requestedStand ? $this->getStandStatus(
Expand All @@ -90,19 +95,31 @@ public function getFormSchema(): array
) : null,
]
),
DateTimePicker::make('requestedTime')
TextInput::make('requestedTime')
->label('Arrival time (Zulu)')
->maxWidth('sm')
->withoutSeconds()
->minDate(Carbon::now())
->maxDate(Carbon::now()->addHours(12))
->placeholder(Carbon::now()->addMinutes(5)->toDateTimeString('minute'))
->helperText('Can be up to 12 hours in advance.')
->numeric()
->rule(fn () => function (string $attribute, $value, Closure $fail) {
if (empty($value)) {
return;
}

// If the time is not valid, fail.
if (!$this->requestedTimeValid()) {
$fail('');
}
})
->placeholder($this->getMinimumRequestableTime()->format('Hi'))
->helperText(sprintf(
'Stands may be requested up to 12 hours in advance. Please enter a time between %s and %s.',
$this->getMinimumRequestableTime()->format('Hi'),
$this->getMaximumRequestableTime()->format('Hi')
))
->reactive()
->required(),
View::make('livewire.stand-booking-applicability')
->hidden(fn () => $this->requestedTime === null)
->viewData($this->getRequestTimeViewData(Carbon::parse($this->requestedTime))),
->hidden(!$this->requestedTimeValid())
->viewData($this->getRequestTimeViewData($requestedTime)),
];
}

Expand All @@ -114,7 +131,7 @@ public function submit(): void
$userAircraft = $this->getUserAircraft();
$requestData = [
'stand_id' => $this->requestedStand,
'requested_time' => $this->requestedTime,
'requested_time' => $this->getRequestedTime(),
'user_id' => $userAircraft->cid,
'callsign' => $userAircraft->callsign,
];
Expand Down Expand Up @@ -153,4 +170,38 @@ private function getSecondPlaceholderText(): string
return 'Disconnecting from the VATSIM network for an extended period of time will cause your stand request to be
automatically relinquished.';
}

private function getRequestedTime(): Carbon
{
$selectedTime = Carbon::parse($this->requestedTime)
->startOfMinute();

return $selectedTime->lt($this->getMinimumRequestableTime()) ? $selectedTime->addDay() : $selectedTime;
}

private function requestedTimeValid(): bool
{
if (!$this->requestedTime) {
return false;
}

try {
Carbon::parse($this->requestedTime);
} catch (Exception) {
return false;
}

return $this->getRequestedTime()->gte($this->getMinimumRequestableTime()) &&
$this->getRequestedTime()->lte($this->getMaximumRequestableTime());
}

private function getMinimumRequestableTime(): Carbon
{
return Carbon::now()->startOfMinute();
}

private function getMaximumRequestableTime(): Carbon
{
return Carbon::now()->addHours(12)->startOfMinute();
}
}
71 changes: 63 additions & 8 deletions tests/app/Http/Livewire/RequestAStandFormTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -88,19 +88,28 @@ public function testItDisplaysAValidationErrorIfNoTimeRequested()
->assertHasErrors('requestedTime');
}

public function testItDisplaysAValidationErrorIfNonNumericTimeEntered()
{
Livewire::test(RequestAStandForm::class)
->set('requestedTime', 'abc')
->call('submit')
->assertHasErrors('requestedTime')
->assertOk();
}

public function testItDisplaysAValidationErrorIfTimeBeforeNow()
{
Livewire::test(RequestAStandForm::class)
->set('requestedTime', Carbon::now()->subMinute()->toDateTimeString())
->set('requestedTime', Carbon::now()->subMinute()->format('Hi'))
->call('submit')
->assertHasErrors('requestedTime')
->assertOk();
}

public function testItDisplaysAValidationErrorIfTimeAfter24Hours()
public function testItDisplaysAValidationErrorIfTimeGreaterThan12HoursInAdvance()
{
Livewire::test(RequestAStandForm::class)
->set('requestedTime', Carbon::now()->addDay()->addMinute()->toDateTimeString())
->set('requestedTime', Carbon::now()->addHours(12)->addMinute()->format('Hi'))
->call('submit')
->assertHasErrors('requestedTime')
->assertOk();
Expand All @@ -109,7 +118,7 @@ public function testItDisplaysAValidationErrorIfTimeAfter24Hours()
public function testItDisplaysTheRequestTimeInformation()
{
Livewire::test(RequestAStandForm::class)
->set('requestedTime', Carbon::now())
->set('requestedTime', Carbon::now()->format('Hi'))
->assertOk()
->assertSeeHtml(
[
Expand All @@ -119,11 +128,22 @@ public function testItDisplaysTheRequestTimeInformation()
);
}

public function testItDisplaysValidTimeInformation()
{
Livewire::test(RequestAStandForm::class)
->assertOk()
->assertSeeHtml(
[
'Stands may be requested up to 12 hours in advance. Please enter a time between 1540 and 0340.',
]
);
}

public function testItRequestsAStand()
{
Livewire::test(RequestAStandForm::class)
->set('requestedStand', 1)
->set('requestedTime', Carbon::now()->addMinute()->startOfMinute())
->set('requestedTime', '1541')
->call('submit')
->assertHasNoErrors()
->assertOk();
Expand All @@ -137,22 +157,57 @@ public function testItRequestsAStand()
$this->assertEquals('BAW123', $request->callsign);
$this->assertEquals(self::ACTIVE_USER_CID, $request->user_id);
$this->assertEquals(1, $request->stand_id);
$this->assertEquals(Carbon::now()->addMinute()->startOfMinute(), $request->requested_time);
$this->assertEquals(Carbon::now()->setMinutes(41)->startOfMinute(), $request->requested_time);
$this->assertNull($request->deleted_at);

$this->assertEquals($request->id, $history->id);
$this->assertEquals('BAW123', $history->callsign);
$this->assertEquals(self::ACTIVE_USER_CID, $history->user_id);
$this->assertEquals(1, $history->stand_id);
$this->assertEquals(Carbon::now()->addMinute()->startOfMinute(), $history->requested_time);
$this->assertEquals(Carbon::now()->setMinutes(41)->startOfMinute(), $history->requested_time);
$this->assertNull($history->deleted_at);
}

public function testItRequestsAStandTomorrow()
{
Livewire::test(RequestAStandForm::class)
->set('requestedStand', 1)
->set('requestedTime', '0240')
->call('submit')
->assertHasNoErrors()
->assertOk();

$this->assertDatabaseCount('stand_requests', 1);
$this->assertDatabaseCount('stand_request_history', 1);

$request = StandRequest::latest()->firstOrFail();
$history = StandRequestHistory::latest()->firstOrFail();

$this->assertEquals('BAW123', $request->callsign);
$this->assertEquals(self::ACTIVE_USER_CID, $request->user_id);
$this->assertEquals(1, $request->stand_id);
$this->assertEquals(
Carbon::now()->addDay()->setHour(2)->setMinutes(40)->startOfMinute(),
$request->requested_time
);
$this->assertNull($request->deleted_at);

$this->assertEquals($request->id, $history->id);
$this->assertEquals('BAW123', $history->callsign);
$this->assertEquals(self::ACTIVE_USER_CID, $history->user_id);
$this->assertEquals(1, $history->stand_id);
$this->assertEquals(
Carbon::now()->addDay()->setHour(2)->setMinutes(40)->startOfMinute(),
$history->requested_time
);
$this->assertNull($history->deleted_at);
}

public function testItEmitsAnUpdateEvent()
{
Livewire::test(RequestAStandForm::class)
->set('requestedStand', 1)
->set('requestedTime', Carbon::now()->addMinute())
->set('requestedTime', '1940')
->call('submit')
->assertHasNoErrors()
->assertOk()
Expand Down

0 comments on commit 95611b0

Please sign in to comment.