Skip to content

Commit 650735d

Browse files
committed
Tweak environment service.
1 parent 20fa825 commit 650735d

File tree

4 files changed

+117
-65
lines changed

4 files changed

+117
-65
lines changed

src/Contracts/Integration/EnvironmentInterface.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
use Neomerx\JsonApi\Contracts\Encoder\EncoderInterface;
2323
use Neomerx\JsonApi\Contracts\Parameters\Headers\MediaTypeInterface;
2424
use Neomerx\JsonApi\Contracts\Parameters\ParametersInterface;
25+
use Neomerx\JsonApi\Contracts\Parameters\SupportedExtensionsInterface;
2526
use Neomerx\JsonApi\Contracts\Schema\ContainerInterface;
2627

2728
/**
@@ -89,4 +90,9 @@ public function getParameters();
8990
* @return bool
9091
*/
9192
public function hasParameters();
93+
94+
/**
95+
* @return SupportedExtensionsInterface|null
96+
*/
97+
public function getSupportedExtensions();
9298
}

src/Contracts/Repositories/CodecMatcherRepositoryInterface.php

Lines changed: 3 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -40,11 +40,6 @@ interface CodecMatcherRepositoryInterface extends ConfigurableInterface
4040
/** Config key for encoder depth. */
4141
const DEPTH = 'depth';
4242

43-
/**
44-
* @return CodecMatcherInterface
45-
*/
46-
public function getCodecMatcher();
47-
4843
/**
4944
* Register the schemas to use when creating a codec matcher.
5045
*
@@ -53,13 +48,6 @@ public function getCodecMatcher();
5348
*/
5449
public function registerSchemas(ContainerInterface $schemas);
5550

56-
/**
57-
* Get the schemas that were used to build encoders within the returned codec matcher.
58-
*
59-
* @return ContainerInterface
60-
*/
61-
public function getSchemas();
62-
6351
/**
6452
* Register the URL prefix to use when creating a codec matcher.
6553
*
@@ -69,9 +57,8 @@ public function getSchemas();
6957
public function registerUrlPrefix($urlPrefix);
7058

7159
/**
72-
* Get the url prefix that was used to build encoders within the returned codec matcher.
73-
*
74-
* @return mixed
60+
* @return CodecMatcherInterface
7561
*/
76-
public function getUrlPrefix();
62+
public function getCodecMatcher();
63+
7764
}

src/Integration/EnvironmentService.php

Lines changed: 76 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,15 @@
1919
namespace CloudCreativity\JsonApi\Integration;
2020

2121
use CloudCreativity\JsonApi\Contracts\Integration\EnvironmentInterface;
22-
use CloudCreativity\JsonApi\Contracts\Repositories\CodecMatcherRepositoryInterface;
22+
use Neomerx\JsonApi\Contracts\Codec\CodecMatcherInterface;
2323
use Neomerx\JsonApi\Contracts\Decoder\DecoderInterface;
2424
use Neomerx\JsonApi\Contracts\Encoder\EncoderInterface;
2525
use Neomerx\JsonApi\Contracts\Integration\CurrentRequestInterface;
2626
use Neomerx\JsonApi\Contracts\Integration\ExceptionThrowerInterface;
2727
use Neomerx\JsonApi\Contracts\Parameters\Headers\MediaTypeInterface;
2828
use Neomerx\JsonApi\Contracts\Parameters\ParametersFactoryInterface;
2929
use Neomerx\JsonApi\Contracts\Parameters\ParametersInterface;
30+
use Neomerx\JsonApi\Contracts\Parameters\SupportedExtensionsInterface;
3031
use Neomerx\JsonApi\Contracts\Schema\ContainerInterface;
3132
use RuntimeException;
3233

@@ -83,6 +84,11 @@ class EnvironmentService implements EnvironmentInterface
8384
*/
8485
private $parameters;
8586

