API: Use resource classes to serialize models
This commit is contained in:
parent
5b237febf8
commit
8894f183f2
|
@ -4,6 +4,8 @@ declare(strict_types=1);
|
|||
|
||||
namespace Engelsystem\Controllers\Api;
|
||||
|
||||
use Engelsystem\Controllers\Api\Resources\AngelTypeResource;
|
||||
use Engelsystem\Controllers\Api\Resources\UserAngelTypeResource;
|
||||
use Engelsystem\Http\Request;
|
||||
use Engelsystem\Http\Response;
|
||||
use Engelsystem\Models\AngelType;
|
||||
|
@ -15,13 +17,9 @@ class AngelTypeController extends ApiController
|
|||
{
|
||||
$models = AngelType::query()
|
||||
->orderBy('name')
|
||||
->get(['id', 'name', 'description']);
|
||||
->get();
|
||||
|
||||
$models->map(function (AngelType $model): void {
|
||||
$model->url = $this->getUrl($model);
|
||||
});
|
||||
|
||||
$data = ['data' => $models];
|
||||
$data = ['data' => AngelTypeResource::collection($models)];
|
||||
return $this->response
|
||||
->withContent(json_encode($data));
|
||||
}
|
||||
|
@ -30,31 +28,9 @@ class AngelTypeController extends ApiController
|
|||
{
|
||||
$id = (int) $request->getAttribute('user_id');
|
||||
$model = User::findOrFail($id);
|
||||
$data = ['data' => UserAngelTypeResource::collection($model->userAngelTypes)];
|
||||
|
||||
$models = $model->userAngelTypes()->get([
|
||||
'angel_types.id',
|
||||
'angel_types.name',
|
||||
'angel_types.description',
|
||||
'angel_types.restricted',
|
||||
]);
|
||||
$data = [];
|
||||
|
||||
$models->map(function (AngelType $model) use (&$data): void {
|
||||
$model->confirmed = !$model->restricted || $model->pivot->supporter || $model->pivot->confirm_user_id;
|
||||
$model->supporter = $model->pivot->supporter;
|
||||
$model->url = $this->getUrl($model);
|
||||
$modelData = $model->attributesToArray();
|
||||
unset($modelData['restricted']);
|
||||
$data[] = $modelData;
|
||||
});
|
||||
|
||||
$data = ['data' => $data];
|
||||
return $this->response
|
||||
->withContent(json_encode($data));
|
||||
}
|
||||
|
||||
protected function getUrl(AngelType $model): string
|
||||
{
|
||||
return $this->url->to('/angeltypes', ['action' => 'view', 'angeltype_id' => $model->id]);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,7 +6,6 @@ namespace Engelsystem\Controllers\Api;
|
|||
|
||||
use Engelsystem\Controllers\BaseController;
|
||||
use Engelsystem\Http\Response;
|
||||
use Engelsystem\Http\UrlGeneratorInterface;
|
||||
|
||||
abstract class ApiController extends BaseController
|
||||
{
|
||||
|
@ -14,7 +13,7 @@ abstract class ApiController extends BaseController
|
|||
'api',
|
||||
];
|
||||
|
||||
public function __construct(protected Response $response, protected UrlGeneratorInterface $url)
|
||||
public function __construct(protected Response $response)
|
||||
{
|
||||
$this->response = $this->response
|
||||
->withHeader('content-type', 'application/json')
|
||||
|
|
|
@ -4,6 +4,7 @@ declare(strict_types=1);
|
|||
|
||||
namespace Engelsystem\Controllers\Api;
|
||||
|
||||
use Engelsystem\Controllers\Api\Resources\LocationResource;
|
||||
use Engelsystem\Http\Response;
|
||||
use Engelsystem\Models\Location;
|
||||
|
||||
|
@ -13,13 +14,9 @@ class LocationsController extends ApiController
|
|||
{
|
||||
$models = Location::query()
|
||||
->orderBy('name')
|
||||
->get(['id', 'name']);
|
||||
->get();
|
||||
|
||||
$models->map(function (Location $model): void {
|
||||
$model->url = $this->url->to('/locations', ['action' => 'view', 'location_id' => $model->id]);
|
||||
});
|
||||
|
||||
$data = ['data' => $models];
|
||||
$data = ['data' => LocationResource::collection($models)];
|
||||
return $this->response
|
||||
->withContent(json_encode($data));
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ declare(strict_types=1);
|
|||
|
||||
namespace Engelsystem\Controllers\Api;
|
||||
|
||||
use Engelsystem\Controllers\Api\Resources\NewsResource;
|
||||
use Engelsystem\Http\Response;
|
||||
use Engelsystem\Models\News;
|
||||
|
||||
|
@ -14,13 +15,9 @@ class NewsController extends ApiController
|
|||
$models = News::query()
|
||||
->orderByDesc('updated_at')
|
||||
->orderByDesc('created_at')
|
||||
->get(['id', 'title', 'text', 'is_meeting', 'is_pinned', 'is_highlighted', 'created_at', 'updated_at']);
|
||||
->get();
|
||||
|
||||
$models->map(function (News $model): void {
|
||||
$model->url = $this->url->to('/news/' . $model->id);
|
||||
});
|
||||
|
||||
$data = ['data' => $models];
|
||||
$data = ['data' => NewsResource::collection($models)];
|
||||
return $this->response
|
||||
->withContent(json_encode($data));
|
||||
}
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Engelsystem\Controllers\Api\Resources;
|
||||
|
||||
class AngelTypeResource extends BasicResource
|
||||
{
|
||||
public function toArray(): array
|
||||
{
|
||||
return [
|
||||
'id' => $this->model->id,
|
||||
'name' => $this->model->name,
|
||||
'description' => $this->model->description,
|
||||
'url' => url('/angeltypes', ['action' => 'view', 'angeltype_id' => $this->model->id]),
|
||||
];
|
||||
}
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Engelsystem\Controllers\Api\Resources;
|
||||
|
||||
use Engelsystem\Models\BaseModel;
|
||||
use Illuminate\Contracts\Support\Arrayable;
|
||||
use Illuminate\Contracts\Support\Jsonable;
|
||||
use Illuminate\Support\Collection;
|
||||
use Stringable;
|
||||
|
||||
/** @phpstan-consistent-constructor */
|
||||
abstract class BasicResource implements Arrayable, Jsonable, Stringable
|
||||
{
|
||||
public function __construct(protected BaseModel|Collection $model)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @param iterable|Collection|BaseModel[]|Collection[] $data
|
||||
*/
|
||||
public static function collection(iterable $data): Collection
|
||||
{
|
||||
$collection = new Collection();
|
||||
foreach ($data as $item) {
|
||||
$collection->add(new static($item));
|
||||
}
|
||||
return $collection;
|
||||
}
|
||||
|
||||
public function toArray(): array
|
||||
{
|
||||
return $this->model->toArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $options
|
||||
*/
|
||||
public function toJson($options = 0): string // phpcs:ignore
|
||||
{
|
||||
return json_encode($this->toArray(), $options);
|
||||
}
|
||||
|
||||
public function __toString(): string
|
||||
{
|
||||
return $this->toJson();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Engelsystem\Controllers\Api\Resources;
|
||||
|
||||
class LocationResource extends BasicResource
|
||||
{
|
||||
public function toArray(): array
|
||||
{
|
||||
return [
|
||||
'id' => $this->model->id,
|
||||
'name' => $this->model->name,
|
||||
'url' => url('/locations', ['action' => 'view', 'location_id' => $this->model->id]),
|
||||
];
|
||||
}
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Engelsystem\Controllers\Api\Resources;
|
||||
|
||||
class NewsResource extends BasicResource
|
||||
{
|
||||
public function toArray(): array
|
||||
{
|
||||
return [
|
||||
'id' => $this->model->id,
|
||||
'title' => $this->model->title,
|
||||
'text' => $this->model->text,
|
||||
'is_meeting' => $this->model->is_meeting,
|
||||
'is_pinned' => $this->model->is_pinned,
|
||||
'is_highlighted' => $this->model->is_highlighted,
|
||||
'created_at' => $this->model->created_at,
|
||||
'updated_at' => $this->model->updated_at,
|
||||
'url' => url('/news/' . $this->model->id),
|
||||
];
|
||||
}
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Engelsystem\Controllers\Api\Resources;
|
||||
|
||||
use Illuminate\Contracts\Support\Arrayable;
|
||||
|
||||
class ShiftResource extends BasicResource
|
||||
{
|
||||
public function toArray(array|Arrayable $location = []): array
|
||||
{
|
||||
return [
|
||||
'id' => $this->model->id,
|
||||
'title' => $this->model->title,
|
||||
'description' => $this->model->description,
|
||||
'starts_at' => $this->model->start,
|
||||
'ends_at' => $this->model->end,
|
||||
'location' => $location instanceof Arrayable ? $location->toArray() : $location,
|
||||
'shift_type' => (new ShiftTypeResource($this->model->shiftType))->toArray(),
|
||||
'created_at' => $this->model->created_at,
|
||||
'updated_at' => $this->model->updated_at,
|
||||
'url' => url('/shifts', ['action' => 'view', 'shift_id' => $this->model->id]),
|
||||
];
|
||||
}
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Engelsystem\Controllers\Api\Resources;
|
||||
|
||||
class ShiftTypeResource extends BasicResource
|
||||
{
|
||||
public function toArray(): array
|
||||
{
|
||||
return [
|
||||
'id' => $this->model->id,
|
||||
'name' => $this->model->name,
|
||||
'description' => $this->model->description,
|
||||
];
|
||||
}
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Engelsystem\Controllers\Api\Resources;
|
||||
|
||||
use Illuminate\Contracts\Support\Arrayable;
|
||||
|
||||
class ShiftWithEntriesResource extends ShiftResource
|
||||
{
|
||||
public function toArray(array|Arrayable $location = [], array|Arrayable $entries = []): array
|
||||
{
|
||||
return [
|
||||
...parent::toArray($location),
|
||||
'entries' => $entries instanceof Arrayable ? $entries->toArray() : $entries,
|
||||
];
|
||||
}
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Engelsystem\Controllers\Api\Resources;
|
||||
|
||||
class UserAngelTypeResource extends AngelTypeResource
|
||||
{
|
||||
public function toArray(): array
|
||||
{
|
||||
return [
|
||||
...parent::toArray(),
|
||||
'confirmed' => !$this->model->restricted
|
||||
|| $this->model->pivot->supporter
|
||||
|| $this->model->pivot->confirm_user_id,
|
||||
'supporter' => $this->model->pivot->supporter,
|
||||
];
|
||||
}
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Engelsystem\Controllers\Api\Resources;
|
||||
|
||||
class UserResource extends BasicResource
|
||||
{
|
||||
public function toArray(): array
|
||||
{
|
||||
return [
|
||||
'id' => $this->model->id,
|
||||
'name' => $this->model->name,
|
||||
'first_name' => $this->model->personalData->first_name,
|
||||
'last_name' => $this->model->personalData->last_name,
|
||||
'pronoun' => $this->model->personalData->pronoun,
|
||||
'contact' => $this->model->contact->only(['dect', 'mobile']),
|
||||
'url' => url('/users', ['action' => 'view', 'user_id' => $this->model->id]),
|
||||
];
|
||||
}
|
||||
}
|
|
@ -4,6 +4,10 @@ declare(strict_types=1);
|
|||
|
||||
namespace Engelsystem\Controllers\Api;
|
||||
|
||||
use Engelsystem\Controllers\Api\Resources\AngelTypeResource;
|
||||
use Engelsystem\Controllers\Api\Resources\LocationResource;
|
||||
use Engelsystem\Controllers\Api\Resources\ShiftWithEntriesResource;
|
||||
use Engelsystem\Controllers\Api\Resources\UserResource;
|
||||
use Engelsystem\Http\Request;
|
||||
use Engelsystem\Http\Response;
|
||||
use Engelsystem\Models\Location;
|
||||
|
@ -39,53 +43,23 @@ class ShiftsController extends ApiController
|
|||
|
||||
$entries = new Collection();
|
||||
foreach ($neededAngelTypes as $neededAngelType) {
|
||||
$users = [];
|
||||
foreach ($neededAngelType->users ?? [] as $user) {
|
||||
$users[] = [
|
||||
'id' => $user->id,
|
||||
'name' => $user->name,
|
||||
'first_name' => $user->personalData->first_name,
|
||||
'last_name' => $user->personalData->last_name,
|
||||
'pronoun' => $user->personalData->pronoun,
|
||||
'contact' => $user->contact->only(['dect', 'mobile']),
|
||||
'url' => $this->url->to('/users', ['action' => 'view', 'user_id' => $user->id]),
|
||||
];
|
||||
}
|
||||
$users = UserResource::collection($neededAngelType->users ?? []);
|
||||
|
||||
// Skip empty entries
|
||||
if ($neededAngelType->count <= 0 && empty($users)) {
|
||||
if ($neededAngelType->count <= 0 && $users->isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$angelTypeData = $neededAngelType->angelType->only(['id', 'name', 'description']);
|
||||
$angelTypeData['url'] = $this->url->to(
|
||||
'/angeltypes',
|
||||
['action' => 'view', 'angeltype_id' => $neededAngelType->angelType->id]
|
||||
);
|
||||
|
||||
$entries[] = [
|
||||
$angelTypeData = new AngelTypeResource($neededAngelType->angelType);
|
||||
$entries[] = new Collection([
|
||||
'users' => $users,
|
||||
'type' => $angelTypeData,
|
||||
'needs' => $neededAngelType->count,
|
||||
];
|
||||
]);
|
||||
}
|
||||
|
||||
$locationData = $location->only(['id', 'name']);
|
||||
$locationData['url'] = $this->url->to('/locations', ['action' => 'view', 'location_id' => $location->id]);
|
||||
|
||||
$shiftEntries[] = [
|
||||
'id' => $shift->id,
|
||||
'title' => $shift->title,
|
||||
'description' => $shift->description,
|
||||
'starts_at' => $shift->start,
|
||||
'ends_at' => $shift->end,
|
||||
'location' => $locationData,
|
||||
'shift_type' => $shift->shiftType->only(['id', 'name', 'description']),
|
||||
'created_at' => $shift->created_at,
|
||||
'updated_at' => $shift->updated_at,
|
||||
'entries' => $entries,
|
||||
'url' => $this->url->to('/shifts', ['action' => 'view', 'shift_id' => $shift->id]),
|
||||
];
|
||||
$locationData = new LocationResource($location);
|
||||
$shiftEntries[] = (new ShiftWithEntriesResource($shift))->toArray($locationData, $entries);
|
||||
}
|
||||
|
||||
$data = ['data' => $shiftEntries];
|
||||
|
|
|
@ -15,14 +15,13 @@ class AngelTypeControllerTest extends ApiBaseControllerTest
|
|||
{
|
||||
/**
|
||||
* @covers \Engelsystem\Controllers\Api\AngelTypeController::index
|
||||
* @covers \Engelsystem\Controllers\Api\AngelTypeController::getUrl
|
||||
*/
|
||||
public function testIndex(): void
|
||||
{
|
||||
$this->initDatabase();
|
||||
$items = AngelType::factory(3)->create();
|
||||
|
||||
$controller = new AngelTypeController(new Response(), $this->url);
|
||||
$controller = new AngelTypeController(new Response());
|
||||
|
||||
$response = $controller->index();
|
||||
$this->validateApiResponse('/angeltypes', 'get', $response);
|
||||
|
@ -39,6 +38,7 @@ class AngelTypeControllerTest extends ApiBaseControllerTest
|
|||
}
|
||||
/**
|
||||
* @covers \Engelsystem\Controllers\Api\AngelTypeController::ofUser
|
||||
* @covers \Engelsystem\Controllers\Api\Resources\UserAngelTypeResource::toArray
|
||||
*/
|
||||
public function testOfUser(): void
|
||||
{
|
||||
|
@ -46,7 +46,7 @@ class AngelTypeControllerTest extends ApiBaseControllerTest
|
|||
$user = User::factory()->create();
|
||||
$items = UserAngelType::factory(3)->create(['user_id' => $user->id]);
|
||||
|
||||
$controller = new AngelTypeController(new Response(), $this->url);
|
||||
$controller = new AngelTypeController(new Response());
|
||||
|
||||
$response = $controller->ofUser(new Request([], [], ['user_id' => $user->id]));
|
||||
$this->validateApiResponse('/users/{id}/angeltypes', 'get', $response);
|
||||
|
|
|
@ -15,7 +15,6 @@ use Psr\Http\Message\ResponseInterface;
|
|||
abstract class ApiBaseControllerTest extends TestCase
|
||||
{
|
||||
protected OpenApiResponseValidator $validator;
|
||||
protected UrlGeneratorInterface $url;
|
||||
|
||||
protected function validateApiResponse(string $path, string $method, ResponseInterface $response): void
|
||||
{
|
||||
|
@ -41,6 +40,6 @@ abstract class ApiBaseControllerTest extends TestCase
|
|||
$query = http_build_query($params);
|
||||
return $path . ($query ? '?' . $query : '');
|
||||
});
|
||||
$this->url = $url;
|
||||
$this->app->instance('http.urlGenerator', $url);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,7 +14,7 @@ class ApiControllerTest extends ApiBaseControllerTest
|
|||
*/
|
||||
public function testConstruct(): void
|
||||
{
|
||||
$controller = new class (new Response('{"some":"json"}'), $this->url) extends ApiController {
|
||||
$controller = new class (new Response('{"some":"json"}')) extends ApiController {
|
||||
public function getResponse(): Response
|
||||
{
|
||||
return $this->response;
|
||||
|
|
|
@ -15,7 +15,7 @@ class IndexControllerTest extends ApiBaseControllerTest
|
|||
*/
|
||||
public function testIndex(): void
|
||||
{
|
||||
$controller = new IndexController(new Response(), $this->url);
|
||||
$controller = new IndexController(new Response());
|
||||
$response = $controller->index();
|
||||
|
||||
$this->assertEquals(200, $response->getStatusCode());
|
||||
|
@ -32,7 +32,7 @@ class IndexControllerTest extends ApiBaseControllerTest
|
|||
*/
|
||||
public function testIndexV0(): void
|
||||
{
|
||||
$controller = new IndexController(new Response(), $this->url);
|
||||
$controller = new IndexController(new Response());
|
||||
$response = $controller->indexV0();
|
||||
|
||||
$this->assertEquals(200, $response->getStatusCode());
|
||||
|
@ -48,7 +48,7 @@ class IndexControllerTest extends ApiBaseControllerTest
|
|||
*/
|
||||
public function testOptions(): void
|
||||
{
|
||||
$controller = new IndexController(new Response(), $this->url);
|
||||
$controller = new IndexController(new Response());
|
||||
$response = $controller->options();
|
||||
|
||||
$this->assertEquals(200, $response->getStatusCode());
|
||||
|
@ -61,7 +61,7 @@ class IndexControllerTest extends ApiBaseControllerTest
|
|||
*/
|
||||
public function testNotFound(): void
|
||||
{
|
||||
$controller = new IndexController(new Response(), $this->url);
|
||||
$controller = new IndexController(new Response());
|
||||
$response = $controller->notFound();
|
||||
|
||||
$this->assertEquals(404, $response->getStatusCode());
|
||||
|
@ -74,7 +74,7 @@ class IndexControllerTest extends ApiBaseControllerTest
|
|||
*/
|
||||
public function testNotImplemented(): void
|
||||
{
|
||||
$controller = new IndexController(new Response(), $this->url);
|
||||
$controller = new IndexController(new Response());
|
||||
$response = $controller->notImplemented();
|
||||
|
||||
$this->assertEquals(405, $response->getStatusCode());
|
||||
|
|
|
@ -12,12 +12,13 @@ class LocationsControllerTest extends ApiBaseControllerTest
|
|||
{
|
||||
/**
|
||||
* @covers \Engelsystem\Controllers\Api\LocationsController::index
|
||||
* @covers \Engelsystem\Controllers\Api\Resources\LocationResource::toArray
|
||||
*/
|
||||
public function testIndex(): void
|
||||
{
|
||||
$items = Location::factory(3)->create();
|
||||
|
||||
$controller = new LocationsController(new Response(), $this->url);
|
||||
$controller = new LocationsController(new Response());
|
||||
|
||||
$response = $controller->index();
|
||||
$this->validateApiResponse('/locations', 'get', $response);
|
||||
|
|
|
@ -12,12 +12,13 @@ class NewsControllerTest extends ApiBaseControllerTest
|
|||
{
|
||||
/**
|
||||
* @covers \Engelsystem\Controllers\Api\NewsController::index
|
||||
* @covers \Engelsystem\Controllers\Api\Resources\NewsResource::toArray
|
||||
*/
|
||||
public function testIndex(): void
|
||||
{
|
||||
$items = News::factory(3)->create();
|
||||
|
||||
$controller = new NewsController(new Response(), $this->url);
|
||||
$controller = new NewsController(new Response());
|
||||
|
||||
$response = $controller->index();
|
||||
$this->validateApiResponse('/news', 'get', $response);
|
||||
|
|
|
@ -0,0 +1,100 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Engelsystem\Test\Unit\Controllers\Api\Resources;
|
||||
|
||||
use Engelsystem\Controllers\Api\Resources\BasicResource;
|
||||
use Engelsystem\Models\BaseModel;
|
||||
use Engelsystem\Test\Unit\TestCase;
|
||||
use Illuminate\Contracts\Support\Arrayable;
|
||||
use Illuminate\Contracts\Support\Jsonable;
|
||||
use Illuminate\Support\Collection;
|
||||
use Stringable;
|
||||
|
||||
class BasicResourceTest extends TestCase
|
||||
{
|
||||
/**
|
||||
* @covers \Engelsystem\Controllers\Api\Resources\BasicResource::__construct
|
||||
* @covers \Engelsystem\Controllers\Api\Resources\BasicResource::toArray
|
||||
*/
|
||||
public function testToArray(): void
|
||||
{
|
||||
$model = $this->getModel();
|
||||
$resource = $this->getResource($model);
|
||||
|
||||
$this->assertInstanceOf(Arrayable::class, $resource);
|
||||
$this->assertEquals(['test' => 'value'], $resource->toArray());
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers \Engelsystem\Controllers\Api\Resources\BasicResource::toJson
|
||||
*/
|
||||
public function testToJson(): void
|
||||
{
|
||||
$model = $this->getModel();
|
||||
$resource = $this->getResource($model);
|
||||
|
||||
$this->assertInstanceOf(Jsonable::class, $resource);
|
||||
$this->assertEquals('{"test":"value"}', $resource->toJson());
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers \Engelsystem\Controllers\Api\Resources\BasicResource::toJson
|
||||
*/
|
||||
public function testToJsonOptions(): void
|
||||
{
|
||||
$resource = $this->getResource(new Collection());
|
||||
|
||||
$this->assertInstanceOf(Jsonable::class, $resource);
|
||||
$this->assertEquals('{}', $resource->toJson(JSON_FORCE_OBJECT));
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers \Engelsystem\Controllers\Api\Resources\BasicResource::__toString
|
||||
*/
|
||||
public function testToString(): void
|
||||
{
|
||||
$model = $this->getModel();
|
||||
$resource = $this->getResource($model);
|
||||
|
||||
$this->assertInstanceOf(Stringable::class, $resource);
|
||||
$this->assertEquals('{"test":"value"}', (string) $resource);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers \Engelsystem\Controllers\Api\Resources\BasicResource::collection
|
||||
*/
|
||||
public function testCollection(): void
|
||||
{
|
||||
$resource = $this->getResource(new Collection());
|
||||
$modelA = $this->getModel();
|
||||
$modelB = $this->getModel()->setAttribute('test', 'B');
|
||||
$collection = $resource->collection([$modelA, $modelB]);
|
||||
|
||||
$this->assertInstanceOf(Collection::class, $collection);
|
||||
$this->assertCount(2, $collection);
|
||||
|
||||
$this->assertInstanceOf(BasicResource::class, $collection->first());
|
||||
$this->assertEquals(['test' => 'value'], $collection->first()->toArray());
|
||||
|
||||
$this->assertInstanceOf(BasicResource::class, $collection->last());
|
||||
$this->assertEquals(['test' => 'B'], $collection->last()->toArray());
|
||||
}
|
||||
|
||||
protected function getResource(BaseModel|Collection $model): BasicResource
|
||||
{
|
||||
return new class ($model) extends BasicResource {
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
protected function getModel(): BaseModel
|
||||
{
|
||||
$model = new class extends BaseModel {
|
||||
};
|
||||
$model->setAttribute('test', 'value');
|
||||
|
||||
return $model;
|
||||
}
|
||||
}
|
|
@ -20,6 +20,11 @@ class ShiftsControllerTest extends ApiBaseControllerTest
|
|||
{
|
||||
/**
|
||||
* @covers \Engelsystem\Controllers\Api\ShiftsController::entriesByLocation
|
||||
* @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
|
||||
* @covers \Engelsystem\Controllers\Api\ShiftsController::getNeededAngelTypes
|
||||
*/
|
||||
public function testEntriesByLocation(): void
|
||||
|
@ -83,7 +88,7 @@ class ShiftsControllerTest extends ApiBaseControllerTest
|
|||
$request = new Request();
|
||||
$request = $request->withAttribute('location_id', $location->id);
|
||||
|
||||
$controller = new ShiftsController(new Response(), $this->url);
|
||||
$controller = new ShiftsController(new Response());
|
||||
|
||||
$response = $controller->entriesByLocation($request);
|
||||
$this->validateApiResponse('/locations/{id}/shifts', 'get', $response);
|
||||
|
|
Loading…
Reference in New Issue