Completed
Push — master ( 00092a...39103d )
by wiese
86:17 queued 21:06
created

assertDoctrineEntityIsInDatabase()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 10
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

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