Completed
Pull Request — master (#650)
by Jeroen De
19:07 queued 01:42
created

testGivenValidRequest_moderationIsNotNeeded()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 5
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 3
nc 1
nop 0
1
<?php
2
3
declare( strict_types = 1 );
4
5
namespace WMDE\Fundraising\Frontend\Tests\Integration\MembershipContext\UseCases\ApplyForMembership;
6
7
use WMDE\Fundraising\Frontend\Infrastructure\TokenGenerator;
8
use WMDE\Fundraising\Frontend\MembershipContext\Authorization\ApplicationTokenFetcher;
9
use WMDE\Fundraising\Frontend\MembershipContext\Authorization\MembershipApplicationTokens;
10
use WMDE\Fundraising\Frontend\MembershipContext\Domain\Model\EmailAddress;
11
use WMDE\Fundraising\Frontend\MembershipContext\Domain\Repositories\ApplicationRepository;
12
use WMDE\Fundraising\Frontend\MembershipContext\Tracking\ApplicationPiwikTracker;
13
use WMDE\Fundraising\Frontend\MembershipContext\Tracking\ApplicationTracker;
14
use WMDE\Fundraising\Frontend\MembershipContext\Tracking\MembershipApplicationTrackingInfo;
15
use WMDE\Fundraising\Frontend\MembershipContext\UseCases\ApplyForMembership\ApplicationValidationResult;
16
use WMDE\Fundraising\Frontend\MembershipContext\UseCases\ApplyForMembership\ApplyForMembershipRequest;
17
use WMDE\Fundraising\Frontend\MembershipContext\UseCases\ApplyForMembership\ApplyForMembershipUseCase;
18
use WMDE\Fundraising\Frontend\MembershipContext\UseCases\ApplyForMembership\MembershipApplicationValidator;
19
use WMDE\Fundraising\Frontend\PaymentContext\Domain\Model\BankData;
20
use WMDE\Fundraising\Frontend\PaymentContext\Domain\Model\Iban;
21
use WMDE\Fundraising\Frontend\Tests\Data\ValidMembershipApplication;
22
use WMDE\Fundraising\Frontend\MembershipContext\Tests\Fixtures\FixedApplicationTokenFetcher;
23
use WMDE\Fundraising\Frontend\Tests\Fixtures\FixedTokenGenerator;
24
use WMDE\Fundraising\Frontend\MembershipContext\Tests\Fixtures\InMemoryApplicationRepository;
25
use WMDE\Fundraising\Frontend\Tests\Fixtures\TemplateBasedMailerSpy;
26
27
/**
28
 * @covers WMDE\Fundraising\Frontend\MembershipContext\UseCases\ApplyForMembership\ApplyForMembershipUseCase
29
 *
30
 * @license GNU GPL v2+
31
 * @author Jeroen De Dauw < [email protected] >
32
 */
33
class ApplyForMembershipUseCaseTest extends \PHPUnit_Framework_TestCase {
34
35
	const ID_OF_NON_EXISTING_APPLICATION = 1337;
36
	const FIRST_APPLICATION_ID = 1;
37
	const ACCESS_TOKEN = 'Gimmeh all the access';
38
	const UPDATE_TOKEN = 'Lemme change all the stuff';
39
40
	/**
41
	 * @var ApplicationRepository
42
	 */
43
	private $repository;
44
45
	/**
46
	 * @var TemplateBasedMailerSpy
47
	 */
48
	private $mailer;
49
50
	/**
51
	 * @var TokenGenerator
52
	 */
53
	private $tokenGenerator;
54
55
	/**
56
	 * @var MembershipApplicationValidator
57
	 */
58
	private $validator;
59
60
	/**
61
	 * @var ApplicationTracker
62
	 */
63
	private $tracker;
64
65
	/**
66
	 * @var ApplicationPiwikTracker
67
	 */
68
	private $piwikTracker;
69
70
	public function setUp() {
71
		$this->repository = new InMemoryApplicationRepository();
72
		$this->mailer = new TemplateBasedMailerSpy( $this );
73
		$this->tokenGenerator = new FixedTokenGenerator( self::ACCESS_TOKEN );
74
		$this->validator = $this->newSucceedingValidator();
75
		$this->tracker = $this->createMock( ApplicationTracker::class );
0 ignored issues
show
Documentation Bug introduced by
It seems like $this->createMock(\WMDE\...licationTracker::class) of type object<PHPUnit_Framework_MockObject_MockObject> is incompatible with the declared type object<WMDE\Fundraising\...ing\ApplicationTracker> of property $tracker.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
76
		$this->piwikTracker = $this->createMock( ApplicationPiwikTracker::class );
0 ignored issues
show
Documentation Bug introduced by
It seems like $this->createMock(\WMDE\...ionPiwikTracker::class) of type object<PHPUnit_Framework_MockObject_MockObject> is incompatible with the declared type object<WMDE\Fundraising\...pplicationPiwikTracker> of property $piwikTracker.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
77
	}
78
79
	private function newSucceedingValidator(): MembershipApplicationValidator {
80
		$validator = $this->getMockBuilder( MembershipApplicationValidator::class )
81
			->disableOriginalConstructor()->getMock();
82
83
		$validator->expects( $this->any() )
84
			->method( 'validate' )
85
			->willReturn( new ApplicationValidationResult() );
86
87
		return $validator;
88
	}
89
90
	public function testGivenValidRequest_applicationSucceeds() {
91
		$response = $this->newUseCase()->applyForMembership( $this->newValidRequest() );
92
93
		$this->assertTrue( $response->isSuccessful() );
94
	}
95
96
	private function newUseCase(): ApplyForMembershipUseCase {
97
		return new ApplyForMembershipUseCase(
98
			$this->repository,
99
			$this->newTokenFetcher(),
100
			$this->mailer,
101
			$this->validator,
102
			$this->tracker,
103
			$this->piwikTracker
104
		);
105
	}
106
107
	private function newTokenFetcher(): ApplicationTokenFetcher {
108
		return new FixedApplicationTokenFetcher( new MembershipApplicationTokens(
109
			self::ACCESS_TOKEN,
110
			self::UPDATE_TOKEN
111
		) );
112
	}
113
114
	private function newValidRequest(): ApplyForMembershipRequest {
115
		$request = new ApplyForMembershipRequest();
116
117
		$request->setMembershipType( ValidMembershipApplication::MEMBERSHIP_TYPE );
118
		$request->setApplicantCompanyName( '' );
119
		$request->setMembershipType( ValidMembershipApplication::MEMBERSHIP_TYPE );
120
		$request->setApplicantSalutation( ValidMembershipApplication::APPLICANT_SALUTATION );
121
		$request->setApplicantTitle( ValidMembershipApplication::APPLICANT_TITLE );
122
		$request->setApplicantFirstName( ValidMembershipApplication::APPLICANT_FIRST_NAME );
123
		$request->setApplicantLastName( ValidMembershipApplication::APPLICANT_LAST_NAME );
124
		$request->setApplicantStreetAddress( ValidMembershipApplication::APPLICANT_STREET_ADDRESS );
125
		$request->setApplicantPostalCode( ValidMembershipApplication::APPLICANT_POSTAL_CODE );
126
		$request->setApplicantCity( ValidMembershipApplication::APPLICANT_CITY );
127
		$request->setApplicantCountryCode( ValidMembershipApplication::APPLICANT_COUNTRY_CODE );
128
		$request->setApplicantEmailAddress( ValidMembershipApplication::APPLICANT_EMAIL_ADDRESS );
129
		$request->setApplicantPhoneNumber( ValidMembershipApplication::APPLICANT_PHONE_NUMBER );
130
		$request->setApplicantDateOfBirth( ValidMembershipApplication::APPLICANT_DATE_OF_BIRTH );
131
		$request->setPaymentIntervalInMonths( ValidMembershipApplication::PAYMENT_PERIOD_IN_MONTHS );
132
		$request->setPaymentAmountInEuros( (string)ValidMembershipApplication::PAYMENT_AMOUNT_IN_EURO );
133
134
		$request->setPaymentBankData( $this->newValidBankData() );
135
136
		$request->setTrackingInfo( $this->newTrackingInfo() );
137
		$request->setPiwikTrackingString( 'foo/bar' );
138
139
		return $request->assertNoNullFields();
140
	}
141
142
	private function newValidBankData(): BankData {
143
		$bankData = new BankData();
144
145
		$bankData->setIban( new Iban( ValidMembershipApplication::PAYMENT_IBAN ) );
146
		$bankData->setBic( ValidMembershipApplication::PAYMENT_BIC );
147
		$bankData->setAccount( ValidMembershipApplication::PAYMENT_BANK_ACCOUNT );
148
		$bankData->setBankCode( ValidMembershipApplication::PAYMENT_BANK_CODE );
149
		$bankData->setBankName( ValidMembershipApplication::PAYMENT_BANK_NAME );
150
151
		return $bankData->assertNoNullFields()->freeze();
152
	}
153
154
	private function newTrackingInfo() {
155
		return new MembershipApplicationTrackingInfo(
156
			ValidMembershipApplication::TEMPLATE_CAMPAIGN,
157
			ValidMembershipApplication::TEMPLATE_NAME
158
		);
159
	}
160
161
	public function testGivenValidRequest_applicationGetsPersisted() {
162
		$this->newUseCase()->applyForMembership( $this->newValidRequest() );
163
164
		$expectedApplication = ValidMembershipApplication::newDomainEntity();
165
		$expectedApplication->assignId( self::FIRST_APPLICATION_ID );
166
167
		$application = $this->repository->getApplicationById( $expectedApplication->getId() );
168
		$this->assertNotNull( $application );
169
170
		$this->assertEquals( $expectedApplication, $application );
171
	}
172
173
	public function testGivenValidRequest_confirmationEmailIsSend() {
174
		$this->newUseCase()->applyForMembership( $this->newValidRequest() );
175
176
		$this->mailer->assertCalledOnceWith(
177
			new EmailAddress( ValidMembershipApplication::APPLICANT_EMAIL_ADDRESS ),
178
			[
179
				'membershipType' => 'active',
180
				'membershipFee' => '10.00',
181
				'paymentIntervalInMonths' => 3,
182
				'salutation' => 'Herr',
183
				'title' => '',
184
				'lastName' => 'The Great'
185
			]
186
		);
187
	}
188
189
	public function testGivenValidRequest_tokenIsGeneratedAndReturned() {
190
		$response = $this->newUseCase()->applyForMembership( $this->newValidRequest() );
191
192
		$this->assertSame( self::ACCESS_TOKEN, $response->getAccessToken() );
193
		$this->assertSame( self::UPDATE_TOKEN, $response->getUpdateToken() );
194
	}
195
196
	public function testWhenValidationFails_failureResultIsReturned() {
197
		$this->validator = $this->newFailingValidator();
198
199
		$response = $this->newUseCase()->applyForMembership( $this->newValidRequest() );
200
201
		$this->assertFalse( $response->isSuccessful() );
202
	}
203
204
	private function newFailingValidator(): MembershipApplicationValidator {
205
		$validator = $this->getMockBuilder( MembershipApplicationValidator::class )
206
			->disableOriginalConstructor()->getMock();
207
208
		$validator->expects( $this->any() )
209
			->method( 'validate' )
210
			->willReturn( $this->newInvalidValidationResult() );
211
212
		return $validator;
213
	}
214
215
	private function newInvalidValidationResult(): ApplicationValidationResult {
216
		$invalidResult = $this->createMock( ApplicationValidationResult::class );
217
218
		$invalidResult->expects( $this->any() )
219
			->method( 'isSuccessful' )
220
			->willReturn( false );
221
222
		return $invalidResult;
223
	}
224
225
	public function testGivenValidRequest_moderationIsNotNeeded() {
226
		$response = $this->newUseCase()->applyForMembership( $this->newValidRequest() );
227
228
		$this->assertFalse( $response->getMembershipApplication()->needsModeration() );
229
	}
230
231
	public function testGivenRequestWithHighYearlyAmount_moderationIsNeeded() {
232
		$request = $this->newValidRequest();
233
		$request->setPaymentAmountInEuros( '1000.01' );
234
		$request->setPaymentIntervalInMonths( 12 );
235
236
		$this->assertRequestResultsInModeration( $request );
237
	}
238
239
	public function testGivenRequestWithHighQuarterlyAmount_moderationIsNeeded() {
240
		$request = $this->newValidRequest();
241
		$request->setPaymentAmountInEuros( '250.01' );
242
		$request->setPaymentIntervalInMonths( 3 );
243
244
		$this->assertRequestResultsInModeration( $request );
245
	}
246
247
	private function assertRequestResultsInModeration( ApplyForMembershipRequest $request ) {
248
		$response = $this->newUseCase()->applyForMembership( $request );
249
		$this->assertTrue( $response->getMembershipApplication()->needsModeration() );
250
	}
251
252
}
253