Completed
Push — master ( e6c518...18cdbd )
by Jeroen De
12s
created

testWhenDateOfBirthIsNotDate_validationFails()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 9
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 9
rs 9.6666
c 0
b 0
f 0
cc 1
eloc 6
nc 1
nop 0
1
<?php
2
3
declare( strict_types = 1 );
4
5
namespace WMDE\Fundraising\Frontend\MembershipContext\Tests\Unit\UseCases\ApplyForMembership;
6
7
use WMDE\Fundraising\Frontend\MembershipContext\Tests\Data\ValidMembershipApplication;
8
use WMDE\Fundraising\Frontend\MembershipContext\Tests\Data\ValidMembershipApplicationRequest;
9
use WMDE\Fundraising\Frontend\MembershipContext\UseCases\ApplyForMembership\ApplicationValidationResult as Result;
10
use WMDE\Fundraising\Frontend\MembershipContext\UseCases\ApplyForMembership\ApplyForMembershipRequest;
11
use WMDE\Fundraising\Frontend\MembershipContext\UseCases\ApplyForMembership\MembershipApplicationValidator;
12
use WMDE\Fundraising\Frontend\PaymentContext\Domain\Model\BankData;
13
use WMDE\Fundraising\Frontend\PaymentContext\Domain\Model\Iban;
14
use WMDE\Fundraising\Frontend\Tests\Fixtures\SucceedingEmailValidator;
15
use WMDE\Fundraising\Frontend\Validation\BankDataValidator;
16
use WMDE\Fundraising\Frontend\Validation\ConstraintViolation;
17
use WMDE\Fundraising\Frontend\Validation\EmailValidator;
18
use WMDE\Fundraising\Frontend\Validation\IbanValidator;
19
use WMDE\Fundraising\Frontend\Validation\MembershipFeeValidator;
20
use WMDE\Fundraising\Frontend\Validation\ValidationResult;
21
22
/**
23
 * @covers WMDE\Fundraising\Frontend\Validation\MembershipFeeValidator
24
 *
25
 * @license GNU GPL v2+
26
 * @author Kai Nissen < [email protected] >
27
 * @author Jeroen De Dauw < [email protected] >
28
 */
