API: Added event / api info endpoint, simplified spec

This commit is contained in:
Igor Scheller 2023-12-22 14:18:12 +01:00 committed by Michael Weimann
parent da8178b0bc
commit dc7c62ffe5
4 changed files with 180 additions and 43 deletions

View File

@ -121,6 +121,7 @@ $route->addGroup(
$route->addRoute(['OPTIONS'], '[/{resource:.+}]', 'Api\IndexController@options');
$route->get('', 'Api\IndexController@indexV0');
$route->get('/openapi', 'Api\IndexController@openApiV0');
$route->get('/info', 'Api\IndexController@info');
$route->get('/angeltypes', 'Api\AngelTypeController@index');
$route->get('/angeltypes/{angeltype_id:\d+}/shifts', 'Api\ShiftsController@entriesByAngeltype');

View File

@ -21,8 +21,12 @@ servers:
description: Your local dev instance
tags:
- name: api
description: API related
- name: angeltype
description: Angeltypes
- name: event
description: Event information
- name: location
description: Event locations
- name: news
@ -105,11 +109,6 @@ components:
required:
- confirmed
- supporter
Error:
type: object
properties:
message:
type: string
News:
type: object
properties:
@ -140,16 +139,9 @@ components:
example: false
description: True if the news should be highlightet and shown on the dashboard
created_at:
type: string
format: date-time
description: DateTime in ISO-8601 format
example: 2023-05-13T13:37:42.000000Z
$ref: '#/components/schemas/DateTime'
updated_at:
type: string
nullable: true
format: date-time
description: DateTime in ISO-8601 format
example: 2023-05-13T23:00:00.000000Z
$ref: '#/components/schemas/DateTimeOptional'
url:
type: string
example: https://example.com/news/42
@ -197,31 +189,17 @@ components:
Shift description, should be added to the shift type description but might be empty.
Normally contains additional information for a specific shift / task.
starts_at:
type: string
format: date-time
description: DateTime in ISO-8601 format
example: 2023-05-13T14:00:00.000000Z
$ref: '#/components/schemas/DateTime'
ends_at:
type: string
format: date-time
description: DateTime in ISO-8601 format
example: 2023-05-13T16:00:00.000000Z23
$ref: '#/components/schemas/DateTime'
location:
$ref: '#/components/schemas/Location'
shift_type:
$ref: '#/components/schemas/ShiftType'
created_at:
type: string
nullable: true
format: date-time
description: DateTime in ISO-8601 format
example: 2023-05-13T13:37:42.000000Z
$ref: '#/components/schemas/DateTimeOptional'
updated_at:
type: string
nullable: true
format: date-time
description: DateTime in ISO-8601 format
example: 2023-05-13T23:00:00.000000Z
$ref: '#/components/schemas/DateTimeOptional'
entries:
type: array
description: Can be empty (for example on Schedule import of unused room)
@ -341,17 +319,9 @@ components:
type: object
properties:
planned_arrival:
type: string
nullable: true
format: date-time
description: DateTime in ISO-8601 format
example: 2023-05-13T00:00:00.000000Z
$ref: '#/components/schemas/DateTimeOptional'
planned_departure:
type: string
nullable: true
format: date-time
description: DateTime in ISO-8601 format
example: 2023-05-23T00:00:00.000000Z
$ref: '#/components/schemas/DateTimeOptional'
arrival:
type: string
nullable: true
@ -375,6 +345,77 @@ components:
- language
- arrived
DateTime:
type: string
format: date-time
description: DateTime in ISO-8601 format
example: 2023-05-23T00:00:00.000000Z
DateTimeOptional:
type: string
format: date-time
description: DateTime in ISO-8601 format
example: 2023-05-23T00:00:00.000000Z
nullable: true
Error:
type: object
properties:
message:
type: string
EventInfo:
type: object
properties:
api:
type: string
description: API version for easier version detection
example: 1.2.3
spec:
type: string
description: Link to OpenAPI specification
example: https://galactic-help.example/api/v1.2.3/openapi
name:
type: string
example: 42. Galactic Conglomeration Congress
app_name:
type: string
example: Engelsystem
url:
type: string
description: URL to be used when linking to the application
example: https://galactic-help.example
timezone:
type: string
example: Europe/Berlin
description: Timezone of the event
buildup:
type: object
properties:
start:
$ref: '#/components/schemas/DateTimeOptional'
end:
$ref: '#/components/schemas/DateTimeOptional'
required:
- start
- end
teardown:
type: object
properties:
start:
$ref: '#/components/schemas/DateTimeOptional'
end:
$ref: '#/components/schemas/DateTimeOptional'
required:
- start
- end
required:
- api
- spec
- name
- app_name
- url
- timezone
- buildup
- teardown
security:
- bearerAuth: [ ]
@ -609,6 +650,28 @@ paths:
'404':
$ref: '#/components/responses/NotFoundError'
/info:
get:
tags:
- event
summary: Get event information
responses:
'200':
description: Ok
content:
application/json:
schema:
type: object
properties:
data:
$ref: '#/components/schemas/EventInfo'
'401':
$ref: '#/components/responses/UnauthorizedError'
'403':
$ref: '#/components/responses/ForbiddenError'
'404':
$ref: '#/components/responses/NotFoundError'
/openapi:
get:
tags:

View File

@ -21,7 +21,7 @@ class IndexController extends ApiController
return $this->response
->withContent(json_encode([
'versions' => [
'0.0.1-beta' => '/v0-beta',
$this->getApiSpecV0()->info->version => '/v0-beta',
],
]));
}
@ -53,6 +53,32 @@ class IndexController extends ApiController
return $this->response->withContent(json_encode($data));
}
public function info(): Response
{
$config = config();
$schema = $this->getApiSpecV0();
$data = ['data' => [
'api' => $schema->info->version,
'spec' => url('/api/v0-beta/openapi'),
'name' => (string) $config->get('name'),
'app_name' => (string) $config->get('app_name'),
'url' => url('/'),
'timezone' => (string) $config->get('timezone'),
'buildup' => [
'start' => $config->get('buildup_start'),
'end' => $config->get('buildup_end'),
],
'teardown' => [
'start' => $config->get('teardown_start'),
'end' => $config->get('teardown_end'),
],
]];
return $this->response
->withContent(json_encode($data));
}
public function options(): Response
{
// Respond to browser preflight options requests

View File

@ -4,6 +4,7 @@ declare(strict_types=1);
namespace Engelsystem\Test\Unit\Controllers\Api;
use Engelsystem\Config\Config;
use Engelsystem\Controllers\Api\IndexController;
use Engelsystem\Http\Response;
@ -63,6 +64,52 @@ class IndexControllerTest extends ApiBaseControllerTest
$this->assertArrayHasKey('info', $data);
}
/**
* @covers \Engelsystem\Controllers\Api\IndexController::info
*/
public function testInfo(): void
{
$config = new Config(['name' => 'TestEvent', 'app_name' => 'TestSystem', 'timezone' => 'UTC']);
$this->app->instance('config', $config);
$controller = new IndexController(new Response());
$response = $controller->info();
$this->validateApiResponse('/info', 'get', $response);
$this->assertEquals(['application/json'], $response->getHeader('content-type'));
$this->assertJson($response->getContent());
$data = json_decode($response->getContent(), true);
$this->assertArrayHasKey('data', $data);
$data = $data['data'];
$this->assertArrayHasKey('api', $data);
$this->assertArrayHasKey('timezone', $data);
$this->assertEquals('UTC', $data['timezone']);
}
/**
* @covers \Engelsystem\Controllers\Api\IndexController::info
*/
public function testInfoNotConfigured(): void
{
$config = new Config([]);
$this->app->instance('config', $config);
$controller = new IndexController(new Response());
$response = $controller->info();
$this->validateApiResponse('/info', '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->assertArrayHasKey('name', $data['data']);
$this->assertEquals('', $data['data']['name']);
}
/**
* @covers \Engelsystem\Controllers\Api\IndexController::options
*/