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(3, $shiftBData['entries']); // No users $entriesB = collect($shiftBData['entries'])->sortBy('type.id'); $this->assertCount(0, $entriesB[0]['users']); } /** * @covers \Engelsystem\Controllers\Api\ShiftsController::entriesByAngeltype * @covers \Engelsystem\Controllers\Api\ShiftsController::getNeededAngelTypes */ public function testEntriesViaShiftType(): void { $this->schedule->needed_from_shift_type = true; $this->schedule->save(); /** @var ShiftEntry $firstEntry */ $firstEntry = $this->shiftB->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(5, $data['data']); $shift = $data['data'][0]; $this->assertTrue(count($shift['entries']) >= 1); } /** * @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); $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); } /** * @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); } public function setUp(): void { parent::setUp(); $this->location = Location::factory()->create(); $this->schedule = Schedule::factory()->create(); // Shifts $this->shiftA = Shift::factory(1) ->create(['location_id' => $this->location->id, 'start' => Carbon::now()->subHour()]) ->first(); $this->shiftB = Shift::factory(1) ->create(['location_id' => $this->location->id, 'start' => Carbon::now()->addHour()]) ->first(); (new ScheduleShift(['shift_id' => $this->shiftB->id, 'schedule_id' => $this->schedule->id, 'guid' => 'a'])) ->save(); // "Empty" entry to be skipped NeededAngelType::factory(1)->create(['location_id' => null, 'shift_id' => $this->shiftA->id, 'count' => 0]); // Needed entry by shift /** @var NeededAngelType $byShift */ $byShift = NeededAngelType::factory(2) ->create(['location_id' => null, 'shift_type_id' => null, 'shift_id' => $this->shiftA->id, 'count' => 2]) ->first(); // Needed entry by location /** @var NeededAngelType $byLocation */ $byLocation = NeededAngelType::factory(1) ->create(['location_id' => $this->location->id, 'shift_type_id' => null, 'shift_id' => null, 'count' => 3]) ->first(); // Needed entry by shift type $shiftType = $this->shiftB->shiftType; /** @var NeededAngelType $byShiftType */ $byShiftType = NeededAngelType::factory(2) ->create(['location_id' => null, 'shift_type_id' => $shiftType->id, 'count' => 3]) ->first(); ShiftEntry::factory(5)->create([ 'shift_id' => $this->shiftB->id, 'angel_type_id' => $byShiftType->angel_type_id, ]); // Added by both NeededAngelType::factory(1) ->create([ 'location_id' => $this->location->id, 'shift_type_id' => null, 'shift_id' => null, 'angel_type_id' => $byShift->angel_type_id, 'count' => 3, ]) ->first(); // By shift ShiftEntry::factory(2)->create([ 'shift_id' => $this->shiftA->id, 'angel_type_id' => $byShift->angel_type_id, ]); // By location ShiftEntry::factory(1)->create([ 'shift_id' => $this->shiftA->id, 'angel_type_id' => $byLocation->angel_type_id, ]); // Additional (not required by shift nor location) ShiftEntry::factory(1)->create(['shift_id' => $this->shiftA->id]); $this->schedule->shiftType()->associate($shiftType); 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]); } } }