Skip to content

Commit

Permalink
Merge pull request #114 from FriendsOfCake/dakota-patch-1
Browse files Browse the repository at this point in the history
  • Loading branch information
dakota authored Jun 30, 2020
2 parents 0e7b21c + f2b64f3 commit 5bea6d7
Show file tree
Hide file tree
Showing 7 changed files with 19 additions and 52 deletions.
4 changes: 2 additions & 2 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
"require":{
"php": ">=7.2.0",
"cakephp/cakephp": "^4.0.2",
"friendsofcake/crud": "^6.0-beta",
"friendsofcake/crud": "^6.0-beta3",
"neomerx/json-api": "^4.0"
},
"require-dev": {
Expand Down Expand Up @@ -66,7 +66,7 @@
"cs-check": "phpcs -p --standard=vendor/cakephp/cakephp-codesniffer/CakePHP src/ tests/",
"cs-fix": "phpcbf --standard=vendor/cakephp/cakephp-codesniffer/CakePHP src/ tests/",
"phpstan-setup": "cp composer.json composer.backup && composer require --dev phpstan/phpstan:\"^0.12\" && mv composer.backup composer.json",
"phpstan": "phpstan analyse src/",
"phpstan": "phpstan analyse --memory-limit=3G src/",
"test": "phpunit"
}
}
3 changes: 0 additions & 3 deletions phpstan.neon
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,6 @@ parameters:
ignoreErrors:
# ORM
- '#Call to an undefined method Cake\\Datasource\\EntityInterface::visibleProperties\(\)\.#'
- '#Call to an undefined method Cake\\ORM\\Association::getAlias\(\)\.#'
- '#Method CrudJsonApi\\Listener\\JsonApiListener::_getSingleEntity\(\) should return Cake\\Datasource\\EntityInterface but returns array\|Cake\\Datasource\\EntityInterface\|null\.#'
- '#Method CrudJsonApi\\Listener\\JsonApiListener::_getSingleEntity\(\) should return Cake\\Datasource\\EntityInterface but returns array\|object\|null\.#'

# Crud properties
- '#Access to an undefined property object::\$created#'
Expand Down
2 changes: 1 addition & 1 deletion src/Listener/JsonApi/DocumentValidator.php
Original file line number Diff line number Diff line change
Expand Up @@ -259,7 +259,7 @@ protected function _primaryDataMayHaveRelationships(): bool
if (empty($relationships)) {
$this->_errorCollection->addRelationshipsError(
$title = '_required',
$detail = "Relationships object does not contain any members",
$detail = 'Relationships object does not contain any members',
$status = null,
$idx = null,
$aboutLink = $this->_getAboutLink('http://jsonapi.org/format/#crud-creating')
Expand Down
40 changes: 8 additions & 32 deletions src/Listener/JsonApiListener.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@

namespace CrudJsonApi\Listener;

use Cake\Core\Configure;
use Cake\Datasource\EntityInterface;
use Cake\Datasource\RepositoryInterface;
use Cake\Datasource\ResultSetDecorator;
use Cake\Datasource\ResultSetInterface;
use Cake\Event\EventInterface;
use Cake\Http\Exception\BadRequestException;
use Cake\Http\Exception\MethodNotAllowedException;
use Cake\Http\Response;
use Cake\ORM\Association;
use Cake\ORM\Query;
Expand Down Expand Up @@ -110,28 +110,6 @@ public function implementedEvents(): array
];
}

/**
* setup
*
* Called when the listener is created
*
* @return void
*/
public function setup(): void
{
if (!$this->_checkRequestType('jsonapi')) {
return;
}

$appClass = Configure::read('App.namespace') . '\Application';

// If `App\Application` class exists it means Cake 3.3's PSR7 middleware
// implementation is used and it's too late to register new error handler.
if (!class_exists($appClass, false)) {
$this->registerExceptionHandler();
}
}

/**
* beforeHandle
*
Expand Down Expand Up @@ -435,7 +413,7 @@ protected function _includeParameter($includes, Subject $subject, $options): voi
}

if ($options['blacklist'] === true || $options['whitelist'] === false) {
throw new BadRequestException("The include parameter is not supported");
throw new BadRequestException('The include parameter is not supported');
}

$this->setConfig('include', []);
Expand Down Expand Up @@ -790,25 +768,23 @@ protected function _validateConfigOptions(): void
* Override ApiListener method to enforce required JSON API request methods.
*
* @throws \Cake\Http\Exception\BadRequestException
* @return bool
* @return void
*/
protected function _checkRequestMethods(): bool
protected function _checkRequestMethods(): void
{
if ($this->_request()->is('put')) {
throw new BadRequestException('JSON API does not support the PUT method, use PATCH instead');
throw new MethodNotAllowedException('JSON API does not support the PUT method, use PATCH instead');
}

if (!$this->_request()->contentType()) {
return true;
return;
}

if ($this->_request()->contentType() !== self::MIME_TYPE) {
throw new BadRequestException(
'JSON API requests with data require the "' . self::MIME_TYPE . '" Content-Type header'
);
}

return true;
}

