Skip to content

Commit

Permalink
Feature: validate only fullpath (GroupPath+ControllerPath+Path) to al…
Browse files Browse the repository at this point in the history
…low tiny controllers.
  • Loading branch information
f3l1x committed Jan 23, 2018
1 parent f5efcdc commit 92061ba
Show file tree
Hide file tree
Showing 5 changed files with 75 additions and 126 deletions.
2 changes: 2 additions & 0 deletions src/DI/Plugin/CoreSchemaPlugin.php
Expand Up @@ -9,6 +9,7 @@
use Apitte\Core\Schema\Serialization\ArraySerializator;
use Apitte\Core\Schema\Serialization\IDecorator;
use Apitte\Core\Schema\Validation\ControllerPathValidation;
use Apitte\Core\Schema\Validation\FullpathValidation;
use Apitte\Core\Schema\Validation\GroupPathValidation;
use Apitte\Core\Schema\Validation\IdValidation;
use Apitte\Core\Schema\Validation\IValidation;
Expand All @@ -29,6 +30,7 @@ class CoreSchemaPlugin extends AbstractPlugin
'controllerPath' => ControllerPathValidation::class,
'groupPath' => GroupPathValidation::class,
'path' => PathValidation::class,
'fullPath' => FullpathValidation::class,
'id' => IdValidation::class,
'requestMapper' => RequestMapperValidation::class,
];
Expand Down
22 changes: 0 additions & 22 deletions src/Schema/Validation/ControllerPathValidation.php
Expand Up @@ -15,32 +15,10 @@ class ControllerPathValidation implements IValidation
*/
public function validate(SchemaBuilder $builder)
{
$this->validateDuplicities($builder);
$this->validateSlashes($builder);
$this->validateRegex($builder);
}

/**
* @param SchemaBuilder $builder
* @return void
*/
protected function validateDuplicities(SchemaBuilder $builder)
{
$paths = [];
$controllers = $builder->getControllers();

foreach ($controllers as $controller) {
// If this ControllerPath exists, throw an exception
if (array_key_exists($controller->getPath(), $paths)) {
throw new InvalidSchemaException(
sprintf('Duplicate @ControllerPath in %s and %s', $controller->getClass(), $paths[$controller->getPath()])
);
}

$paths[$controller->getPath()] = $controller->getClass();
}
}

/**
* @param SchemaBuilder $builder
* @return void
Expand Down
73 changes: 73 additions & 0 deletions src/Schema/Validation/FullpathValidation.php
@@ -0,0 +1,73 @@
<?php

namespace Apitte\Core\Schema\Validation;

use Apitte\Core\Exception\Logical\InvalidSchemaException;
use Apitte\Core\Schema\Builder\SchemaBuilder;
use Apitte\Core\Schema\Endpoint;
use Apitte\Core\Utils\Helpers;

class FullpathValidation implements IValidation
{

/**
* @param SchemaBuilder $builder
* @return void
*/
public function validate(SchemaBuilder $builder)
{
$this->validateDuplicities($builder);
}

/**
* @param SchemaBuilder $builder
* @return void
*/
protected function validateDuplicities(SchemaBuilder $builder)
{
$controllers = $builder->getControllers();

// Init paths
$paths = [
Endpoint::METHOD_GET => [],
Endpoint::METHOD_POST => [],
Endpoint::METHOD_PUT => [],
Endpoint::METHOD_DELETE => [],
Endpoint::METHOD_OPTIONS => [],
Endpoint::METHOD_PATCH => [],
];

foreach ($controllers as $controller) {
foreach ($controller->getMethods() as $method) {
foreach ($method->getMethods() as $httpMethod) {

$maskp = array_merge(
$controller->getGroupPaths(),
[$controller->getPath()],
[$method->getPath()]
);
$mask = implode('/', $maskp);
$mask = Helpers::slashless($mask);
$mask = '/' . trim($mask, '/');

if (array_key_exists($mask, $paths[$httpMethod])) {
throw new InvalidSchemaException(
sprintf(
'Duplicate path "%s" in "%s()" and "%s()"',
$mask,
$controller->getClass() . '::' . $method->getName(),
$paths[$httpMethod][$mask]['controller']->getClass() . '::' . $paths[$httpMethod][$mask]['method']->getName()
)
);
}

$paths[$httpMethod][$mask] = [
'controller' => $controller,
'method' => $method,
];
}
}
}
}

}
45 changes: 0 additions & 45 deletions src/Schema/Validation/PathValidation.php
Expand Up @@ -4,7 +4,6 @@