87+
/**
88+
* @var SupportedExtensionsInterface|null
89+
*/
90+
private $supportedExtensions;
91+
8692
/**
8793
* @param ParametersFactoryInterface $factory
8894
* @param CurrentRequestInterface $currentRequest
@@ -99,45 +105,12 @@ public function __construct(
99105
}
100106

101107
/**
102-
* Initialise JSON API support for the current request.
103-
*
104-
* An application should initialise support on the routes that are JSON API endpoints. Alternatively, if the whole
105-
* application is a JSON API, then this can be initialised on every request.
106-
*
107-
* The initialisation process configures the JSON API environment based on the supplied codec matcher repository.
108-
* It will check request headers and ensure that an encoder is matched to the accept header, and if there is a
109-
* content-type header, that a decoder matches this as well.
110-
*
111-
* @param CodecMatcherRepositoryInterface $repository
108+
* @param $urlPrefix
112109
* @return $this
113110
*/
114-
public function init(CodecMatcherRepositoryInterface $repository)
111+
public function registerUrlPrefix($urlPrefix)
115112
{
116-
$codecMatcher = $repository->getCodecMatcher();
117-
$this->urlPrefix = $repository->getUrlPrefix();
118-
$this->schemas = $repository->getSchemas();
119-
120-
$this->parameters = $this->factory
121-
->createParametersParser()
122-
->parse($this->currentRequest, $this->exceptionThrower);
123-
124-
$this->factory
125-
->createHeadersChecker($this->exceptionThrower, $codecMatcher)
126-
->checkHeaders($this->parameters);
127-
128-
$this->encoder = $codecMatcher->getEncoder();
129-
$this->encoderMediaType = $codecMatcher->getEncoderHeaderMatchedType();
130-
131-
if (!$this->encoderMediaType) {
132-
$this->encoderMediaType = $codecMatcher->getEncoderRegisteredMatchedType();
133-
}
134-
135-
$this->decoder = $codecMatcher->getDecoder();
136-
$this->decoderMediaType = $codecMatcher->getDecoderHeaderMatchedType();
137-
138-
if ($this->decoder && !$this->decoderMediaType) {
139-
$this->decoderMediaType = $codecMatcher->getDecoderRegisteredMatchedType();
140-
}
113+
$this->urlPrefix = $urlPrefix ?: null;
141114

142115
return $this;
143116
}
@@ -152,6 +125,17 @@ public function getUrlPrefix()
152125
return $this->urlPrefix;
153126
}
154127

