Skip to content

Commit

Permalink
Merge 5897512 into bac3f25
Browse files Browse the repository at this point in the history
  • Loading branch information
mabar committed Aug 3, 2018
2 parents bac3f25 + 5897512 commit c7344f8
Show file tree
Hide file tree
Showing 14 changed files with 671 additions and 6 deletions.
3 changes: 3 additions & 0 deletions src/Schema/Builder/Controller/Method.php
Expand Up @@ -155,6 +155,9 @@ public function getArguments(): array
return $this->arguments;
}

/**
* @internal
*/
public function addParameter(string $name): MethodParameter
{
$parameter = new MethodParameter($name);
Expand Down
2 changes: 1 addition & 1 deletion src/Schema/Serialization/ArraySerializator.php
Expand Up @@ -149,7 +149,7 @@ protected function serializePattern(array &$endpoint, Controller $controller, Me
// and number fo parameters in mask
if (count($pathParameters) > count($maskParameters)) {
throw new InvalidStateException(sprintf(
'Controller "%s::%s()" has more @RequestParameters (%d / %d) then typed in his mask.',
'Method "%s::%s()" has more @RequestParameter(in=path) (%d / %d) then typed in its mask.',
$controller->getClass(),
$method->getName(),
count($pathParameters),
Expand Down
7 changes: 2 additions & 5 deletions src/Schema/Validation/ControllerPathValidation.php
Expand Up @@ -22,12 +22,9 @@ protected function validateSlashes(SchemaBuilder $builder): void
foreach ($controllers as $controller) {
$path = $controller->getPath();

if (strlen($path) === 1) {
if ($path === '/') continue;

// MUST: Be exactly /
if ($path === null) {
throw new InvalidSchemaException(
sprintf('@ControllerPath "%s" in "%s" must be exactly "/" (slash).', $path, $controller->getClass())
sprintf('@ControllerPath in "%s" must be set.', $controller->getClass())
);
}

Expand Down
91 changes: 91 additions & 0 deletions tests/cases/Schema/Endpoint.phpt
@@ -0,0 +1,91 @@
<?php declare(strict_types = 1);

/**
* Test: Schema\Endpoint
*/

require_once __DIR__ . '/../../bootstrap.php';

use Apitte\Core\Exception\Logical\InvalidArgumentException;
use Apitte\Core\Exception\Logical\InvalidStateException;
use Apitte\Core\Schema\Endpoint;
use Apitte\Core\Schema\EndpointParameter;
use Tester\Assert;

// AddMethod: success
test(function (): void {
$endpoint = new Endpoint();

$endpoint->addMethod($endpoint::METHOD_GET);
$endpoint->addMethod($endpoint::METHOD_POST);

Assert::same([$endpoint::METHOD_GET, $endpoint::METHOD_POST], $endpoint->getMethods());
});

// AddMethod: fail
test(function (): void {
$endpoint = new Endpoint();

Assert::exception(function () use ($endpoint): void {
$endpoint->addMethod('foo');
}, InvalidArgumentException::class, 'Method FOO is not allowed');

Assert::exception(function () use ($endpoint): void {
$endpoint->addMethod('FOO');
}, InvalidArgumentException::class, 'Method FOO is not allowed');
});

// HasMethod: success
test(function (): void {
$endpoint = new Endpoint();

$endpoint->addMethod($endpoint::METHOD_GET);

Assert::true($endpoint->hasMethod('get'));
Assert::true($endpoint->hasMethod('GET'));
});

// HasMethod: fail
test(function (): void {
$endpoint = new Endpoint();

Assert::false($endpoint->hasMethod('foo'));
});

// GetPattern: fail, empty
test(function (): void {
$endpoint = new Endpoint();

Assert::exception(function () use ($endpoint): void {
$endpoint->getPattern();
}, InvalidStateException::class, 'Pattern attribute is required');
});

// GetParametersByIn: empty
test(function (): void {
$endpoint = new Endpoint();

Assert::same([], $endpoint->getParametersByIn('foo'));
});

// GetParametersByIn: success, in cookie
test(function (): void {
$endpoint = new Endpoint();

$p1 = new EndpointParameter();
$p1->setIn(EndpointParameter::IN_COOKIE);
$p1->setName('p1');
$endpoint->addParameter($p1);

$p2 = new EndpointParameter();
$p2->setIn(EndpointParameter::IN_COOKIE);
$p2->setName('p2');
$endpoint->addParameter($p2);

$p3 = new EndpointParameter();
$p3->setIn(EndpointParameter::IN_PATH);
$p3->setName('p3');
$endpoint->addParameter($p3);

Assert::same(['p1' => $p1, 'p2' => $p2], $endpoint->getParametersByIn(EndpointParameter::IN_COOKIE));
});
75 changes: 75 additions & 0 deletions tests/cases/Schema/SchemaInspector.phpt
@@ -0,0 +1,75 @@
<?php declare(strict_types = 1);

/**
* Test: Schema\SchemaInspector
*/

require_once __DIR__ . '/../../bootstrap.php';

use Apitte\Core\Schema\Endpoint;
use Apitte\Core\Schema\Schema;
use Apitte\Core\Schema\SchemaInspector;
use Tester\Assert;

// GetEndpointsByTag: empty
test(function (): void {
$schema = new Schema();

$e1 = new Endpoint();
$e1->addTag('bar', 'bar1');
$schema->addEndpoint($e1);

$inspector = new SchemaInspector($schema);

Assert::same([], $inspector->getEndpointsByTag('foo'));
});

// GetEndpointsByTag: by name
test(function (): void {
$schema = new Schema();

$e1 = new Endpoint();
$e1->addTag('foo', 'foo1');
$schema->addEndpoint($e1);

$e2 = new Endpoint();
$e2->addTag('foo', 'foo2');
$schema->addEndpoint($e2);

$e3 = new Endpoint();
$e3->addTag('foo', 'foo3');
$schema->addEndpoint($e3);

$e4 = new Endpoint();
$e4->addTag('bar', 'bar1');
$schema->addEndpoint($e4);

$inspector = new SchemaInspector($schema);

Assert::same([$e1, $e2, $e3], $inspector->getEndpointsByTag('foo'));
});

// GetEndpointsByTag: by name and value
test(function (): void {
$schema = new Schema();

$e1 = new Endpoint();
$e1->addTag('foo', 'foo1');
$schema->addEndpoint($e1);

$e2 = new Endpoint();
$e2->addTag('foo', 'foo2');
$schema->addEndpoint($e2);

$e3 = new Endpoint();
$e3->addTag('foo', 'foo3');
$schema->addEndpoint($e3);

$e4 = new Endpoint();
$e4->addTag('bar', 'bar1');
$schema->addEndpoint($e4);

$inspector = new SchemaInspector($schema);

Assert::same([$e1], $inspector->getEndpointsByTag('foo', 'foo1'));
});
17 changes: 17 additions & 0 deletions tests/cases/Schema/Serialization/ArrayHydrator.phpt
@@ -0,0 +1,17 @@
<?php declare(strict_types = 1);

/**
* Test: Schema\Serialization\ArrayHydrator
*/

require_once __DIR__ . '/../../../bootstrap.php';

use Apitte\Core\Schema\Serialization\ArrayHydrator;
use Tester\Assert;

// AddMethod: success
test(function (): void {
$hydrator = new ArrayHydrator();

Assert::same(true, true);
});
126 changes: 126 additions & 0 deletions tests/cases/Schema/Serialization/ArraySerializator.phpt
@@ -0,0 +1,126 @@
<?php declare(strict_types = 1);

/**
* Test: Schema\Serialization\ArraySerializator
*/

require_once __DIR__ . '/../../../bootstrap.php';

use Apitte\Core\Schema\Builder\SchemaBuilder;
use Apitte\Core\Schema\Endpoint;
use Apitte\Core\Schema\EndpointParameter;
use Apitte\Core\Schema\Serialization\ArraySerializator;
use Contributte\Psr7\Psr7Response;
use Tester\Assert;

// Serialize: success
test(function (): void {
$serializator = new ArraySerializator();

$builder = new SchemaBuilder();

$c1 = $builder->addController('c1-class');
$c1->setId('c1-id');
$c1->setPath('c1-path');
$c1->addGroupId('c1-group-id');
$c1->addGroupPath('group1-path');
$c1->addGroupPath('group2-path');
$c1->addTag('c1-t1', 'c1-t1-value');

$m1 = $c1->addMethod('m1'); // Skipped, missing path

$m2 = $c1->addMethod('m2');
$m2->addMethod(Endpoint::METHOD_GET);
$m2->addMethod(Endpoint::METHOD_POST);
$m2->addMethod(Endpoint::METHOD_PUT);
$m2->setPath('m2-path');

$m3 = $c1->addMethod('m3');
$m3->setId('m3-id');
$m3->addMethod(Endpoint::METHOD_GET);
$m3->addMethod(Endpoint::METHOD_POST);
$m3->setPath('m3-path/{m3-p1}');
$m3->addTag('m3-t1');
$m3->setDescription('m3-description');
$m3->addArgument('m3-a1', Psr7Response::class);

$m3n1 = $m3->addNegotiation();
$m3n1->setSuffix('json');
$m3n1->setDefault(true);
$m3n1->setRenderer('A\\Middleware\\Implementing\\Class');

$m3n2 = $m3->addNegotiation();
$m3n2->setSuffix('xml');
$m3n2->setDefault(true);

$m3p1 = $m3->addParameter('m3-p1');
$m3p1->setType(EndpointParameter::TYPE_INTEGER);
$m3p1->setDescription('m3-p1-desc');
$m3p1->setIn(EndpointParameter::IN_PATH);
$m3p1->setRequired(true);
$m3p1->setAllowEmpty(true);
$m3p1->setDeprecated(true);

$m3p2 = $m3->addParameter('m3-p2');
$m3p2->setType(EndpointParameter::TYPE_STRING);
$m3p2->setIn(EndpointParameter::IN_QUERY);

$expected = [
[
'handler' => ['class' => 'c1-class', 'method' => 'm2', 'arguments' => []],
'id' => null,
'tags' => ['c1-t1' => 'c1-t1-value'],
'methods' => ['GET', 'POST', 'PUT'],
'mask' => '/group1-path/group2-path/c1-path/m2-path',
'description' => null,
'parameters' => [],
'negotiations' => [],
'attributes' => ['pattern' => '/group1-path/group2-path/c1-path/m2-path'],
],
[
'handler' => [
'class' => 'c1-class',
'method' => 'm3',
'arguments' => ['m3-a1' => 'Contributte\\Psr7\\Psr7Response'],
],
'id' => 'c1-group-id.c1-id.m3-id',
'tags' => ['c1-t1' => 'c1-t1-value', 'm3-t1'],
'methods' => ['GET', 'POST'],
'mask' => '/group1-path/group2-path/c1-path/m3-path/{m3-p1}',
'description' => 'm3-description',
'parameters' => [
'm3-p1' => [
'name' => 'm3-p1',
'type' => 'int',
'description' => 'm3-p1-desc',
'in' => 'path',
'required' => 1,
'allowEmpty' => 1,
'deprecated' => 1,
],
'm3-p2' => [
'name' => 'm3-p2',
'type' => 'string',
'description' => null,
'in' => 'query',
'required' => 1,
'allowEmpty' => 0,
'deprecated' => 0,
],
],
'negotiations' => [
[
'suffix' => 'json',
'default' => true,
'renderer' => 'A\\Middleware\\Implementing\\Class',
],
['suffix' => 'xml', 'default' => true, 'renderer' => null],
],
'attributes' => [
'pattern' => '/group1-path/group2-path/c1-path/m3-path/(?P<m3-p1>[^/]+)',
],
],
];

Assert::same($expected, $serializator->serialize($builder));
});

0 comments on commit c7344f8

Please sign in to comment.