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