Completed
Push — master ( f48979...1564bf )
by wiese
195:26 queued 130:26
created

newPurgedApplication()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 4

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 4
nc 1
nop 0
1
<?php
2
3
declare( strict_types = 1 );
4
5
namespace WMDE\Fundraising\Frontend\MembershipContext\Tests\Integration\DataAccess;
6
7
use Doctrine\ORM\EntityManager;
8
use WMDE\EmailAddress\EmailAddress;
9
use WMDE\Fundraising\Entities\MembershipApplication as DoctrineApplication;
10
use WMDE\Fundraising\Frontend\MembershipContext\DataAccess\DoctrineApplicationRepository;
11
use WMDE\Fundraising\Frontend\MembershipContext\Domain\Repositories\ApplicationPurgedException;
12
use WMDE\Fundraising\Frontend\MembershipContext\Domain\Repositories\ApplicationRepository;
13
use WMDE\Fundraising\Frontend\MembershipContext\Domain\Repositories\GetMembershipApplicationException;
14
use WMDE\Fundraising\Frontend\MembershipContext\Domain\Repositories\StoreMembershipApplicationException;
15
use WMDE\Fundraising\Frontend\MembershipContext\Tests\Data\ValidMembershipApplication;
16
use WMDE\Fundraising\Frontend\MembershipContext\Tests\Fixtures\ThrowingEntityManager;
17
use WMDE\Fundraising\Frontend\Tests\TestEnvironment;
18
19
/**
20
 * @covers \WMDE\Fundraising\Frontend\MembershipContext\DataAccess\DoctrineApplicationRepository
21
 *
22
 * @licence GNU GPL v2+
23
 * @author Jeroen De Dauw < [email protected] >
24
 */
