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; namespace App\Test\Helper;
use Cake\Http\Exception\NotImplementedException;
use \League\OpenAPIValidation\PSR7\ValidatorBuilder; use \League\OpenAPIValidation\PSR7\ValidatorBuilder;
use \League\OpenAPIValidation\PSR7\RequestValidator; use \League\OpenAPIValidation\PSR7\RequestValidator;
use \League\OpenAPIValidation\PSR7\ResponseValidator; 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 * Parse the OpenAPI specification and create a validator
* *

View File

@ -1,5 +1,5 @@
# Testing # Testing
## Configuration
1. Add a `cerebrate_test` database to the db: 1. Add a `cerebrate_test` database to the db:
```mysql ```mysql
CREATE DATABASE cerebrate_test; 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 $ 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: tags:
- name: Users - name: Users
description: "TODO: users resource descriptions" description: "Users enrolled in this Cerebrate instance."
paths: 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: /api/v1/users/view:
get: get:
summary: "Get information about the current user" summary: "Get information about the current user"
@ -22,7 +38,7 @@ paths:
- Users - Users
responses: responses:
"200": "200":
$ref: "#/components/responses/ViewUserResponse" $ref: "#/components/responses/GetUserResponse"
"403": "403":
$ref: "#/components/responses/UnauthorizedApiErrorResponse" $ref: "#/components/responses/UnauthorizedApiErrorResponse"
default: default:
@ -38,7 +54,7 @@ paths:
- $ref: "#/components/parameters/userId" - $ref: "#/components/parameters/userId"
responses: responses:
"200": "200":
$ref: "#/components/responses/ViewUserResponse" $ref: "#/components/responses/GetUserResponse"
"403": "403":
$ref: "#/components/responses/UnauthorizedApiErrorResponse" $ref: "#/components/responses/UnauthorizedApiErrorResponse"
default: default:
@ -90,6 +106,11 @@ components:
organisation_id: organisation_id:
$ref: "#/components/schemas/ID" $ref: "#/components/schemas/ID"
UserList:
type: array
items:
$ref: "#/components/schemas/User"
# Individuals # Individuals
# Organisations # Organisations
@ -120,51 +141,69 @@ components:
ApiError: ApiError:
type: object type: object
required: required:
- name
- message - message
- url - url
- code
properties: properties:
name:
type: string
message: message:
type: string type: string
url: url:
type: string type: string
example: "/users" example: "/api/v1/users"
code:
type: integer
example: 500
UnauthorizedApiError: UnauthorizedApiError:
type: object type: object
required: required:
- name
- message - message
- url - url
- code
properties: 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: message:
type: string type: string
example: "Authentication failed. Please make sure you pass the API key of an API enabled user along in the Authorization header." example: "Authentication failed. Please make sure you pass the API key of an API enabled user along in the Authorization header."
url: url:
type: string 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: NotFoundApiError:
type: object type: object
required: required:
- name
- message - message
- url - url
- code
properties: properties:
name:
type: string
example: "Invalid user"
message: message:
type: string type: string
example: "Invalid user" example: "Invalid user"
url: url:
type: string type: string
example: "/users/1234" example: "/api/v1/users/users/view/1234"
code:
type: integer
example: 404
parameters: parameters:
userId: userId:
@ -189,13 +228,20 @@ components:
responses: responses:
# User # User
ViewUserResponse: GetUserResponse:
description: "User response" description: "User response"
content: content:
application/json: application/json:
schema: schema:
$ref: "#/components/schemas/User" $ref: "#/components/schemas/User"
GetUsersResponse:
description: "User response"
content:
application/json:
schema:
$ref: "#/components/schemas/UserList"
# Errors # Errors
ApiErrorResponse: ApiErrorResponse:
description: "Unexpected API error" description: "Unexpected API error"
@ -211,5 +257,12 @@ components:
schema: schema:
$ref: "#/components/schemas/UnauthorizedApiError" $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: security:
- ApiKeyAuth: [] - ApiKeyAuth: []