128+
/**
129+
* @param ContainerInterface $schemas
130+
* @return $this
131+
*/
132+
public function registerSchemas(ContainerInterface $schemas)
133+
{
134+
$this->schemas = $schemas;
135+
136+
return $this;
137+
}
138+
155139
/**
156140
* Get the schemas for the current request.
157141
*
@@ -160,7 +144,7 @@ public function getUrlPrefix()
160144
public function getSchemas()
161145
{
162146
if (!$this->schemas instanceof ContainerInterface) {
163-
throw new RuntimeException('No schemas registered. Has JSON API support been initialised for the current request?');
147+
throw new RuntimeException('No schemas registered.');
164148
}
165149

166150
return $this->schemas;
@@ -174,13 +158,44 @@ public function hasSchemas()
174158
return $this->schemas instanceof ContainerInterface;
175159
}
176160

161+
/**
162+
* @param CodecMatcherInterface $codecMatcher
163+
* @return $this
164+
*/
165+
public function registerCodecMatcher(CodecMatcherInterface $codecMatcher)
166+
{
167+
$this->parameters = $this->factory
168+
->createParametersParser()
169+
->parse($this->currentRequest, $this->exceptionThrower);
170+
171+
$this->factory
172+
->createHeadersChecker($this->exceptionThrower, $codecMatcher)
173+
->checkHeaders($this->parameters);
174+
175+
$this->encoder = $codecMatcher->getEncoder();
176+
$this->encoderMediaType = $codecMatcher->getEncoderHeaderMatchedType();
177+
178+
if (!$this->encoderMediaType) {
179+
$this->encoderMediaType = $codecMatcher->getEncoderRegisteredMatchedType();
180+
}
181+
182+
$this->decoder = $codecMatcher->getDecoder();
183+
$this->decoderMediaType = $codecMatcher->getDecoderHeaderMatchedType();
184+
185+
if ($this->decoder && !$this->decoderMediaType) {
186+
$this->decoderMediaType = $codecMatcher->getDecoderRegisteredMatchedType();
187+
}
188+
189+
return $this;
190+
}
191+
177192
/**
178193
* @return EncoderInterface
179194
*/
180195
public function getEncoder()
181196
{
182197
if (!$this->encoder instanceof EncoderInterface) {
183-
throw new RuntimeException('No encoder registered. Has JSON API support been initialised for the current request?');
198+
throw new RuntimeException('No encoder registered. Has a codec matcher been registered?');
184199
}
185200

186201
return $this->encoder;
@@ -200,7 +215,7 @@ public function hasEncoder()
200215
public function getEncoderMediaType()
201216
{
202217
if (!$this->hasEncoder()) {
203-
throw new RuntimeException('No encoder registered. Has JSON API support been initialised for the current request?');
218+
throw new RuntimeException('No encoder registered. Has a codec matcher been registered?');
204219
}
205220

206221
return $this->encoderMediaType;
@@ -212,7 +227,7 @@ public function getEncoderMediaType()
212227
public function getDecoder()
213228
{
214229
if (!$this->decoder instanceof DecoderInterface) {
215-
throw new RuntimeException('No decoder registered. Has JSON API support been initialised for the current request, and has the current request supplied content?');
230+
throw new RuntimeException('No decoder registered. Has a codec matcher been registered?');
216231
}
217232

218233
return $this->decoder;
@@ -232,7 +247,7 @@ public function hasDecoder()
232247
public function getDecoderMediaType()
233248
{
234249
if (!$this->hasDecoder()) {
235-
throw new RuntimeException('No decoder registered. Has JSON API support been initialised for the current request, and has the current request supplied content?');
250+
throw new RuntimeException('No decoder registered. Has a codec matcher been registered?');
236251
}
237252

238253
return $this->decoderMediaType;
@@ -258,4 +273,23 @@ public function hasParameters()
258273
return $this->parameters instanceof ParametersInterface;
259274
}
260275

276+
/**
277+
* @param SupportedExtensionsInterface $extensions
278+
* @return $this
279+
*/
280+
public function registerSupportedExtensions(SupportedExtensionsInterface $extensions)
281+
{
282+
$this->supportedExtensions = $extensions;
283+
284+
return $this;
285+
}
286+
287+
/**
288+
* @return SupportedExtensionsInterface|null
289+
*/
290+
public function getSupportedExtensions()
291+
{
292+
return $this->supportedExtensions;
293+
}
294+
261295
}

test/Integration/EnvironmentServiceTest.php

Lines changed: 32 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,13 @@
66
use CloudCreativity\JsonApi\Exceptions\ExceptionThrower;
77
use CloudCreativity\JsonApi\Repositories\CodecMatcherRepository;
88
use Neomerx\JsonApi\Contracts\Integration\CurrentRequestInterface;
9+
use Neomerx\JsonApi\Contracts\Parameters\SupportedExtensionsInterface;
10+
use Neomerx\JsonApi\Contracts\Schema\ContainerInterface;
911
use Neomerx\JsonApi\Decoders\ObjectDecoder;
1012
use Neomerx\JsonApi\Factories\Factory;
1113
use Neomerx\JsonApi\Parameters\Headers\AcceptHeader;
1214
use Neomerx\JsonApi\Parameters\Headers\Header;
15+
use Neomerx\JsonApi\Parameters\SupportedExtensions;
1316

1417
class EnvironmentServiceTest extends \PHPUnit_Framework_TestCase
1518
{
@@ -24,14 +27,28 @@ class EnvironmentServiceTest extends \PHPUnit_Framework_TestCase
2427
*/
2528
private $repository;
2629

30+
/**
31+
* @var ContainerInterface
32+
*/
2733
private $schemas;
34+
2835
private $urlPrefix;
36+
2937
private $currentRequest;
38+
39+
/**
40+
* @var array
41+
*/
3042
private $parameters = [
3143
'foo' => 'bar',
3244
'baz' => 'bat',
3345
];
3446

47+
/**
48+
* @var SupportedExtensionsInterface
49+
*/
50+
private $supportedExtensions;
51+
3552
/**
3653
* @var EnvironmentService
3754
*/
@@ -42,6 +59,7 @@ protected function setUp()
4259
$this->factory = new Factory();
4360
$this->schemas = $this->factory->createContainer(['Author' => 'AuthorSchema']);
4461
$this->urlPrefix = 'http://www.example.tld/api';
62+
$this->supportedExtensions = new SupportedExtensions('ext1,ext2');
4563
$this->repository = new CodecMatcherRepository($this->factory);
4664
$this->repository->registerSchemas($this->schemas)->registerUrlPrefix($this->urlPrefix);
4765

@@ -71,15 +89,15 @@ protected function setUp()
7189

7290
public function testUrlPrefix()
7391
{
74-
$this->service->init($this->repository);
92+
$this->service->registerUrlPrefix($this->urlPrefix);
7593

7694
$this->assertEquals($this->urlPrefix, $this->service->getUrlPrefix());
7795
}
7896

7997
public function testSchemas()
8098
{
8199
$this->assertFalse($this->service->hasSchemas());
82-
$this->service->init($this->repository);
100+
$this->service->registerSchemas($this->schemas);
83101
$this->assertEquals($this->schemas, $this->service->getSchemas());
84102
$this->assertTrue($this->service->hasSchemas());
85103
}
@@ -90,7 +108,7 @@ public function testEncoder()
90108
$matcher->matchEncoder(AcceptHeader::parse('application/vnd.api+json'));
91109

92110
$this->assertFalse($this->service->hasEncoder());
93-
$this->service->init($this->repository);
111+
$this->service->registerCodecMatcher($this->repository->getCodecMatcher());
94112
$this->assertEquals($matcher->getEncoder(), $this->service->getEncoder());
95113
$this->assertEquals($matcher->getEncoderHeaderMatchedType(), $this->service->getEncoderMediaType());
96114
$this->assertTrue($this->service->hasEncoder());
@@ -102,7 +120,7 @@ public function testDecoder()
102120
$matcher->findDecoder(Header::parse('application/vnd.api+json', 'Content-Type'));
103121

104122
$this->assertFalse($this->service->hasDecoder());
105-
$this->service->init($this->repository);
123+
$this->service->registerCodecMatcher($this->repository->getCodecMatcher());
106124
$this->assertEquals($matcher->getDecoder(), $this->service->getDecoder());
107125
$this->assertEquals($matcher->getDecoderHeaderMatchedType(), $this->service->getDecoderMediaType());
108126
$this->assertTrue($this->service->hasDecoder());
@@ -116,7 +134,7 @@ public function testParameters()
116134
->parse($this->currentRequest, new ExceptionThrower());
117135

118136
$this->assertFalse($this->service->hasParameters());
119-
$this->service->init($this->repository);
137+
$this->service->registerCodecMatcher($this->repository->getCodecMatcher());
120138
$this->assertEquals($expected, $this->service->getParameters());
121139
$this->assertTrue($this->service->hasParameters());
122140
}
@@ -135,7 +153,7 @@ public function testInvalidAccept()
135153
$service = new EnvironmentService($this->factory, $currentRequest, new ExceptionThrower());
136154

137155
try {
138-
$service->init($this->repository);
156+
$service->registerCodecMatcher($this->repository->getCodecMatcher());
139157
$this->fail('No exception thrown.');
140158
} catch (ThrowableError $e) {
141159
$this->assertEquals(406, $e->getStatus());
@@ -157,10 +175,17 @@ public function testInvalidContentType()
157175
$service = new EnvironmentService($this->factory, $currentRequest, new ExceptionThrower());
158176

159177
try {
160-
$service->init($this->repository);
178+
$service->registerCodecMatcher($this->repository->getCodecMatcher());
161179
$this->fail('No exception thrown.');
162180
} catch (ThrowableError $e) {
163181
$this->assertEquals(415, $e->getStatus());
164182
}
165183
}
184+
185+
public function testSupportedExtensions()
186+
{
187+
$this->assertNull($this->service->getSupportedExtensions());
188+
$this->service->registerSupportedExtensions($this->supportedExtensions);
189+
$this->assertEquals($this->supportedExtensions, $this->service->getSupportedExtensions());
190+
}
166191
}

0 commit comments

Comments
 (0)