29
class MembershipApplicationValidatorTest extends \PHPUnit_Framework_TestCase {
30
31
	/*
32
	 * @var MembershipFeeValidator
33
	 */
34
	private $feeValidator;
35
36
	/**
37
	 * @var BankDataValidator
38
	 */
39
	private $bankDataValidator;
40
41
	/**
42
	 * @var EmailValidator
43
	 */
44
	private $emailValidator;
45
46
	public function setUp() {
47
		$this->feeValidator = $this->newSucceedingFeeValidator();
48
		$this->bankDataValidator = $this->newSucceedingBankDataValidator();
49
		$this->emailValidator = new SucceedingEmailValidator();
50
	}
51
52
	public function testGivenValidRequest_validationSucceeds() {
53
		$validRequest = $this->newValidRequest();
54
		$response = $this->newValidator()->validate( $validRequest );
55
56
		$this->assertEquals( new Result(), $response );
57
		$this->assertEmpty( $response->getViolationSources() );
58
		$this->assertTrue( $response->isSuccessful() );
59
	}
60
61
	private function newValidator() {
62
		return new MembershipApplicationValidator(
63
			$this->feeValidator,
64
			$this->bankDataValidator,
65
			$this->emailValidator
66
		);
67
	}
68
69
	public function testWhenFeeValidationFails_overallValidationAlsoFails() {
70
		$this->feeValidator = $this->newFailingFeeValidator();
71
72
		$response = $this->newValidator()->validate( $this->newValidRequest() );
73
74
		$this->assertEquals( $this->newFeeViolationResult(), $response );
75
	}
76
77
	private function newFailingFeeValidator(): MembershipFeeValidator {
78
		$feeValidator = $this->getMockBuilder( MembershipFeeValidator::class )
79
			->disableOriginalConstructor()->getMock();
80
81
		$feeValidator->method( 'validate' )
82
			->willReturn( $this->newFeeViolationResult() );
83
84
		return $feeValidator;
85
	}
86
87
	private function newSucceedingFeeValidator(): MembershipFeeValidator {
88
		$feeValidator = $this->getMockBuilder( MembershipFeeValidator::class )
89
			->disableOriginalConstructor()->getMock();
90
91
		$feeValidator->method( 'validate' )
92
			->willReturn( new Result() );
93
94
		return $feeValidator;
95
	}
96
97
	private function newValidRequest(): ApplyForMembershipRequest {
98
		return ValidMembershipApplicationRequest::newValidRequest();
99
	}
100
101
	private function newFeeViolationResult() {
102
		return new Result( [
103
			Result::SOURCE_PAYMENT_AMOUNT => Result::VIOLATION_NOT_MONEY
104
		] );
105
	}
106
107
	private function newSucceedingBankDataValidator(): BankDataValidator {
108
		$feeValidator = $this->getMockBuilder( BankDataValidator::class )
109
			->disableOriginalConstructor()->getMock();
110
111
		$feeValidator->method( 'validate' )
112
			->willReturn( new ValidationResult() );
113
114
		return $feeValidator;
115
	}
116
117
	public function testWhenIbanIsMissing_validationFails() {
118
		$this->bankDataValidator = $this->newRealBankDataValidator();
119
120
		$request = $this->newValidRequest();
121
		$request->getBankData()->setIban( new Iban( '' ) );
122
123
		$this->assertRequestValidationResultInErrors(
124
			$request,
125
			[ Result::SOURCE_IBAN => Result::VIOLATION_MISSING ]
126
		);
127
	}
128
129
	private function assertRequestValidationResultInErrors( ApplyForMembershipRequest $request, array $expectedErrors ) {
130
		$this->assertEquals(
131
			new Result( $expectedErrors ),
132
			$this->newValidator()->validate( $request )
133
		);
134
	}
135
136
	private function newRealBankDataValidator(): BankDataValidator {
137
		return new BankDataValidator( $this->newSucceedingIbanValidator() );
138
	}
139
140
	private function newSucceedingIbanValidator(): IbanValidator {
141
		$ibanValidator = $this->getMockBuilder( IbanValidator::class )
142
			->disableOriginalConstructor()->getMock();
143
144
		$ibanValidator->method( 'validate' )
145
			->willReturn( new ValidationResult() );
146
147
		return $ibanValidator;
148
	}
149
150
	public function testWhenBicIsMissing_validationFails() {
151
		$this->bankDataValidator = $this->newRealBankDataValidator();
152
153
		$request = $this->newValidRequest();
154
		$request->getBankData()->setBic( '' );
155
156
		$this->assertRequestValidationResultInErrors(
157
			$request,
158
			[ Result::SOURCE_BIC => Result::VIOLATION_MISSING ]
159
		);
160
	}
161
162
	public function testWhenBankNameIsMissing_validationSucceeds() {
163
		$this->bankDataValidator = $this->newRealBankDataValidator();
164
165
		$request = $this->newValidRequest();
166
		$request->getBankData()->setBankName( '' );
167
		$response = $this->newValidator()->validate( $request );
168
169
		$this->assertEquals( new Result(), $response );
170
		$this->assertEmpty( $response->getViolationSources() );
171
		$this->assertTrue( $response->isSuccessful() );
172
	}
173
174
	public function testWhenBankCodeIsMissing_validationFails() {
175
		$this->bankDataValidator = $this->newRealBankDataValidator();
176
177
		$request = $this->newValidRequest();
178
		$request->getBankData()->setBankCode( '' );
179
180
		$this->assertRequestValidationResultInErrors(
181
			$request,
182
			[ Result::SOURCE_BANK_CODE => Result::VIOLATION_MISSING ]
183
		);
184
	}
185
186
	public function testWhenBankAccountIsMissing_validationFails() {
187
		$this->bankDataValidator = $this->newRealBankDataValidator();
188
189
		$request = $this->newValidRequest();
190
		$request->getBankData()->setAccount( '' );
191
192
		$this->assertRequestValidationResultInErrors(
193
			$request,
194
			[ Result::SOURCE_BANK_ACCOUNT => Result::VIOLATION_MISSING ]
195
		);
196
	}
197
198
	public function testWhenTooLongBankAccount_validationFails() {
199
		$this->bankDataValidator = $this->newRealBankDataValidator();
200
201
		$request = $this->newValidRequest();
202
		$request->getBankData()->setAccount( '01189998819991197253' );
203
204
		$this->assertRequestValidationResultInErrors(
205
			$request,
206
			[ Result::SOURCE_BANK_ACCOUNT => Result::VIOLATION_WRONG_LENGTH ]
207
		);
208
	}
209
210
	public function testWhenTooLongBankCode_validationFails() {
211
		$this->bankDataValidator = $this->newRealBankDataValidator();
212
213
		$request = $this->newValidRequest();
214
		$request->getBankData()->setBankCode( '01189998819991197253' );
215
216
		$this->assertRequestValidationResultInErrors(
217
			$request,
218
			[ Result::SOURCE_BANK_CODE => Result::VIOLATION_WRONG_LENGTH ]
219
		);
220
	}
221
222
	public function testWhenDateOfBirthIsNotDate_validationFails() {
223
		$request = $this->newValidRequest();
224
		$request->setApplicantDateOfBirth( 'this is not a valid date' );
225
226
		$this->assertRequestValidationResultInErrors(
227
			$request,
228
			[ Result::SOURCE_APPLICANT_DATE_OF_BIRTH => Result::VIOLATION_NOT_DATE ]
229
		);
230
	}
231
232
	/**
233
	 * @dataProvider invalidPhoneNumberProvider
234
	 */
235
	public function testWhenApplicantPhoneNumberIsInvalid_validationFails( string $invalidPhoneNumber ) {
236
		$request = $this->newValidRequest();
237
		$request->setApplicantPhoneNumber( $invalidPhoneNumber );
238
239
		$this->assertRequestValidationResultInErrors(
240
			$request,
241
			[ Result::SOURCE_APPLICANT_PHONE_NUMBER => Result::VIOLATION_NOT_PHONE_NUMBER ]
242
		);
243
	}
244
245
	public function invalidPhoneNumberProvider() {
246
		return [
247
			'potato' => [ 'potato' ],
248
249
			// TODO: we use the regex from the old app, which allows for lots of bugus. Improve when time
250
//			'number plus stuff' => [ '01189998819991197253 (invalid edition)' ],
251
		];
252
	}
253
254
	/**
255
	 * @dataProvider emailViolationTypeProvider
256
	 */
257
	public function testWhenApplicantEmailIsInvalid_validationFails( string $emailViolationType ) {
258
		$this->emailValidator = $this->newFailingEmailValidator( $emailViolationType );
259
260
		$request = $this->newValidRequest();
261
		$request->setApplicantEmailAddress( 'this is not a valid email' );
262
263
		$this->assertRequestValidationResultInErrors(
264
			$request,
265
			[ Result::SOURCE_APPLICANT_EMAIL => Result::VIOLATION_NOT_EMAIL ]
266
		);
267
	}
268
269
	public function emailViolationTypeProvider() {
270
		return [
271
			[ 'email_address_wrong_format' ],
272
			[ 'email_address_invalid' ],
273
			[ 'email_address_domain_record_not_found' ],
274
		];
275
	}
276
277
	/**
278
	 * @param string $violationType
279
	 *
280
	 * @return EmailValidator
281
	 */
282
	private function newFailingEmailValidator( string $violationType ): EmailValidator {
283
		$feeValidator = $this->getMockBuilder( EmailValidator::class )
284
			->disableOriginalConstructor()->getMock();
285
286
		$feeValidator->method( 'validate' )
287
			->willReturn( new ValidationResult( new ConstraintViolation( 'this is not a valid email', $violationType ) ) );
288
289
		return $feeValidator;
290
	}
291
292
	public function testWhenCompanyIsMissingFromCompanyApplication_validationFails() {
293
		$request = $this->newValidRequest();
294
		$request->markApplicantAsCompany();
295
		$request->setApplicantCompanyName( '' );
296
297
		$this->assertRequestValidationResultInErrors(
298
			$request,
299
			[ Result::SOURCE_APPLICANT_COMPANY => Result::VIOLATION_MISSING ]
300
		);
301
	}
302
303
	public function testWhenFirstNameIsMissingFromPersonalApplication_validationFails() {
304
		$request = $this->newValidRequest();
305
		$request->setApplicantFirstName( '' );
306
307
		$this->assertRequestValidationResultInErrors(
308
			$request,
309
			[ Result::SOURCE_APPLICANT_FIRST_NAME => Result::VIOLATION_MISSING ]
310
		);
311
	}
312
313
	public function testWhenLastNameIsMissingFromPersonalApplication_validationFails() {
314
		$request = $this->newValidRequest();
315
		$request->setApplicantLastName( '' );
316
317
		$this->assertRequestValidationResultInErrors(
318
			$request,
319
			[ Result::SOURCE_APPLICANT_LAST_NAME => Result::VIOLATION_MISSING ]
320
		);
321
	}
322
323
	public function testWhenSalutationIsMissingFromPersonalApplication_validationFails() {
324
		$request = $this->newValidRequest();
325
		$request->setApplicantSalutation( '' );
326
327
		$this->assertRequestValidationResultInErrors(
328
			$request,
329
			[ Result::SOURCE_APPLICANT_SALUTATION => Result::VIOLATION_MISSING ]
330
		);
331
	}
332
333
	public function testWhenStreetAddressIsMissing_validationFails() {
334
		$request = $this->newValidRequest();
335
		$request->setApplicantStreetAddress( '' );
336
337
		$this->assertRequestValidationResultInErrors(
338
			$request,
339
			[ Result::SOURCE_APPLICANT_STREET_ADDRESS => Result::VIOLATION_MISSING ]
340
		);
341
	}
342
343
	public function testWhenPostalCodeIsMissing_validationFails() {
344
		$request = $this->newValidRequest();
345
		$request->setApplicantPostalCode( '' );
346
347
		$this->assertRequestValidationResultInErrors(
348
			$request,
349
			[ Result::SOURCE_APPLICANT_POSTAL_CODE => Result::VIOLATION_MISSING ]
350
		);
351
	}
352
353
	public function testWhenCityIsMissing_validationFails() {
354
		$request = $this->newValidRequest();
355
		$request->setApplicantCity( '' );
356
357
		$this->assertRequestValidationResultInErrors(
358
			$request,
359
			[ Result::SOURCE_APPLICANT_CITY => Result::VIOLATION_MISSING ]
360
		);
361
	}
362
363
	public function testWhenCountryCodeIsMissing_validationFails() {
364
		$request = $this->newValidRequest();
365
		$request->setApplicantCountryCode( '' );
366
367
		$this->assertRequestValidationResultInErrors(
368
			$request,
369
			[ Result::SOURCE_APPLICANT_COUNTRY => Result::VIOLATION_MISSING ]
370
		);
371
	}
372
373
	public function testPhoneNumberIsNotProvided_validationDoesNotFail() {
374
		$request = $this->newValidRequest();
375
		$request->setApplicantPhoneNumber( '' );
376
377
		$this->assertTrue( $this->newValidator()->validate( $request )->isSuccessful() );
378
	}
379
380
	public function testDateOfBirthIsNotProvided_validationDoesNotFail() {
381
		$request = $this->newValidRequest();
382
		$request->setApplicantDateOfBirth( '' );
383
384
		$this->assertTrue( $this->newValidator()->validate( $request )->isSuccessful() );
385
	}
386
387
	public function testPersonalInfoWithLongFields_validationFails() {
388
		$longText = str_repeat( 'Cats ', 500 );
389
		$request = $this->newValidRequest();
390
		$request->setApplicantFirstName( $longText );
391
		$request->setApplicantLastName( $longText );
392
		$request->setApplicantTitle( $longText );
393
		$request->setApplicantSalutation( $longText );
394
		$request->setApplicantStreetAddress( $longText );
395
		$request->setApplicantPostalCode( $longText );
396
		$request->setApplicantCity( $longText );
397
		$request->setApplicantCountryCode( $longText );
398
		$this->assertRequestValidationResultInErrors(
399
			$request,
400
			[
401
				Result::SOURCE_APPLICANT_FIRST_NAME => Result::VIOLATION_WRONG_LENGTH,
402
				Result::SOURCE_APPLICANT_LAST_NAME => Result::VIOLATION_WRONG_LENGTH,
403
				Result::SOURCE_APPLICANT_SALUTATION => Result::VIOLATION_WRONG_LENGTH,
404
				Result::SOURCE_APPLICANT_STREET_ADDRESS => Result::VIOLATION_WRONG_LENGTH,
405
				Result::SOURCE_APPLICANT_POSTAL_CODE => Result::VIOLATION_WRONG_LENGTH,
406
				Result::SOURCE_APPLICANT_CITY => Result::VIOLATION_WRONG_LENGTH,
407
				Result::SOURCE_APPLICANT_COUNTRY => Result::VIOLATION_WRONG_LENGTH
408
			]
409
		);
410
	}
411
412
	public function testContactInfoWithLongFields_validationFails() {
413
		$request = $this->newValidRequest();
414
		$request->setApplicantEmailAddress( str_repeat( 'Cats', 500 ) . '@example.com' );
415
		$request->setApplicantPhoneNumber( str_repeat( '1234', 500 ) );
416
417
		$this->assertRequestValidationResultInErrors(
418
			$request,
419
			[
420
				Result::SOURCE_APPLICANT_EMAIL => Result::VIOLATION_WRONG_LENGTH,
421
				Result::SOURCE_APPLICANT_PHONE_NUMBER => Result::VIOLATION_WRONG_LENGTH
422
			]
423
		);
424
	}
425
426
	public function testBankDataWithLongFields_validationFails() {
427
		$longText = str_repeat( 'Cats ', 500 );
428
		$request = $this->newValidRequest();
429
		$bankData = $request->getBankData();
430
		$bankData->setBic( $longText );
431
		$bankData->setBankName( $longText );
432
		// Other length violations will be caught by IBAN validation
433
434
		$this->assertRequestValidationResultInErrors(
435
			$request,
436
			[
437
				Result::SOURCE_BANK_NAME => Result::VIOLATION_WRONG_LENGTH,
438
				Result::SOURCE_BIC => Result::VIOLATION_WRONG_LENGTH
439
			]
440
		);
441
	}
442
443
	public function testGivenValidRequestUsingPayPal_validationSucceeds() {
444
		$validRequest = $this->newValidRequestUsingPayPal();
445
		$response = $this->newValidator()->validate( $validRequest );
446
447
		$this->assertEquals( new Result(), $response );
448
		$this->assertEmpty( $response->getViolationSources() );
449
		$this->assertTrue( $response->isSuccessful() );
450
	}
451
452
	private function newValidRequestUsingPayPal(): ApplyForMembershipRequest {
453
		$request = ValidMembershipApplicationRequest::newValidRequest();
454
		$request->setPaymentType( ValidMembershipApplication::PAYMENT_TYPE_PAYPAL );
455
		$request->setBankData( new BankData() );
456
		return $request;
457
	}
458
459
}
460