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;
|
namespace Engelsystem\Controllers\Api;
|
||||||
|
|
||||||
|
use Engelsystem\Controllers\Api\Resources\AngelTypeResource;
|
||||||
|
use Engelsystem\Controllers\Api\Resources\UserAngelTypeResource;
|
||||||
use Engelsystem\Http\Request;
|
use Engelsystem\Http\Request;
|
||||||
use Engelsystem\Http\Response;
|
use Engelsystem\Http\Response;
|
||||||
use Engelsystem\Models\AngelType;
|
use Engelsystem\Models\AngelType;
|
||||||
|
@ -15,13 +17,9 @@ class AngelTypeController extends ApiController
|
||||||
{
|
{
|
||||||
$models = AngelType::query()
|
$models = AngelType::query()
|
||||||
->orderBy('name')
|
->orderBy('name')
|
||||||
->get(['id', 'name', 'description']);
|
->get();
|
||||||
|
|
||||||
$models->map(function (AngelType $model): void {
|
$data = ['data' => AngelTypeResource::collection($models)];
|
||||||
$model->url = $this->getUrl($model);
|
|
||||||
});
|
|
||||||
|
|
||||||
$data = ['data' => $models];
|
|
||||||
return $this->response
|
return $this->response
|
||||||
->withContent(json_encode($data));
|
->withContent(json_encode($data));
|
||||||
}
|
}
|
||||||
|
@ -30,31 +28,9 @@ class AngelTypeController extends ApiController
|
||||||
{
|
{
|
||||||
$id = (int) $request->getAttribute('user_id');
|
$id = (int) $request->getAttribute('user_id');
|
||||||
$model = User::findOrFail($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
|
return $this->response
|
||||||
->withContent(json_encode($data));
|
->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\Controllers\BaseController;
|
||||||
use Engelsystem\Http\Response;
|
use Engelsystem\Http\Response;
|
||||||
use Engelsystem\Http\UrlGeneratorInterface;
|
|
||||||
|
|
||||||
abstract class ApiController extends BaseController
|
abstract class ApiController extends BaseController
|
||||||
{
|
{
|
||||||
|
@ -14,7 +13,7 @@ abstract class ApiController extends BaseController
|
||||||
'api',
|
'api',
|
||||||
];
|
];
|
||||||
|
|
||||||
public function __construct(protected Response $response, protected UrlGeneratorInterface $url)
|
public function __construct(protected Response $response)
|
||||||
{
|
{
|
||||||
$this->response = $this->response
|
$this->response = $this->response
|
||||||
->withHeader('content-type', 'application/json')
|
->withHeader('content-type', 'application/json')
|
||||||
|
|
|
@ -4,6 +4,7 @@ declare(strict_types=1);
|
||||||
|
|
||||||
namespace Engelsystem\Controllers\Api;
|
namespace Engelsystem\Controllers\Api;
|
||||||
|
|
||||||
|
use Engelsystem\Controllers\Api\Resources\LocationResource;
|
||||||
use Engelsystem\Http\Response;
|
use Engelsystem\Http\Response;
|
||||||
use Engelsystem\Models\Location;
|
use Engelsystem\Models\Location;
|
||||||
|
|
||||||
|
@ -13,13 +14,9 @@ class LocationsController extends ApiController
|
||||||
{
|
{
|
||||||
$models = Location::query()
|
$models = Location::query()
|
||||||
->orderBy('name')
|
->orderBy('name')
|
||||||
->get(['id', 'name']);
|
->get();
|
||||||
|
|
||||||
$models->map(function (Location $model): void {
|
$data = ['data' => LocationResource::collection($models)];
|
||||||
$model->url = $this->url->to('/locations', ['action' => 'view', 'location_id' => $model->id]);
|
|
||||||
});
|
|
||||||
|
|
||||||
$data = ['data' => $models];
|
|
||||||
return $this->response
|
return $this->response
|
||||||
->withContent(json_encode($data));
|
->withContent(json_encode($data));
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@ declare(strict_types=1);
|
||||||
|
|
||||||
namespace Engelsystem\Controllers\Api;
|
namespace Engelsystem\Controllers\Api;
|
||||||
|
|
||||||
|
use Engelsystem\Controllers\Api\Resources\NewsResource;
|
||||||
use Engelsystem\Http\Response;
|
use Engelsystem\Http\Response;
|
||||||
use Engelsystem\Models\News;
|
use Engelsystem\Models\News;
|
||||||
|
|
||||||
|
@ -14,13 +15,9 @@ class NewsController extends ApiController
|
||||||
$models = News::query()
|
$models = News::query()
|
||||||
->orderByDesc('updated_at')
|
->orderByDesc('updated_at')
|
||||||
->orderByDesc('created_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 {
|
$data = ['data' => NewsResource::collection($models)];
|
||||||
$model->url = $this->url->to('/news/' . $model->id);
|
|
||||||
});
|
|
||||||
|
|
||||||
$data = ['data' => $models];
|
|
||||||
return $this->response
|
return $this->response
|
||||||
->withContent(json_encode($data));
|
->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;
|
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\Request;
|
||||||
use Engelsystem\Http\Response;
|
use Engelsystem\Http\Response;
|
||||||
use Engelsystem\Models\Location;
|
use Engelsystem\Models\Location;
|
||||||
|
@ -39,53 +43,23 @@ class ShiftsController extends ApiController
|
||||||
|
|
||||||
$entries = new Collection();
|
$entries = new Collection();
|
||||||
foreach ($neededAngelTypes as $neededAngelType) {
|
foreach ($neededAngelTypes as $neededAngelType) {
|
||||||
$users = [];
|
$users = UserResource::collection($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]),
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Skip empty entries
|
// Skip empty entries
|
||||||
if ($neededAngelType->count <= 0 && empty($users)) {
|
if ($neededAngelType->count <= 0 && $users->isEmpty()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
$angelTypeData = $neededAngelType->angelType->only(['id', 'name', 'description']);
|
$angelTypeData = new AngelTypeResource($neededAngelType->angelType);
|
||||||
$angelTypeData['url'] = $this->url->to(
|
$entries[] = new Collection([
|
||||||
'/angeltypes',
|
|
||||||
['action' => 'view', 'angeltype_id' => $neededAngelType->angelType->id]
|
|
||||||
);
|
|
||||||
|
|
||||||
$entries[] = [
|
|
||||||
'users' => $users,
|
'users' => $users,
|
||||||
'type' => $angelTypeData,
|
'type' => $angelTypeData,
|
||||||
'needs' => $neededAngelType->count,
|
'needs' => $neededAngelType->count,
|
||||||
];
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
$locationData = $location->only(['id', 'name']);
|
$locationData = new LocationResource($location);
|
||||||
$locationData['url'] = $this->url->to('/locations', ['action' => 'view', 'location_id' => $location->id]);
|
$shiftEntries[] = (new ShiftWithEntriesResource($shift))->toArray($locationData, $entries);
|
||||||
|
|
||||||
$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]),
|
|
||||||
];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$data = ['data' => $shiftEntries];
|
$data = ['data' => $shiftEntries];
|
||||||
|
|
|
@ -15,14 +15,13 @@ class AngelTypeControllerTest extends ApiBaseControllerTest
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @covers \Engelsystem\Controllers\Api\AngelTypeController::index
|
* @covers \Engelsystem\Controllers\Api\AngelTypeController::index
|
||||||
* @covers \Engelsystem\Controllers\Api\AngelTypeController::getUrl
|
|
||||||
*/
|
*/
|
||||||
public function testIndex(): void
|
public function testIndex(): void
|
||||||
{
|
{
|
||||||
$this->initDatabase();
|
$this->initDatabase();
|
||||||
$items = AngelType::factory(3)->create();
|
$items = AngelType::factory(3)->create();
|
||||||
|
|
||||||
$controller = new AngelTypeController(new Response(), $this->url);
|
$controller = new AngelTypeController(new Response());
|
||||||
|
|
||||||
$response = $controller->index();
|
$response = $controller->index();
|
||||||
$this->validateApiResponse('/angeltypes', 'get', $response);
|
$this->validateApiResponse('/angeltypes', 'get', $response);
|
||||||
|
@ -39,6 +38,7 @@ class AngelTypeControllerTest extends ApiBaseControllerTest
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* @covers \Engelsystem\Controllers\Api\AngelTypeController::ofUser
|
* @covers \Engelsystem\Controllers\Api\AngelTypeController::ofUser
|
||||||
|
* @covers \Engelsystem\Controllers\Api\Resources\UserAngelTypeResource::toArray
|
||||||
*/
|
*/
|
||||||
public function testOfUser(): void
|
public function testOfUser(): void
|
||||||
{
|
{
|
||||||
|
@ -46,7 +46,7 @@ class AngelTypeControllerTest extends ApiBaseControllerTest
|
||||||
$user = User::factory()->create();
|
$user = User::factory()->create();
|
||||||
$items = UserAngelType::factory(3)->create(['user_id' => $user->id]);
|
$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]));
|
$response = $controller->ofUser(new Request([], [], ['user_id' => $user->id]));
|
||||||
$this->validateApiResponse('/users/{id}/angeltypes', 'get', $response);
|
$this->validateApiResponse('/users/{id}/angeltypes', 'get', $response);
|
||||||
|
|
|
@ -15,7 +15,6 @@ use Psr\Http\Message\ResponseInterface;
|
||||||
abstract class ApiBaseControllerTest extends TestCase
|
abstract class ApiBaseControllerTest extends TestCase
|
||||||
{
|
{
|
||||||
protected OpenApiResponseValidator $validator;
|
protected OpenApiResponseValidator $validator;
|
||||||
protected UrlGeneratorInterface $url;
|
|
||||||
|
|
||||||
protected function validateApiResponse(string $path, string $method, ResponseInterface $response): void
|
protected function validateApiResponse(string $path, string $method, ResponseInterface $response): void
|
||||||
{
|
{
|
||||||
|
@ -41,6 +40,6 @@ abstract class ApiBaseControllerTest extends TestCase
|
||||||
$query = http_build_query($params);
|
$query = http_build_query($params);
|
||||||
return $path . ($query ? '?' . $query : '');
|
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
|
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
|
public function getResponse(): Response
|
||||||
{
|
{
|
||||||
return $this->response;
|
return $this->response;
|
||||||
|
|
|
@ -15,7 +15,7 @@ class IndexControllerTest extends ApiBaseControllerTest
|
||||||
*/
|
*/
|
||||||
public function testIndex(): void
|
public function testIndex(): void
|
||||||
{
|
{
|
||||||
$controller = new IndexController(new Response(), $this->url);
|
$controller = new IndexController(new Response());
|
||||||
$response = $controller->index();
|
$response = $controller->index();
|
||||||
|
|
||||||
$this->assertEquals(200, $response->getStatusCode());
|
$this->assertEquals(200, $response->getStatusCode());
|
||||||
|
@ -32,7 +32,7 @@ class IndexControllerTest extends ApiBaseControllerTest
|
||||||
*/
|
*/
|
||||||
public function testIndexV0(): void
|
public function testIndexV0(): void
|
||||||
{
|
{
|
||||||
$controller = new IndexController(new Response(), $this->url);
|
$controller = new IndexController(new Response());
|
||||||
$response = $controller->indexV0();
|
$response = $controller->indexV0();
|
||||||
|
|
||||||
$this->assertEquals(200, $response->getStatusCode());
|
$this->assertEquals(200, $response->getStatusCode());
|
||||||
|
@ -48,7 +48,7 @@ class IndexControllerTest extends ApiBaseControllerTest
|
||||||
*/
|
*/
|
||||||
public function testOptions(): void
|
public function testOptions(): void
|
||||||
{
|
{
|
||||||
$controller = new IndexController(new Response(), $this->url);
|
$controller = new IndexController(new Response());
|
||||||
$response = $controller->options();
|
$response = $controller->options();
|
||||||
|
|
||||||
$this->assertEquals(200, $response->getStatusCode());
|
$this->assertEquals(200, $response->getStatusCode());
|
||||||
|
@ -61,7 +61,7 @@ class IndexControllerTest extends ApiBaseControllerTest
|
||||||
*/
|
*/
|
||||||
public function testNotFound(): void
|
public function testNotFound(): void
|
||||||
{
|
{
|
||||||
$controller = new IndexController(new Response(), $this->url);
|
$controller = new IndexController(new Response());
|
||||||
$response = $controller->notFound();
|
$response = $controller->notFound();
|
||||||
|
|
||||||
$this->assertEquals(404, $response->getStatusCode());
|
$this->assertEquals(404, $response->getStatusCode());
|
||||||
|
@ -74,7 +74,7 @@ class IndexControllerTest extends ApiBaseControllerTest
|
||||||
*/
|
*/
|
||||||
public function testNotImplemented(): void
|
public function testNotImplemented(): void
|
||||||
{
|
{
|
||||||
$controller = new IndexController(new Response(), $this->url);
|
$controller = new IndexController(new Response());
|
||||||
$response = $controller->notImplemented();
|
$response = $controller->notImplemented();
|
||||||
|
|
||||||
$this->assertEquals(405, $response->getStatusCode());
|
$this->assertEquals(405, $response->getStatusCode());
|
||||||
|
|
|
@ -12,12 +12,13 @@ class LocationsControllerTest extends ApiBaseControllerTest
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @covers \Engelsystem\Controllers\Api\LocationsController::index
|
* @covers \Engelsystem\Controllers\Api\LocationsController::index
|
||||||
|
* @covers \Engelsystem\Controllers\Api\Resources\LocationResource::toArray
|
||||||
*/
|
*/
|
||||||
public function testIndex(): void
|
public function testIndex(): void
|
||||||
{
|
{
|
||||||
$items = Location::factory(3)->create();
|
$items = Location::factory(3)->create();
|
||||||
|
|
||||||
$controller = new LocationsController(new Response(), $this->url);
|
$controller = new LocationsController(new Response());
|
||||||
|
|
||||||
$response = $controller->index();
|
$response = $controller->index();
|
||||||
$this->validateApiResponse('/locations', 'get', $response);
|
$this->validateApiResponse('/locations', 'get', $response);
|
||||||
|
|
|
@ -12,12 +12,13 @@ class NewsControllerTest extends ApiBaseControllerTest
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @covers \Engelsystem\Controllers\Api\NewsController::index
|
* @covers \Engelsystem\Controllers\Api\NewsController::index
|
||||||
|
* @covers \Engelsystem\Controllers\Api\Resources\NewsResource::toArray
|
||||||
*/
|
*/
|
||||||
public function testIndex(): void
|
public function testIndex(): void
|
||||||
{
|
{
|
||||||
$items = News::factory(3)->create();
|
$items = News::factory(3)->create();
|
||||||
|
|
||||||
$controller = new NewsController(new Response(), $this->url);
|
$controller = new NewsController(new Response());
|
||||||
|
|
||||||
$response = $controller->index();
|
$response = $controller->index();
|
||||||
$this->validateApiResponse('/news', 'get', $response);
|
$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\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
|
* @covers \Engelsystem\Controllers\Api\ShiftsController::getNeededAngelTypes
|
||||||
*/
|
*/
|
||||||
public function testEntriesByLocation(): void
|
public function testEntriesByLocation(): void
|
||||||
|
@ -83,7 +88,7 @@ class ShiftsControllerTest extends ApiBaseControllerTest
|
||||||
$request = new Request();
|
$request = new Request();
|
||||||
$request = $request->withAttribute('location_id', $location->id);
|
$request = $request->withAttribute('location_id', $location->id);
|
||||||
|
|
||||||
$controller = new ShiftsController(new Response(), $this->url);
|
$controller = new ShiftsController(new Response());
|
||||||
|
|
||||||
$response = $controller->entriesByLocation($request);
|
$response = $controller->entriesByLocation($request);
|
||||||
$this->validateApiResponse('/locations/{id}/shifts', 'get', $response);
|
$this->validateApiResponse('/locations/{id}/shifts', 'get', $response);
|
||||||
|
|
Loading…
Reference in New Issue