1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
declare( strict_types = 1 ); |
4
|
|
|
|
5
|
|
|
namespace WMDE\Fundraising\Frontend\DonationContext\Tests\Integration\UseCases\HandlePayPalPaymentNotification; |
6
|
|
|
|
7
|
|
|
use WMDE\Fundraising\Frontend\DonationContext\DataAccess\DoctrineDonationRepository; |
8
|
|
|
use WMDE\Fundraising\Frontend\DonationContext\Domain\Model\Donation; |
9
|
|
|
use WMDE\Fundraising\Frontend\DonationContext\Domain\Model\DonorName; |
10
|
|
|
use WMDE\Fundraising\Frontend\DonationContext\Infrastructure\DonationConfirmationMailer; |
11
|
|
|
use WMDE\Fundraising\Frontend\DonationContext\Infrastructure\DonationEventLogger; |
12
|
|
|
use WMDE\Fundraising\Frontend\DonationContext\Tests\Data\ValidPayPalNotificationRequest; |
13
|
|
|
use WMDE\Fundraising\Frontend\DonationContext\Tests\Fixtures\DonationEventLoggerSpy; |
14
|
|
|
use WMDE\Fundraising\Frontend\DonationContext\Tests\Fixtures\DonationRepositorySpy; |
15
|
|
|
use WMDE\Fundraising\Frontend\DonationContext\Tests\Fixtures\FailingDonationAuthorizer; |
16
|
|
|
use WMDE\Fundraising\Frontend\DonationContext\Tests\Fixtures\FakeDonationRepository; |
17
|
|
|
use WMDE\Fundraising\Frontend\DonationContext\Tests\Fixtures\SucceedingDonationAuthorizer; |
18
|
|
|
use WMDE\Fundraising\Frontend\DonationContext\UseCases\HandlePayPalPaymentNotification\HandlePayPalPaymentNotificationUseCase; |
19
|
|
|
use WMDE\Fundraising\Frontend\PaymentContext\Domain\Model\PayPalData; |
20
|
|
|
use WMDE\Fundraising\Frontend\DonationContext\Tests\Data\ValidDonation; |
21
|
|
|
use WMDE\Fundraising\Frontend\Tests\Fixtures\ThrowingEntityManager; |
22
|
|
|
|
23
|
|
|
/** |
24
|
|
|
* @covers WMDE\Fundraising\Frontend\DonationContext\UseCases\HandlePayPalPaymentNotification\HandlePayPalPaymentNotificationUseCase |
25
|
|
|
* |
26
|
|
|
* @licence GNU GPL v2+ |
27
|
|
|
* @author Kai Nissen < [email protected] > |
28
|
|
|
* @author Gabriel Birke < [email protected] > |
29
|
|
|
*/ |
30
|
|
|
class HandlePayPalPaymentNotificationUseCaseTest extends \PHPUnit\Framework\TestCase { |
31
|
|
|
|
32
|
|
|
public function testWhenRepositoryThrowsException_errorResponseIsReturned() { |
33
|
|
|
$useCase = new HandlePayPalPaymentNotificationUseCase( |
34
|
|
|
new DoctrineDonationRepository( ThrowingEntityManager::newInstance( $this ) ), |
35
|
|
|
new FailingDonationAuthorizer(), |
36
|
|
|
$this->getMailer(), |
|
|
|
|
37
|
|
|
$this->getEventLogger() |
|
|
|
|
38
|
|
|
); |
39
|
|
|
$request = ValidPayPalNotificationRequest::newInstantPayment( 1 ); |
40
|
|
|
$reponse = $useCase->handleNotification( $request ); |
41
|
|
|
$this->assertFalse( $reponse->notificationWasHandled() ); |
42
|
|
|
$this->assertTrue( $reponse->hasErrors() ); |
43
|
|
|
} |
44
|
|
|
|
45
|
|
|
public function testWhenAuthorizationFails_unhandledResponseIsReturned() { |
46
|
|
|
$fakeRepository = new FakeDonationRepository(); |
47
|
|
|
$fakeRepository->storeDonation( ValidDonation::newIncompletePayPalDonation() ); |
48
|
|
|
|
49
|
|
|
$useCase = new HandlePayPalPaymentNotificationUseCase( |
50
|
|
|
$fakeRepository, |
51
|
|
|
new FailingDonationAuthorizer(), |
52
|
|
|
$this->getMailer(), |
|
|
|
|
53
|
|
|
$this->getEventLogger() |
|
|
|
|
54
|
|
|
); |
55
|
|
|
|
56
|
|
|
$request = ValidPayPalNotificationRequest::newInstantPayment( 1 ); |
57
|
|
|
$this->assertFalse( $useCase->handleNotification( $request )->notificationWasHandled() ); |
58
|
|
|
} |
59
|
|
|
|
60
|
|
|
public function testWhenAuthorizationSucceeds_successResponseIsReturned() { |
61
|
|
|
$fakeRepository = new FakeDonationRepository(); |
62
|
|
|
$fakeRepository->storeDonation( ValidDonation::newIncompletePayPalDonation() ); |
63
|
|
|
|
64
|
|
|
$useCase = new HandlePayPalPaymentNotificationUseCase( |
65
|
|
|
$fakeRepository, |
66
|
|
|
new SucceedingDonationAuthorizer(), |
67
|
|
|
$this->getMailer(), |
|
|
|
|
68
|
|
|
$this->getEventLogger() |
|
|
|
|
69
|
|
|
); |
70
|
|
|
|
71
|
|
|
$request = ValidPayPalNotificationRequest::newInstantPayment( 1 ); |
72
|
|
|
$this->assertTrue( $useCase->handleNotification( $request )->notificationWasHandled() ); |
73
|
|
|
} |
74
|
|
|
|
75
|
|
|
public function testWhenPaymentTypeIsNonPayPal_unhandledResponseIsReturned() { |
76
|
|
|
$fakeRepository = new FakeDonationRepository(); |
77
|
|
|
$fakeRepository->storeDonation( ValidDonation::newDirectDebitDonation() ); |
78
|
|
|
|
79
|
|
|
$request = ValidPayPalNotificationRequest::newInstantPayment( 1 ); |
80
|
|
|
$useCase = new HandlePayPalPaymentNotificationUseCase( |
81
|
|
|
$fakeRepository, |
82
|
|
|
new SucceedingDonationAuthorizer(), |
83
|
|
|
$this->getMailer(), |
|
|
|
|
84
|
|
|
$this->getEventLogger() |
|
|
|
|
85
|
|
|
); |
86
|
|
|
|
87
|
|
|
$this->assertFalse( $useCase->handleNotification( $request )->notificationWasHandled() ); |
88
|
|
|
} |
89
|
|
|
|
90
|
|
|
public function testWhenPaymentStatusIsPending_unhandledResponseIsReturned() { |
91
|
|
|
$request = ValidPayPalNotificationRequest::newPendingPayment(); |
92
|
|
|
|
93
|
|
|
$useCase = new HandlePayPalPaymentNotificationUseCase( |
94
|
|
|
new FakeDonationRepository(), |
95
|
|
|
new SucceedingDonationAuthorizer(), |
96
|
|
|
$this->getMailer(), |
|
|
|
|
97
|
|
|
$this->getEventLogger() |
|
|
|
|
98
|
|
|
); |
99
|
|
|
|
100
|
|
|
$this->assertFalse( $useCase->handleNotification( $request )->notificationWasHandled() ); |
101
|
|
|
} |
102
|
|
|
|
103
|
|
|
public function testWhenTransactionTypeIsForSubscriptionChanges_unhandledResponseIsReturned() { |
104
|
|
|
$request = ValidPayPalNotificationRequest::newSubscriptionModification(); |
105
|
|
|
|
106
|
|
|
$useCase = new HandlePayPalPaymentNotificationUseCase( |
107
|
|
|
new FakeDonationRepository(), |
108
|
|
|
new SucceedingDonationAuthorizer(), |
109
|
|
|
$this->getMailer(), |
|
|
|
|
110
|
|
|
$this->getEventLogger() |
|
|
|
|
111
|
|
|
); |
112
|
|
|
$this->assertFalse( $useCase->handleNotification( $request )->notificationWasHandled() ); |
113
|
|
|
} |
114
|
|
|
|
115
|
|
|
public function testWhenAuthorizationSucceeds_confirmationMailIsSent() { |
116
|
|
|
$donation = ValidDonation::newIncompletePayPalDonation(); |
117
|
|
|
$fakeRepository = new FakeDonationRepository(); |
118
|
|
|
$fakeRepository->storeDonation( $donation ); |
119
|
|
|
|
120
|
|
|
$mailer = $this->getMailer(); |
121
|
|
|
$mailer->expects( $this->once() ) |
|
|
|
|
122
|
|
|
->method( 'sendConfirmationMailFor' ); |
123
|
|
|
// TODO: assert that the correct values are passed to the mailer |
124
|
|
|
|
125
|
|
|
$useCase = new HandlePayPalPaymentNotificationUseCase( |
126
|
|
|
$fakeRepository, |
127
|
|
|
new SucceedingDonationAuthorizer(), |
128
|
|
|
$mailer, |
|
|
|
|
129
|
|
|
$this->getEventLogger() |
|
|
|
|
130
|
|
|
); |
131
|
|
|
|
132
|
|
|
$request = ValidPayPalNotificationRequest::newInstantPayment( 1 ); |
133
|
|
|
$this->assertTrue( $useCase->handleNotification( $request )->notificationWasHandled() ); |
134
|
|
|
} |
135
|
|
|
|
136
|
|
|
public function testWhenAuthorizationSucceedsForAnonymousDonation_confirmationMailIsNotSent() { |
137
|
|
|
$donation = ValidDonation::newIncompleteAnonymousPayPalDonation(); |
138
|
|
|
$fakeRepository = new FakeDonationRepository(); |
139
|
|
|
$fakeRepository->storeDonation( $donation ); |
140
|
|
|
|
141
|
|
|
$mailer = $this->getMailer(); |
142
|
|
|
$mailer->expects( $this->never() ) |
|
|
|
|
143
|
|
|
->method( 'sendConfirmationMailFor' ); |
144
|
|
|
|
145
|
|
|
$request = ValidPayPalNotificationRequest::newInstantPayment( 1 ); |
146
|
|
|
$useCase = new HandlePayPalPaymentNotificationUseCase( |
147
|
|
|
$fakeRepository, |
148
|
|
|
new SucceedingDonationAuthorizer(), |
149
|
|
|
$mailer, |
|
|
|
|
150
|
|
|
$this->getEventLogger() |
|
|
|
|
151
|
|
|
); |
152
|
|
|
|
153
|
|
|
$this->assertTrue( $useCase->handleNotification( $request )->notificationWasHandled() ); |
154
|
|
|
} |
155
|
|
|
|
156
|
|
|
public function testWhenAuthorizationSucceeds_donationIsStored() { |
157
|
|
|
$donation = ValidDonation::newIncompletePayPalDonation(); |
158
|
|
|
$repositorySpy = new DonationRepositorySpy( $donation ); |
159
|
|
|
|
160
|
|
|
$request = ValidPayPalNotificationRequest::newInstantPayment( 1 ); |
161
|
|
|
$useCase = new HandlePayPalPaymentNotificationUseCase( |
162
|
|
|
$repositorySpy, |
163
|
|
|
new SucceedingDonationAuthorizer(), |
164
|
|
|
$this->getMailer(), |
|
|
|
|
165
|
|
|
$this->getEventLogger() |
|
|
|
|
166
|
|
|
); |
167
|
|
|
|
168
|
|
|
$this->assertTrue( $useCase->handleNotification( $request )->notificationWasHandled() ); |
169
|
|
|
$this->assertCount( 1, $repositorySpy->getStoreDonationCalls() ); |
170
|
|
|
} |
171
|
|
|
|
172
|
|
|
public function testWhenAuthorizationSucceeds_donationIsBooked() { |
173
|
|
|
$donation = ValidDonation::newIncompletePayPalDonation(); |
174
|
|
|
$repository = new FakeDonationRepository( $donation ); |
175
|
|
|
|
176
|
|
|
$request = ValidPayPalNotificationRequest::newInstantPayment( 1 ); |
177
|
|
|
$useCase = new HandlePayPalPaymentNotificationUseCase( |
178
|
|
|
$repository, |
179
|
|
|
new SucceedingDonationAuthorizer(), |
180
|
|
|
$this->getMailer(), |
|
|
|
|
181
|
|
|
$this->getEventLogger() |
|
|
|
|
182
|
|
|
); |
183
|
|
|
|
184
|
|
|
$this->assertTrue( $useCase->handleNotification( $request )->notificationWasHandled() ); |
185
|
|
|
$this->assertTrue( $repository->getDonationById( $donation->getId() )->isBooked() ); |
186
|
|
|
} |
187
|
|
|
|
188
|
|
|
public function testWhenAuthorizationSucceeds_bookingEventIsLogged() { |
189
|
|
|
$donation = ValidDonation::newIncompletePayPalDonation(); |
190
|
|
|
$repositorySpy = new DonationRepositorySpy( $donation ); |
191
|
|
|
|
192
|
|
|
$eventLogger = new DonationEventLoggerSpy(); |
193
|
|
|
|
194
|
|
|
$request = ValidPayPalNotificationRequest::newInstantPayment( 1 ); |
195
|
|
|
$useCase = new HandlePayPalPaymentNotificationUseCase( |
196
|
|
|
$repositorySpy, |
197
|
|
|
new SucceedingDonationAuthorizer(), |
198
|
|
|
$this->getMailer(), |
|
|
|
|
199
|
|
|
$eventLogger |
200
|
|
|
); |
201
|
|
|
|
202
|
|
|
$this->assertTrue( $useCase->handleNotification( $request )->notificationWasHandled() ); |
203
|
|
|
|
204
|
|
|
$this->assertEventLogContainsExpression( $eventLogger, $donation->getId(), '/booked/' ); |
205
|
|
|
} |
206
|
|
|
|
207
|
|
|
public function testWhenSendingConfirmationMailFails_handlerReturnsTrue() { |
208
|
|
|
$fakeRepository = new FakeDonationRepository(); |
209
|
|
|
$fakeRepository->storeDonation( ValidDonation::newIncompletePayPalDonation() ); |
210
|
|
|
|
211
|
|
|
$mailer = $this->getMailer(); |
212
|
|
|
$mailer->expects( $this->once() ) |
|
|
|
|
213
|
|
|
->method( 'sendConfirmationMailFor' ) |
214
|
|
|
->willThrowException( new \RuntimeException( 'Oh noes!' ) ); |
215
|
|
|
|
216
|
|
|
$request = ValidPayPalNotificationRequest::newInstantPayment( 1 ); |
217
|
|
|
$useCase = new HandlePayPalPaymentNotificationUseCase( |
218
|
|
|
$fakeRepository, |
219
|
|
|
new SucceedingDonationAuthorizer(), |
220
|
|
|
$mailer, |
|
|
|
|
221
|
|
|
$this->getEventLogger() |
|
|
|
|
222
|
|
|
); |
223
|
|
|
|
224
|
|
|
$this->assertTrue( $useCase->handleNotification( $request )->notificationWasHandled() ); |
225
|
|
|
} |
226
|
|
|
|
227
|
|
|
public function testGivenNewTransactionIdForBookedDonation_transactionIdShowsUpInChildPayments() { |
228
|
|
|
$donation = ValidDonation::newBookedPayPalDonation(); |
229
|
|
|
$transactionId = '16R12136PU8783961'; |
230
|
|
|
|
231
|
|
|
$fakeRepository = new FakeDonationRepository(); |
232
|
|
|
$fakeRepository->storeDonation( $donation ); |
233
|
|
|
|
234
|
|
|
$request = ValidPayPalNotificationRequest::newDuplicatePayment( $donation->getId(), $transactionId ); |
235
|
|
|
|
236
|
|
|
$useCase = new HandlePayPalPaymentNotificationUseCase( |
237
|
|
|
$fakeRepository, |
238
|
|
|
new SucceedingDonationAuthorizer(), |
239
|
|
|
$this->getMailer(), |
|
|
|
|
240
|
|
|
$this->getEventLogger() |
|
|
|
|
241
|
|
|
); |
242
|
|
|
|
243
|
|
|
$this->assertTrue( $useCase->handleNotification( $request )->notificationWasHandled() ); |
244
|
|
|
|
245
|
|
|
/** @var \WMDE\Fundraising\Frontend\PaymentContext\Domain\Model\PayPalPayment $payment */ |
246
|
|
|
$payment = $fakeRepository->getDonationById( $donation->getId() )->getPaymentMethod(); |
247
|
|
|
|
248
|
|
|
$this->assertTrue( |
249
|
|
|
$payment->getPayPalData()->hasChildPayment( $transactionId ), |
250
|
|
|
'Parent payment must have new transaction ID in its list' |
251
|
|
|
); |
252
|
|
|
} |
253
|
|
|
|
254
|
|
|
public function testGivenNewTransactionIdForBookedDonation_childTransactionWithSameDataIsCreated() { |
255
|
|
|
$donation = ValidDonation::newBookedPayPalDonation(); |
256
|
|
|
$transactionId = '16R12136PU8783961'; |
257
|
|
|
|
258
|
|
|
$fakeRepository = new FakeDonationRepository(); |
259
|
|
|
$fakeRepository->storeDonation( $donation ); |
260
|
|
|
|
261
|
|
|
$request = ValidPayPalNotificationRequest::newDuplicatePayment( $donation->getId(), $transactionId ); |
262
|
|
|
|
263
|
|
|
$useCase = new HandlePayPalPaymentNotificationUseCase( |
264
|
|
|
$fakeRepository, |
265
|
|
|
new SucceedingDonationAuthorizer(), |
266
|
|
|
$this->getMailer(), |
|
|
|
|
267
|
|
|
$this->getEventLogger() |
|
|
|
|
268
|
|
|
); |
269
|
|
|
|
270
|
|
|
$this->assertTrue( $useCase->handleNotification( $request )->notificationWasHandled() ); |
271
|
|
|
|
272
|
|
|
$donation = $fakeRepository->getDonationById( $donation->getId() ); |
273
|
|
|
/** @var \WMDE\Fundraising\Frontend\PaymentContext\Domain\Model\PayPalPayment $payment */ |
274
|
|
|
$payment = $donation->getPaymentMethod(); |
275
|
|
|
$childDonation = $fakeRepository->getDonationById( $payment->getPayPalData()->getChildPaymentEntityId( $transactionId ) ); |
276
|
|
|
$this->assertNotNull( $childDonation ); |
277
|
|
|
/** @var \WMDE\Fundraising\Frontend\PaymentContext\Domain\Model\PayPalPayment $childDonationPaymentMethod */ |
278
|
|
|
$childDonationPaymentMethod = $childDonation->getPaymentMethod(); |
279
|
|
|
$this->assertEquals( $transactionId, $childDonationPaymentMethod->getPayPalData()->getPaymentId() ); |
280
|
|
|
$this->assertEquals( $donation->getAmount(), $childDonation->getAmount() ); |
281
|
|
|
$this->assertEquals( $donation->getDonor(), $childDonation->getDonor() ); |
282
|
|
|
$this->assertEquals( $donation->getPaymentIntervalInMonths(), $childDonation->getPaymentIntervalInMonths() ); |
283
|
|
|
$this->assertTrue( $childDonation->isBooked() ); |
284
|
|
|
} |
285
|
|
|
|
286
|
|
|
public function testGivenNewTransactionIdForBookedDonation_childCreationeventIsLogged() { |
287
|
|
|
$donation = ValidDonation::newBookedPayPalDonation(); |
288
|
|
|
$transactionId = '16R12136PU8783961'; |
289
|
|
|
|
290
|
|
|
$fakeRepository = new FakeDonationRepository(); |
291
|
|
|
$fakeRepository->storeDonation( $donation ); |
292
|
|
|
|
293
|
|
|
$request = ValidPayPalNotificationRequest::newDuplicatePayment( $donation->getId(), $transactionId ); |
294
|
|
|
|
295
|
|
|
$eventLogger = new DonationEventLoggerSpy(); |
296
|
|
|
|
297
|
|
|
$useCase = new HandlePayPalPaymentNotificationUseCase( |
298
|
|
|
$fakeRepository, |
299
|
|
|
new SucceedingDonationAuthorizer(), |
300
|
|
|
$this->getMailer(), |
|
|
|
|
301
|
|
|
$eventLogger |
302
|
|
|
); |
303
|
|
|
|
304
|
|
|
$this->assertTrue( $useCase->handleNotification( $request )->notificationWasHandled() ); |
305
|
|
|
|
306
|
|
|
$donation = $fakeRepository->getDonationById( $donation->getId() ); |
307
|
|
|
/** @var \WMDE\Fundraising\Frontend\PaymentContext\Domain\Model\PayPalPayment $payment */ |
308
|
|
|
$payment = $donation->getPaymentMethod(); |
309
|
|
|
$childDonationId = $payment->getPayPalData()->getChildPaymentEntityId( $transactionId ); |
310
|
|
|
|
311
|
|
|
$this->assertEventLogContainsExpression( $eventLogger, $donation->getId(), '/child donation.*' . $childDonationId .'/' ); |
312
|
|
|
$this->assertEventLogContainsExpression( $eventLogger, $childDonationId, '/parent donation.*' . $donation->getId() .'/' ); |
313
|
|
|
} |
314
|
|
|
|
315
|
|
|
public function testGivenExistingTransactionIdForBookedDonation_handlerReturnsFalse() { |
316
|
|
|
$fakeRepository = new FakeDonationRepository(); |
317
|
|
|
$fakeRepository->storeDonation( ValidDonation::newBookedPayPalDonation() ); |
318
|
|
|
|
319
|
|
|
$request = ValidPayPalNotificationRequest::newInstantPayment( 1 ); |
320
|
|
|
|
321
|
|
|
$useCase = new HandlePayPalPaymentNotificationUseCase( |
322
|
|
|
$fakeRepository, |
323
|
|
|
new SucceedingDonationAuthorizer(), |
324
|
|
|
$this->getMailer(), |
|
|
|
|
325
|
|
|
$this->getEventLogger() |
|
|
|
|
326
|
|
|
); |
327
|
|
|
|
328
|
|
|
$this->assertFalse( $useCase->handleNotification( $request )->notificationWasHandled() ); |
329
|
|
|
} |
330
|
|
|
|
331
|
|
|
public function testGivenTransactionIdInBookedChildDonation_noNewDonationIsCreated() { |
332
|
|
|
$transactionId = '16R12136PU8783961'; |
333
|
|
|
$fakeChildEntityId = 2; |
334
|
|
|
$donation = ValidDonation::newBookedPayPalDonation(); |
335
|
|
|
$donation->getPaymentMethod()->getPaypalData()->addChildPayment( $transactionId, $fakeChildEntityId ); |
|
|
|
|
336
|
|
|
|
337
|
|
|
$fakeRepository = new FakeDonationRepository(); |
338
|
|
|
$fakeRepository->storeDonation( $donation ); |
339
|
|
|
|
340
|
|
|
$request = ValidPayPalNotificationRequest::newDuplicatePayment( $donation->getId(), $transactionId ); |
341
|
|
|
|
342
|
|
|
$useCase = new HandlePayPalPaymentNotificationUseCase( |
343
|
|
|
$fakeRepository, |
344
|
|
|
new SucceedingDonationAuthorizer(), |
345
|
|
|
$this->getMailer(), |
|
|
|
|
346
|
|
|
$this->getEventLogger() |
|
|
|
|
347
|
|
|
); |
348
|
|
|
|
349
|
|
|
$this->assertFalse( $useCase->handleNotification( $request )->notificationWasHandled() ); |
350
|
|
|
} |
351
|
|
|
|
352
|
|
|
public function testWhenNotificationIsForNonExistingDonation_newDonationIsCreated() { |
353
|
|
|
$repositorySpy = new DonationRepositorySpy(); |
354
|
|
|
|
355
|
|
|
$request = ValidPayPalNotificationRequest::newInstantPayment( 12345 ); |
356
|
|
|
$useCase = new HandlePayPalPaymentNotificationUseCase( |
357
|
|
|
$repositorySpy, |
358
|
|
|
new SucceedingDonationAuthorizer(), |
359
|
|
|
$this->getMailer(), |
|
|
|
|
360
|
|
|
$this->getEventLogger() |
|
|
|
|
361
|
|
|
); |
362
|
|
|
|
363
|
|
|
$useCase->handleNotification( $request ); |
364
|
|
|
|
365
|
|
|
$storeDonationCalls = $repositorySpy->getStoreDonationCalls(); |
366
|
|
|
$this->assertCount( 1, $storeDonationCalls, 'Donation is stored' ); |
367
|
|
|
$this->assertNull( $storeDonationCalls[0]->getId(), 'ID is not taken from request' ); |
368
|
|
|
$this->assertDonationIsCreatedWithNotficationRequestData( $storeDonationCalls[0] ); |
369
|
|
|
} |
370
|
|
|
|
371
|
|
|
public function testGivenRecurringPaymentForIncompleteDonation_donationIsBooked() { |
372
|
|
|
$donation = ValidDonation::newIncompletePayPalDonation(); |
373
|
|
|
$repositorySpy = new DonationRepositorySpy( $donation ); |
374
|
|
|
|
375
|
|
|
$request = ValidPayPalNotificationRequest::newRecurringPayment( $donation->getId() ); |
376
|
|
|
|
377
|
|
|
$useCase = new HandlePayPalPaymentNotificationUseCase( |
378
|
|
|
$repositorySpy, |
379
|
|
|
new SucceedingDonationAuthorizer(), |
380
|
|
|
$this->getMailer(), |
|
|
|
|
381
|
|
|
$this->getEventLogger() |
|
|
|
|
382
|
|
|
); |
383
|
|
|
|
384
|
|
|
$useCase->handleNotification( $request ); |
385
|
|
|
$donation = $repositorySpy->getDonationById( $donation->getId() ); |
386
|
|
|
|
387
|
|
|
$this->assertCount( 1, $repositorySpy->getStoreDonationCalls() ); |
388
|
|
|
$this->assertEquals( $donation, $repositorySpy->getStoreDonationCalls()[0] ); |
389
|
|
|
$this->assertTrue( $donation->isBooked() ); |
390
|
|
|
} |
391
|
|
|
|
392
|
|
|
public function testWhenNotificationIsForNonExistingDonation_confirmationMailIsSent() { |
393
|
|
|
$request = ValidPayPalNotificationRequest::newInstantPayment( 12345 ); |
394
|
|
|
$mailer = $this->getMailer(); |
395
|
|
|
$mailer->expects( $this->once() ) |
|
|
|
|
396
|
|
|
->method( 'sendConfirmationMailFor' ) |
397
|
|
|
->with( $this->anything() ); |
398
|
|
|
$useCase = new HandlePayPalPaymentNotificationUseCase( |
399
|
|
|
new FakeDonationRepository(), |
400
|
|
|
new SucceedingDonationAuthorizer(), |
401
|
|
|
$mailer, |
|
|
|
|
402
|
|
|
$this->getEventLogger() |
|
|
|
|
403
|
|
|
); |
404
|
|
|
|
405
|
|
|
$useCase->handleNotification( $request ); |
406
|
|
|
} |
407
|
|
|
|
408
|
|
|
public function testWhenNotificationIsForNonExistingDonation_bookingEventIsLogged() { |
409
|
|
|
$request = ValidPayPalNotificationRequest::newInstantPayment( 12345 ); |
410
|
|
|
$eventLogger = new DonationEventLoggerSpy(); |
411
|
|
|
|
412
|
|
|
$useCase = new HandlePayPalPaymentNotificationUseCase( |
413
|
|
|
new FakeDonationRepository(), |
414
|
|
|
new SucceedingDonationAuthorizer(), |
415
|
|
|
$this->getMailer(), |
|
|
|
|
416
|
|
|
$eventLogger |
417
|
|
|
); |
418
|
|
|
|
419
|
|
|
$useCase->handleNotification( $request ); |
420
|
|
|
|
421
|
|
|
$this->assertEventLogContainsExpression( $eventLogger, 1, '/booked/' ); // 1 is the generated donation id |
422
|
|
|
} |
423
|
|
|
|
424
|
|
|
private function assertDonationIsCreatedWithNotficationRequestData( Donation $donation ) { |
425
|
|
|
$this->assertSame( 0, $donation->getPaymentIntervalInMonths(), 'Payment interval is always empty' ); |
426
|
|
|
$this->assertTrue( $donation->isBooked() ); |
427
|
|
|
|
428
|
|
|
$donorName = $donation->getDonor()->getName(); |
429
|
|
|
$this->assertSame( DonorName::PERSON_PRIVATE, $donorName->getPersonType(), 'Person is always private' ); |
430
|
|
|
$this->assertSame( ValidPayPalNotificationRequest::PAYER_ADDRESS_NAME, $donorName->getFullName() ); |
431
|
|
|
|
432
|
|
|
$this->assertSame( ValidPayPalNotificationRequest::PAYER_EMAIL, $donation->getDonor()->getEmailAddress() ); |
433
|
|
|
|
434
|
|
|
$address = $donation->getDonor()->getPhysicalAddress(); |
435
|
|
|
$this->assertSame( ValidPayPalNotificationRequest::PAYER_ADDRESS_STREET, $address->getStreetAddress() ); |
436
|
|
|
$this->assertSame( ValidPayPalNotificationRequest::PAYER_ADDRESS_CITY, $address->getCity() ); |
437
|
|
|
$this->assertSame( ValidPayPalNotificationRequest::PAYER_ADDRESS_POSTAL_CODE, $address->getPostalCode() ); |
438
|
|
|
$this->assertSame( ValidPayPalNotificationRequest::PAYER_ADDRESS_COUNTRY_CODE, $address->getCountryCode() ); |
439
|
|
|
|
440
|
|
|
$payment = $donation->getPayment(); |
441
|
|
|
$this->assertSame( ValidPayPalNotificationRequest::AMOUNT_GROSS_CENTS, $payment->getAmount()->getEuroCents() ); |
442
|
|
|
|
443
|
|
|
/** @var PayPalData $paypalData */ |
444
|
|
|
$paypalData = $payment->getPaymentMethod()->getPaypalData(); |
|
|
|
|
445
|
|
|
$this->assertSame( ValidPayPalNotificationRequest::PAYER_ADDRESS_NAME, $paypalData->getAddressName() ); |
446
|
|
|
} |
447
|
|
|
|
448
|
|
|
private function assertEventLogContainsExpression( DonationEventLoggerSpy $eventLoggerSpy, int $donationId, string $expr ) { |
449
|
|
|
$foundCalls = array_filter( $eventLoggerSpy->getLogCalls(), function( $call ) use ( $donationId, $expr ) { |
450
|
|
|
return $call[0] == $donationId && preg_match( $expr, $call[1] ); |
451
|
|
|
} ); |
452
|
|
|
$assertMsg = 'Failed to assert that donation event log log contained "' . $expr . '" for donation id '.$donationId; |
453
|
|
|
$this->assertCount( 1, $foundCalls, $assertMsg ); |
454
|
|
|
} |
455
|
|
|
|
456
|
|
|
/** |
457
|
|
|
* @return DonationConfirmationMailer|\PHPUnit_Framework_MockObject_MockObject |
458
|
|
|
*/ |
459
|
|
|
private function getMailer(): DonationConfirmationMailer { |
460
|
|
|
return $this->getMockBuilder( DonationConfirmationMailer::class )->disableOriginalConstructor()->getMock(); |
461
|
|
|
} |
462
|
|
|
|
463
|
|
|
/** |
464
|
|
|
* @return DonationEventLogger|\PHPUnit_Framework_MockObject_MockObject |
465
|
|
|
*/ |
466
|
|
|
private function getEventLogger(): DonationEventLogger { |
467
|
|
|
return $this->createMock( DonationEventLogger::class ); |
468
|
|
|
} |
469
|
|
|
|
470
|
|
|
} |
471
|
|
|
|
This check looks at variables that are passed out again to other methods.
If the outgoing method call has stricter type requirements than the method itself, an issue is raised.
An additional type check may prevent trouble.