Skip to content

Commit 4709ef3

Browse files
authored
Improve (#5)
1 parent 0676174 commit 4709ef3

File tree

11 files changed

+240
-43
lines changed

11 files changed

+240
-43
lines changed

.scrutinizer.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,14 @@ build:
1515
tests:
1616
stop_on_failure: true
1717
override:
18-
- php-scrutinizer-run --enable-security-analysis
19-
- make codestyle
2018
-
2119
command: make coverage
2220
idle_timeout: 1200
2321
coverage:
2422
file: 'build/coverage/clover.xml'
2523
format: 'php-clover'
24+
- php-scrutinizer-run --enable-security-analysis
25+
- make codestyle
2626
cache:
2727
directories:
2828
- ~/.composer

.travis.yml

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,19 @@
11
language: php
22

33
php:
4-
- '7.0'
54
- '7.1'
65
- '7.2'
6+
- '7.3'
77

88
env:
99
global:
1010
CI: 'true'
1111
TEST_OUTPUT_STYLE: 'pretty'
1212
PHPCS_REPORT_STYLE: 'full'
1313
COMPOSER_OPTIONS: '--optimize-autoloader'
14+
matrix:
15+
- SYMFONY_VERSION: '~3.0'
16+
- SYMFONY_VERSION: '~4.0'
1417

1518
sudo: false
1619

@@ -19,9 +22,10 @@ matrix:
1922

2023
before_install:
2124
# remove xdebug to speed up build
22-
- phpenv config-rm xdebug.ini
25+
- phpenv config-rm xdebug.ini || true
2326

2427
install:
28+
- composer require symfony/validator:$SYMFONY_VERSION
2529
- make build
2630
script:
2731
- make test-technical

composer.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,12 @@
2121
"autoload-dev": {
2222
"psr-4": {
2323
"Tests\\": "tests",
24-
"Tests\\Functional\\BehatContext\\": "features/bootstrap"
24+
"Tests\\Functional\\BehatContext\\": "features/bootstrap",
25+
"DemoApp\\": "features/demo_app/src"
2526
}
2627
},
2728
"require": {
28-
"php": ">=7.0",
29+
"php": ">=7.1",
2930
"yoanm/jsonrpc-server-sdk": "dev-release/3.0.0",
3031
"symfony/validator": "^3.0 || ^4.0"
3132
},

features/bootstrap/FeatureContext.php

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,86 @@
22
namespace Tests\Functional\BehatContext;
33

44
use Behat\Behat\Context\Context;
5+
use Behat\Behat\Context\Environment\InitializedContextEnvironment;
6+
use Behat\Behat\Hook\Scope\BeforeScenarioScope;
7+
use Behat\Gherkin\Node\PyStringNode;
8+
use PHPUnit\Framework\Assert;
9+
use PHPUnit\Framework\Constraint\IsIdentical;
10+
use Prophecy\Argument;
11+
use Symfony\Component\Validator\ValidatorBuilder;
12+
use Tests\Functional\BehatContext\App\FakeEndpointCreator;
13+
use Yoanm\JsonRpcParamsSymfonyValidator\Infra\JsonRpcParamsValidator;
14+
use Yoanm\JsonRpcServer\Domain\Model\JsonRpcRequest;
515

616
/**
717
* Defines application features from the specific context.
818
*/
919
class FeatureContext implements Context
1020
{
21+
/** @var array */
22+
private $lastViolationList = [];
1123

24+
/**
25+
* @When I validate method :methodClass with:
26+
*/
27+
public function whenIValidateMethodWith($methodClass, PyStringNode $payload)
28+
{
29+
$jsonRpcRequest = new JsonRpcRequest('2.0', $methodClass);
30+
$jsonRpcRequest->setParamList(json_decode($payload->getRaw(), true));
31+
32+
$this->lastViolationList = $this->getValidator()->validate($jsonRpcRequest, new $methodClass);
33+
}
34+
35+
/**
36+
* @Then I should have no violation
37+
*/
38+
public function thenIShouldHaveNoViolation()
39+
{
40+
Assert::assertEmpty($this->lastViolationList);
41+
}
42+
43+
/**
44+
* @Then I should have 1 violation
45+
* @Then I should have :count violations
46+
*/
47+
public function thenIShouldHaveXViolation($count = 1)
48+
{
49+
Assert::assertCount((int) $count, $this->lastViolationList);
50+
}
51+
52+
/**
53+
* @Then I should have the following validation error:
54+
* @param PyStringNode $node
55+
*/
56+
public function thenIShouldHaveTheFollowingViolation(PyStringNode $node)
57+
{
58+
$found = false;
59+
$decoded = json_decode($node->getRaw(), true);
60+
$constraint = new IsIdentical($decoded);
61+
foreach ($this->lastViolationList as $violation) {
62+
if (true === $constraint->evaluate($violation, '', true)) {
63+
$found = true;
64+
break;
65+
}
66+
}
67+
68+
if (true !== $found) {
69+
throw new \Exception(
70+
sprintf(
71+
'Violation "%s" not found in violation list : %s',
72+
json_encode($decoded),
73+
json_encode($this->lastViolationList)
74+
)
75+
);
76+
}
77+
}
78+
/**
79+
* @return JsonRpcParamsValidator
80+
*/
81+
private function getValidator() : JsonRpcParamsValidator
82+
{
83+
return new JsonRpcParamsValidator(
84+
(new ValidatorBuilder())->getValidator()
85+
);
86+
}
1287
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<?php
2+
namespace DemoApp\Method;
3+
4+
use Yoanm\JsonRpcServer\Domain\JsonRpcMethodInterface;
5+
6+
class BasicMethod implements JsonRpcMethodInterface
7+
{
8+
/**
9+
* {@inheritdoc}
10+
*/
11+
public function apply(array $paramList = null)
12+
{
13+
return 'basic-method-result';
14+
}
15+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
<?php
2+
namespace DemoApp\Method;
3+
4+
use Symfony\Component\Validator\Constraint;
5+
use Symfony\Component\Validator\Constraints\Collection;
6+
use Symfony\Component\Validator\Constraints\NotBlank;
7+
use Symfony\Component\Validator\Constraints\NotNull;
8+
use Yoanm\JsonRpcParamsSymfonyValidator\Domain\MethodWithValidatedParamsInterface;
9+
use Yoanm\JsonRpcServer\Domain\JsonRpcMethodInterface;
10+
11+
class BasicMethodWithRequiredParams implements JsonRpcMethodInterface, MethodWithValidatedParamsInterface
12+
{
13+
/**
14+
* {@inheritdoc}
15+
*/
16+
public function apply(array $paramList = null)
17+
{
18+
return 'basic-method-with-params-result';
19+
}
20+
21+
public function getParamsConstraint(): Constraint
22+
{
23+
return new Collection(
24+
[
25+
'fields' => [
26+
'fieldA' => new NotNull(),
27+
'fieldB' => new NotBlank(),
28+
],
29+
'allowExtraFields' => false,
30+
'allowMissingFields' => false,
31+
]
32+
);
33+
}
34+
}

features/validator.feature

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
Feature: Validator
2+
3+
Scenario: Validator should do nothing for method which does not implement right interface
4+
When I validate method "DemoApp\Method\BasicMethod" with:
5+
"""
6+
{
7+
"fieldA": "A",
8+
"unknownField": "B"
9+
}
10+
"""
11+
Then I should have no violation
12+
13+
Scenario: Validator should return an empty list if there is no violations
14+
When I validate method "DemoApp\Method\BasicMethodWithRequiredParams" with:
15+
"""
16+
{
17+
"fieldA": "plop",
18+
"fieldB": "plip"
19+
}
20+
"""
21+
Then I should have no violation
22+
23+
Scenario: Validator should return list of violations if there is some
24+
When I validate method "DemoApp\Method\BasicMethodWithRequiredParams" with:
25+
"""
26+
{
27+
"fieldA": null,
28+
"fieldB": ""
29+
}
30+
"""
31+
Then I should have 2 violations
32+
And I should have the following validation error:
33+
"""
34+
{
35+
"path": "[fieldA]",
36+
"message": "This value should not be null.",
37+
"code": "ad32d13f-c3d4-423b-909a-857b961eb720"
38+
}
39+
"""
40+
And I should have the following validation error:
41+
"""
42+
{
43+
"path": "[fieldB]",
44+
"message": "This value should not be blank.",
45+
"code":"c1051bb4-d103-4f74-8988-acbcafc7fdc3"
46+
}
47+
"""

phpunit.xml.dist

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,6 @@
88
processIsolation="false"
99

1010
stopOnRisky="true"
11-
processUncoveredFilesFromWhitelist="true"
12-
addUncoveredFilesFromWhitelist="true"
13-
checkForUnintentionallyCoveredCode="true"
1411

1512
stopOnError="true"
1613
stopOnFailure="true"

src/Domain/Model/MethodWithValidatedParams.php renamed to src/Domain/MethodWithValidatedParamsInterface.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
<?php
2-
namespace Yoanm\JsonRpcParamsSymfonyValidator\Domain\Model;
2+
namespace Yoanm\JsonRpcParamsSymfonyValidator\Domain;
33

44
use Symfony\Component\Validator\Constraint;
55

66
/**
7-
* Interface MethodWithValidatedParams
7+
* Interface MethodWithValidatedParamsInterface
88
*/
9-
interface MethodWithValidatedParams
9+
interface MethodWithValidatedParamsInterface
1010
{
1111
/**
1212
* @return Constraint Usually a Collection constraint

src/Infra/JsonRpcParamsValidator.php

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,15 @@
33

44
use Symfony\Component\Validator\ConstraintViolationInterface;
55
use Symfony\Component\Validator\Validator\ValidatorInterface;
6-
use Yoanm\JsonRpcParamsSymfonyValidator\Domain\Model\MethodWithValidatedParams;
7-
use Yoanm\JsonRpcServer\Domain\Event\Action\ValidateParamsEvent;
6+
use Yoanm\JsonRpcParamsSymfonyValidator\Domain\MethodWithValidatedParamsInterface;
7+
use Yoanm\JsonRpcServer\Domain\JsonRpcMethodInterface;
8+
use Yoanm\JsonRpcServer\Domain\JsonRpcMethodParamsValidatorInterface;
9+
use Yoanm\JsonRpcServer\Domain\Model\JsonRpcRequest;
810

911
/**
1012
* Class JsonRpcParamsValidator
1113
*/
12-
class JsonRpcParamsValidator
14+
class JsonRpcParamsValidator implements JsonRpcMethodParamsValidatorInterface
1315
{
1416
/** @var ValidatorInterface */
1517
private $validator;
@@ -22,22 +24,26 @@ public function __construct(ValidatorInterface $validator)
2224
$this->validator = $validator;
2325
}
2426

25-
/**
26-
* @param ValidateParamsEvent $event
27-
*/
28-
public function validate(ValidateParamsEvent $event)
27+
public function validate(JsonRpcRequest $jsonRpcRequest, JsonRpcMethodInterface $method) : array
2928
{
30-
$method = $event->getMethod();
31-
if (!$method instanceof MethodWithValidatedParams) {
32-
return;
29+
$violationList = [];
30+
if (!$method instanceof MethodWithValidatedParamsInterface) {
31+
return $violationList;
3332
}
34-
foreach ($this->validator->validate($event->getParamList(), $method->getParamsConstraint()) as $violation) {
33+
$sfViolationList = $this->validator->validate(
34+
$jsonRpcRequest->getParamList(),
35+
$method->getParamsConstraint()
36+
);
37+
38+
foreach ($sfViolationList as $violation) {
3539
/** @var ConstraintViolationInterface $violation */
36-
$event->addViolation([
40+
$violationList[] = [
3741
'path' => $violation->getPropertyPath(),
3842
'message' => $violation->getMessage(),
3943
'code' => $violation->getCode(),
40-
]);
44+
];
4145
}
46+
47+
return $violationList;
4248
}
4349
}

0 commit comments

Comments
 (0)