add: add/edit operations api tests and openapi spec

pull/80/head
Luciano Righetti 2022-01-10 16:19:58 +01:00
parent 71072f60eb
commit b954e11064
9 changed files with 339 additions and 2 deletions

View File

@ -31,7 +31,7 @@ QUIT;
```
$ composer install
$ vendor/bin/phpunit
$ vendor/bin/phpunit
PHPUnit 8.5.22 by Sebastian Bergmann and contributors.
..... 5 / 5 (100%)
@ -43,7 +43,7 @@ OK (5 tests, 15 assertions)
Running a specific suite:
```
$ vendor/bin/phpunit --testsuite=api
$ vendor/bin/phpunit --testsuite=api --testdox
```
Available suites:
* `app`: runs all test suites

View File

@ -0,0 +1,85 @@
<?php
declare(strict_types=1);
namespace App\Test\TestCase\Api\Users;
use Cake\TestSuite\IntegrationTestTrait;
use Cake\TestSuite\TestCase;
use App\Test\Fixture\AuthKeysFixture;
use App\Test\Helper\ApiTestTrait;
class AddOrganisationApiTest extends TestCase
{
use IntegrationTestTrait;
use ApiTestTrait;
protected const ENDPOINT = '/api/v1/organisations/add';
protected $fixtures = [
'app.Organisations',
'app.Individuals',
'app.Roles',
'app.Users',
'app.AuthKeys'
];
public function setUp(): void
{
parent::setUp();
$this->initializeValidator(APP . '../webroot/docs/openapi.yaml');
}
public function testAddOrganisation(): void
{
$this->setAuthToken(AuthKeysFixture::ADMIN_API_KEY);
$faker = \Faker\Factory::create();
$uuid = $faker->uuid;
$this->post(
self::ENDPOINT,
[
'name' => 'Test Organisation',
'description' => $faker->text,
'uuid' => $uuid,
'url' => 'http://example.com',
'nationality' => 'US',
'sector' => 'sector',
'type' => 'type',
]
);
$this->assertResponseOk();
$this->assertResponseContains(sprintf('"uuid": "%s"', $uuid));
$this->assertDbRecordExists('Organisations', ['uuid' => $uuid]);
//TODO: $this->assertRequestMatchesOpenApiSpec();
$this->assertResponseMatchesOpenApiSpec(self::ENDPOINT, 'post');
}
public function testAddOrganisationNotAllowedToRegularUser(): void
{
$this->setAuthToken(AuthKeysFixture::REGULAR_USER_API_KEY);
$faker = \Faker\Factory::create();
$uuid = $faker->uuid;
$this->post(
self::ENDPOINT,
[
'name' => 'Test Organisation',
'description' => $faker->text,
'uuid' => $uuid,
'url' => 'http://example.com',
'nationality' => 'US',
'sector' => 'sector',
'type' => 'type',
]
);
$this->assertResponseCode(405);
$this->assertDbRecordNotExists('Organisations', ['uuid' => $uuid]);
//TODO: $this->assertRequestMatchesOpenApiSpec();
$this->assertResponseMatchesOpenApiSpec(self::ENDPOINT, 'post');
}
}

View File

@ -0,0 +1,81 @@
<?php
declare(strict_types=1);
namespace App\Test\TestCase\Api\Users;
use Cake\TestSuite\IntegrationTestTrait;
use Cake\TestSuite\TestCase;
use App\Test\Fixture\AuthKeysFixture;
use App\Test\Fixture\OrganisationsFixture;
use App\Test\Helper\ApiTestTrait;
class EditOrganisationApiTest extends TestCase
{
use IntegrationTestTrait;
use ApiTestTrait;
protected const ENDPOINT = '/api/v1/organisations/edit';
protected $fixtures = [
'app.Organisations',
'app.Individuals',
'app.Roles',
'app.Users',
'app.AuthKeys'
];
public function setUp(): void
{
parent::setUp();
$this->initializeValidator(APP . '../webroot/docs/openapi.yaml');
}
public function testEditOrganisation(): void
{
$this->setAuthToken(AuthKeysFixture::ADMIN_API_KEY);
$url = sprintf('%s/%d', self::ENDPOINT, OrganisationsFixture::ORGANISATION_A_ID);
$this->put(
$url,
[
'name' => 'Test Organisation 4321',
]
);
$this->assertResponseOk();
$this->assertDbRecordExists(
'Organisations',
[
'id' => OrganisationsFixture::ORGANISATION_A_ID,
'name' => 'Test Organisation 4321',
]
);
//TODO: $this->assertRequestMatchesOpenApiSpec();
$this->assertResponseMatchesOpenApiSpec($url, 'put');
}
public function testEditOrganisationNotAllowedToRegularUser(): void
{
$this->setAuthToken(AuthKeysFixture::REGULAR_USER_API_KEY);
$url = sprintf('%s/%d', self::ENDPOINT, OrganisationsFixture::ORGANISATION_B_ID);
$this->put(
$url,
[
'name' => 'Test Organisation 1234'
]
);
$this->assertResponseCode(405);
$this->assertDbRecordNotExists(
'Organisations',
[
'id' => OrganisationsFixture::ORGANISATION_B_ID,
'name' => 'Test Organisation 1234'
]
);
//TODO: $this->assertRequestMatchesOpenApiSpec();
$this->assertResponseMatchesOpenApiSpec($url, 'put');
}
}

View File

@ -20,6 +20,7 @@ class AddUserApiTest extends TestCase
protected const ENDPOINT = '/api/v1/users/add';
protected $fixtures = [
'app.Organisations',
'app.Individuals',
'app.Roles',
'app.Users',

View File

@ -20,6 +20,7 @@ class DeleteUserApiTest extends TestCase
protected const ENDPOINT = '/api/v1/users/delete';
protected $fixtures = [
'app.Organisations',
'app.Individuals',
'app.Roles',
'app.Users',

View File

@ -20,6 +20,7 @@ class EditUserApiTest extends TestCase
protected const ENDPOINT = '/api/v1/users/edit';
protected $fixtures = [
'app.Organisations',
'app.Individuals',
'app.Roles',
'app.Users',

View File

@ -18,6 +18,7 @@ class IndexUsersApiTest extends TestCase
protected const ENDPOINT = '/api/v1/users/index';
protected $fixtures = [
'app.Organisations',
'app.Individuals',
'app.Roles',
'app.Users',

View File

@ -18,6 +18,7 @@ class ViewUserApiTest extends TestCase
protected const ENDPOINT = '/api/v1/users/view';
protected $fixtures = [
'app.Organisations',
'app.Individuals',
'app.Roles',
'app.Users',

View File

@ -11,6 +11,8 @@ servers:
tags:
- name: Users
description: "Users enrolled in this Cerebrate instance."
- name: Organisations
description: "Organisations can be equivalent to legal entities or specific individual teams within such entities. Their purpose is to relate individuals to their affiliations and for release control of information using the Trust Circles."
paths:
/api/v1/users/index:
@ -137,6 +139,44 @@ paths:
default:
$ref: "#/components/responses/ApiErrorResponse"
/api/v1/organisations/add:
post:
summary: "Add organisation"
operationId: addOrganisation
tags:
- Organisations
requestBody:
$ref: "#/components/requestBodies/AddOrganisationRequest"
responses:
"200":
$ref: "#/components/responses/OrganisationResponse"
"403":
$ref: "#/components/responses/UnauthorizedApiErrorResponse"
"405":
$ref: "#/components/responses/MethodNotAllowedApiErrorResponse"
default:
$ref: "#/components/responses/ApiErrorResponse"
/api/v1/organisations/edit/{organisationId}:
put:
summary: "Edit organisation"
operationId: editOrganisation
tags:
- Organisations
parameters:
- $ref: "#/components/parameters/organisationId"
requestBody:
$ref: "#/components/requestBodies/EditOrganisationRequest"
responses:
"200":
$ref: "#/components/responses/OrganisationResponse"
"403":
$ref: "#/components/responses/UnauthorizedApiErrorResponse"
"405":
$ref: "#/components/responses/MethodNotAllowedApiErrorResponse"
default:
$ref: "#/components/responses/ApiErrorResponse"
components:
schemas:
# General
@ -191,6 +231,73 @@ components:
# Individuals
# Organisations
OrganisationName:
type: string
OrganisationUrl:
type: string
OrganisationSector:
type: string
nullable: true
OrganisationType:
type: string
nullable: true
OrganisationContacts:
type: string
nullable: true
OrganisationNationality:
type: string
nullable: true
Organisation:
type: object
properties:
id:
$ref: "#/components/schemas/ID"
uuid:
$ref: "#/components/schemas/UUID"
name:
$ref: "#/components/schemas/OrganisationName"
url:
$ref: "#/components/schemas/OrganisationUrl"
nationality:
$ref: "#/components/schemas/OrganisationNationality"
sector:
$ref: "#/components/schemas/OrganisationSector"
type:
$ref: "#/components/schemas/OrganisationType"
contacts:
$ref: "#/components/schemas/OrganisationContacts"
created:
$ref: "#/components/schemas/DateTime"
modified:
$ref: "#/components/schemas/DateTime"
tags:
$ref: "#/components/schemas/TagList"
aligments:
$ref: "#/components/schemas/AligmentList"
# Tags
Tag:
type: object
TagList:
type: array
items:
$ref: "#/components/schemas/Tag"
# Alignments
Alignment:
type: object
AligmentList:
type: array
items:
$ref: "#/components/schemas/Alignment"
# Roles
RoleName:
@ -291,6 +398,14 @@ components:
schema:
$ref: "#/components/schemas/ID"
organisationId:
name: organisationId
in: path
description: "Numeric ID of the Organisation"
required: true
schema:
$ref: "#/components/schemas/ID"
securitySchemes:
ApiKeyAuth:
type: apiKey
@ -342,6 +457,50 @@ components:
password:
type: string
AddOrganisationRequest:
required: true
content:
application/json:
schema:
type: object
properties:
uuid:
$ref: "#/components/schemas/UUID"
name:
$ref: "#/components/schemas/OrganisationName"
url:
$ref: "#/components/schemas/OrganisationUrl"
nationality:
$ref: "#/components/schemas/OrganisationNationality"
sector:
$ref: "#/components/schemas/OrganisationSector"
type:
$ref: "#/components/schemas/OrganisationType"
contacts:
$ref: "#/components/schemas/OrganisationContacts"
EditOrganisationRequest:
required: true
content:
application/json:
schema:
type: object
properties:
uuid:
$ref: "#/components/schemas/UUID"
name:
$ref: "#/components/schemas/OrganisationName"
url:
$ref: "#/components/schemas/OrganisationUrl"
nationality:
$ref: "#/components/schemas/OrganisationNationality"
sector:
$ref: "#/components/schemas/OrganisationSector"
type:
$ref: "#/components/schemas/OrganisationType"
contacts:
$ref: "#/components/schemas/OrganisationContacts"
responses:
# User
UserResponse:
@ -358,6 +517,13 @@ components:
schema:
$ref: "#/components/schemas/UserList"
OrganisationResponse:
description: "Organisation response"
content:
application/json:
schema:
$ref: "#/components/schemas/Organisation"
# Errors
ApiErrorResponse:
description: "Unexpected API error"