API: Added event / api info endpoint, simplified spec
This commit is contained in:
parent
da8178b0bc
commit
dc7c62ffe5
|
@ -121,6 +121,7 @@ $route->addGroup(
|
||||||
$route->addRoute(['OPTIONS'], '[/{resource:.+}]', 'Api\IndexController@options');
|
$route->addRoute(['OPTIONS'], '[/{resource:.+}]', 'Api\IndexController@options');
|
||||||
$route->get('', 'Api\IndexController@indexV0');
|
$route->get('', 'Api\IndexController@indexV0');
|
||||||
$route->get('/openapi', 'Api\IndexController@openApiV0');
|
$route->get('/openapi', 'Api\IndexController@openApiV0');
|
||||||
|
$route->get('/info', 'Api\IndexController@info');
|
||||||
|
|
||||||
$route->get('/angeltypes', 'Api\AngelTypeController@index');
|
$route->get('/angeltypes', 'Api\AngelTypeController@index');
|
||||||
$route->get('/angeltypes/{angeltype_id:\d+}/shifts', 'Api\ShiftsController@entriesByAngeltype');
|
$route->get('/angeltypes/{angeltype_id:\d+}/shifts', 'Api\ShiftsController@entriesByAngeltype');
|
||||||
|
|
|
@ -21,8 +21,12 @@ servers:
|
||||||
description: Your local dev instance
|
description: Your local dev instance
|
||||||
|
|
||||||
tags:
|
tags:
|
||||||
|
- name: api
|
||||||
|
description: API related
|
||||||
- name: angeltype
|
- name: angeltype
|
||||||
description: Angeltypes
|
description: Angeltypes
|
||||||
|
- name: event
|
||||||
|
description: Event information
|
||||||
- name: location
|
- name: location
|
||||||
description: Event locations
|
description: Event locations
|
||||||
- name: news
|
- name: news
|
||||||
|
@ -105,11 +109,6 @@ components:
|
||||||
required:
|
required:
|
||||||
- confirmed
|
- confirmed
|
||||||
- supporter
|
- supporter
|
||||||
Error:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
message:
|
|
||||||
type: string
|
|
||||||
News:
|
News:
|
||||||
type: object
|
type: object
|
||||||
properties:
|
properties:
|
||||||
|
@ -140,16 +139,9 @@ components:
|
||||||
example: false
|
example: false
|
||||||
description: True if the news should be highlightet and shown on the dashboard
|
description: True if the news should be highlightet and shown on the dashboard
|
||||||
created_at:
|
created_at:
|
||||||
type: string
|
$ref: '#/components/schemas/DateTime'
|
||||||
format: date-time
|
|
||||||
description: DateTime in ISO-8601 format
|
|
||||||
example: 2023-05-13T13:37:42.000000Z
|
|
||||||
updated_at:
|
updated_at:
|
||||||
type: string
|
$ref: '#/components/schemas/DateTimeOptional'
|
||||||
nullable: true
|
|
||||||
format: date-time
|
|
||||||
description: DateTime in ISO-8601 format
|
|
||||||
example: 2023-05-13T23:00:00.000000Z
|
|
||||||
url:
|
url:
|
||||||
type: string
|
type: string
|
||||||
example: https://example.com/news/42
|
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.
|
Shift description, should be added to the shift type description but might be empty.
|
||||||
Normally contains additional information for a specific shift / task.
|
Normally contains additional information for a specific shift / task.
|
||||||
starts_at:
|
starts_at:
|
||||||
type: string
|
$ref: '#/components/schemas/DateTime'
|
||||||
format: date-time
|
|
||||||
description: DateTime in ISO-8601 format
|
|
||||||
example: 2023-05-13T14:00:00.000000Z
|
|
||||||
ends_at:
|
ends_at:
|
||||||
type: string
|
$ref: '#/components/schemas/DateTime'
|
||||||
format: date-time
|
|
||||||
description: DateTime in ISO-8601 format
|
|
||||||
example: 2023-05-13T16:00:00.000000Z23
|
|
||||||
location:
|
location:
|
||||||
$ref: '#/components/schemas/Location'
|
$ref: '#/components/schemas/Location'
|
||||||
shift_type:
|
shift_type:
|
||||||
$ref: '#/components/schemas/ShiftType'
|
$ref: '#/components/schemas/ShiftType'
|
||||||
created_at:
|
created_at:
|
||||||
type: string
|
$ref: '#/components/schemas/DateTimeOptional'
|
||||||
nullable: true
|
|
||||||
format: date-time
|
|
||||||
description: DateTime in ISO-8601 format
|
|
||||||
example: 2023-05-13T13:37:42.000000Z
|
|
||||||
updated_at:
|
updated_at:
|
||||||
type: string
|
$ref: '#/components/schemas/DateTimeOptional'
|
||||||
nullable: true
|
|
||||||
format: date-time
|
|
||||||
description: DateTime in ISO-8601 format
|
|
||||||
example: 2023-05-13T23:00:00.000000Z
|
|
||||||
entries:
|
entries:
|
||||||
type: array
|
type: array
|
||||||
description: Can be empty (for example on Schedule import of unused room)
|
description: Can be empty (for example on Schedule import of unused room)
|
||||||
|
@ -341,17 +319,9 @@ components:
|
||||||
type: object
|
type: object
|
||||||
properties:
|
properties:
|
||||||
planned_arrival:
|
planned_arrival:
|
||||||
type: string
|
$ref: '#/components/schemas/DateTimeOptional'
|
||||||
nullable: true
|
|
||||||
format: date-time
|
|
||||||
description: DateTime in ISO-8601 format
|
|
||||||
example: 2023-05-13T00:00:00.000000Z
|
|
||||||
planned_departure:
|
planned_departure:
|
||||||
type: string
|
$ref: '#/components/schemas/DateTimeOptional'
|
||||||
nullable: true
|
|
||||||
format: date-time
|
|
||||||
description: DateTime in ISO-8601 format
|
|
||||||
example: 2023-05-23T00:00:00.000000Z
|
|
||||||
arrival:
|
arrival:
|
||||||
type: string
|
type: string
|
||||||
nullable: true
|
nullable: true
|
||||||
|
@ -375,6 +345,77 @@ components:
|
||||||
- language
|
- language
|
||||||
- arrived
|
- 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:
|
security:
|
||||||
- bearerAuth: [ ]
|
- bearerAuth: [ ]
|
||||||
|
|
||||||
|
@ -609,6 +650,28 @@ paths:
|
||||||
'404':
|
'404':
|
||||||
$ref: '#/components/responses/NotFoundError'
|
$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:
|
/openapi:
|
||||||
get:
|
get:
|
||||||
tags:
|
tags:
|
||||||
|
|
|
@ -21,7 +21,7 @@ class IndexController extends ApiController
|
||||||
return $this->response
|
return $this->response
|
||||||
->withContent(json_encode([
|
->withContent(json_encode([
|
||||||
'versions' => [
|
'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));
|
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
|
public function options(): Response
|
||||||
{
|
{
|
||||||
// Respond to browser preflight options requests
|
// Respond to browser preflight options requests
|
||||||
|
|
|
@ -4,6 +4,7 @@ declare(strict_types=1);
|
||||||
|
|
||||||
namespace Engelsystem\Test\Unit\Controllers\Api;
|
namespace Engelsystem\Test\Unit\Controllers\Api;
|
||||||
|
|
||||||
|
use Engelsystem\Config\Config;
|
||||||
use Engelsystem\Controllers\Api\IndexController;
|
use Engelsystem\Controllers\Api\IndexController;
|
||||||
use Engelsystem\Http\Response;
|
use Engelsystem\Http\Response;
|
||||||
|
|
||||||
|
@ -63,6 +64,52 @@ class IndexControllerTest extends ApiBaseControllerTest
|
||||||
$this->assertArrayHasKey('info', $data);
|
$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
|
* @covers \Engelsystem\Controllers\Api\IndexController::options
|
||||||
*/
|
*/
|
||||||
|
|
Loading…
Reference in New Issue