Completed
Push — feat/add-quality-gates ( b24265...ab5d16 )
by Guillem
02:59
created

MessageValidatorTest::itValidateAResponse()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 51
Code Lines 34

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 34
dl 0
loc 51
rs 9.376
c 0
b 0
f 0
cc 1
nc 1
nop 0

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
namespace ElevenLabs\Api\Validator;
3
4
use ElevenLabs\Api\Decoder\Adapter\SymfonyDecoderAdapter;
5
use ElevenLabs\Api\Definition\MessageDefinition;
6
use ElevenLabs\Api\Definition\RequestDefinition;
7
use ElevenLabs\Api\Definition\ResponseDefinition;
8
use JsonSchema\Validator;
9
use PHPUnit\Framework\TestCase;
10
use Psr\Http\Message\MessageInterface;
11
use Psr\Http\Message\RequestInterface;
12
use Psr\Http\Message\ResponseInterface;
13
use Psr\Http\Message\UriInterface;
14
use Symfony\Component\Serializer\Encoder\JsonDecode;
15
16
/**
17
 * Class RequestValidatorTest
18
 */
19
class MessageValidatorTest extends TestCase
20
{
21
    /** @var MessageValidator */
22
    private $messageValidator;
23
24
    public function setUp()
25
    {
26
        $validator = new Validator();
27
        $decoder = new SymfonyDecoderAdapter(new JsonDecode());
28
29
        $this->messageValidator = new MessageValidator(
30
            $validator,
31
            $decoder
32
        );
33
    }
34
35
    /** @test */
36
    public function itValidateAMessageContentType()
37
    {
38
        $expectedViolations = [
39
            new ConstraintViolation(
40
                'Content-Type',
41
                'Content-Type should not be empty',
42
                'required',
43
                'header'
44
            )
45
        ];
46
47
        $message = $this->prophesize(MessageInterface::class);
48
        $message->getHeaderLine('Content-Type')->willReturn('');
49
50
        $definition = $this->prophesize(MessageDefinition::class);
51
        $definition->getContentTypes()->willReturn(['application/json']);
52
53
        $this->messageValidator->validateContentType(
54
            $message->reveal(),
55
            $definition->reveal()
56
        );
57
58
        assertThat($this->messageValidator->hasViolations(), isTrue());
59
        assertThat($this->messageValidator->getViolations(), containsOnlyInstancesOf(ConstraintViolation::class));
60
        assertThat($this->messageValidator->getViolations(), equalTo($expectedViolations));
61
    }
62
63
    /** @test */
64
    public function itValidateAMessageUnsupportedContentType()
65
    {
66
        $expectedViolations = [
67
            new ConstraintViolation(
68
                'Content-Type',
69
                'text/plain is not a supported content type, supported: application/json',
70
                'enum',
71
                'header'
72
            )
73
        ];
74
75
        $message = $this->prophesize(MessageInterface::class);
76
        $message->getHeaderLine('Content-Type')->willReturn('text/plain');
77
78
        $definition = $this->prophesize(MessageDefinition::class);
79
        $definition->getContentTypes()->willReturn(['application/json']);
80
81
        $this->messageValidator->validateContentType(
82
            $message->reveal(),
83
            $definition->reveal()
84
        );
85
86
        assertThat($this->messageValidator->hasViolations(), isTrue());
87
        assertThat($this->messageValidator->getViolations(), containsOnlyInstancesOf(ConstraintViolation::class));
88
        assertThat($this->messageValidator->getViolations(), equalTo($expectedViolations));
89
    }
90
91
    /** @test */
92
    public function itValidateAMessageHeaders()
93
    {
94
        $expectedViolation = [
95
            new ConstraintViolation(
96
                'X-Required-Header',
97
                'The property X-Required-Header is required',
98
                'required',
99
                'header'
100
            )
101
        ];
102
103
        $headersSchema = $this->toObject([
104
            'type' => 'object',
105
            'required' => ['X-Required-Header'],
106
            'properties' => [
107
                'X-Required-Header' => [
108
                    'type' => 'string'
109
                ]
110
            ]
111
        ]);
112
113
        $message = $this->prophesize(MessageInterface::class);
114
        $message->getHeaders()->willReturn(['X-Foo' => ['bar', 'baz']]);
115
116
        $definition = $this->prophesize(MessageDefinition::class);
117
        $definition->hasHeadersSchema()->willReturn(true);
118
        $definition->getHeadersSchema()->willReturn($headersSchema);
119
120
        $this->messageValidator->validateHeaders(
121
            $message->reveal(),
122
            $definition->reveal()
123
        );
124
125
        assertThat($this->messageValidator->hasViolations(), isTrue());
126
        assertThat($this->messageValidator->getViolations(), containsOnlyInstancesOf(ConstraintViolation::class));
127
        assertThat($this->messageValidator->getViolations(), equalTo($expectedViolation));
128
    }
129
130
    /** @test */
131
    public function itValidateTheRequestBody()
132
    {
133
        $expectedViolation = [
134
            new ConstraintViolation(
135
                'id',
136
                'String value found, but an integer is required',
137
                'type',
138
                'body'
139
            ),
140
        ];
141
142
        $bodySchema = $this->toObject([
143
            'type' => 'object',
144
            'properties' => [
145
                'id' => [
146
                    'type' => 'integer',
147
                    'format' => 'int32'
148
                ]
149
            ]
150
        ]);
151
152
        $message = $this->prophesize(MessageInterface::class);
153
        $message->getHeaderLine('Content-Type')->willReturn('application/json');
154
        $message->getBody()->willReturn('{"id": "invalid"}');
155
156
        $definition = $this->prophesize(MessageDefinition::class);
157
        $definition->getContentTypes()->willReturn(['application/json']);
158
        $definition->hasBodySchema()->willReturn(true);
159
        $definition->getBodySchema()->willReturn($bodySchema);
160
161
        $this->messageValidator->validateMessageBody(
162
            $message->reveal(),
163
            $definition->reveal()
164
        );
165
166
        assertThat($this->messageValidator->hasViolations(), isTrue());
167
        assertThat($this->messageValidator->getViolations(), containsOnlyInstancesOf(ConstraintViolation::class));
168
        assertThat($this->messageValidator->getViolations(), equalTo($expectedViolation));
169
    }
170
171
    /** @test */
172
    public function itValidateARequestQueryParameters()
173
    {
174
        $expectedViolation = [
175
            new ConstraintViolation(
176
                'limit',
177
                'String value found, but an integer is required',
178
                'type',
179
                'query'
180
            )
181
        ];
182
183
        $queryParametersSchema = $this->toObject([
184
            'type' => 'object',
185
            'properties' => [
186
                'limit' => [
187
                    'type' => 'integer'
188
                ]
189
            ]
190
        ]);
191
192
        $requestUri = $this->prophesize(UriInterface::class);
193
        $requestUri->getQuery()->willreturn('limit=invalid');
194
195
        $request = $this->prophesize(RequestInterface::class);
196
        $request->getUri()->willReturn($requestUri);
197
198
        $definition = $this->prophesize(RequestDefinition::class);
199
        $definition->hasQueryParametersSchema()->willReturn(true);
200
        $definition->getQueryParametersSchema()->willReturn($queryParametersSchema);
201
202
        $this->messageValidator->validateQueryParameters(
203
            $request->reveal(),
204
            $definition->reveal()
205
        );
206
207
        assertThat($this->messageValidator->hasViolations(), isTrue());
208
        assertThat($this->messageValidator->getViolations(), containsOnlyInstancesOf(ConstraintViolation::class));
209
        assertThat($this->messageValidator->getViolations(), equalTo($expectedViolation));
210
    }
211
212
    /** @test */
213
    public function itValidateARequest()
214
    {
215
        $expectedViolations = [
216
            new ConstraintViolation('id', 'String value found, but an integer is required', 'type', 'body'),
217
            new ConstraintViolation('X-Required-Header', 'The property X-Required-Header is required', 'required', 'header'),
218
            new ConstraintViolation('limit', 'String value found, but an integer is required', 'type', 'query'),
219
        ];
220
221
        $headersSchema = $this->toObject([
222
            'type' => 'object',
223
            'required' => ['X-Required-Header'],
224
            'properties' => [
225
                'X-Required-Header' => [
226
                    'type' => 'string'
227
                ]
228
            ]
229
        ]);
230
231
        $bodySchema = $this->toObject([
232
            'type' => 'object',
233
            'properties' => [
234
                'id' => [
235
                    'type' => 'integer',
236
                    'format' => 'int32'
237
                ]
238
            ]
239
        ]);
240
241
        $queryParametersSchema = $this->toObject([
242
            'type' => 'object',
243
            'properties' => [
244
                'limit' => [
245
                    'type' => 'integer'
246
                ]
247
            ]
248
        ]);
249
250
        $uri = $this->prophesize(UriInterface::class);
251
        $uri->getQuery()->willreturn('limit=invalid');
252
253
        $request = $this->prophesize(RequestInterface::class);
254
        $request->getMethod()->willReturn('POST');
255
        $request->getUri()->willReturn($uri);
256
        $request->getBody()->willReturn('{"id": "invalid"}');
257
        $request->getHeaderLine('Content-Type')->willReturn('application/json');
258
        $request->getHeaders()->willReturn([]);
259
260
        $definition = $this->prophesize(RequestDefinition::class);
261
        $definition->getContentTypes()->willReturn(['application/json']);
262
        $definition->hasBodySchema()->willReturn(true);
263
        $definition->getBodySchema()->willReturn($bodySchema);
264
        $definition->hasHeadersSchema()->willReturn(true);
265
        $definition->getHeadersSchema()->willReturn($headersSchema);
266
        $definition->hasQueryParametersSchema()->willReturn(true);
267
        $definition->getQueryParametersSchema()->willReturn($queryParametersSchema);
268
269
        $this->messageValidator->validateRequest(
270
            $request->reveal(),
271
            $definition->reveal()
272
        );
273
274
        assertThat($this->messageValidator->hasViolations(), isTrue());
275
        assertThat($this->messageValidator->getViolations(), containsOnlyInstancesOf(ConstraintViolation::class));
276
        assertThat($this->messageValidator->getViolations(), equalTo($expectedViolations));
277
    }
278
279
    /** @test */
280
    public function itValidateAResponse()
281
    {
282
        $expectedViolations = [
283
            new ConstraintViolation('id', 'String value found, but an integer is required', 'type', 'body'),
284
            new ConstraintViolation('X-Required-Header', 'The property X-Required-Header is required', 'required', 'header'),
285
        ];
286
287
        $headersSchema = $this->toObject([
288
            'type' => 'object',
289
            'required' => ['X-Required-Header'],
290
            'properties' => [
291
                'X-Required-Header' => [
292
                    'type' => 'string'
293
                ]
294
            ]
295
        ]);
296
297
        $bodySchema = $this->toObject([
298
            'type' => 'object',
299
            'properties' => [
300
                'id' => [
301
                    'type' => 'integer',
302
                    'format' => 'int32'
303
                ]
304
            ]
305
        ]);
306
307
        $response = $this->prophesize(ResponseInterface::class);
308
        $response->getStatusCode()->willReturn('200');
309
        $response->getBody()->willReturn('{"id": "invalid"}');
310
        $response->getHeaderLine('Content-Type')->willReturn('application/json');
311
        $response->getHeaders()->willReturn([]);
312
313
        $responseDefinition = $this->prophesize(RequestDefinition::class);
314
        $responseDefinition->getContentTypes()->willReturn(['application/json']);
315
        $responseDefinition->hasBodySchema()->willReturn(true);
316
        $responseDefinition->getBodySchema()->willReturn($bodySchema);
317
        $responseDefinition->hasHeadersSchema()->willReturn(true);
318
        $responseDefinition->getHeadersSchema()->willReturn($headersSchema);
319
320
        $definition = $this->prophesize(RequestDefinition::class);
321
        $definition->getResponseDefinition('200')->willReturn($responseDefinition);
322
323
        $this->messageValidator->validateResponse(
324
            $response->reveal(),
325
            $definition->reveal()
326
        );
327
328
        assertThat($this->messageValidator->hasViolations(), isTrue());
329
        assertThat($this->messageValidator->getViolations(), containsOnlyInstancesOf(ConstraintViolation::class));
330
        assertThat($this->messageValidator->getViolations(), equalTo($expectedViolations));
331
    }
332
333
    private function toObject(array $array)
334
    {
335
        return json_decode(json_encode($array));
336
    }
337
}
338