Skip to content

Commit

Permalink
feat: add tests for ApiProxyTrait
Browse files Browse the repository at this point in the history
  • Loading branch information
batopa committed Jun 1, 2020
1 parent 7420c4e commit be3cb1b
Show file tree
Hide file tree
Showing 4 changed files with 174 additions and 4 deletions.
27 changes: 23 additions & 4 deletions src/Controller/ApiProxyTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,18 +15,34 @@
namespace BEdita\WebTools\Controller;

use BEdita\SDK\BEditaClientException;
use BEdita\WebTools\ApiClientProvider;
use Cake\Http\Exception\MethodNotAllowedException;
use Cake\Routing\Router;
use Cake\Utility\Hash;

/**
* Trait to directly proxy requests to BE4 API.
* Use this Trait in a controller to directly proxy requests to BE4 API.
* The response will be the same of the API itself with links masked.
*
* It should be used in controller with route rules configured as
* You need also to define routing rules configured as (for ApiController)
*
* ```
* $builder->scope('/api', ['_namePrefix' => 'api:'], function (RouteBuilder $builder) {
* $builder->get('/**', ['controller' => 'Api', 'action' => 'get'], 'get');
* $builder->post('/**', ['controller' => 'Api', 'action' => 'post'], 'post');
* // and so on for patch, delete if you want to use it
* });
* ```
*/
trait ApiProxyTrait
{
/**
* BEdita4 API client
*
* @var \BEdita\SDK\BEditaClient
*/
protected $apiClient = null;

/**
* Base URL used for mask links.
*
Expand All @@ -36,13 +52,15 @@ trait ApiProxyTrait

/**
* {@inheritDoc}
*
* @codeCoverageIgnore
*/
public function initialize(): void
{
parent::initialize();

if ($this->apiClient === null) {
$this->apiClient = ApiClientProvider::getApiClient();
}

$this->viewBuilder()
->setClassName('Json')
->setOption('serialize', true);
Expand Down Expand Up @@ -131,6 +149,7 @@ protected function request(array $options): void

/**
* Handle error.
* Set error var for view.
*
* @param \Throwable $error The error thrown.
* @return void
Expand Down
104 changes: 104 additions & 0 deletions tests/TestCase/Controller/ApiProxyTraitTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,113 @@
*/
namespace BEdita\WebTools\Test\TestCase\Controller;

use BEdita\WebTools\ApiClientProvider;
use Cake\Routing\Router;
use Cake\TestSuite\IntegrationTestTrait;
use Cake\TestSuite\TestCase;
use Cake\Utility\Hash;

/**
* ApiProxyTraitTest class
*
* {@see \BEdita\WebTools\Controller\ApiProxyTrait} Test Case
*
* @coversDefaultClass \BEdita\WebTools\Controller\ApiProxyTrait
*/
class ApiProxyTraitTest extends TestCase
{
use IntegrationTestTrait;

/**
* Instance of BEditaClient
*
* @var \BEdita\SDK\BEditaClient
*/
protected $apiClient = null;

/**
* {@inheritDoc}
*/
public function setUp(): void
{
parent::setUp();

$this->apiClient = ApiClientProvider::getApiClient();
$response = $this->apiClient->authenticate(env('BEDITA_ADMIN_USR'), env('BEDITA_ADMIN_PWD'));
$this->apiClient->setupTokens($response['meta']);
}

/**
* {@inheritDoc}
*/
public function tearDown(): void
{
parent::tearDown();

$this->apiClient = null;
}

/**
* Test get() method
*
* @return void
*
* @covers ::initialize()
* @covers ::get()
* @covers ::setBaseUrl()
* @covers ::request()
* @covers ::maskResponseLinks()
* @covers ::maskMultiLinks()
* @covers ::maskLinks()
*/
public function testGet(): void
{
$this->get('/api/users/1');
$this->assertResponseOk();
$this->assertContentType('application/json');
$data = $this->viewVariable('data');
$links = $this->viewVariable('links');
$meta = $this->viewVariable('meta');
static::assertNotEmpty($data);
static::assertNotEmpty($links);
static::assertNotEmpty($meta);
static::assertEquals('1', Hash::get($data, 'id'));

$response = json_decode((string)$this->_response, true);
static::assertArrayHasKey('data', $response);
static::assertArrayHasKey('links', $response);
static::assertArrayHasKey('meta', $response);

$baseUrl = Router::url('/', true);
foreach ($response['links'] as $link) {
static::assertStringContainsString($baseUrl, $link);
}

foreach (Hash::extract($response, 'data.relationships.{s}.links') as $link) {
static::assertStringContainsString($baseUrl, $link);
}
}

/**
* Test non found error proxied from API.
*
* @return void
*
* @covers ::get()
* @covers ::request()
* @covers ::handleError()
*/
public function testNotFoundError(): void
{
$this->get('/api/users/1000');
$this->assertResponseError();
$this->assertContentType('application/json');
$error = $this->viewVariable('error');
static::assertNotEmpty($error);

$response = json_decode((string)$this->_response, true);
static::assertArrayHasKey('error', $response);
static::assertArrayHasKey('status', $response['error']);
static::assertArrayHasKey('title', $response['error']);
}
}
24 changes: 24 additions & 0 deletions tests/test_app/TestApp/Application.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@

use Cake\Http\BaseApplication;
use Cake\Http\MiddlewareQueue;
use Cake\Routing\Middleware\RoutingMiddleware;
use Cake\Routing\RouteBuilder;

/**
* Application setup class.
Expand All @@ -14,11 +16,33 @@
*/
class Application extends BaseApplication
{
/**
* {@inheritDoc}
*
* Do not require config/bootstrap.php
*/
public function bootstrap(): void
{
}

/**
* {@inheritDoc}
*/
public function routes(RouteBuilder $routes): void
{
// add rules for ApiProxyTrait
$routes->scope('/api', ['_namePrefix' => 'api:'], function (RouteBuilder $routes) {
$routes->get('/**', ['controller' => 'Api', 'action' => 'get'], 'get');
});
}

/**
* {@inheritDoc}
*/
public function middleware(MiddlewareQueue $middleware): MiddlewareQueue
{
$middleware->add(new RoutingMiddleware($this));

return $middleware;
}
}
23 changes: 23 additions & 0 deletions tests/test_app/TestApp/Controller/ApiController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?php
declare(strict_types=1);

/**
* BEdita, API-first content management framework
* Copyright 2018 ChannelWeb Srl, Chialab Srl
*
* This file is part of BEdita: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* See LICENSE.LGPL or <http://gnu.org/licenses/lgpl-3.0.html> for more details.
*/
namespace TestApp\Controller;

use BEdita\WebTools\Controller\ApiProxyTrait;
use Cake\Controller\Controller;

class ApiController extends Controller
{
use ApiProxyTrait;
}

0 comments on commit be3cb1b

Please sign in to comment.