/**
Expand Down Expand Up @@ -866,11 +842,11 @@ protected function _getFindResult(Subject $subject)
*
* @param \Crud\Event\Subject $subject Subject
* @return \Cake\Datasource\EntityInterface|null
* @phpstan-ignore
*/
protected function _getSingleEntity(Subject $subject): ?EntityInterface
{
if (!empty($subject->entities) && $subject->entities instanceof Query) {
// @phpstan-ignore-next-line
return (clone $subject->entities)->first();
}

Expand Down Expand Up @@ -987,7 +963,7 @@ protected function _getRepositoryList(RepositoryInterface $repository, array $as
];

if ($association['association'] === null) {
throw new InvalidArgumentException("Association does not have an association object set");
throw new InvalidArgumentException('Association does not have an association object set');
}

$associationRepository = $association['association']->getTarget();
Expand Down
4 changes: 2 additions & 2 deletions src/Schema/JsonApi/DynamicEntitySchema.php
Original file line number Diff line number Diff line change
Expand Up @@ -356,13 +356,13 @@ public function getRelationshipRelatedLink($entity, string $name): LinkInterface
// generate the link for hasMany relationship
$foreignKeys = (array)$association->getForeignKey();
$primaryKeys = $entity->extract((array)$this->getRepository()->getPrimaryKey());
$keys = array_combine($foreignKeys, $primaryKeys);
$keys = (array)array_combine($foreignKeys, $primaryKeys);

$url = Router::url(
$this->_getRepositoryRoutingParameters($relatedRepository) + $keys + [
'_method' => 'GET',
'action' => 'index',
'?' => $keys
'?' => $keys,
],
$this->view->getConfig('absoluteLinks', false)
);
Expand Down
16 changes: 5 additions & 11 deletions tests/TestCase/Listener/JsonApiListenerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
use Cake\Event\Event;
use Cake\Filesystem\File;
use Cake\Http\Exception\BadRequestException;
use Cake\Http\Exception\MethodNotAllowedException;
use Cake\Http\Response;
use Cake\Http\ServerRequest;
use Cake\ORM\Entity;
Expand Down Expand Up @@ -192,10 +193,6 @@ public function testBeforeHandle()
->method('_convertJsonApiDocumentArray')
->willReturn([]);

$listener
->method('_checkRequestMethods')
->willReturn(true);

$listener->beforeHandle(new Event('Crud.beforeHandle'));
$this->assertTrue(true);
}
Expand Down Expand Up @@ -737,15 +734,16 @@ public function testCheckRequestMethodsSuccess()
$listener->setupDetectors();

$this->setReflectionClassInstance($listener);
$this->assertTrue($this->callProtectedMethod('_checkRequestMethods', [], $listener));
$this->callProtectedMethod('_checkRequestMethods', [], $listener);
$this->assertTrue(true); //No exception was thrown
}

/**
* Make sure the listener fails on non JSON API request Content-Type header
*/
public function testCheckRequestMethodsFailContentHeader()
{
$this->expectException('Cake\Http\Exception\BadRequestException');
$this->expectException(BadRequestException::class);
$this->expectExceptionMessage('JSON API requests with data require the "application/vnd.api+json" Content-Type header');
$request = new ServerRequest();
$request = $request->withEnv('HTTP_ACCEPT', 'application/vnd.api+json')
Expand All @@ -765,7 +763,7 @@ public function testCheckRequestMethodsFailContentHeader()
*/
public function testCheckRequestMethodsFailOnPutMethod()
{
$this->expectException('Cake\Http\Exception\BadRequestException');
$this->expectException(MethodNotAllowedException::class);
$this->expectExceptionMessage('JSON API does not support the PUT method, use PATCH instead');
$request = new ServerRequest();
$request = $request->withEnv('HTTP_ACCEPT', 'application/vnd.api+json')
Expand Down Expand Up @@ -1148,10 +1146,6 @@ public function testCheckRequestData()
->method('_convertJsonApiDocumentArray')
->willReturn([]);

$listener
->method('_checkRequestMethods')
->willReturn(true);

$this->setReflectionClassInstance($listener);

// assert null if there is no Content-Type
Expand Down
2 changes: 1 addition & 1 deletion tests/test_app/src/Model/Table/CountriesTable.php
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ public function validationDefault(Validator $validator): Validator
->add('code', [
'UPPERCASE_ONLY' => [
'rule' => ['custom', '/^([A-Z]+)+$/'],
'message' => "Field must be uppercase only",
'message' => 'Field must be uppercase only',
],
]);

Expand Down

0 comments on commit 5bea6d7

Please sign in to comment.