Completed
Push — master ( 324cad...e6dbd1 )
by Gabriel
107:45 queued 42:39
created

getMockDuplicateValidator()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 7
c 0
b 0
f 0
rs 9.4285
cc 1
eloc 5
nc 1
nop 0
1
<?php
2
3
declare( strict_types = 1 );
4
5
namespace WMDE\Fundraising\Frontend\Tests\Integration\Validation;
6
7
use WMDE\Fundraising\Entities\Address;
8
use WMDE\Fundraising\Entities\Subscription;
9
use WMDE\Fundraising\Frontend\Infrastructure\NullDomainNameValidator;
10
use WMDE\Fundraising\Frontend\SubscriptionContext\Validation\SubscriptionDuplicateValidator;
11
use WMDE\Fundraising\Frontend\SubscriptionContext\Validation\SubscriptionValidator;
12
use WMDE\Fundraising\Frontend\SubscriptionContext\Tests\Fixtures\InMemorySubscriptionRepository;
13
use WMDE\FunValidators\ConstraintViolation;
14
use WMDE\FunValidators\ValidationResult;
15
use WMDE\FunValidators\Validators\AllowedValuesValidator;
16
use WMDE\FunValidators\Validators\EmailValidator;
17
use WMDE\FunValidators\Validators\TextPolicyValidator;
18
19
/**
20
 * @covers \WMDE\Fundraising\Frontend\SubscriptionContext\Validation\SubscriptionValidator
21
 *
22
 * @license GNU GPL v2+
23
 * @author Gabriel Birke < [email protected] >
24
 */
25
class SubscriptionValidatorTest extends \PHPUnit\Framework\TestCase {
26
27
	private function getMockTextPolicyValidator(): TextPolicyValidator {
28
		$mock = $this->createMock( TextPolicyValidator::class );
29
		$mock->method( 'hasHarmlessContent' )
30
			->willReturn( true );
31
		return $mock;
32
	}
33
34
	private function getMockDuplicateValidator(): SubscriptionDuplicateValidator {
35
		$mock = $this->getMockBuilder( SubscriptionDuplicateValidator::class )
36
			->disableOriginalConstructor()->getMock();
37
38
		$mock->method( 'validate' )->willReturn( new ValidationResult() );
39
		return $mock;
40
	}
41
42
	private function createAddress( string $saluation, string $firstName, string $lastName ): Address {
43
		$address = new Address();
44
		$address->setSalutation( $saluation );
45
		$address->setFirstName( $firstName );
46
		$address->setLastName( $lastName );
47
		$address->setTitle( '' );
48
		$address->setCompany( '' );
49
		$address->setAddress( '' );
50
		$address->setCity( '' );
51
		$address->setPostcode( '' );
52
		return $address;
53
	}
54
55
	public function testEmailIsValidated(): void {
56
		$mailValidator = new EmailValidator( new NullDomainNameValidator() );
57
		$subscriptionValidator = new SubscriptionValidator(
58
			$mailValidator,
59
			$this->getMockTextPolicyValidator(),
60
			$this->getMockDuplicateValidator(),
61
			new AllowedValuesValidator( [''] )
62
		);
63
		$subscription = new Subscription();
64
		$subscription->setAddress( $this->createAddress( 'Herr', 'Nyan', 'Cat' ) );
65
		$subscription->setEmail( 'this is not a mail addess' );
66
		$this->assertConstraintWasViolated( $subscriptionValidator->validate( $subscription ), 'email' );
67
	}
68
69
	private function assertConstraintWasViolated( ValidationResult $result, string $fieldName ): void {
70
		$this->assertContainsOnlyInstancesOf( ConstraintViolation::class, $result->getViolations() );
71
		$this->assertTrue( $result->hasViolations() );
72
73
		$violated = false;
74
		foreach ( $result->getViolations() as $violation ) {
75
			if ( $violation->getSource() === $fieldName ) {
76
				$violated = true;
77
			}
78
		}
79
80
		$this->assertTrue(
81
			$violated,
82
			'Failed asserting that constraint for field "' . $fieldName . '"" was violated.'
83
		);
84
	}
85
86
	public function testGivenBadWords_subscriptionIsStillValid(): void {
87
		$mailValidator = new EmailValidator( new NullDomainNameValidator() );
88
		$policyValidator = $this->createMock( TextPolicyValidator::class );
89
		$policyValidator->method( 'hasHarmlessContent' )
90
			->willReturn( false );
91
		$subscriptionValidator = new SubscriptionValidator(
92
			$mailValidator,
93
			$policyValidator,
94
			$this->getMockDuplicateValidator(),
95
			new AllowedValuesValidator( [''] )
96
		);
97
		$subscription = new Subscription();
98
		$subscription->setAddress( $this->createAddress( 'Herr', 'Nyan', 'Cat' ) );
99
		$subscription->setEmail( '[email protected]' );
100
		$this->assertTrue( $subscriptionValidator->validate( $subscription )->isSuccessful() );
101
	}
102
103
	public function testGivenBadWords_needsModerationIsTrue(): void {
104
		$mailValidator = new EmailValidator( new NullDomainNameValidator() );
105
		$policyValidator = $this->createMock( TextPolicyValidator::class );
106
		$policyValidator->method( 'hasHarmlessContent' )
107
			->willReturn( false );
108
		$subscriptionValidator = new SubscriptionValidator(
109
			$mailValidator,
110
			$policyValidator,
111
			$this->getMockDuplicateValidator(),
112
			new AllowedValuesValidator( [''] )
113
		);
114
		$subscription = new Subscription();
115
		$subscription->setAddress( $this->createAddress( 'Herr', 'Nyan', 'Cat' ) );
116
		$subscription->setEmail( '[email protected]' );
117
		$this->assertTrue( $subscriptionValidator->needsModeration( $subscription ) );
118
	}
119
120
	public function testDuplicateSubscriptionIsValidated(): void {
121
		$subscription = new Subscription();
122
		$subscription->setAddress( $this->createAddress( 'Herr', 'Nyan', 'Cat' ) );
123
		$subscription->setEmail( '[email protected]' );
124
		$subscription->setCreatedAt( new \DateTime( '5 minutes ago' ) );
125
126
		$mailValidator = new EmailValidator( new NullDomainNameValidator() );
127
		$repository = new InMemorySubscriptionRepository();
128
		$repository->storeSubscription( $subscription );
129
		$duplicateValidator = new SubscriptionDuplicateValidator( $repository, new \DateTime( '30 minutes ago' ) );
130
		$subscriptionValidator = new SubscriptionValidator(
131
			$mailValidator,
132
			$this->getMockTextPolicyValidator(),
133
			$duplicateValidator,
134
			new AllowedValuesValidator( [''] )
135
		);
136
		$this->assertConstraintWasViolated(
137
			$subscriptionValidator->validate( $subscription ),
138
			SubscriptionDuplicateValidator::SOURCE_NAME
139
		);
140
	}
141
142
	public function testHonorificIsValidated(): void {
143
		$subscription = new Subscription();
144
		$address = $this->createAddress( 'Herr', 'Nyan', 'Cat' );
145
		$address->setTitle( 'Overlord' );
146
		$subscription->setAddress( $address );
147
		$subscription->setEmail( '[email protected]' );
148
149
		$mailValidator = new EmailValidator( new NullDomainNameValidator() );
150
		$subscriptionValidator = new SubscriptionValidator(
151
			$mailValidator,
152
			$this->getMockTextPolicyValidator(),
153
			$this->getMockDuplicateValidator(),
154
			new AllowedValuesValidator( ['', 'Dr.', 'Prof.'] )
155
		);
156
		$this->assertConstraintWasViolated( $subscriptionValidator->validate( $subscription ), 'title' );
157
	}
158
}
159