<?php declare(strict_types=1); namespace Engelsystem\Test\Unit\Controllers; use Engelsystem\Controllers\NotificationType; use Engelsystem\Controllers\ShiftsController; use Engelsystem\Helpers\Authenticator; use Engelsystem\Helpers\Carbon; use Engelsystem\Http\Redirector; use Engelsystem\Http\UrlGeneratorInterface; use Engelsystem\Models\AngelType; use Engelsystem\Models\Shifts\NeededAngelType; use Engelsystem\Models\Shifts\Shift; use Engelsystem\Models\Shifts\ShiftEntry; use Engelsystem\Models\User\User; use Illuminate\Support\Str; use PHPUnit\Framework\MockObject\MockObject; class ShiftsControllerTest extends ControllerTest { protected Authenticator|MockObject $auth; protected Redirector|MockObject $redirect; protected UrlGeneratorInterface $url; protected User $user; /** * @covers \Engelsystem\Controllers\ShiftsController::random * @covers \Engelsystem\Controllers\ShiftsController::__construct */ public function testRandomNonShiftsFound(): void { $this->createModels(); $this->setExpects($this->redirect, 'to', ['http://localhost/shifts'], $this->response); $this->setExpects($this->auth, 'user', null, $this->user); $controller = new ShiftsController($this->auth, $this->redirect, $this->url); $return = $controller->random(); $this->assertEquals($this->response, $return); $this->assertHasNotification('notification.shift.no_next_found', NotificationType::WARNING); } /** * @covers \Engelsystem\Controllers\ShiftsController::random * @covers \Engelsystem\Controllers\ShiftsController::getNextFreeShifts * @covers \Engelsystem\Controllers\ShiftsController::queryShiftEntries */ public function testRandom(): void { $this->createModels(); $this->setExpects($this->auth, 'user', null, $this->user, $this->atLeastOnce()); $start = Carbon::now()->addHour(); $otherUser = User::factory()->create(); [$userAngelType, $otherAngelType] = AngelType::factory(2)->create(); [$possibleShift1, $possibleShift2, $otherAngelTypeShift, $alreadySubscribedShift] = Shift::factory(4) ->create(['start' => $start, 'end' => $start->addHours(2)]); $this->user->userAngelTypes()->attach($userAngelType, ['confirm_user_id' => $this->user->id]); NeededAngelType::factory()->create([ 'shift_id' => $possibleShift1->id, 'angel_type_id' => $userAngelType->id, 'count' => 2, ]); NeededAngelType::factory()->create([ 'shift_id' => $possibleShift2->id, 'angel_type_id' => $userAngelType->id, 'count' => 1, ]); NeededAngelType::factory()->create([ 'shift_id' => $otherAngelTypeShift->id, 'angel_type_id' => $otherAngelType->id, 'count' => 3, ]); ShiftEntry::factory()->create([ 'shift_id' => $alreadySubscribedShift->id, 'angel_type_id' => $userAngelType->id, 'user_id' => $this->user->id, ]); $otherUser->userAngelTypes()->attach($userAngelType, ['confirm_user_id' => $otherUser->id]); ShiftEntry::factory()->create([ 'shift_id' => $possibleShift1->id, 'angel_type_id' => $userAngelType->id, 'user_id' => $otherUser, ]); $this->redirect->expects($this->exactly(10)) ->method('to') ->willReturnCallback(function (string $url) use ($possibleShift1, $possibleShift2) { parse_str(parse_url($url)['query'] ?? '', $parameters); $this->assertTrue(Str::startsWith($url, 'http://localhost/shifts')); $this->assertArrayHasKey('shift_id', $parameters); $shiftId = $parameters['shift_id'] ?? 0; $this->assertTrue(in_array($shiftId, [$possibleShift1->id, $possibleShift2->id])); return $this->response; }); $controller = new ShiftsController($this->auth, $this->redirect, $this->url); $return = $controller->random(); $this->assertEquals($this->response, $return); // Try multiple times for ($i = 1; $i < 10; $i++) { $controller->random(); } } protected function createModels(): void { $this->user = User::factory()->create(); $this->auth = $this->createMock(Authenticator::class); $this->redirect = $this->createMock(Redirector::class); $this->url = $this->app->make(UrlGeneratorInterface::class); } }