add: add users add/edit/delete api tests and openapi docs.
parent
6776789fdf
commit
28650fa91c
|
@ -14,7 +14,7 @@ class AuthKeysFixture extends TestFixture
|
||||||
public const ADMIN_API_KEY = 'd033e22ae348aeb5660fc2140aec35850c4da997';
|
public const ADMIN_API_KEY = 'd033e22ae348aeb5660fc2140aec35850c4da997';
|
||||||
public const SYNC_API_KEY = '6b387ced110858dcbcda36edb044dc18f91a0894';
|
public const SYNC_API_KEY = '6b387ced110858dcbcda36edb044dc18f91a0894';
|
||||||
public const ORG_ADMIN_API_KEY = '1c4685d281d478dbcebd494158024bc3539004d0';
|
public const ORG_ADMIN_API_KEY = '1c4685d281d478dbcebd494158024bc3539004d0';
|
||||||
public const USER_API_KEY = '12dea96fec20593566ab75692c9949596833adc9';
|
public const REGULAR_USER_API_KEY = '12dea96fec20593566ab75692c9949596833adc9';
|
||||||
|
|
||||||
public function init(): void
|
public function init(): void
|
||||||
{
|
{
|
||||||
|
@ -57,9 +57,9 @@ class AuthKeysFixture extends TestFixture
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
'uuid' => $faker->uuid(),
|
'uuid' => $faker->uuid(),
|
||||||
'authkey' => $hasher->hash(self::USER_API_KEY),
|
'authkey' => $hasher->hash(self::REGULAR_USER_API_KEY),
|
||||||
'authkey_start' => substr(self::USER_API_KEY, 0, 4),
|
'authkey_start' => substr(self::REGULAR_USER_API_KEY, 0, 4),
|
||||||
'authkey_end' => substr(self::USER_API_KEY, -4),
|
'authkey_end' => substr(self::REGULAR_USER_API_KEY, -4),
|
||||||
'expiration' => 0,
|
'expiration' => 0,
|
||||||
'user_id' => UsersFixture::USER_REGULAR_USER_ID,
|
'user_id' => UsersFixture::USER_REGULAR_USER_ID,
|
||||||
'comment' => '',
|
'comment' => '',
|
||||||
|
|
|
@ -65,7 +65,7 @@ trait ApiTestTrait
|
||||||
* @param string $method The HTTP method used to call the endpoint
|
* @param string $method The HTTP method used to call the endpoint
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function validateRequest(string $endpoint, string $method = 'get'): void
|
public function assertRequestMatchesOpenApiSpec(string $endpoint, string $method = 'get'): void
|
||||||
{
|
{
|
||||||
// TODO: find a workaround to create a PSR-7 request object for validation
|
// TODO: find a workaround to create a PSR-7 request object for validation
|
||||||
throw NotImplementedException("Unfortunately cakephp does not save the PSR-7 request object in the test context");
|
throw NotImplementedException("Unfortunately cakephp does not save the PSR-7 request object in the test context");
|
||||||
|
@ -78,9 +78,49 @@ trait ApiTestTrait
|
||||||
* @param string $method The HTTP method used to call the endpoint
|
* @param string $method The HTTP method used to call the endpoint
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function validateResponse(string $endpoint, string $method = 'get'): void
|
public function assertResponseMatchesOpenApiSpec(string $endpoint, string $method = 'get'): void
|
||||||
{
|
{
|
||||||
$address = new OperationAddress($endpoint, $method);
|
$address = new OperationAddress($endpoint, $method);
|
||||||
$this->responseValidator->validate($address, $this->_response);
|
$this->responseValidator->validate($address, $this->_response);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validates a record exists in the database
|
||||||
|
*
|
||||||
|
* @param string $table The table name
|
||||||
|
* @param array $conditions The conditions to check
|
||||||
|
* @return void
|
||||||
|
* @throws \Exception
|
||||||
|
* @throws \Cake\Datasource\Exception\RecordNotFoundException
|
||||||
|
*
|
||||||
|
* @see https://book.cakephp.org/4/en/orm-query-builder.html
|
||||||
|
*/
|
||||||
|
public function assertDbRecordExists(string $table, array $conditions): void
|
||||||
|
{
|
||||||
|
$record = $this->getTableLocator()->get($table)->find()->where($conditions)->first();
|
||||||
|
if (!$record) {
|
||||||
|
throw new \PHPUnit\Framework\AssertionFailedError("Record not found in table '$table' with conditions: " . json_encode($conditions));
|
||||||
|
}
|
||||||
|
$this->assertNotEmpty($record);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validates a record do notexists in the database
|
||||||
|
*
|
||||||
|
* @param string $table The table name
|
||||||
|
* @param array $conditions The conditions to check
|
||||||
|
* @return void
|
||||||
|
* @throws \Exception
|
||||||
|
* @throws \Cake\Datasource\Exception\RecordNotFoundException
|
||||||
|
*
|
||||||
|
* @see https://book.cakephp.org/4/en/orm-query-builder.html
|
||||||
|
*/
|
||||||
|
public function assertDbRecordNotExists(string $table, array $conditions): void
|
||||||
|
{
|
||||||
|
$record = $this->getTableLocator()->get($table)->find()->where($conditions)->first();
|
||||||
|
if ($record) {
|
||||||
|
throw new \PHPUnit\Framework\AssertionFailedError("Record found in table '$table' with conditions: " . json_encode($conditions));
|
||||||
|
}
|
||||||
|
$this->assertEmpty($record);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,77 @@
|
||||||
|
<?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\UsersFixture;
|
||||||
|
use App\Test\Fixture\OrganisationsFixture;
|
||||||
|
use App\Test\Fixture\RolesFixture;
|
||||||
|
use App\Test\Helper\ApiTestTrait;
|
||||||
|
|
||||||
|
class AddUserApiTest extends TestCase
|
||||||
|
{
|
||||||
|
use IntegrationTestTrait;
|
||||||
|
use ApiTestTrait;
|
||||||
|
|
||||||
|
protected const ENDPOINT = '/api/v1/users/add';
|
||||||
|
|
||||||
|
protected $fixtures = [
|
||||||
|
'app.Individuals',
|
||||||
|
'app.Roles',
|
||||||
|
'app.Users',
|
||||||
|
'app.AuthKeys'
|
||||||
|
];
|
||||||
|
|
||||||
|
public function setUp(): void
|
||||||
|
{
|
||||||
|
parent::setUp();
|
||||||
|
$this->initializeValidator(APP . '../webroot/docs/openapi.yaml');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testAddUser(): void
|
||||||
|
{
|
||||||
|
$this->setAuthToken(AuthKeysFixture::ADMIN_API_KEY);
|
||||||
|
$this->post(
|
||||||
|
self::ENDPOINT,
|
||||||
|
[
|
||||||
|
'individual_id' => UsersFixture::USER_REGULAR_USER_ID,
|
||||||
|
'organisation_id' => OrganisationsFixture::ORGANISATION_A_ID,
|
||||||
|
'role_id' => RolesFixture::ROLE_REGULAR_USER_ID,
|
||||||
|
'disabled' => false,
|
||||||
|
'username' => 'test',
|
||||||
|
'password' => 'Password123456!',
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->assertResponseOk();
|
||||||
|
$this->assertResponseContains('"username": "test"');
|
||||||
|
$this->assertDbRecordExists('Users', ['username' => 'test']);
|
||||||
|
//TODO: $this->assertRequestMatchesOpenApiSpec();
|
||||||
|
$this->assertResponseMatchesOpenApiSpec(self::ENDPOINT, 'post');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testAddUserNotAllowedToRegularUser(): void
|
||||||
|
{
|
||||||
|
$this->setAuthToken(AuthKeysFixture::REGULAR_USER_API_KEY);
|
||||||
|
$this->post(
|
||||||
|
self::ENDPOINT,
|
||||||
|
[
|
||||||
|
'individual_id' => UsersFixture::USER_REGULAR_USER_ID,
|
||||||
|
'organisation_id' => OrganisationsFixture::ORGANISATION_A_ID,
|
||||||
|
'role_id' => RolesFixture::ROLE_REGULAR_USER_ID,
|
||||||
|
'disabled' => false,
|
||||||
|
'username' => 'test',
|
||||||
|
'password' => 'Password123456!'
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->assertResponseCode(405);
|
||||||
|
$this->assertDbRecordNotExists('Users', ['username' => 'test']);
|
||||||
|
//TODO: $this->assertRequestMatchesOpenApiSpec();
|
||||||
|
$this->assertResponseMatchesOpenApiSpec(self::ENDPOINT, 'post');
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,60 @@
|
||||||
|
<?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\UsersFixture;
|
||||||
|
use App\Test\Fixture\OrganisationsFixture;
|
||||||
|
use App\Test\Fixture\RolesFixture;
|
||||||
|
use App\Test\Helper\ApiTestTrait;
|
||||||
|
|
||||||
|
class DeleteUserApiTest extends TestCase
|
||||||
|
{
|
||||||
|
use IntegrationTestTrait;
|
||||||
|
use ApiTestTrait;
|
||||||
|
|
||||||
|
protected const ENDPOINT = '/api/v1/users/delete';
|
||||||
|
|
||||||
|
protected $fixtures = [
|
||||||
|
'app.Individuals',
|
||||||
|
'app.Roles',
|
||||||
|
'app.Users',
|
||||||
|
'app.AuthKeys'
|
||||||
|
];
|
||||||
|
|
||||||
|
public function setUp(): void
|
||||||
|
{
|
||||||
|
parent::setUp();
|
||||||
|
$this->initializeValidator(APP . '../webroot/docs/openapi.yaml');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testDeleteUser(): void
|
||||||
|
{
|
||||||
|
$this->setAuthToken(AuthKeysFixture::ADMIN_API_KEY);
|
||||||
|
$url = sprintf('%s/%d', self::ENDPOINT, UsersFixture::USER_REGULAR_USER_ID);
|
||||||
|
$this->delete($url);
|
||||||
|
|
||||||
|
$this->assertResponseOk();
|
||||||
|
$this->assertDbRecordNotExists('Users', ['id' => UsersFixture::USER_REGULAR_USER_ID]);
|
||||||
|
//TODO: $this->assertRequestMatchesOpenApiSpec();
|
||||||
|
$this->assertResponseMatchesOpenApiSpec($url, 'delete');
|
||||||
|
$this->addWarning('TODO: CRUDComponent::delete() sets some view variables, does not take into account `isRest()`, fix it.');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testDeleteUserNotAllowedToRegularUser(): void
|
||||||
|
{
|
||||||
|
$this->setAuthToken(AuthKeysFixture::REGULAR_USER_API_KEY);
|
||||||
|
$url = sprintf('%s/%d', self::ENDPOINT, UsersFixture::USER_ORG_ADMIN_ID);
|
||||||
|
$this->delete($url);
|
||||||
|
|
||||||
|
$this->assertResponseCode(405);
|
||||||
|
$this->assertDbRecordExists('Users', ['id' => UsersFixture::USER_ORG_ADMIN_ID]);
|
||||||
|
//TODO: $this->assertRequestMatchesOpenApiSpec();
|
||||||
|
$this->assertResponseMatchesOpenApiSpec($url, 'delete');
|
||||||
|
$this->addWarning('TODO: CRUDComponent::delete() sets some view variables, does not take into account `isRest()`, fix it.');
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,91 @@
|
||||||
|
<?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\UsersFixture;
|
||||||
|
use App\Test\Fixture\OrganisationsFixture;
|
||||||
|
use App\Test\Fixture\RolesFixture;
|
||||||
|
use App\Test\Helper\ApiTestTrait;
|
||||||
|
|
||||||
|
class EditUserApiTest extends TestCase
|
||||||
|
{
|
||||||
|
use IntegrationTestTrait;
|
||||||
|
use ApiTestTrait;
|
||||||
|
|
||||||
|
protected const ENDPOINT = '/api/v1/users/edit';
|
||||||
|
|
||||||
|
protected $fixtures = [
|
||||||
|
'app.Individuals',
|
||||||
|
'app.Roles',
|
||||||
|
'app.Users',
|
||||||
|
'app.AuthKeys'
|
||||||
|
];
|
||||||
|
|
||||||
|
public function setUp(): void
|
||||||
|
{
|
||||||
|
parent::setUp();
|
||||||
|
$this->initializeValidator(APP . '../webroot/docs/openapi.yaml');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testEditUser(): void
|
||||||
|
{
|
||||||
|
$this->setAuthToken(AuthKeysFixture::ADMIN_API_KEY);
|
||||||
|
$url = sprintf('%s/%d', self::ENDPOINT, UsersFixture::USER_REGULAR_USER_ID);
|
||||||
|
$this->put(
|
||||||
|
$url,
|
||||||
|
[
|
||||||
|
'id' => UsersFixture::USER_REGULAR_USER_ID,
|
||||||
|
'role_id' => RolesFixture::ROLE_ORG_ADMIN_ID,
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->assertResponseOk();
|
||||||
|
$this->assertDbRecordExists('Users', [
|
||||||
|
'id' => UsersFixture::USER_REGULAR_USER_ID,
|
||||||
|
'role_id' => RolesFixture::ROLE_ORG_ADMIN_ID
|
||||||
|
]);
|
||||||
|
//TODO: $this->assertRequestMatchesOpenApiSpec();
|
||||||
|
$this->assertResponseMatchesOpenApiSpec($url, 'put');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testEditRoleNotAllowedToRegularUser(): void
|
||||||
|
{
|
||||||
|
$this->setAuthToken(AuthKeysFixture::REGULAR_USER_API_KEY);
|
||||||
|
$this->put(
|
||||||
|
self::ENDPOINT,
|
||||||
|
[
|
||||||
|
'role_id' => RolesFixture::ROLE_ADMIN_ID,
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->assertDbRecordNotExists('Users', [
|
||||||
|
'id' => UsersFixture::USER_REGULAR_USER_ID,
|
||||||
|
'role_id' => RolesFixture::ROLE_ADMIN_ID
|
||||||
|
]);
|
||||||
|
//TODO: $this->assertRequestMatchesOpenApiSpec();
|
||||||
|
$this->assertResponseMatchesOpenApiSpec(self::ENDPOINT, 'put');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testEditSelfUser(): void
|
||||||
|
{
|
||||||
|
$this->setAuthToken(AuthKeysFixture::REGULAR_USER_API_KEY);
|
||||||
|
$this->put(
|
||||||
|
self::ENDPOINT,
|
||||||
|
[
|
||||||
|
'username' => 'test',
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->assertDbRecordExists('Users', [
|
||||||
|
'id' => UsersFixture::USER_REGULAR_USER_ID,
|
||||||
|
'username' => 'test'
|
||||||
|
]);
|
||||||
|
//TODO: $this->assertRequestMatchesOpenApiSpec();
|
||||||
|
$this->assertResponseMatchesOpenApiSpec(self::ENDPOINT, 'put');
|
||||||
|
}
|
||||||
|
}
|
|
@ -30,14 +30,14 @@ class IndexUsersApiTest extends TestCase
|
||||||
$this->initializeValidator(APP . '../webroot/docs/openapi.yaml');
|
$this->initializeValidator(APP . '../webroot/docs/openapi.yaml');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testIndex(): void
|
public function testIndexUsers(): void
|
||||||
{
|
{
|
||||||
$this->setAuthToken(AuthKeysFixture::ADMIN_API_KEY);
|
$this->setAuthToken(AuthKeysFixture::ADMIN_API_KEY);
|
||||||
$this->get(self::ENDPOINT);
|
$this->get(self::ENDPOINT);
|
||||||
|
|
||||||
$this->assertResponseOk();
|
$this->assertResponseOk();
|
||||||
$this->assertResponseContains(sprintf('"username": "%s"', UsersFixture::USER_ADMIN_USERNAME));
|
$this->assertResponseContains(sprintf('"username": "%s"', UsersFixture::USER_ADMIN_USERNAME));
|
||||||
// TODO: $this->validateRequest()
|
// TODO: $this->assertRequestMatchesOpenApiSpec();
|
||||||
$this->validateResponse(self::ENDPOINT);
|
$this->assertResponseMatchesOpenApiSpec(self::ENDPOINT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,26 +30,26 @@ class ViewUserApiTest extends TestCase
|
||||||
$this->initializeValidator(APP . '../webroot/docs/openapi.yaml');
|
$this->initializeValidator(APP . '../webroot/docs/openapi.yaml');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testViewMe(): void
|
public function testViewMyUser(): void
|
||||||
{
|
{
|
||||||
$this->setAuthToken(AuthKeysFixture::ADMIN_API_KEY);
|
$this->setAuthToken(AuthKeysFixture::ADMIN_API_KEY);
|
||||||
$this->get(self::ENDPOINT);
|
$this->get(self::ENDPOINT);
|
||||||
|
|
||||||
$this->assertResponseOk();
|
$this->assertResponseOk();
|
||||||
$this->assertResponseContains(sprintf('"username": "%s"', UsersFixture::USER_ADMIN_USERNAME));
|
$this->assertResponseContains(sprintf('"username": "%s"', UsersFixture::USER_ADMIN_USERNAME));
|
||||||
// TODO: $this->validateRequest()
|
// TODO: $this->assertRequestMatchesOpenApiSpec();
|
||||||
$this->validateResponse(self::ENDPOINT);
|
$this->assertResponseMatchesOpenApiSpec(self::ENDPOINT);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testViewById(): void
|
public function testViewUserById(): void
|
||||||
{
|
{
|
||||||
$this->setAuthToken(AuthKeysFixture::ADMIN_API_KEY);
|
$this->setAuthToken(AuthKeysFixture::ADMIN_API_KEY);
|
||||||
$url = sprintf('%s/%d', self::ENDPOINT, UsersFixture::USER_ADMIN_ID);
|
$url = sprintf('%s/%d', self::ENDPOINT, UsersFixture::USER_REGULAR_USER_ID);
|
||||||
$this->get($url);
|
$this->get($url);
|
||||||
|
|
||||||
$this->assertResponseOk();
|
$this->assertResponseOk();
|
||||||
$this->assertResponseContains(sprintf('"username": "%s"', UsersFixture::USER_ADMIN_USERNAME));
|
$this->assertResponseContains(sprintf('"username": "%s"', UsersFixture::USER_REGULAR_USER_USERNAME));
|
||||||
// TODO: $this->validateRequest()
|
// TODO: $this->assertRequestMatchesOpenApiSpec();
|
||||||
$this->validateResponse($url);
|
$this->assertResponseMatchesOpenApiSpec($url);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue