Completed
Pull Request — master (#649)
by Jeroen De
50:49
created

newSucceedingBankDataValidator()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 9
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

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