1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
declare(strict_types=1); |
4
|
|
|
|
5
|
|
|
namespace ApplicationTest\Handler; |
6
|
|
|
|
7
|
|
|
use Application\Handler\DatatransHandler; |
8
|
|
|
use Application\Model\User; |
9
|
|
|
use ApplicationTest\Traits\TestWithTransactionAndUser; |
10
|
|
|
use Laminas\Diactoros\ServerRequest; |
11
|
|
|
use Mezzio\Template\TemplateRendererInterface; |
12
|
|
|
use Money\Money; |
13
|
|
|
use PHPUnit\Framework\TestCase; |
14
|
|
|
|
15
|
|
|
class DatatransHandlerTest extends TestCase |
16
|
|
|
{ |
17
|
|
|
use TestWithTransactionAndUser; |
18
|
|
|
|
19
|
|
|
/** |
20
|
|
|
* @dataProvider providerProcess |
21
|
|
|
*/ |
22
|
|
|
public function testProcess(?array $data, ?int $accountId, Money $expectedAmount, array $expectedViewModel): void |
23
|
|
|
{ |
24
|
|
|
$userId = $data['refno'] ?? null; |
25
|
|
|
$user = $this->getEntityManager()->getRepository(User::class)->getOneById((int) $userId); |
26
|
|
|
User::setCurrent($user); |
27
|
|
|
|
28
|
|
|
// Message always include input data |
29
|
|
|
$expectedViewModel['message']['detail'] = $data ?? []; |
30
|
|
|
$renderer = $this->createMock(TemplateRendererInterface::class); |
31
|
|
|
$renderer->expects(self::atLeastOnce())->method('render')->with('app::datatrans', $expectedViewModel)->willReturn(''); |
32
|
|
|
|
33
|
|
|
$request = new ServerRequest(); |
34
|
|
|
$request = $request->withParsedBody($data); |
35
|
|
|
|
36
|
|
|
$config = [ |
37
|
|
|
'key' => '1a03b7bcf2752c8c8a1b46616b0c12658d2c7643403e655450bedb7c78bb2d2f659c2ff4e647e4ea72d37ef6745ebda6733c7b859439107069f291cda98f4844', |
38
|
|
|
]; |
39
|
|
|
|
40
|
|
|
$handler = new DatatransHandler($this->getEntityManager(), $renderer, $config); |
41
|
|
|
$handler->handle($request); |
42
|
|
|
|
43
|
|
|
// Submit the same request again to make sure it is accounted only once |
44
|
|
|
$handler->handle($request); |
45
|
|
|
|
46
|
|
|
if (is_int($accountId)) { |
47
|
|
|
$actualBalance = $this->getEntityManager()->getConnection()->fetchColumn('SELECT balance FROM account WHERE id = ' . $accountId); |
|
|
|
|
48
|
|
|
self::assertSame($expectedAmount->getAmount(), $actualBalance); |
49
|
|
|
} |
50
|
|
|
|
51
|
|
|
self::assertTrue(true); // Workaround when we only assert via prophesize |
52
|
|
|
} |
53
|
|
|
|
54
|
|
|
public function providerProcess(): array |
55
|
|
|
{ |
56
|
|
|
return [ |
57
|
|
|
'normal' => [ |
58
|
|
|
[ |
59
|
|
|
'uppTransactionId' => '123456789012345678', |
60
|
|
|
'status' => 'success', |
61
|
|
|
'refno' => '1007', |
62
|
|
|
'merchantId' => '123456789', |
63
|
|
|
'amount' => '10000', |
64
|
|
|
'currency' => 'CHF', |
65
|
|
|
'responseMessage' => 'Payment was successful', |
66
|
|
|
'sign' => 'e591bc45430b1a14ad7e1a3a14a8218fb9a5ae944557c96366ec98feae6b17f4', |
67
|
|
|
], |
68
|
|
|
10096, |
69
|
|
|
Money::CHF(15000), |
70
|
|
|
[ |
71
|
|
|
'message' => [ |
72
|
|
|
'status' => 'success', |
73
|
|
|
'message' => 'Payment was successful', |
74
|
|
|
], |
75
|
|
|
], |
76
|
|
|
], |
77
|
|
|
'duplicate' => [ |
78
|
|
|
[ |
79
|
|
|
'uppTransactionId' => '123456789012345678', |
80
|
|
|
'status' => 'success', |
81
|
|
|
'refno' => '1007', |
82
|
|
|
'merchantId' => '123456789', |
83
|
|
|
'amount' => '10000', |
84
|
|
|
'currency' => 'CHF', |
85
|
|
|
'responseMessage' => 'Payment was successful', |
86
|
|
|
'sign' => 'e591bc45430b1a14ad7e1a3a14a8218fb9a5ae944557c96366ec98feae6b17f4', |
87
|
|
|
], |
88
|
|
|
10096, |
89
|
|
|
Money::CHF(15000), |
90
|
|
|
[ |
91
|
|
|
'message' => [ |
92
|
|
|
'status' => 'success', |
93
|
|
|
'message' => 'Payment was successful', |
94
|
|
|
], |
95
|
|
|
], |
96
|
|
|
], |
97
|
|
|
'invalid HMAC signature' => [ |
98
|
|
|
[ |
99
|
|
|
'uppTransactionId' => '123456789012345678', |
100
|
|
|
'status' => 'success', |
101
|
|
|
'refno' => '1007', |
102
|
|
|
'merchantId' => '123456789', |
103
|
|
|
'amount' => '10000', |
104
|
|
|
'currency' => 'CHF', |
105
|
|
|
'responseMessage' => 'Payment was successful', |
106
|
|
|
'sign' => 'a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0', |
107
|
|
|
], |
108
|
|
|
10096, |
109
|
|
|
Money::CHF(5000), |
110
|
|
|
[ |
111
|
|
|
'message' => [ |
112
|
|
|
'status' => 'error', |
113
|
|
|
'message' => 'Invalid HMAC signature', |
114
|
|
|
], |
115
|
|
|
], |
116
|
|
|
], |
117
|
|
|
'missing HMAC signature' => [ |
118
|
|
|
[ |
119
|
|
|
'uppTransactionId' => '123456789012345678', |
120
|
|
|
'status' => 'success', |
121
|
|
|
'refno' => '1007', |
122
|
|
|
'merchantId' => '123456789', |
123
|
|
|
'amount' => '10000', |
124
|
|
|
'currency' => 'CHF', |
125
|
|
|
'responseMessage' => 'Payment was successful', |
126
|
|
|
], |
127
|
|
|
10096, |
128
|
|
|
Money::CHF(5000), |
129
|
|
|
[ |
130
|
|
|
'message' => [ |
131
|
|
|
'status' => 'error', |
132
|
|
|
'message' => 'Missing HMAC signature', |
133
|
|
|
], |
134
|
|
|
], |
135
|
|
|
], |
136
|
|
|
'user without account yet (child can credit householder)' => [ |
137
|
|
|
[ |
138
|
|
|
'uppTransactionId' => '123456789012345678', |
139
|
|
|
'status' => 'success', |
140
|
|
|
'refno' => '1008', |
141
|
|
|
'merchantId' => '123456789', |
142
|
|
|
'amount' => '10000', |
143
|
|
|
'currency' => 'CHF', |
144
|
|
|
'responseMessage' => 'Payment was successful', |
145
|
|
|
'sign' => '3005b015945fb625ee25d7d804a65cc17f9dacd4fcba72329d34c8081230c146', |
146
|
|
|
], |
147
|
|
|
10096, |
148
|
|
|
Money::CHF(15000), |
149
|
|
|
[ |
150
|
|
|
'message' => [ |
151
|
|
|
'status' => 'success', |
152
|
|
|
'message' => 'Payment was successful', |
153
|
|
|
], |
154
|
|
|
], |
155
|
|
|
], |
156
|
|
|
'error' => [ |
157
|
|
|
[ |
158
|
|
|
'uppTransactionId' => '876543210987654321', |
159
|
|
|
'status' => 'error', |
160
|
|
|
'refno' => '1007', |
161
|
|
|
'merchantId' => '123456789', |
162
|
|
|
'errorMessage' => 'Dear Sir/Madam, Fire! fire! help me! All the best, Maurice Moss.', |
163
|
|
|
'sign' => '38151b15a4c680cccafe9dfff6edb236fa9bf1eeec65799b2720312ae9c4b233', |
164
|
|
|
], |
165
|
|
|
10096, |
166
|
|
|
Money::CHF(5000), |
167
|
|
|
[ |
168
|
|
|
'message' => [ |
169
|
|
|
'status' => 'error', |
170
|
|
|
'message' => 'Dear Sir/Madam, Fire! fire! help me! All the best, Maurice Moss.', |
171
|
|
|
], |
172
|
|
|
], |
173
|
|
|
], |
174
|
|
|
'cancel' => [ |
175
|
|
|
[ |
176
|
|
|
'uppTransactionId' => '876543210987654321', |
177
|
|
|
'status' => 'cancel', |
178
|
|
|
'refno' => '1007', |
179
|
|
|
'merchantId' => '123456789', |
180
|
|
|
'sign' => '38151b15a4c680cccafe9dfff6edb236fa9bf1eeec65799b2720312ae9c4b233', |
181
|
|
|
], |
182
|
|
|
10096, |
183
|
|
|
Money::CHF(5000), |
184
|
|
|
[ |
185
|
|
|
'message' => [ |
186
|
|
|
'status' => 'cancel', |
187
|
|
|
'message' => 'Cancelled', |
188
|
|
|
], |
189
|
|
|
], |
190
|
|
|
], |
191
|
|
|
'invalid body' => [ |
192
|
|
|
null, |
193
|
|
|
null, |
194
|
|
|
Money::CHF(0), |
195
|
|
|
[ |
196
|
|
|
'message' => [ |
197
|
|
|
'status' => 'error', |
198
|
|
|
'message' => 'Parsed body is expected to be an array but got: NULL', |
199
|
|
|
], |
200
|
|
|
], |
201
|
|
|
], |
202
|
|
|
'invalid status' => [ |
203
|
|
|
[ |
204
|
|
|
'uppTransactionId' => '123456789012345678', |
205
|
|
|
'status' => 'non-existing-status', |
206
|
|
|
'refno' => '1007', |
207
|
|
|
'merchantId' => '123456789', |
208
|
|
|
'amount' => '10000', |
209
|
|
|
'currency' => 'CHF', |
210
|
|
|
'responseMessage' => 'Payment was successful', |
211
|
|
|
'sign' => 'e591bc45430b1a14ad7e1a3a14a8218fb9a5ae944557c96366ec98feae6b17f4', |
212
|
|
|
], |
213
|
|
|
10096, |
214
|
|
|
Money::CHF(5000), |
215
|
|
|
[ |
216
|
|
|
'message' => [ |
217
|
|
|
'status' => 'error', |
218
|
|
|
'message' => 'Unsupported status in Datatrans data: non-existing-status', |
219
|
|
|
], |
220
|
|
|
], |
221
|
|
|
], |
222
|
|
|
'non-existing user' => [ |
223
|
|
|
[ |
224
|
|
|
'uppTransactionId' => '123456789012345678', |
225
|
|
|
'status' => 'success', |
226
|
|
|
'merchantId' => '123456789', |
227
|
|
|
'amount' => '10000', |
228
|
|
|
'currency' => 'CHF', |
229
|
|
|
'responseMessage' => 'Payment was successful', |
230
|
|
|
'sign' => 'f875347d4c66a4f82717ae88f13812289db79b4c1cab4df4fe1c7fdbaaacff05', |
231
|
|
|
], |
232
|
|
|
null, |
233
|
|
|
Money::CHF(0), |
234
|
|
|
[ |
235
|
|
|
'message' => [ |
236
|
|
|
'status' => 'error', |
237
|
|
|
'message' => 'Cannot create transactions without a user', |
238
|
|
|
], |
239
|
|
|
], |
240
|
|
|
], |
241
|
|
|
'non-existing amount' => [ |
242
|
|
|
[ |
243
|
|
|
'uppTransactionId' => '123456789012345678', |
244
|
|
|
'status' => 'success', |
245
|
|
|
'merchantId' => '123456789', |
246
|
|
|
'refno' => '1007', |
247
|
|
|
'currency' => 'CHF', |
248
|
|
|
'responseMessage' => 'Payment was successful', |
249
|
|
|
'sign' => 'e2ca709347d5bec5fd169cd3e1243a95d2eae0abf23a34e26e57698d30b3645d', |
250
|
|
|
], |
251
|
|
|
10096, |
252
|
|
|
Money::CHF(5000), |
253
|
|
|
[ |
254
|
|
|
'message' => [ |
255
|
|
|
'status' => 'error', |
256
|
|
|
'message' => 'Cannot create transactions without an amount', |
257
|
|
|
], |
258
|
|
|
], |
259
|
|
|
], |
260
|
|
|
'invalid currency' => [ |
261
|
|
|
[ |
262
|
|
|
'uppTransactionId' => '123456789012345678', |
263
|
|
|
'status' => 'success', |
264
|
|
|
'refno' => '1007', |
265
|
|
|
'merchantId' => '123456789', |
266
|
|
|
'amount' => '10000', |
267
|
|
|
'currency' => 'USD', |
268
|
|
|
'responseMessage' => 'Payment was successful', |
269
|
|
|
'sign' => 'a591b4bb76872f8fcb01f841e4b0cf092ae7c26561e93326243d7f48a9181849', |
270
|
|
|
], |
271
|
|
|
10096, |
272
|
|
|
Money::CHF(5000), |
273
|
|
|
[ |
274
|
|
|
'message' => [ |
275
|
|
|
'status' => 'error', |
276
|
|
|
'message' => 'Can only create transactions for CHF, but got: USD', |
277
|
|
|
], |
278
|
|
|
], |
279
|
|
|
], |
280
|
|
|
]; |
281
|
|
|
} |
282
|
|
|
} |
283
|
|
|
|
This function has been deprecated. The supplier of the function has supplied an explanatory message.
The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.