use Apitte\Core\Exception\Logical\InvalidSchemaException;
use Apitte\Core\Schema\Builder\SchemaBuilder;
use Apitte\Core\Schema\Endpoint;
use Apitte\Core\Utils\Regex;

class PathValidation implements IValidation
Expand All @@ -16,54 +15,10 @@ class PathValidation implements IValidation
*/
public function validate(SchemaBuilder $builder)
{
$this->validateDuplicities($builder);
$this->validateSlashes($builder);
$this->validateRegex($builder);
}

/**
* @param SchemaBuilder $builder
* @return void
*/
protected function validateDuplicities(SchemaBuilder $builder)
{
$controllers = $builder->getControllers();
$paths = [];

foreach ($controllers as $controller) {
foreach ($controller->getMethods() as $method) {
// Init controller paths
if (!isset($paths[$controller->getClass()])) {
$paths[$controller->getClass()] = [
Endpoint::METHOD_GET => [],
Endpoint::METHOD_POST => [],
Endpoint::METHOD_PUT => [],
Endpoint::METHOD_DELETE => [],
Endpoint::METHOD_OPTIONS => [],
Endpoint::METHOD_PATCH => [],
];
}

// If this ControllerPath exists, throw an exception
foreach ($method->getMethods() as $httpMethod) {
if (array_key_exists($method->getPath(), $paths[$controller->getClass()][$httpMethod])) {
throw new InvalidSchemaException(
sprintf(
'Duplicate @Path "%s" in %s at methods "%s()" and "%s()"',
$method->getPath(),
$controller->getClass(),
$method->getName(),
$paths[$controller->getClass()][$httpMethod][$method->getPath()]
)
);
}

$paths[$controller->getClass()][$httpMethod][$method->getPath()] = $method->getName();
}
}
}
}

/**
* @param SchemaBuilder $builder
* @return void
Expand Down
59 changes: 0 additions & 59 deletions tests/cases/Schema/Validation/PathValidator.phpt
Expand Up @@ -39,65 +39,6 @@ test(function () {
}, InvalidSchemaException::class, '@Path "/foobar/" in "c1::foo()" must not ends with "/" (slash).');
});

// Validate: duplicities
test(function () {
$builder = new SchemaBuilder();

$c1 = $builder->addController('c1');
$c1m1 = $c1->addMethod('foo1');
$c1m1->setPath('/foobar');
$c1m1->addMethod('GET');

$c1m2 = $c1->addMethod('foo2');
$c1m2->setPath('/foobar');
$c1m2->addMethod('GET');

Assert::exception(function () use ($builder) {
$validator = new PathValidation();
$validator->validate($builder);
}, InvalidSchemaException::class, 'Duplicate @Path "/foobar" in c1 at methods "foo2()" and "foo1()"');
});

// Validate: duplicities
test(function () {
$builder = new SchemaBuilder();

$c1 = $builder->addController('c1');
$c1m1 = $c1->addMethod('foo1');
$c1m1->setPath('/foobar');
$c1m1->setMethods(['GET', 'POST']);

$c1m2 = $c1->addMethod('foo2');
$c1m2->setPath('/foobar');
$c1m2->setMethods(['POST', 'PUT']);

Assert::exception(function () use ($builder) {
$validator = new PathValidation();
$validator->validate($builder);
}, InvalidSchemaException::class, 'Duplicate @Path "/foobar" in c1 at methods "foo2()" and "foo1()"');
});

// Validate: [NOT] duplicities
test(function () {
$builder = new SchemaBuilder();

$c1 = $builder->addController('c1');
$c1m1 = $c1->addMethod('foo1');
$c1m1->setPath('/foobar');
$c1m1->addMethod('GET');

$c1m2 = $c1->addMethod('foo2');
$c1m2->setPath('/foobar');
$c1m2->setMethods(['POST']);

try {
$validator = new PathValidation();
$validator->validate($builder);
} catch (Exception $e) {
Assert::fail('This is fail. Paths+Method are different.');
}
});

// Validate: invalid parameter (ends)
test(function () {
$builder = new SchemaBuilder();
Expand Down

0 comments on commit 92061ba

Please sign in to comment.