2023-07-23 13:52:33 +02:00
|
|
|
<?php
|
|
|
|
|
|
|
|
declare(strict_types=1);
|
|
|
|
|
|
|
|
namespace Engelsystem\Test\Unit\Controllers\Api;
|
|
|
|
|
|
|
|
use Engelsystem\Controllers\Api\ShiftsController;
|
2023-12-14 18:45:49 +01:00
|
|
|
use Engelsystem\Helpers\Authenticator;
|
2023-07-31 20:49:17 +02:00
|
|
|
use Engelsystem\Helpers\Carbon;
|
2023-07-23 13:52:33 +02:00
|
|
|
use Engelsystem\Http\Request;
|
|
|
|
use Engelsystem\Http\Response;
|
2023-11-03 19:03:31 +01:00
|
|
|
use Engelsystem\Models\Location;
|
2023-07-29 21:37:46 +02:00
|
|
|
use Engelsystem\Models\Shifts\NeededAngelType;
|
2023-12-14 00:54:58 +01:00
|
|
|
use Engelsystem\Models\Shifts\Schedule;
|
|
|
|
use Engelsystem\Models\Shifts\ScheduleShift;
|
2023-07-23 13:52:33 +02:00
|
|
|
use Engelsystem\Models\Shifts\Shift;
|
|
|
|
use Engelsystem\Models\Shifts\ShiftEntry;
|
|
|
|
use Engelsystem\Models\User\Contact;
|
|
|
|
use Engelsystem\Models\User\PersonalData;
|
|
|
|
use Engelsystem\Models\User\User;
|
2023-12-14 18:45:49 +01:00
|
|
|
use Illuminate\Database\Eloquent\ModelNotFoundException;
|
2023-07-23 13:52:33 +02:00
|
|
|
|
|
|
|
class ShiftsControllerTest extends ApiBaseControllerTest
|
|
|
|
{
|
2023-12-14 00:54:58 +01:00
|
|
|
protected Location $location;
|
|
|
|
protected Shift $shiftA;
|
|
|
|
protected Shift $shiftB;
|
|
|
|
|
2023-07-23 13:52:33 +02:00
|
|
|
/**
|
2023-11-03 19:03:31 +01:00
|
|
|
* @covers \Engelsystem\Controllers\Api\ShiftsController::entriesByLocation
|
2023-12-14 00:54:58 +01:00
|
|
|
* @covers \Engelsystem\Controllers\Api\ShiftsController::shiftEntriesResponse
|
2023-11-15 02:29:58 +01:00
|
|
|
* @covers \Engelsystem\Controllers\Api\Resources\ShiftResource::toArray
|
|
|
|
* @covers \Engelsystem\Controllers\Api\Resources\ShiftTypeResource::toArray
|
|
|
|
* @covers \Engelsystem\Controllers\Api\Resources\ShiftWithEntriesResource::toArray
|
|
|
|
* @covers \Engelsystem\Controllers\Api\Resources\UserResource::toArray
|
|
|
|
* @covers \Engelsystem\Controllers\Api\Resources\AngelTypeResource::toArray
|
2023-07-29 21:37:46 +02:00
|
|
|
* @covers \Engelsystem\Controllers\Api\ShiftsController::getNeededAngelTypes
|
2023-07-23 13:52:33 +02:00
|
|
|
*/
|
2023-11-03 19:03:31 +01:00
|
|
|
public function testEntriesByLocation(): void
|
2023-07-23 13:52:33 +02:00
|
|
|
{
|
2023-12-14 00:54:58 +01:00
|
|
|
$request = new Request();
|
|
|
|
$request = $request->withAttribute('location_id', $this->location->id);
|
|
|
|
|
|
|
|
$controller = new ShiftsController(new Response());
|
|
|
|
|
|
|
|
$response = $controller->entriesByLocation($request);
|
|
|
|
$this->validateApiResponse('/locations/{id}/shifts', 'get', $response);
|
|
|
|
|
|
|
|
$this->assertEquals(['application/json'], $response->getHeader('content-type'));
|
|
|
|
$this->assertJson($response->getContent());
|
|
|
|
|
|
|
|
$data = json_decode($response->getContent(), true);
|
|
|
|
$this->assertArrayHasKey('data', $data);
|
|
|
|
$this->assertCount(2, $data['data']);
|
|
|
|
|
|
|
|
// First shift
|
|
|
|
$shiftAData = $data['data'][0];
|
|
|
|
$this->assertEquals($this->shiftA->title, $shiftAData['title'], 'Title is equal');
|
|
|
|
$this->assertEquals($this->location->id, $shiftAData['location']['id'], 'Same location');
|
|
|
|
$this->assertEquals($this->shiftA->shiftType->id, $shiftAData['shift_type']['id'], 'Shift type equals');
|
|
|
|
$this->assertCount(4, $shiftAData['entries']);
|
|
|
|
// Has users
|
|
|
|
$entriesA = collect($shiftAData['entries'])->sortBy('type.id');
|
|
|
|
$entry = $entriesA[0];
|
|
|
|
$this->assertCount(2, $entry['users']);
|
|
|
|
$this->assertEquals(2, $entry['needs']);
|
|
|
|
$user = $entry['users'][0];
|
|
|
|
$this->assertEquals('/users?action=view&user_id=' . $user['id'], $user['url']);
|
|
|
|
$this->assertCount(0, $entriesA[1]['users']);
|
|
|
|
$this->assertCount(1, $entriesA[2]['users']);
|
|
|
|
$this->assertCount(1, $entriesA[3]['users']);
|
|
|
|
|
|
|
|
// Second (empty) shift
|
|
|
|
$shiftBData = $data['data'][1];
|
|
|
|
$this->assertEquals($this->shiftB->title, $shiftBData['title'], 'Title is equal');
|
|
|
|
$this->assertEquals($this->location->id, $shiftBData['location']['id'], 'Same location');
|
|
|
|
$this->assertEquals($this->shiftB->shiftType->id, $shiftBData['shift_type']['id'], 'Shift type equals');
|
|
|
|
$this->assertCount(2, $shiftBData['entries']);
|
|
|
|
// No users
|
|
|
|
$entriesB = collect($shiftBData['entries'])->sortBy('type.id');
|
|
|
|
$this->assertCount(0, $entriesB[0]['users']);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @covers \Engelsystem\Controllers\Api\ShiftsController::entriesByAngeltype
|
|
|
|
*/
|
|
|
|
public function testEntriesByAngeltype(): void
|
|
|
|
{
|
|
|
|
/** @var ShiftEntry $firstEntry */
|
|
|
|
$firstEntry = $this->shiftA->shiftEntries->first();
|
|
|
|
|
|
|
|
$request = new Request();
|
|
|
|
$request = $request->withAttribute('angeltype_id', $firstEntry->angelType->id);
|
|
|
|
|
|
|
|
$controller = new ShiftsController(new Response());
|
|
|
|
|
|
|
|
$response = $controller->entriesByAngeltype($request);
|
|
|
|
$this->validateApiResponse('/angeltypes/{id}/shifts', 'get', $response);
|
|
|
|
|
|
|
|
$this->assertEquals(['application/json'], $response->getHeader('content-type'));
|
|
|
|
$this->assertJson($response->getContent());
|
|
|
|
|
|
|
|
$data = json_decode($response->getContent(), true);
|
|
|
|
$this->assertArrayHasKey('data', $data);
|
|
|
|
$this->assertCount(2, $data['data']);
|
|
|
|
|
|
|
|
$shift = $data['data'][0];
|
|
|
|
$this->assertTrue(count($shift['entries']) >= 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @covers \Engelsystem\Controllers\Api\ShiftsController::entriesByUser
|
|
|
|
*/
|
|
|
|
public function testEntriesByUser(): void
|
|
|
|
{
|
|
|
|
/** @var ShiftEntry $firstEntry */
|
|
|
|
$firstEntry = $this->shiftA->shiftEntries->first();
|
|
|
|
|
|
|
|
$request = new Request();
|
|
|
|
$request = $request->withAttribute('user_id', $firstEntry->user->id);
|
|
|
|
|
|
|
|
$controller = new ShiftsController(new Response());
|
|
|
|
|
|
|
|
$response = $controller->entriesByUser($request);
|
|
|
|
$this->validateApiResponse('/users/{id}/shifts', 'get', $response);
|
2023-07-23 13:52:33 +02:00
|
|
|
|
2023-12-14 00:54:58 +01:00
|
|
|
$this->assertEquals(['application/json'], $response->getHeader('content-type'));
|
|
|
|
$this->assertJson($response->getContent());
|
|
|
|
|
|
|
|
$data = json_decode($response->getContent(), true);
|
|
|
|
$this->assertArrayHasKey('data', $data);
|
|
|
|
$this->assertCount(1, $data['data']);
|
|
|
|
|
|
|
|
$shift = $data['data'][0];
|
|
|
|
$this->assertTrue(count($shift['entries']) >= 1);
|
|
|
|
}
|
|
|
|
|
2023-12-14 18:45:49 +01:00
|
|
|
/**
|
|
|
|
* @covers \Engelsystem\Controllers\Api\ShiftsController::entriesByUser
|
|
|
|
*/
|
|
|
|
public function testEntriesByUserSelf(): void
|
|
|
|
{
|
|
|
|
$user = User::query()->first();
|
|
|
|
|
|
|
|
$auth = $this->createMock(Authenticator::class);
|
|
|
|
$this->setExpects($auth, 'user', null, $user);
|
|
|
|
|
|
|
|
$request = new Request();
|
|
|
|
$request = $request->withAttribute('user_id', 'self');
|
|
|
|
|
|
|
|
$controller = new ShiftsController(new Response());
|
|
|
|
$controller->setAuth($auth);
|
|
|
|
|
|
|
|
$response = $controller->entriesByUser($request);
|
|
|
|
$this->validateApiResponse('/users/{id}/shifts', 'get', $response);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @covers \Engelsystem\Controllers\Api\ShiftsController::entriesByUser
|
|
|
|
*/
|
|
|
|
public function testEntriesByUserNotFound(): void
|
|
|
|
{
|
|
|
|
$request = new Request();
|
|
|
|
$request = $request->withAttribute('user_id', 42);
|
|
|
|
|
|
|
|
$controller = new ShiftsController(new Response());
|
|
|
|
|
|
|
|
$this->expectException(ModelNotFoundException::class);
|
|
|
|
$controller->entriesByUser($request);
|
|
|
|
}
|
|
|
|
|
2023-12-14 00:54:58 +01:00
|
|
|
public function setUp(): void
|
|
|
|
{
|
|
|
|
parent::setUp();
|
|
|
|
|
|
|
|
$this->location = Location::factory()->create();
|
|
|
|
$schedule = Schedule::factory()->create();
|
2023-07-23 13:52:33 +02:00
|
|
|
|
2023-07-29 21:37:46 +02:00
|
|
|
// Shifts
|
2023-12-14 00:54:58 +01:00
|
|
|
$this->shiftA = Shift::factory(1)
|
|
|
|
->create(['location_id' => $this->location->id, 'start' => Carbon::now()->subHour()])
|
2023-07-31 20:49:17 +02:00
|
|
|
->first();
|
2023-12-14 00:54:58 +01:00
|
|
|
$this->shiftB = Shift::factory(1)
|
|
|
|
->create(['location_id' => $this->location->id, 'start' => Carbon::now()->addHour()])
|
2023-07-31 20:49:17 +02:00
|
|
|
->first();
|
2023-12-14 00:54:58 +01:00
|
|
|
(new ScheduleShift(['shift_id' => $this->shiftB->id, 'schedule_id' => $schedule->id, 'guid' => 'a']))->save();
|
2023-07-29 21:37:46 +02:00
|
|
|
|
|
|
|
// "Empty" entry to be skipped
|
2023-12-14 00:54:58 +01:00
|
|
|
NeededAngelType::factory(1)->create(['location_id' => null, 'shift_id' => $this->shiftA->id, 'count' => 0]);
|
2023-07-29 21:37:46 +02:00
|
|
|
|
|
|
|
// Needed entry by shift
|
|
|
|
/** @var NeededAngelType $byShift */
|
|
|
|
$byShift = NeededAngelType::factory(2)
|
2023-12-14 00:54:58 +01:00
|
|
|
->create(['location_id' => null, 'shift_id' => $this->shiftA->id, 'count' => 2])
|
2023-07-29 21:37:46 +02:00
|
|
|
->first();
|
|
|
|
|
2023-11-03 19:03:31 +01:00
|
|
|
// Needed entry by location
|
|
|
|
/** @var NeededAngelType $byLocation */
|
|
|
|
$byLocation = NeededAngelType::factory(1)
|
2023-12-14 00:54:58 +01:00
|
|
|
->create(['location_id' => $this->location->id, 'shift_id' => null, 'count' => 3])
|
2023-07-29 21:37:46 +02:00
|
|
|
->first();
|
|
|
|
|
|
|
|
// Added by both
|
|
|
|
NeededAngelType::factory(1)
|
|
|
|
->create([
|
2023-12-14 00:54:58 +01:00
|
|
|
'location_id' => $this->location->id,
|
2023-11-03 19:03:31 +01:00
|
|
|
'shift_id' => null,
|
|
|
|
'angel_type_id' => $byShift->angel_type_id,
|
|
|
|
'count' => 3,
|
2023-07-29 21:37:46 +02:00
|
|
|
])
|
|
|
|
->first();
|
|
|
|
|
|
|
|
// By shift
|
2023-12-14 00:54:58 +01:00
|
|
|
ShiftEntry::factory(2)->create([
|
|
|
|
'shift_id' => $this->shiftA->id,
|
|
|
|
'angel_type_id' => $byShift->angel_type_id,
|
|
|
|
]);
|
2023-07-29 21:37:46 +02:00
|
|
|
|
2023-11-03 19:03:31 +01:00
|
|
|
// By location
|
2023-12-14 00:54:58 +01:00
|
|
|
ShiftEntry::factory(1)->create([
|
|
|
|
'shift_id' => $this->shiftA->id,
|
|
|
|
'angel_type_id' => $byLocation->angel_type_id,
|
|
|
|
]);
|
2023-07-29 21:37:46 +02:00
|
|
|
|
2023-11-03 19:03:31 +01:00
|
|
|
// Additional (not required by shift nor location)
|
2023-12-14 00:54:58 +01:00
|
|
|
ShiftEntry::factory(1)->create(['shift_id' => $this->shiftA->id]);
|
2023-07-23 13:52:33 +02:00
|
|
|
|
|
|
|
foreach (User::all() as $user) {
|
|
|
|
// Generate user data
|
|
|
|
/** @var User $user */
|
|
|
|
PersonalData::factory()->create(['user_id' => $user->id]);
|
|
|
|
Contact::factory()->create(['user_id' => $user->id]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|