Skip to content

Commit fbcbcde

Browse files
committed
Fix support of jsonapi format
1 parent 53021dc commit fbcbcde

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+1811
-1038
lines changed

.travis.yml

-2
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,7 @@ matrix:
1818
before_install:
1919
- phpenv config-rm xdebug.ini || echo "xdebug not available"
2020
- echo "memory_limit=-1" >> ~/.phpenv/versions/$(phpenv version-name)/etc/conf.d/travis.ini
21-
- rm -rf ~/.nvm && git clone https://github.com/creationix/nvm.git ~/.nvm && (cd ~/.nvm && git checkout `git describe --abbrev=0 --tags`) && source ~/.nvm/nvm.sh && nvm install 6.10.2
2221
- npm install -g swagger-cli
23-
- npm install -g jsonapi-validator
2422
- if [[ $coverage = 1 ]]; then mkdir -p build/logs build/cov; fi
2523
- if [[ $coverage = 1 ]]; then wget https://phar.phpunit.de/phpcov.phar; fi
2624
- if [[ $coverage = 1 ]]; then wget https://github.com/satooshi/php-coveralls/releases/download/v1.0.1/coveralls.phar; fi

appveyor.yml

-5
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,13 @@ build: false
22
platform: x86
33
clone_folder: c:\projects\api-platform\core
44

5-
environment:
6-
nodejs_version: "6"
7-
85
cache:
96
- '%LOCALAPPDATA%\Composer\files'
107

118
init:
129
- SET PATH=c:\tools\php71;%PATH%
1310

1411
install:
15-
- ps: Install-Product node $env:nodejs_version
16-
- npm install -g jsonapi-validator
1712
- ps: Set-Service wuauserv -StartupType Manual
1813
- cinst -y php
1914
- cd c:\tools\php71

behat.yml.dist

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ default:
66
- 'HydraContext'
77
- 'SwaggerContext'
88
- 'HttpCacheContext'
9-
- 'JsonApiContext': { doctrine: '@doctrine' }
9+
- 'JsonApiContext': { doctrine: '@doctrine', jsonApiSchemaFile: 'tests/Fixtures/JsonSchema/jsonapi.json' }
1010
- 'Behat\MinkExtension\Context\MinkContext'
1111
- 'Behatch\Context\RestContext'
1212
- 'Behatch\Context\JsonContext'

features/bootstrap/FeatureContext.php

+4-4
Original file line numberDiff line numberDiff line change
@@ -294,7 +294,7 @@ public function thereIsDummyObjectsWithDummyDateAndDummyBoolean($nb, $bool)
294294
$bool = false;
295295
} else {
296296
$expected = ['true', 'false', '1', '0'];
297-
throw new InvalidArgumentException(sprintf('Invalid boolean value for "%s" property, expected one of ( "%s" )', $bool, implode('" | "', $expected)));
297+
throw new \InvalidArgumentException(sprintf('Invalid boolean value for "%s" property, expected one of ( "%s" )', $bool, implode('" | "', $expected)));
298298
}
299299

300300
for ($i = 1; $i <= $nb; ++$i) {
@@ -403,7 +403,7 @@ public function thereIsDummyObjectsWithDummyBoolean($nb, $bool)
403403
$bool = false;
404404
} else {
405405
$expected = ['true', 'false', '1', '0'];
406-
throw new InvalidArgumentException(sprintf('Invalid boolean value for "%s" property, expected one of ( "%s" )', $bool, implode('" | "', $expected)));
406+
throw new \InvalidArgumentException(sprintf('Invalid boolean value for "%s" property, expected one of ( "%s" )', $bool, implode('" | "', $expected)));
407407
}
408408
$descriptions = ['Smart dummy.', 'Not so smart dummy.'];
409409

@@ -431,7 +431,7 @@ public function thereIsDummyObjectsWithEmbeddedDummyBoolean($nb, $bool)
431431
$bool = false;
432432
} else {
433433
$expected = ['true', 'false', '1', '0'];
434-
throw new InvalidArgumentException(sprintf('Invalid boolean value for "%s" property, expected one of ( "%s" )', $bool, implode('" | "', $expected)));
434+
throw new \InvalidArgumentException(sprintf('Invalid boolean value for "%s" property, expected one of ( "%s" )', $bool, implode('" | "', $expected)));
435435
}
436436

