new: add /api/v1/users/index api test

pull/80/head
Luciano Righetti 2022-01-07 17:08:00 +01:00
parent c14b84fcc0
commit 6776789fdf
4 changed files with 90 additions and 74 deletions

View File

@ -4,6 +4,7 @@ declare(strict_types=1);
namespace App\Test\Helper;
use Cake\Http\Exception\NotImplementedException;
use \League\OpenAPIValidation\PSR7\ValidatorBuilder;
use \League\OpenAPIValidation\PSR7\RequestValidator;
use \League\OpenAPIValidation\PSR7\ResponseValidator;
@ -38,6 +39,12 @@ trait ApiTestTrait
]);
}
public function assertResponseContainsArray(array $expected): void
{
$responseArray = json_decode((string)$this->_response->getBody(), true);
throw new NotImplementedException('TODO: see codeception seeResponseContainsJson()');
}
/**
* Parse the OpenAPI specification and create a validator
*

View File

@ -1,5 +1,5 @@
# Testing
## Configuration
1. Add a `cerebrate_test` database to the db:
```mysql
CREATE DATABASE cerebrate_test;
@ -55,3 +55,14 @@ By default the database is re-generated before running the test suite, to skip t
```
$ vendor/bin/phpunit -d skip-migrations
```
## Coverage
HTML:
```
$ vendor/bin/phpunit --coverage-html tmp/coverage
```
XML:
```
$ vendor/bin/phpunit --verbose --coverage-clover=coverage.xml
```

View File

@ -1,55 +0,0 @@
<?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\Helper\ApiTestTrait;
class UsersApiTest extends TestCase
{
use IntegrationTestTrait;
use ApiTestTrait;
protected const ENDPOINT = '/api/v1/users/view';
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 testViewMe(): void
{
$this->setAuthToken(AuthKeysFixture::ADMIN_API_KEY);
$this->get(self::ENDPOINT);
$this->assertResponseOk();
$this->assertResponseContains(sprintf('"username": "%s"', UsersFixture::USER_ADMIN_USERNAME));
// TODO: $this->validateRequest()
$this->validateResponse(self::ENDPOINT);
}
public function testViewById(): void
{
$this->setAuthToken(AuthKeysFixture::ADMIN_API_KEY);
$url = sprintf('%s/%d', self::ENDPOINT, UsersFixture::USER_ADMIN_ID);
$this->get($url);
$this->assertResponseOk();
$this->assertResponseContains(sprintf('"username": "%s"', UsersFixture::USER_ADMIN_USERNAME));
// TODO: $this->validateRequest()
$this->validateResponse($url);
}
}

View File

@ -11,9 +11,25 @@ servers:
tags:
- name: Users
description: "TODO: users resource descriptions"
description: "Users enrolled in this Cerebrate instance."
paths:
/api/v1/users/index:
get:
summary: "Get users list"
operationId: getUsers
tags:
- Users
responses:
"200":
$ref: "#/components/responses/GetUsersResponse"
"403":
$ref: "#/components/responses/UnauthorizedApiErrorResponse"
"405":
$ref: "#/components/responses/MethodNotAllowedApiErrorResponse"
default:
$ref: "#/components/responses/ApiErrorResponse"
/api/v1/users/view:
get:
summary: "Get information about the current user"
@ -22,7 +38,7 @@ paths:
- Users
responses:
"200":
$ref: "#/components/responses/ViewUserResponse"
$ref: "#/components/responses/GetUserResponse"
"403":
$ref: "#/components/responses/UnauthorizedApiErrorResponse"
default:
@ -38,7 +54,7 @@ paths:
- $ref: "#/components/parameters/userId"
responses:
"200":
$ref: "#/components/responses/ViewUserResponse"
$ref: "#/components/responses/GetUserResponse"
"403":
$ref: "#/components/responses/UnauthorizedApiErrorResponse"
default:
@ -90,6 +106,11 @@ components:
organisation_id:
$ref: "#/components/schemas/ID"
UserList:
type: array
items:
$ref: "#/components/schemas/User"
# Individuals
# Organisations
@ -120,51 +141,69 @@ components:
ApiError:
type: object
required:
- name
- message
- url
- code
properties:
name:
type: string
message:
type: string
url:
type: string
example: "/users"
example: "/api/v1/users"
code:
type: integer
example: 500
UnauthorizedApiError:
type: object
required:
- name
- message
- url
- code
properties:
name:
type: string
example: "Authentication failed. Please make sure you pass the API key of an API enabled user along in the Authorization header."
message:
type: string
example: "Authentication failed. Please make sure you pass the API key of an API enabled user along in the Authorization header."
url:
type: string
example: "/users"
example: "/api/v1/users"
code:
type: integer
example: 403
MethodNotAllowedApiError:
type: object
required:
- message
- url
- code
properties:
message:
type: string
example: "You do not have permission to use this functionality."
url:
type: string
example: "/api/v1/users/index"
code:
type: integer
example: 405
NotFoundApiError:
type: object
required:
- name
- message
- url
- code
properties:
name:
type: string
example: "Invalid user"
message:
type: string
example: "Invalid user"
url:
type: string
example: "/users/1234"
example: "/api/v1/users/users/view/1234"
code:
type: integer
example: 404
parameters:
userId:
@ -189,13 +228,20 @@ components:
responses:
# User
ViewUserResponse:
GetUserResponse:
description: "User response"
content:
application/json:
schema:
$ref: "#/components/schemas/User"
GetUsersResponse:
description: "User response"
content:
application/json:
schema:
$ref: "#/components/schemas/UserList"
# Errors
ApiErrorResponse:
description: "Unexpected API error"
@ -211,5 +257,12 @@ components:
schema:
$ref: "#/components/schemas/UnauthorizedApiError"
MethodNotAllowedApiErrorResponse:
description: "Method not allowed. Your User Role is not allowed to access this resource."
content:
application/json:
schema:
$ref: "#/components/schemas/MethodNotAllowedApiError"
security:
- ApiKeyAuth: []