Skip to content

Commit

Permalink
Merge pull request #34 from bedita/feat/2.x/backport-api-proxy-post-p…
Browse files Browse the repository at this point in the history
…atch-delete

feat: add `post`, `patch` and `delete` to ApiProxyTrait
  • Loading branch information
batopa authored Oct 7, 2020
2 parents 2a022f0 + 524b2c8 commit 339c395
Show file tree
Hide file tree
Showing 3 changed files with 162 additions and 17 deletions.
83 changes: 66 additions & 17 deletions src/Controller/ApiProxyTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -100,16 +100,60 @@ protected function setBaseUrl($path): void
* @param string $path The path for API request
* @return void
*/
public function get($path = '')
public function get($path = ''): void
{
$this->setBaseUrl($path);
$this->apiRequest([
'method' => 'get',
'path' => $path,
'query' => $this->request->getQueryParams(),
]);
}

/**
* Proxy for POST requests to BEdita4 API
*
* @param string $path The path for API request
* @return void
*/
public function post($path = ''): void
{
$this->apiRequest([
'method' => 'post',
'path' => $path,
'body' => $this->request->getData(),
]);
}

/**
* Proxy for PATCH requests to BEdita4 API
*
* @param string $path The path for API request
* @return void
*/
public function patch($path = ''): void
{
$this->apiRequest([
'method' => 'patch',
'path' => $path,
'body' => $this->request->getData(),
]);
}

/**
* Proxy for DELETE requests to BEdita4 API
*
* @param string $path The path for API request
* @return void
*/
public function delete($path = ''): void
{
$this->apiRequest([
'method' => 'delete',
'path' => $path,
'body' => $this->request->getData(),
]);
}

/**
* Routes a request to the API handling response and errors.
*
Expand All @@ -133,22 +177,27 @@ protected function apiRequest(array $options): void
'headers' => null,
];

if (empty($options['body'])) {
$options['body'] = null;
}
if (is_array($options['body'])) {
$options['body'] = json_encode($options['body']);
}

try {
switch (strtolower($options['method'])) {
case 'get':
$response = $this->apiClient->get($options['path'], $options['query'], $options['headers']);
break;
// case 'post':
// $response = $this->apiClient->post($options['path'], $options['body'], $options['headers']);
// break;
// case 'patch':
// $response = $this->apiClient->patch($options['path'], $options['body'], $options['headers']);
// break;
// case 'delete':
// $response = $this->apiClient->delete($options['path'], $options['body'], $options['headers']);
// break;
default:
throw new MethodNotAllowedException();
$this->setBaseUrl($options['path']);
$method = strtolower($options['method']);
if (!in_array($method, ['get', 'post', 'patch', 'delete'])) {
throw new MethodNotAllowedException();
}

if ($method === 'get') {
$response = $this->apiClient->get($options['path'], $options['query'], $options['headers']);
} else {
$response = call_user_func_array(
[$this->apiClient, $method], // call 'post', 'patch' or 'delete'
[$options['path'], $options['body'], $options['headers']]
);
}

if ($response === null) {
Expand Down
93 changes: 93 additions & 0 deletions tests/TestCase/Controller/ApiProxyTraitTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -279,4 +279,97 @@ protected function setBaseUrl($path): void
$body = (string)$controller->getResponse()->getBody();
static::assertEmpty($body);
}

/**
* Test POST request
*
* @return void
*
* @covers ::post()
* @covers ::apiRequest()
*/
public function testPost(): void
{
$this->post('/api/documents', [
'data' => [
'type' => 'documents',
'attributes' => [
'title' => 'The Doc',
],
],
]);

$this->assertResponseOk();
$this->assertContentType('application/json');
$response = json_decode((string)$this->_response, true);
static::assertArrayHasKey('data', $response);
static::assertArrayHasKey('links', $response);
static::assertArrayHasKey('meta', $response);
static::assertEquals('The Doc', Hash::get($response, 'data.attributes.title'));
}

/**
* Test PATCH request
*
* @return void
*
* @covers ::patch()
* @covers ::apiRequest()
*/
public function testPatch(): void
{
$data = [
'type' => 'documents',
'attributes' => [
'title' => 'new doc',
],
];
$this->post('/api/documents', compact('data'));
$this->assertResponseOk();

$response = json_decode((string)$this->_response, true);
$id = Hash::get($response, 'data.id');
$data['id'] = $id;
$data['attributes']['title'] = 'new doc title';

Router::resetRoutes();

$this->patch('/api/documents/' . $id, compact('data'));
$this->assertResponseOk();
$response = json_decode((string)$this->_response, true);
static::assertArrayHasKey('data', $response);
static::assertArrayHasKey('links', $response);
static::assertArrayHasKey('meta', $response);

static::assertEquals($data['attributes']['title'], Hash::get($response, 'data.attributes.title'));
}

/**
* Test DELETE request
*
* @return void
*
* @covers ::delete()
* @covers ::apiRequest()
*/
public function testDelete(): void
{
$data = [
'type' => 'documents',
'attributes' => [
'title' => 'new doc',
],
];
$this->post('/api/documents', compact('data'));
$this->assertResponseOk();

Router::resetRoutes();

$response = json_decode((string)$this->_response, true);
$id = Hash::get($response, 'data.id');
$this->delete('/api/documents/' . $id);
$this->assertResponseOk();
$response = json_decode((string)$this->_response, true);
static::assertEmpty($response);
}
}
3 changes: 3 additions & 0 deletions tests/test_app/TestApp/Application.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@ 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');
$routes->post('/**', ['controller' => 'Api', 'action' => 'post'], 'post');
$routes->patch('/**', ['controller' => 'Api', 'action' => 'patch'], 'patch');
$routes->delete('/**', ['controller' => 'Api', 'action' => 'delete'], 'delete');
});
}
}

0 comments on commit 339c395

Please sign in to comment.