aboutsummaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorJan-Hendrik Willms <tleilax+studip@gmail.com>2022-06-17 07:39:22 +0000
committerDavid Siegfried <david.siegfried@uni-vechta.de>2022-06-17 07:39:22 +0000
commitbb62df65ac6aa71a757b58a01f9cb95a859a38f9 (patch)
treeb59576cb558380c7d09847862e796a2fde670fc2 /tests
parentad8f5f3b12e4f12bd77f6e2b0f0c3e36c47c5694 (diff)
implement tests for consultation jsonapi routes
Closes #1174 Merge request studip/studip!696
Diffstat (limited to 'tests')
-rw-r--r--tests/jsonapi/ConsultationHelper.php184
-rw-r--r--tests/jsonapi/ConsultationsBlockShowTest.php43
-rw-r--r--tests/jsonapi/ConsultationsBlocksByRangeIndexTest.php40
-rw-r--r--tests/jsonapi/ConsultationsBookingCreateBySlotIndexTest.php101
-rw-r--r--tests/jsonapi/ConsultationsBookingCreateTest.php108
-rw-r--r--tests/jsonapi/ConsultationsBookingDeleteTest.php66
-rw-r--r--tests/jsonapi/ConsultationsBookingShowTest.php41
-rw-r--r--tests/jsonapi/ConsultationsBookingsBySlotIndexTest.php34
-rw-r--r--tests/jsonapi/ConsultationsSlotShowTest.php45
-rw-r--r--tests/jsonapi/ConsultationsSlotsByBlockIndexTest.php28
10 files changed, 690 insertions, 0 deletions
diff --git a/tests/jsonapi/ConsultationHelper.php b/tests/jsonapi/ConsultationHelper.php
new file mode 100644
index 0000000..f7992e7
--- /dev/null
+++ b/tests/jsonapi/ConsultationHelper.php
@@ -0,0 +1,184 @@
+<?php
+use WoohooLabs\Yang\JsonApi\Response\JsonApiResponse;
+use WoohooLabs\Yang\JsonApi\Schema\Document;
+use WoohooLabs\Yang\JsonApi\Schema\Resource\ResourceObject;
+
+// Required for consultation mailer
+require_once 'vendor/flexi/flexi.php';
+
+trait ConsultationHelper
+{
+ /**
+ * @var \UnitTester
+ */
+ protected $tester;
+
+ protected function _before()
+ {
+ \DBManager::getInstance()->setConnection('studip', $this->getModule('\\Helper\\StudipDb')->dbh);
+ }
+
+ protected static $BLOCK_DATA = [
+ 'room' => 'Testraum',
+ 'calendar_events' => false,
+ 'show_participants' => false,
+ 'require_reason' => 'no',
+ 'confirmation_text' => null,
+ 'note' => 'Testnotiz für Block',
+ 'size' => 1,
+ ];
+
+ protected static $SLOT_DATA = [
+ 'note' => 'Testnotiz für Slot',
+ ];
+
+ protected static $BOOKING_DATA = [
+ 'reason' => 'Test reason',
+ ];
+
+ protected function getUserForCredentials(array $credentials): User
+ {
+ return User::find($credentials['id']);
+ }
+
+ protected function createBlockWithSlotsForRange(Range $range): ConsultationBlock
+ {
+ $blocks = ConsultationBlock::generateBlocks(
+ $range,
+ strtotime('today 8:00'),
+ strtotime('today 10:00'),
+ date('w'),
+ 1
+ );
+ $blocks = iterator_to_array($blocks);
+
+ $block = reset($blocks);
+ $block->setData(self::$BLOCK_DATA);
+
+ $block->createSlots(15);
+ foreach ($block->slots as $slot) {
+ $slot->setData(self::$SLOT_DATA['note']);
+ }
+
+ $block->store();
+
+ return ConsultationBlock::find($block->id);
+ }
+
+ protected function getSlotFromBlock(ConsultationBlock $block): ConsultationSlot
+ {
+ return $block->slots->first();
+ }
+
+ protected function withStudipEnv(array $credentials, callable $fn)
+ {
+ // Create global template factory if neccessary
+ $has_template_factory = isset($GLOBALS['template_factory']);
+ if (!$has_template_factory) {
+ $GLOBALS['template_factory'] = new Flexi_TemplateFactory($GLOBALS['STUDIP_BASE_PATH'] . '/templates');
+ }
+
+ $result = $this->tester->withPHPLib($credentials, $fn);
+
+ if (!$has_template_factory) {
+ unset($GLOBALS['template_factory']);
+ }
+
+ return $result;
+ }
+
+ protected function createBookingForSlot(array $credentials, ConsultationSlot $slot, User $user): ConsultationBooking
+ {
+ return $this->withStudipEnv(
+ $credentials,
+ function () use ($slot, $user): ConsultationBooking {
+ $booking = new ConsultationBooking();
+ $booking->slot_id = $slot->id;
+ $booking->user_id = $user->id;
+
+ $booking->setData(self::$BOOKING_DATA);
+
+ $booking->store();
+
+ return $booking;
+ }
+ );
+ }
+
+ protected function sendMockRequest(string $route, string $handler, array $credentials, array $variables = [], array $options = []): JsonApiResponse
+ {
+ $options = array_merge([
+ 'method' => 'GET',
+ 'considered_successful' => [200],
+ 'json_body' => null,
+ ], $options);
+
+ $app = $this->tester->createApp(
+ $credentials,
+ strtolower($options['method']),
+ $route,
+ $handler
+ );
+
+ $evaluated_route = preg_replace_callback(
+ '/\{(.+?)(:[^}]+)?}/',
+ function ($match) use ($variables) {
+ $key = $match[1];
+ if (!isset($variables[$key])) {
+ throw new Exception("No variable '{$key}' defined");
+ }
+ return $variables[$key];
+ },
+ $route
+ );
+
+ $requestBuilder = $this->tester->createRequestBuilder($credentials);
+ $requestBuilder->setUri($evaluated_route)->setMethod(strtoupper($options['method']));
+
+ if (isset($options['json_body'])) {
+ $requestBuilder->setJsonApiBody($options['json_body']);
+
+ }
+
+ /** @var JsonApiResponse $response */
+ $response = $this->withStudipEnv($credentials, function () use ($app, $requestBuilder) {
+ return $this->tester->sendMockRequest($app, $requestBuilder->getRequest());
+ });
+
+ if ($options['considered_successful']) {
+ $this->assertTrue(
+ $response->isSuccessful($options['considered_successful']),
+ 'Actual status code is ' . $response->getStatusCode()
+ );
+ }
+
+ return $response;
+ }
+
+ protected function getSingleResourceDocument(JsonApiResponse $response): Document
+ {
+ $this->assertTrue($response->hasDocument());
+
+ $document = $response->document();
+ $this->assertTrue($document->isSingleResourceDocument());
+
+ return $document;
+ }
+
+ protected function getResourceCollectionDocument(JsonApiResponse $response): Document
+ {
+ $this->assertTrue($response->hasDocument());
+
+ $document = $response->document();
+ $this->assertTrue($document->isResourceCollectionDocument());
+
+ return $document;
+ }
+
+ protected function assertHasRelations(ResourceObject $resource, ...$relations)
+ {
+ foreach ($relations as $relation) {
+ $this->assertTrue($resource->hasRelationship($relation));
+ }
+ }
+}
diff --git a/tests/jsonapi/ConsultationsBlockShowTest.php b/tests/jsonapi/ConsultationsBlockShowTest.php
new file mode 100644
index 0000000..62c7ed7
--- /dev/null
+++ b/tests/jsonapi/ConsultationsBlockShowTest.php
@@ -0,0 +1,43 @@
+<?php
+use JsonApi\Routes\Consultations\BlockShow;
+use JsonApi\Schemas\ConsultationBlock as Schema;
+
+require_once __DIR__ . '/ConsultationHelper.php';
+
+class ConsultationsBlockShowTest extends Codeception\Test\Unit
+{
+ use ConsultationHelper;
+
+ public function testFetchBlock(): void
+ {
+ $credentials = $this->tester->getCredentialsForTestDozent();
+ $range = User::find($credentials['id']);
+
+ $block = $this->createBlockWithSlotsForRange($range);
+
+ $response = $this->sendMockRequest(
+ '/consultation-blocks/{id}',
+ BlockShow::class,
+ $credentials,
+ ['id' => $block->id]
+ );
+ $document = $this->getSingleResourceDocument($response);
+
+ $resourceObject = $document->primaryResource();
+ $this->assertTrue(is_string($resourceObject->id()));
+ $this->assertSame($block->id, $resourceObject->id());
+ $this->assertSame(Schema::TYPE, $resourceObject->type());
+
+ $this->assertEquals($block->start, strtotime($resourceObject->attribute('start')));
+ $this->assertEquals($block->end, strtotime($resourceObject->attribute('end')));
+
+ $this->assertSame(self::$BLOCK_DATA['room'], $resourceObject->attribute('room'));
+ $this->assertSame(self::$BLOCK_DATA['show_participants'], $resourceObject->attribute('show-participants'));
+ $this->assertSame(self::$BLOCK_DATA['require_reason'], $resourceObject->attribute('require-reason'));
+ $this->assertSame(self::$BLOCK_DATA['confirmation_text'], $resourceObject->attribute('confirmation-text'));
+ $this->assertSame(self::$BLOCK_DATA['note'], $resourceObject->attribute('note'));
+ $this->assertSame(self::$BLOCK_DATA['size'], $resourceObject->attribute('size'));
+
+ $this->assertHasRelations($resourceObject, Schema::REL_RANGE, Schema::REL_SLOTS);
+ }
+}
diff --git a/tests/jsonapi/ConsultationsBlocksByRangeIndexTest.php b/tests/jsonapi/ConsultationsBlocksByRangeIndexTest.php
new file mode 100644
index 0000000..89300b5
--- /dev/null
+++ b/tests/jsonapi/ConsultationsBlocksByRangeIndexTest.php
@@ -0,0 +1,40 @@
+<?php
+use JsonApi\Routes\Consultations\BlocksByRangeIndex;
+
+require_once __DIR__ . '/ConsultationHelper.php';
+
+// TODO: Activate consultations on institute for testing
+class ConsultationsBlocksByRangeIndexTest extends Codeception\Test\Unit
+{
+ use ConsultationHelper;
+
+ public static function rangeProvider(): array
+ {
+ return [
+ 'Course' => ['course', 'a07535cf2f8a72df33c12ddfa4b53dde'],
+ 'User' => ['user', '205f3efb7997a0fc9755da2b535038da'],
+ ];
+ }
+
+ /**
+ * @dataProvider rangeProvider
+ */
+ public function testFetchBlocksByRangeIndex(string $range_type, string $range_id): void
+ {
+ $credentials = $this->tester->getCredentialsForTestDozent();
+ $range = RangeFactory::createRange($range_type, $range_id);
+
+ $this->createBlockWithSlotsForRange($range);
+
+ $response = $this->sendMockRequest(
+ "/{type:courses|institutes|users}/{id}/consultations",
+ BlocksByRangeIndex::class,
+ $credentials,
+ ['type' => "{$range_type}s", 'id' => $range_id]
+ );
+ $document = $this->getResourceCollectionDocument($response);
+
+ $resources = $document->primaryResources();
+ $this->tester->assertCount(1, $resources);
+ }
+}
diff --git a/tests/jsonapi/ConsultationsBookingCreateBySlotIndexTest.php b/tests/jsonapi/ConsultationsBookingCreateBySlotIndexTest.php
new file mode 100644
index 0000000..058e5dd
--- /dev/null
+++ b/tests/jsonapi/ConsultationsBookingCreateBySlotIndexTest.php
@@ -0,0 +1,101 @@
+<?php
+use JsonApi\Routes\Consultations\BookingsCreate;
+use JsonApi\Schemas\ConsultationBooking as Schema;
+use JsonAPi\Schemas\User as UserSchema;
+use WoohooLabs\Yang\JsonApi\Response\JsonApiResponse;
+
+require_once __DIR__ . '/ConsultationHelper.php';
+
+class ConsultationsBookingCreateBySlotIndexTest extends Codeception\Test\Unit
+{
+ use ConsultationHelper;
+
+ public function testAutorMayCreateBooking(): void
+ {
+ $credentials = $this->tester->getCredentialsForTestDozent();
+ $range = User::find($credentials['id']);
+
+ $block = $this->createBlockWithSlotsForRange($range);
+ $slot = $this->getSlotFromBlock($block);
+
+ $this->createBooking(
+ $credentials,
+ $slot,
+ $this->tester->getCredentialsForTestAutor()['id'],
+ [201]
+ );
+ }
+
+ public function testSlotIsOccupied(): void
+ {
+ $credentials = $this->tester->getCredentialsForTestDozent();
+ $range = User::find($credentials['id']);
+
+ $block = $this->createBlockWithSlotsForRange($range);
+ $slot = $this->getSlotFromBlock($block);
+
+ $this->createBooking(
+ $credentials,
+ $slot,
+ $this->tester->getCredentialsForTestAutor()['id'],
+ [201]
+ );
+
+ $response = $this->createBooking(
+ $credentials,
+ $slot,
+ $this->tester->getCredentialsForTestAutor()['id'],
+ null
+ );
+
+ $this->assertEquals(409, $response->getStatusCode());
+ }
+
+ public function testRootMayNotCreateBooking(): void
+ {
+ $credentials = $this->tester->getCredentialsForTestDozent();
+ $range = User::find($credentials['id']);
+
+ $block = $this->createBlockWithSlotsForRange($range);
+ $slot = $this->getSlotFromBlock($block);
+
+ $response = $this->createBooking(
+ $credentials,
+ $slot,
+ $this->tester->getCredentialsForRoot()['id'],
+ null
+ );
+
+ $this->assertEquals(403, $response->getStatusCode());
+ }
+
+ private function createBooking(array $credentials, ConsultationSlot $slot, string $user_id, ?array $considered_succssfull): JsonApiResponse
+ {
+ return $this->sendMockRequest(
+ '/consultation-slots/{id}/bookings',
+ BookingsCreate::class,
+ $credentials,
+ ['id' => $slot->id],
+ [
+ 'considered_successful' => $considered_succssfull,
+ 'method' => 'POST',
+ 'json_body' => [
+ 'data' => [
+ 'type' => Schema::TYPE,
+ 'attributes' => [
+ 'reason' => self::$BOOKING_DATA['reason'],
+ ],
+ 'relationships' => [
+ Schema::REL_USER => [
+ 'data' => [
+ 'type' => UserSchema::TYPE,
+ 'id' => $user_id,
+ ],
+ ]
+ ]
+ ]
+ ]
+ ]
+ );
+ }
+}
diff --git a/tests/jsonapi/ConsultationsBookingCreateTest.php b/tests/jsonapi/ConsultationsBookingCreateTest.php
new file mode 100644
index 0000000..493bf97
--- /dev/null
+++ b/tests/jsonapi/ConsultationsBookingCreateTest.php
@@ -0,0 +1,108 @@
+<?php
+use JsonApi\Routes\Consultations\BookingsCreate;
+use JsonApi\Schemas\ConsultationBooking as Schema;
+use JsonAPi\Schemas\User as UserSchema;
+use JsonAPi\Schemas\ConsultationSlot as SlotSchema;
+use WoohooLabs\Yang\JsonApi\Response\JsonApiResponse;
+
+require_once __DIR__ . '/ConsultationHelper.php';
+
+class ConsultationsBookingCreateTest extends Codeception\Test\Unit
+{
+ use ConsultationHelper;
+
+ public function testAutorMayCreateBooking(): void
+ {
+ $credentials = $this->tester->getCredentialsForTestDozent();
+ $range = User::find($credentials['id']);
+
+ $block = $this->createBlockWithSlotsForRange($range);
+ $slot = $this->getSlotFromBlock($block);
+
+ $this->createBooking(
+ $credentials,
+ $slot,
+ $this->tester->getCredentialsForTestAutor()['id'],
+ [201]
+ );
+ }
+
+ public function testSlotIsOccupied(): void
+ {
+ $credentials = $this->tester->getCredentialsForTestDozent();
+ $range = User::find($credentials['id']);
+
+ $block = $this->createBlockWithSlotsForRange($range);
+ $slot = $this->getSlotFromBlock($block);
+
+ $this->createBooking(
+ $credentials,
+ $slot,
+ $this->tester->getCredentialsForTestAutor()['id'],
+ [201]
+ );
+
+ $response = $this->createBooking(
+ $credentials,
+ $slot,
+ $this->tester->getCredentialsForTestAutor()['id'],
+ null
+ );
+
+ $this->assertEquals(409, $response->getStatusCode());
+ }
+
+ public function testRootMayNotCreateBooking(): void
+ {
+ $credentials = $this->tester->getCredentialsForTestDozent();
+ $range = User::find($credentials['id']);
+
+ $block = $this->createBlockWithSlotsForRange($range);
+ $slot = $this->getSlotFromBlock($block);
+
+ $response = $this->createBooking(
+ $credentials,
+ $slot,
+ $this->tester->getCredentialsForRoot()['id'],
+ null
+ );
+
+ $this->assertEquals(403, $response->getStatusCode());
+ }
+
+ private function createBooking(array $credentials, ConsultationSlot $slot, string $user_id, ?array $considered_succssfull): JsonApiResponse
+ {
+ return $this->sendMockRequest(
+ '/consultation-bookings',
+ BookingsCreate::class,
+ $credentials,
+ [],
+ [
+ 'considered_successful' => $considered_succssfull,
+ 'method' => 'POST',
+ 'json_body' => [
+ 'data' => [
+ 'type' => Schema::TYPE,
+ 'attributes' => [
+ 'reason' => self::$BOOKING_DATA['reason'],
+ ],
+ 'relationships' => [
+ Schema::REL_SLOT => [
+ 'data' => [
+ 'type' => SlotSchema::TYPE,
+ 'id' => $slot->id,
+ ],
+ ],
+ Schema::REL_USER => [
+ 'data' => [
+ 'type' => UserSchema::TYPE,
+ 'id' => $user_id,
+ ],
+ ],
+ ]
+ ]
+ ]
+ ]
+ );
+ }
+}
diff --git a/tests/jsonapi/ConsultationsBookingDeleteTest.php b/tests/jsonapi/ConsultationsBookingDeleteTest.php
new file mode 100644
index 0000000..2e154de
--- /dev/null
+++ b/tests/jsonapi/ConsultationsBookingDeleteTest.php
@@ -0,0 +1,66 @@
+<?php
+use JsonApi\Routes\Consultations\BookingsDelete;
+
+require_once __DIR__ . '/ConsultationHelper.php';
+
+class ConsultationsBookingDeleteTest extends Codeception\Test\Unit
+{
+ use ConsultationHelper;
+
+ public function testDeleteBookingWithoutReason(): void
+ {
+ $credentials = $this->tester->getCredentialsForTestDozent();
+ $range = User::find($credentials['id']);
+
+ $block = $this->createBlockWithSlotsForRange($range);
+ $slot = $this->getSlotFromBlock($block);
+ $booking = $this->createBookingForSlot(
+ $credentials,
+ $slot,
+ $this->getUserForCredentials($this->tester->getCredentialsForTestAutor())
+ );
+
+ $this->sendMockRequest(
+ '/consultation-bookings/{id}',
+ BookingsDelete::class,
+ $credentials,
+ ['id' => $booking->id],
+ [
+ 'considered_successful' => [204],
+ 'method' => 'DELETE',
+ ]
+ );
+ }
+
+ public function testDeleteBookingWithReason(): void
+ {
+ $credentials = $this->tester->getCredentialsForTestDozent();
+ $range = User::find($credentials['id']);
+
+ $block = $this->createBlockWithSlotsForRange($range);
+ $slot = $this->getSlotFromBlock($block);
+ $booking = $this->createBookingForSlot(
+ $credentials,
+ $slot,
+ $this->getUserForCredentials($this->tester->getCredentialsForTestAutor())
+ );
+
+ $this->sendMockRequest(
+ '/consultation-bookings/{id}',
+ BookingsDelete::class,
+ $credentials,
+ ['id' => $booking->id],
+ [
+ 'considered_successful' => [204],
+ 'method' => 'DELETE',
+ 'json_body' => [
+ 'data' => [
+ 'attributes' => [
+ 'reason' => self::$BOOKING_DATA['reason'],
+ ]
+ ],
+ ],
+ ]
+ );
+ }
+}
diff --git a/tests/jsonapi/ConsultationsBookingShowTest.php b/tests/jsonapi/ConsultationsBookingShowTest.php
new file mode 100644
index 0000000..8788b77
--- /dev/null
+++ b/tests/jsonapi/ConsultationsBookingShowTest.php
@@ -0,0 +1,41 @@
+<?php
+use JsonApi\Routes\Consultations\BookingsShow;
+use JsonApi\Schemas\ConsultationBooking as Schema;
+
+require_once __DIR__ . '/ConsultationHelper.php';
+
+class ConsultationsBookingShowTest extends Codeception\Test\Unit
+{
+ use ConsultationHelper;
+
+ public function testFetchBlock(): void
+ {
+ $credentials = $this->tester->getCredentialsForTestDozent();
+ $range = User::find($credentials['id']);
+
+ $block = $this->createBlockWithSlotsForRange($range);
+ $slot = $this->getSlotFromBlock($block);
+ $booking = $this->createBookingForSlot(
+ $credentials,
+ $slot,
+ $this->getUserForCredentials($this->tester->getCredentialsForTestAutor())
+ );
+
+ $response = $this->sendMockRequest(
+ '/consultation-bookings/{id}',
+ BookingsShow::class,
+ $credentials,
+ ['id' => $booking->id]
+ );
+ $document = $this->getSingleResourceDocument($response);
+
+ $resourceObject = $document->primaryResource();
+ $this->assertTrue(is_string($resourceObject->id()));
+ $this->assertSame($booking->id, $resourceObject->id());
+ $this->assertSame(Schema::TYPE, $resourceObject->type());
+
+ $this->assertEquals(self::$BOOKING_DATA['reason'], $resourceObject->attribute('reason'));
+
+ $this->assertHasRelations($resourceObject, Schema::REL_SLOT, Schema::REL_USER);
+ }
+}
diff --git a/tests/jsonapi/ConsultationsBookingsBySlotIndexTest.php b/tests/jsonapi/ConsultationsBookingsBySlotIndexTest.php
new file mode 100644
index 0000000..e927aad
--- /dev/null
+++ b/tests/jsonapi/ConsultationsBookingsBySlotIndexTest.php
@@ -0,0 +1,34 @@
+<?php
+use JsonApi\Routes\Consultations\BookingsBySlotIndex;
+
+require_once __DIR__ . '/ConsultationHelper.php';
+
+class ConsultationsBookingsBySlotIndexTest extends Codeception\Test\Unit
+{
+ use ConsultationHelper;
+
+ public function testFetchSlots(): void
+ {
+ $credentials = $this->tester->getCredentialsForTestDozent();
+ $range = $this->getUserForCredentials($credentials);
+
+ $block = $this->createBlockWithSlotsForRange($range);
+ $slot = $this->getSlotFromBlock($block);
+ $this->createBookingForSlot(
+ $credentials,
+ $slot,
+ $this->getUserForCredentials($this->tester->getCredentialsForTestAutor())
+ );
+
+ $response = $this->sendMockRequest(
+ '/consultation-slots/{id}/bookings',
+ BookingsBySlotIndex::class,
+ $credentials,
+ ['id' => $slot->id]
+ );
+ $document = $this->getResourceCollectionDocument($response);
+
+ $resources = $document->primaryResources();
+ $this->tester->assertCount(1, $resources);
+ }
+}
diff --git a/tests/jsonapi/ConsultationsSlotShowTest.php b/tests/jsonapi/ConsultationsSlotShowTest.php
new file mode 100644
index 0000000..be8f5b7
--- /dev/null
+++ b/tests/jsonapi/ConsultationsSlotShowTest.php
@@ -0,0 +1,45 @@
+<?php
+use JsonApi\Routes\Consultations\SlotShow;
+use JsonApi\Schemas\ConsultationSlot as Schema;
+
+require_once __DIR__ . '/ConsultationHelper.php';
+
+class ConsultationsSlotShowTest extends Codeception\Test\Unit
+{
+ use ConsultationHelper;
+
+ public function testFetchBlock(): void
+ {
+ $credentials = $this->tester->getCredentialsForTestDozent();
+ $range = User::find($credentials['id']);
+
+ $block = $this->createBlockWithSlotsForRange($range);
+ $slot = $this->getSlotFromBlock($block);
+
+ $response = $this->sendMockRequest(
+ '/consultation-slots/{id}',
+ SlotShow::class,
+ $credentials,
+ ['id' => $slot->id]
+ );
+ $document = $this->getSingleResourceDocument($response);
+
+ $resourceObject = $document->primaryResource();
+ $this->assertTrue(is_string($resourceObject->id()));
+ $this->assertSame($slot->id, $resourceObject->id());
+ $this->assertSame(Schema::TYPE, $resourceObject->type());
+
+ $this->assertEquals($slot->start_time, strtotime($resourceObject->attribute('start_time')));
+ $this->assertEquals($slot->end_time, strtotime($resourceObject->attribute('end_time')));
+
+ $this->assertHasRelations($resourceObject, Schema::REL_BLOCK, Schema::REL_BOOKINGS);
+
+//
+// $this->assertSame(self::$BLOCK_DATA['room'], $resourceObject->attribute('room'));
+// $this->assertSame(self::$BLOCK_DATA['show_participants'], $resourceObject->attribute('show-participants'));
+// $this->assertSame(self::$BLOCK_DATA['require_reason'], $resourceObject->attribute('require-reason'));
+// $this->assertSame(self::$BLOCK_DATA['confirmation_text'], $resourceObject->attribute('confirmation-text'));
+// $this->assertSame(self::$BLOCK_DATA['note'], $resourceObject->attribute('note'));
+// $this->assertSame(self::$BLOCK_DATA['size'], $resourceObject->attribute('size'));
+ }
+}
diff --git a/tests/jsonapi/ConsultationsSlotsByBlockIndexTest.php b/tests/jsonapi/ConsultationsSlotsByBlockIndexTest.php
new file mode 100644
index 0000000..70bb6d9
--- /dev/null
+++ b/tests/jsonapi/ConsultationsSlotsByBlockIndexTest.php
@@ -0,0 +1,28 @@
+<?php
+use JsonApi\Routes\Consultations\SlotsByBlockIndex;
+
+require_once __DIR__ . '/ConsultationHelper.php';
+
+class ConsultationsSlotsByBlockIndexTest extends Codeception\Test\Unit
+{
+ use ConsultationHelper;
+
+ public function testFetchSlots(): void
+ {
+ $credentials = $this->tester->getCredentialsForTestDozent();
+ $range = User::find($credentials['id']);
+
+ $block = $this->createBlockWithSlotsForRange($range);
+
+ $response = $this->sendMockRequest(
+ '/consultation-blocks/{id}/slots',
+ SlotsByBlockIndex::class,
+ $credentials,
+ ['id' => $block->id]
+ );
+ $document = $this->getResourceCollectionDocument($response);
+
+ $resources = $document->primaryResources();
+ $this->tester->assertCount(8, $resources);
+ }
+}