437437
for ($i = 1; $i <= $nb; ++$i) {
@@ -458,7 +458,7 @@ public function thereIsDummyObjectsWithRelationEmbeddedDummyBoolean($nb, $bool)
458458
$bool = false;
459459
} else {
460460
$expected = ['true', 'false', '1', '0'];
461-
throw new InvalidArgumentException(sprintf('Invalid boolean value for "%s" property, expected one of ( "%s" )', $bool, implode('" | "', $expected)));
461+
throw new \InvalidArgumentException(sprintf('Invalid boolean value for "%s" property, expected one of ( "%s" )', $bool, implode('" | "', $expected)));
462462
}
463463

464464
for ($i = 1; $i <= $nb; ++$i) {

features/bootstrap/JsonApiContext.php

+59-76
Original file line numberDiff line numberDiff line change
@@ -11,32 +11,35 @@
1111

1212
declare(strict_types=1);
1313

14+
use ApiPlatform\Core\Tests\Fixtures\TestBundle\Entity\CircularReference;
1415
use ApiPlatform\Core\Tests\Fixtures\TestBundle\Entity\DummyFriend;
1516
use ApiPlatform\Core\Tests\Fixtures\TestBundle\Entity\RelatedDummy;
1617
use Behat\Behat\Context\Context;
17-
use Behat\Behat\Context\Environment\InitializedContextEnvironment;
1818
use Behat\Behat\Hook\Scope\BeforeScenarioScope;
1919
use Behatch\Context\RestContext;
2020
use Behatch\Json\Json;
2121
use Behatch\Json\JsonInspector;
22+
use Behatch\Json\JsonSchema;
2223
use Doctrine\Common\Persistence\ManagerRegistry;
24+
use JsonSchema\RefResolver;
25+
use JsonSchema\Uri\UriRetriever;
26+
use JsonSchema\Validator;
2327

2428
final class JsonApiContext implements Context
2529
{
26-
private $restContext;
27-
2830
private $inspector;
29-
30-
private $doctrine;
31-
32-
/**
33-
* @var \Doctrine\Common\Persistence\ObjectManager
34-
*/
31+
private $jsonApiSchemaFile;
32+
private $restContext;
3533
private $manager;
3634

37-
public function __construct(ManagerRegistry $doctrine)
35+
public function __construct(ManagerRegistry $doctrine, string $jsonApiSchemaFile)
3836
{
39-
$this->doctrine = $doctrine;
37+
if (!is_file($jsonApiSchemaFile)) {
38+
throw new \InvalidArgumentException('The JSON API schema doesn\'t exist.');
39+
}
40+
41+
$this->inspector = new JsonInspector('javascript');
42+
$this->jsonApiSchemaFile = $jsonApiSchemaFile;
4043
$this->manager = $doctrine->getManager();
4144
}
4245

@@ -49,48 +52,21 @@ public function __construct(ManagerRegistry $doctrine)
4952
*/
5053
public function gatherContexts(BeforeScenarioScope $scope)
5154
{
52-
/** @var InitializedContextEnvironment $environment */
53-
$environment = $scope->getEnvironment();
54-
55-
$this->restContext = $environment->getContext(RestContext::class);
56-
57-
$this->inspector = new JsonInspector('javascript');
55+
$this->restContext = $scope->getEnvironment()->getContext(RestContext::class);
5856
}
5957

6058
/**
61-
* @Then I save the response
59+
* @Then the JSON should be valid according to the JSON API schema
6260
*/
63-
public function iSaveTheResponse()
61+
public function theJsonShouldBeValidAccordingToTheJsonApiSchema()
6462
{
65-
$content = $this->getContent();
63+
$refResolver = new RefResolver(new UriRetriever());
64+
$refResolver::$maxDepth = 15;
6665

67-
if (null === ($decoded = json_decode($content))) {
68-
throw new \RuntimeException('JSON response seems to be invalid');
69-
}
70-
71-
$fileName = __DIR__.'/response.json';
72-
73-
file_put_contents($fileName, $content);
74-
75-
return $fileName;
76-
}
77-
78-
/**
79-
* @Then I validate it with jsonapi-validator
80-
*/
81-
public function iValidateItWithJsonapiValidator()
82-
{
83-
$fileName = $this->iSaveTheResponse();
84-
85-
$validationResponse = exec(sprintf('cd %s && jsonapi-validator -f response.json', __DIR__));
86-
87-
$isValidJsonapi = 'response.json is valid JSON API.' === $validationResponse;
88-
89-
unlink($fileName);
90-
91-
if (!$isValidJsonapi) {
92-
throw new \RuntimeException('JSON response seems to be invalid JSON API');
93-
}
66+
(new JsonSchema(file_get_contents($this->jsonApiSchemaFile), 'file://'.__DIR__))
67+
->resolve($refResolver)
68+
->validate($this->getJson(), new Validator())
69+
;
9470
}
9571

9672
/**
@@ -100,9 +76,7 @@ public function iValidateItWithJsonapiValidator()
10076
*/
10177
public function theJsonNodeShouldBeAnEmptyArray($node)
10278
{
103-
$actual = $this->getValueOfNode($node);
104-
105-
if (!is_array($actual) || !empty($actual)) {
79+
if (!is_array($actual = $this->getValueOfNode($node)) || !empty($actual)) {
10680
throw new \Exception(
10781
sprintf("The node value is '%s'", json_encode($actual))
10882
);
@@ -116,9 +90,7 @@ public function theJsonNodeShouldBeAnEmptyArray($node)
11690
*/
11791
public function theJsonNodeShouldBeANumber($node)
11892
{
119-
$actual = $this->getValueOfNode($node);
120-
121-
if (!is_numeric($actual)) {
93+
if (!is_numeric($actual = $this->getValueOfNode($node))) {
12294
throw new \Exception(
12395
sprintf('The node value is `%s`', json_encode($actual))
12496
);
@@ -132,43 +104,22 @@ public function theJsonNodeShouldBeANumber($node)
132104
*/
133105
public function theJsonNodeShouldNotBeAnEmptyString($node)
134106
{
135-
$actual = $this->getValueOfNode($node);
136-
137-
if ($actual === '') {
107+
if ('' === $actual = $this->getValueOfNode($node)) {
138108
throw new \Exception(
139109
sprintf('The node value is `%s`', json_encode($actual))
140110
);
141111
}
142112
}
143113

144-
private function getValueOfNode($node)
145-
{
146-
$json = $this->getJson();
147-
148-
return $this->inspector->evaluate($json, $node);
149-
}
150-
151-
private function getJson()
152-
{
153-
return new Json($this->getContent());
154-
}
155-
156-
private function getContent()
157-
{
158-
return $this->restContext->getMink()->getSession()->getDriver()->getContent();
159-
}
160-
161114
/**
162115
* @Given there is a RelatedDummy
163116
*/
164117
public function thereIsARelatedDummy()
165118
{
166119
$relatedDummy = new RelatedDummy();
167-
168120
$relatedDummy->setName('RelatedDummy with no friends');
169121

170122
$this->manager->persist($relatedDummy);
171-
172123
$this->manager->flush();
173124
}
174125

@@ -178,11 +129,43 @@ public function thereIsARelatedDummy()
178129
public function thereIsADummyFriend()
179130
{
180131
$friend = new DummyFriend();
181-
182132
$friend->setName('DummyFriend');
183133

184134
$this->manager->persist($friend);
135+
$this->manager->flush();
136+
}
185137

138+
/**
139+
* @Given there is a CircularReference
140+
*/
141+
public function thereIsACircularReference()
142+
{
143+
$circularReference = new CircularReference();
144+
$circularReference->parent = $circularReference;
145+
146+
$circularReferenceBis = new CircularReference();
147+
$circularReferenceBis->parent = $circularReference;
148+
149+
$circularReference->children->add($circularReference);
150+
$circularReference->children->add($circularReferenceBis);
151+
152+
$this->manager->persist($circularReference);
153+
$this->manager->persist($circularReferenceBis);
186154
$this->manager->flush();
187155
}
156+
157+
private function getValueOfNode($node)
158+
{
159+
return $this->inspector->evaluate($this->getJson(), $node);
160+
}
161+
162+
private function getJson()
163+
{
164+
return new Json($this->getContent());
165+
}
166+
167+
private function getContent()
168+
{
169+
return $this->restContext->getMink()->getSession()->getDriver()->getContent();
170+
}
188171
}

0 commit comments

Comments
 (0)