25
class DoctrineMembershipApplicationRepositoryTest extends \PHPUnit\Framework\TestCase {
26
27
	const MEMBERSHIP_APPLICATION_ID = 1;
28
	const ID_OF_APPLICATION_NOT_IN_DB = 35505;
29
30
	/**
31
	 * @var EntityManager
32
	 */
33
	private $entityManager;
34
35
	public function setUp(): void {
36
		$factory = TestEnvironment::newInstance()->getFactory();
37
		$factory->disableDoctrineSubscribers();
38
		$this->entityManager = $factory->getEntityManager();
39
		parent::setUp();
40
	}
41
42
	public function testValidMembershipApplicationGetPersisted(): void {
43
		$this->newRepository()->storeApplication( ValidMembershipApplication::newDomainEntity() );
44
45
		$expectedDoctrineEntity = ValidMembershipApplication::newDoctrineEntity();
46
		$expectedDoctrineEntity->setId( self::MEMBERSHIP_APPLICATION_ID );
47
48
		$this->assertDoctrineEntityIsInDatabase( $expectedDoctrineEntity );
49
	}
50
51
	private function newRepository(): ApplicationRepository {
52
		return new DoctrineApplicationRepository( $this->entityManager );
53
	}
54
55
	private function assertDoctrineEntityIsInDatabase( DoctrineApplication $expected ): void {
56
		$actual = $this->getApplicationFromDatabase( $expected->getId() );
57
58
		$this->assertNotNull( $actual->getCreationTime() );
59
		$actual->setCreationTime( null );
60
61
		$this->assertEquals( $expected->getDecodedData(), $actual->getDecodedData() );
62
63
		$this->assertEquals( $expected, $actual );
64
	}
65
66
	private function getApplicationFromDatabase( int $id ): DoctrineApplication {
67
		$applicationRepo = $this->entityManager->getRepository( DoctrineApplication::class );
68
		$donation = $applicationRepo->find( $id );
69
		$this->assertInstanceOf( DoctrineApplication::class, $donation );
70
		return $donation;
71
	}
72
73
	public function testIdGetsAssigned(): void {
74
		$application = ValidMembershipApplication::newDomainEntity();
75
76
		$this->newRepository()->storeApplication( $application );
77
78
		$this->assertSame( self::MEMBERSHIP_APPLICATION_ID, $application->getId() );
79
	}
80
81
	public function testWhenPersistenceFails_domainExceptionIsThrown(): void {
82
		$donation = ValidMembershipApplication::newDomainEntity();
83
84
		$repository = new DoctrineApplicationRepository( ThrowingEntityManager::newInstance( $this ) );
85
86
		$this->expectException( StoreMembershipApplicationException::class );
87
		$repository->storeApplication( $donation );
88
	}
89
90
	public function testWhenMembershipApplicationInDatabase_itIsReturnedAsMatchingDomainEntity(): void {
91
		$this->storeDoctrineApplication( ValidMembershipApplication::newDoctrineEntity() );
92
93
		$expected = ValidMembershipApplication::newAutoConfirmedDomainEntity();
94
		$expected->assignId( self::MEMBERSHIP_APPLICATION_ID );
95
96
		$this->assertEquals(
97
			$expected,
98
			$this->newRepository()->getApplicationById( self::MEMBERSHIP_APPLICATION_ID )
99
		);
100
	}
101
102
	private function storeDoctrineApplication( DoctrineApplication $application ): void {
103
		$this->entityManager->persist( $application );
104
		$this->entityManager->flush();
105
	}
106
107
	public function testWhenEntityDoesNotExist_getEntityReturnsNull(): void {
108
		$this->assertNull( $this->newRepository()->getApplicationById( self::ID_OF_APPLICATION_NOT_IN_DB ) );
109
	}
110
111
	public function testWhenReadFails_domainExceptionIsThrown(): void {
112
		$repository = new DoctrineApplicationRepository( ThrowingEntityManager::newInstance( $this ) );
113
114
		$this->expectException( GetMembershipApplicationException::class );
115
		$repository->getApplicationById( self::ID_OF_APPLICATION_NOT_IN_DB );
116
	}
117
118
	public function testWhenApplicationAlreadyExists_persistingCausesUpdate(): void {
119
		$repository = $this->newRepository();
120
		$originalApplication = ValidMembershipApplication::newDomainEntity();
121
122
		$repository->storeApplication( $originalApplication );
123
124
		// It is important a new instance is created here to test "detached entity" handling
125
		$newApplication = ValidMembershipApplication::newDomainEntity();
126
		$newApplication->assignId( $originalApplication->getId() );
127
		$newApplication->getApplicant()->changeEmailAddress( new EmailAddress( '[email protected]' ) );
128
129
		$repository->storeApplication( $newApplication );
130
131
		$doctrineApplication = $this->getApplicationFromDatabase( $newApplication->getId() );
132
133
		$this->assertSame( '[email protected]', $doctrineApplication->getApplicantEmailAddress() );
134
	}
135
136
	public function testWriteAndReadRoundtrip(): void {
137
		$repository = $this->newRepository();
138
		$application = ValidMembershipApplication::newAutoConfirmedDomainEntity();
139
140
		$repository->storeApplication( $application );
141
142
		$this->assertEquals(
143
			$application,
144
			$repository->getApplicationById( self::MEMBERSHIP_APPLICATION_ID )
145
		);
146
	}
147
148
	public function testWhenPersistingDeletedApplication_exceptionIsThrown(): void {
149
		$application = ValidMembershipApplication::newDomainEntity();
150
		$application->assignId( self::ID_OF_APPLICATION_NOT_IN_DB );
151
152
		$repository = $this->newRepository();
153
154
		$this->expectException( StoreMembershipApplicationException::class );
155
		$repository->storeApplication( $application );
156
	}
157
158
	public function testWhenPersistingApplicationWithModerationFlag_doctrineApplicationHasFlag(): void {
159
		$application = ValidMembershipApplication::newDomainEntity();
160
		$application->markForModeration();
161
162
		$this->newRepository()->storeApplication( $application );
163
		$doctrineApplication = $this->getApplicationFromDatabase( $application->getId() );
164
165
		$this->assertTrue( $doctrineApplication->needsModeration() );
166
		$this->assertFalse( $doctrineApplication->isCancelled() );
167
	}
168
169
	public function testWhenPersistingApplicationWithCancelledFlag_doctrineApplicationHasFlag(): void {
170
		$application = ValidMembershipApplication::newDomainEntity();
171
		$application->cancel();
172
173
		$this->newRepository()->storeApplication( $application );
174
		$doctrineApplication = $this->getApplicationFromDatabase( $application->getId() );
175
176
		$this->assertFalse( $doctrineApplication->needsModeration() );
177
		$this->assertTrue( $doctrineApplication->isCancelled() );
178
	}
179
180
	public function testWhenPersistingCancelledModerationApplication_doctrineApplicationHasFlags(): void {
181
		$application = ValidMembershipApplication::newDomainEntity();
182
		$application->markForModeration();
183
		$application->cancel();
184
185
		$this->newRepository()->storeApplication( $application );
186
		$doctrineApplication = $this->getApplicationFromDatabase( $application->getId() );
187
188
		$this->assertTrue( $doctrineApplication->needsModeration() );
189
		$this->assertTrue( $doctrineApplication->isCancelled() );
190
	}
191
192
	public function testGivenDoctrineApplicationWithModerationAndCancelled_domainEntityHasFlags(): void {
193
		$doctrineApplication = ValidMembershipApplication::newDoctrineEntity();
194
		$doctrineApplication->setStatus( DoctrineApplication::STATUS_CANCELED + DoctrineApplication::STATUS_MODERATION );
195
196
		$this->storeDoctrineApplication( $doctrineApplication );
197
		$application = $this->newRepository()->getApplicationById( $doctrineApplication->getId() );
198
199
		$this->assertTrue( $application->needsModeration() );
200
		$this->assertTrue( $application->isCancelled() );
201
	}
202
203
	public function testGivenDoctrineApplicationWithModerationFlag_domainEntityHasFlag(): void {
204
		$doctrineApplication = ValidMembershipApplication::newDoctrineEntity();
205
		$doctrineApplication->setStatus( DoctrineApplication::STATUS_MODERATION );
206
207
		$this->storeDoctrineApplication( $doctrineApplication );
208
		$application = $this->newRepository()->getApplicationById( $doctrineApplication->getId() );
209
210
		$this->assertTrue( $application->needsModeration() );
211
		$this->assertFalse( $application->isCancelled() );
212
	}
213
214
	public function testGivenDoctrineApplicationWithCancelledFlag_domainEntityHasFlag(): void {
215
		$doctrineApplication = ValidMembershipApplication::newDoctrineEntity();
216
		$doctrineApplication->setStatus( DoctrineApplication::STATUS_CANCELED );
217
218
		$this->storeDoctrineApplication( $doctrineApplication );
219
		$application = $this->newRepository()->getApplicationById( $doctrineApplication->getId() );
220
221
		$this->assertFalse( $application->needsModeration() );
222
		$this->assertTrue( $application->isCancelled() );
223
	}
224
225
	public function testGivenDoctrineApplicationWithCancelledFlag_initialStatusIsPreserved(): void {
226
		$application = ValidMembershipApplication::newDomainEntity();
227
		$application->cancel();
228
229
		$this->newRepository()->storeApplication( $application );
230
		$doctrineApplication = $this->getApplicationFromDatabase( $application->getId() );
231
232
		$this->assertSame( DoctrineApplication::STATUS_CONFIRMED, $doctrineApplication->getDataObject()->getPreservedStatus() );
233
	}
234
235
	public function testGivenCompanyApplication_companyNameIsPersisted(): void {
236
		$this->newRepository()->storeApplication( ValidMembershipApplication::newCompanyApplication() );
237
238
		$expectedDoctrineEntity = ValidMembershipApplication::newDoctrineCompanyEntity();
239
		$expectedDoctrineEntity->setId( self::MEMBERSHIP_APPLICATION_ID );
240
241
		$this->assertDoctrineEntityIsInDatabase( $expectedDoctrineEntity );
242
	}
243
244
	public function testReadingPurgedApplication_purgedExceptionIsThrown(): void {
245
		$this->storeDoctrineApplication( $this->newPurgedApplication() );
246
247
		$this->expectException( ApplicationPurgedException::class );
248
249
		$this->newRepository()->getApplicationById( self::MEMBERSHIP_APPLICATION_ID );
250
	}
251
252
	private function newPurgedApplication(): DoctrineApplication {
253
		$application = ValidMembershipApplication::newDoctrineEntity();
254
		$application->setBackup( new \DateTime() );
255
		return $application;
256
	}
257
258
}
259