ServerTest::cbProvider()   B
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 314

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 314
rs 8
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
3
namespace Xsolla\SDK\Tests\Integration\Webhook;
4
5
use GuzzleHttp\Client;
6
use GuzzleHttp\Exception\BadResponseException;
7
use GuzzleHttp\Exception\ClientException;
8
use PHPUnit\Framework\TestCase;
9
use Symfony\Component\HttpFoundation\Response;
10
use Symfony\Component\Process\Process;
11
use Xsolla\SDK\API\XsollaClient;
12
use Xsolla\SDK\Tests\Helper\DebugHelper;
13
use Xsolla\SDK\Version;
14
15
/**
16
 * @group webhook-php-server
17
 */
18
class ServerTest extends TestCase
19
{
20
    const PROJECT_SECRET_KEY = 'PROJECT_SECRET_KEY';
21
22
    /**
23
     * @var Process
24
     */
25
    protected static $process;
26
27
    /**
28
     * @var Client
29
     */
30
    protected static $httpClient;
31
32
    public static function setUpBeforeClass()
33
    {
34
        self::setUpPhpServer();
35
        self::setUpHttpClient();
36
    }
37
38
    private static function setUpPhpServer()
39
    {
40
        self::$process = new Process('php -S 127.0.0.1:8999', __DIR__ . '/../../Resources/Scripts');
0 ignored issues
show
Documentation introduced by
'php -S 127.0.0.1:8999' is of type string, but the function expects a array.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
41
        self::$process->setTimeout(1);
42
        self::$process->start();
43
        usleep(100000);
44
    }
45
46
    private static function setUpHttpClient()
47
    {
48
        self::$httpClient = new Client([
49
            'base_uri' => 'http://127.0.0.1:8999',
50
            'debug' => DebugHelper::isDebug(),
51
        ]);
52
    }
53
54
    public static function tearDownAfterClass()
55
    {
56
        self::$process->stop(0);
57
    }
58
59
    /**
60
     * @param $expectedStatusCode
61
     * @param $expectedResponseContent
62
     * @param $request
63
     * @param $testCase
64
     * @param $testHeaders
65
     *
66
     * @dataProvider cbProvider
67
     */
68
    public function testResponse($expectedStatusCode, $expectedResponseContent, $request, $testCase, $testHeaders)
69
    {
70
        $signature = sha1($request . self::PROJECT_SECRET_KEY);
71
        $headers = $testHeaders ? $testHeaders : ['Authorization' => 'Signature ' . $signature];
72
73
        try {
74
            $response = self::$httpClient->post('/webhook_server.php?test_case=' . $testCase,
75
                ['headers' => $headers, 'body' => $request]);
76
        } catch (BadResponseException | ClientException $e) {
77
            $response = $e->getResponse();
78
        }
79
        static::assertSame($expectedResponseContent, $response->getBody()->getContents());
80
        static::assertSame($expectedStatusCode, $response->getStatusCode());
81
        static::assertArrayHasKey('x-xsolla-sdk', $response->getHeaders());
82
        static::assertSame(Version::getVersion(), (string)$response->getHeader('x-xsolla-sdk')[0]);
83
        static::assertNotNull((string)$response->getHeader('content-type')[0]);
84
        if (Response::HTTP_NO_CONTENT === $response->getStatusCode()) {
85
            static::assertStringStartsWith('text/plain', (string)$response->getHeader('content-type')[0]);
86
        } else {
87
            static::assertStringStartsWith('application/json', (string)$response->getHeader('content-type')[0]);
88
        }
89
    }
90
91
    public function cbProvider()
92
    {
93
        return [
94
            // notifications
95
            'notification_type:payment success' => [
96
                'expectedStatusCode' => 204,
97
                'expectedResponseContent' => '',
98
                'request' => '{"notification_type": "payment"}',
99
                'testCase' => 'payment_success',
100
                'testHeaders' => null,
101
            ],
102
            'notification_type:user_validation success' => [
103
                'expectedStatusCode' => 204,
104
                'expectedResponseContent' => '',
105
                'request' => '{"notification_type": "user_validation"}',
106
                'testCase' => 'user_validation_success',
107
                'testHeaders' => null,
108
            ],
109
            'notification_type:refund success' => [
110
                'expectedStatusCode' => 204,
111
                'expectedResponseContent' => '',
112
                'request' => '{"notification_type": "refund"}',
113
                'testCase' => 'refund_success',
114
                'testHeaders' => null,
115
            ],
116
            'notification_type:create_subscription success' => [
117
                'expectedStatusCode' => 204,
118
                'expectedResponseContent' => '',
119
                'request' => '{"notification_type": "create_subscription"}',
120
                'testCase' => 'create_subscription_success',
121
                'testHeaders' => null,
122
            ],
123
            'notification_type:cancel_subscription success' => [
124
                'expectedStatusCode' => 204,
125
                'expectedResponseContent' => '',
126
                'request' => '{"notification_type": "cancel_subscription"}',
127
                'testCase' => 'cancel_subscription_success',
128
                'testHeaders' => null,
129
            ],
130
            'notification_type:update_subscription success' => [
131
                'expectedStatusCode' => 204,
132
                'expectedResponseContent' => '',
133
                'request' => '{"notification_type": "update_subscription"}',
134
                'testCase' => 'update_subscription_success',
135
                'testHeaders' => null,
136
            ],
137
            'notification_type:user_balance_operation success' => [
138
                'expectedStatusCode' => 204,
139
                'expectedResponseContent' => '',
140
                'request' => '{"notification_type": "user_balance_operation"}',
141
                'testCase' => 'user_balance_operation_success',
142
                'testHeaders' => null,
143
            ],
144
            'notification_type:afs_reject success' => [
145
                'expectedStatusCode' => 204,
146
                'expectedResponseContent' => '',
147
                'request' => '{"notification_type": "afs_reject"}',
148
                'testCase' => 'afs_reject_success',
149
                'testHeaders' => null,
150
            ],
151
            //common errors
152
            'notification_type not sent' => [
153
                'expectedStatusCode' => 422,
154
                'expectedResponseContent' => XsollaClient::jsonEncode(
155
                    [
156
                        'error' => [
157
                            'code' => 'INVALID_PARAMETER',
158
                            'message' => 'notification_type key not found in Xsolla webhook request',
159
                        ],
160
                    ]
161
                ),
162
                'request' => '{"foo": "bar"}',
163
                'testCase' => 'empty_request',
164
                'testHeaders' => null,
165
            ],
166
            'Unknown notification_type sent' => [
167
                'expectedStatusCode' => 422,
168
                'expectedResponseContent' => XsollaClient::jsonEncode(
169
                    [
170
                        'error' => [
171
                            'code' => 'INVALID_PARAMETER',
172
                            'message' => 'Unknown notification_type in Xsolla webhook request: unknown',
173
                        ],
174
                    ]
175
                ),
176
                'request' => '{"notification_type": "unknown"}',
177
                'testCase' => 'unknown_notification_type',
178
                'testHeaders' => null,
179
            ],
180
            'Invalid signature' => [
181
                'expectedStatusCode' => 401,
182
                'expectedResponseContent' => XsollaClient::jsonEncode(
183
                    [
184
                        'error' => [
185
                            'code' => 'INVALID_SIGNATURE',
186
                            'message' => 'Invalid Signature. Signature provided in "Authorization" header (78143a5ac4b892a68ce8b0b8b49e26667db0fa00) does not match with expected',
187
                        ],
188
                    ]
189
                ),
190
                'request' => null,
191
                'testCase' => 'invalid_signature',
192
                'testHeaders' => ['Authorization' => 'Signature 78143a5ac4b892a68ce8b0b8b49e26667db0fa00'],
193
            ],
194
            'Authorization header not sent' => [
195
                'expectedStatusCode' => 401,
196
                'expectedResponseContent' => XsollaClient::jsonEncode(
197
                    [
198
                        'error' => [
199
                            'code' => 'INVALID_SIGNATURE',
200
                            'message' => '"Authorization" header not found in Xsolla webhook request. Please check troubleshooting section in README.md https://github.com/xsolla/xsolla-sdk-php#troubleshooting',
201
                        ],
202
                    ]
203
                ),
204
                'request' => null,
205
                'testCase' => 'authorization_header_not_found',
206
                'testHeaders' => ['foo' => 'bar'],
207
            ],
208
            'Authorization header has invalid format' => [
209
                'expectedStatusCode' => 401,
210
                'expectedResponseContent' => XsollaClient::jsonEncode(
211
                    [
212
                        'error' => [
213
                            'code' => 'INVALID_SIGNATURE',
214
                            'message' => 'Signature not found in "Authorization" header from Xsolla webhook request: INVALID_FORMAT',
215
                        ],
216
                    ]
217
                ),
218
                'request' => null,
219
                'testCase' => 'invalid_signature_format',
220
                'testHeaders' => ['Authorization' => 'INVALID_FORMAT'],
221
            ],
222
            'Invalid JSON sent' => [
223
                'expectedStatusCode' => 422,
224
                'expectedResponseContent' => XsollaClient::jsonEncode(
225
                    [
226
                        'error' => [
227
                            'code' => 'INVALID_PARAMETER',
228
                            'message' => 'Unable to parse Xsolla webhook request into JSON: Syntax error.',
229
                        ],
230
                    ]
231
                ),
232
                'request' => 'INVALID_REQUEST_CONTENT',
233
                'testCase' => 'invalid_request_content',
234
                'testHeaders' => null,
235
            ],
236
            'Request from unknown client ip address rejected' => [
237
                'expectedStatusCode' => 401,
238
                'expectedResponseContent' => XsollaClient::jsonEncode(
239
                    [
240
                        'error' => [
241
                            'code' => 'INVALID_CLIENT_IP',
242
                            'message' => 'Client IP address (127.0.0.1) not found in allowed IP addresses whitelist (159.255.220.240/28, 185.30.20.16/29, 185.30.21.0/24, 185.30.21.16/29). Please check troubleshooting section in README.md https://github.com/xsolla/xsolla-sdk-php#troubleshooting',
243
                        ],
244
                    ]
245
                ),
246
                'request' => null,
247
                'testCase' => 'invalid_ip',
248
                'testHeaders' => null,
249
            ],
250
            // exceptions from callback
251
            'Callback throws ServerErrorException' => [
252
                'expectedStatusCode' => 500,
253
                'expectedResponseContent' => XsollaClient::jsonEncode(
254
                    [
255
                        'error' => [
256
                            'code' => 'SERVER_ERROR',
257
                            'message' => 'callback_server_error',
258
                        ],
259
                    ]
260
                ),
261
                'request' => '{"notification_type": "payment"}',
262
                'testCase' => 'callback_server_error',
263
                'testHeaders' => null,
264
            ],
265
            'Callback throws ClientErrorException' => [
266
                'expectedStatusCode' => 400,
267
                'expectedResponseContent' => XsollaClient::jsonEncode(
268
                    [
269
                        'error' => [
270
                            'code' => 'CLIENT_ERROR',
271
                            'message' => 'callback_client_error',
272
                        ],
273
                    ]
274
                ),
275
                'request' => '{"notification_type": "payment"}',
276
                'testCase' => 'callback_client_error',
277
                'testHeaders' => null,
278
            ],
279
            'Callback throws \Exception' => [
280
                'expectedStatusCode' => 500,
281
                'expectedResponseContent' => XsollaClient::jsonEncode(
282
                    [
283
                        'error' => [
284
                            'code' => 'FATAL_ERROR',
285
                            'message' => 'callback_exception',
286
                        ],
287
                    ]
288
                ),
289
                'request' => '{"notification_type": "payment"}',
290
                'testCase' => 'callback_exception',
291
                'testHeaders' => null,
292
            ],
293
            'Callback throws InvalidUserException' => [
294
                'expectedStatusCode' => 422,
295
                'expectedResponseContent' => XsollaClient::jsonEncode(
296
                    [
297
                        'error' => [
298
                            'code' => 'INVALID_USER',
299
                            'message' => 'callback_invalid_user_exception',
300
                        ],
301
                    ]
302
                ),
303
                'request' => '{"notification_type": "payment"}',
304
                'testCase' => 'callback_invalid_user_exception',
305
                'testHeaders' => null,
306
            ],
307
            'Callback throws InvalidAmountException' => [
308
                'expectedStatusCode' => 422,
309
                'expectedResponseContent' => XsollaClient::jsonEncode(
310
                    [
311
                        'error' => [
312
                            'code' => 'INCORRECT_AMOUNT',
313
                            'message' => 'callback_invalid_amount_exception',
314
                        ],
315
                    ]
316
                ),
317
                'request' => '{"notification_type": "payment"}',
318
                'testCase' => 'callback_invalid_amount_exception',
319
                'testHeaders' => null,
320
            ],
321
            'Callback throws InvalidInvoiceException' => [
322
                'expectedStatusCode' => 422,
323
                'expectedResponseContent' => XsollaClient::jsonEncode(
324
                    [
325
                        'error' => [
326
                            'code' => 'INCORRECT_INVOICE',
327
                            'message' => 'callback_invalid_invoice_exception',
328
                        ],
329
                    ]
330
                ),
331
                'request' => '{"notification_type": "payment"}',
332
                'testCase' => 'callback_invalid_invoice_exception',
333
                'testHeaders' => null,
334
            ],
335
            // get_pincode
336
            'get_pincode with empty webhook response' => [
337
                'expectedStatusCode' => 204,
338
                'expectedResponseContent' => '',
339
                'request' => '{"notification_type": "get_pincode"}',
340
                'testCase' => 'get_pincode_empty',
341
                'testHeaders' => null,
342
            ],
343
            'get_pincode with webhook response' => [
344
                'expectedStatusCode' => 200,
345
                'expectedResponseContent' => '{
346
    "pin_code": "CODE"
347
}',
348
                'request' => '{"notification_type": "get_pincode"}',
349
                'testCase' => 'get_pincode_success',
350
                'testHeaders' => null,
351
            ],
352
            'get_pincode invalid pin code from callback' => [
353
                'expectedStatusCode' => 500,
354
                'expectedResponseContent' => XsollaClient::jsonEncode(
355
                    [
356
                        'error' => [
357
                            'code' => 'SERVER_ERROR',
358
                            'message' => 'Pin code should be non-empty string. NULL given',
359
                        ],
360
                    ]
361
                ),
362
                'request' => '{"notification_type": "get_pincode"}',
363
                'testCase' => 'get_pincode_invalid',
364
                'testHeaders' => null,
365
            ],
366
            // user_search
367
            'user_search with empty webhook response' => [
368
                'expectedStatusCode' => 204,
369
                'expectedResponseContent' => '',
370
                'request' => '{"notification_type": "user_search"}',
371
                'testCase' => 'user_search_empty',
372
                'testHeaders' => null,
373
            ],
374
            'user_search with webhook response' => [
375
                'expectedStatusCode' => 200,
376
                'expectedResponseContent' => '{
377
    "user": {
378
        "id": "USER_ID",
379
        "name": "User Name",
380
        "public_id": "PUBLIC_ID",
381
        "email": "[email protected]",
382
        "phone": "123456789"
383
    }
384
}',
385
                'request' => '{"notification_type": "user_search"}',
386
                'testCase' => 'user_search_success',
387
                'testHeaders' => null,
388
            ],
389
            'user_search invalid user id from callback' => [
390
                'expectedStatusCode' => 500,
391
                'expectedResponseContent' => XsollaClient::jsonEncode(
392
                    [
393
                        'error' => [
394
                            'code' => 'SERVER_ERROR',
395
                            'message' => 'User id should be non-empty string. NULL given',
396
                        ],
397
                    ]
398
                ),
399
                'request' => '{"notification_type": "user_search"}',
400
                'testCase' => 'user_search_invalid',
401
                'testHeaders' => null,
402
            ],
403
        ];
404
    }
405
}
406