Completed
Pull Request — master (#647)
by Jeroen De
51:35 queued 34:49
created

testWhenPersistingCancelledModerationApplication_doctrineApplicationHas()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 11
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 8
nc 1
nop 0
dl 0
loc 11
rs 9.4285
c 0
b 0
f 0
1
<?php
2
3
declare( strict_types = 1 );
4
5
namespace WMDE\Fundraising\Frontend\Tests\Integration\MembershipApplicationContext\DataAccess;
6
7
use Doctrine\ORM\EntityManager;
8
use WMDE\Fundraising\Entities\MembershipApplication as DoctrineApplication;
9
use WMDE\Fundraising\Frontend\MembershipApplicationContext\DataAccess\DoctrineApplicationRepository;
10
use WMDE\Fundraising\Frontend\MembershipApplicationContext\Domain\Model\EmailAddress;
11
use WMDE\Fundraising\Frontend\MembershipApplicationContext\Domain\Repositories\ApplicationRepository;
12
use WMDE\Fundraising\Frontend\MembershipApplicationContext\Domain\Repositories\GetMembershipApplicationException;
13
use WMDE\Fundraising\Frontend\MembershipApplicationContext\Domain\Repositories\StoreMembershipApplicationException;
14
use WMDE\Fundraising\Frontend\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\MembershipApplicationContext\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() {
35
		$factory = TestEnvironment::newInstance()->getFactory();
36
		$factory->disableDoctrineSubscribers();
37
		$this->entityManager = $factory->getEntityManager();
38
		parent::setUp();
39
	}
40
41
	public function testValidApplicationGetPersisted() {
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 ) {
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
		$expected->encodeAndSetData( [] );
62
		$actual->encodeAndSetData( [] );
63
64
		$this->assertEquals( $expected, $actual );
65
	}
66
67
	private function getApplicationFromDatabase( int $id ): DoctrineApplication {
68
		$applicationRepo = $this->entityManager->getRepository( DoctrineApplication::class );
69
		$donation = $applicationRepo->find( $id );
70
		$this->assertInstanceOf( DoctrineApplication::class, $donation );
71
		return $donation;
72
	}
73
74
	public function testIdGetsAssigned() {
75
		$application = ValidMembershipApplication::newDomainEntity();
76
77
		$this->newRepository()->storeApplication( $application );
78
79
		$this->assertSame( self::MEMBERSHIP_APPLICATION_ID, $application->getId() );
80
	}
81
82
	public function testWhenPersistenceFails_domainExceptionIsThrown() {
83
		$donation = ValidMembershipApplication::newDomainEntity();
84
85
		$repository = new DoctrineApplicationRepository( ThrowingEntityManager::newInstance( $this ) );
86
87
		$this->expectException( StoreMembershipApplicationException::class );
88
		$repository->storeApplication( $donation );
89
	}
90
91
	public function testWhenDonationInDatabase_itIsReturnedAsMatchingDomainEntity() {
92
		$this->storeDoctrineApplication( ValidMembershipApplication::newDoctrineEntity() );
93
94
		$expected = ValidMembershipApplication::newDomainEntity();
95
		$expected->assignId( self::MEMBERSHIP_APPLICATION_ID );
96
97
		$this->assertEquals(
98
			$expected,
99
			$this->newRepository()->getApplicationById( self::MEMBERSHIP_APPLICATION_ID )
100
		);
101
	}
102
103
	private function storeDoctrineApplication( DoctrineApplication $application ) {
104
		$this->entityManager->persist( $application );
105
		$this->entityManager->flush();
106
	}
107
108
	public function testWhenEntityDoesNotExist_getEntityReturnsNull() {
109
		$this->assertNull( $this->newRepository()->getApplicationById( self::ID_OF_APPLICATION_NOT_IN_DB ) );
110
	}
111
112
	public function testWhenReadFails_domainExceptionIsThrown() {
113
		$repository = new DoctrineApplicationRepository( ThrowingEntityManager::newInstance( $this ) );
114
115
		$this->expectException( GetMembershipApplicationException::class );
116
		$repository->getApplicationById( self::ID_OF_APPLICATION_NOT_IN_DB );
117
	}
118
119
	public function testWhenApplicationAlreadyExists_persistingCausesUpdate() {
120
		$repository = $this->newRepository();
121
		$originalApplication = ValidMembershipApplication::newDomainEntity();
122
123
		$repository->storeApplication( $originalApplication );
124
125
		// It is important a new instance is created here to test "detached entity" handling
126
		$newApplication = ValidMembershipApplication::newDomainEntity();
127
		$newApplication->assignId( $originalApplication->getId() );
128
		$newApplication->getApplicant()->changeEmailAddress( new EmailAddress( '[email protected]' ) );
129
130
		$repository->storeApplication( $newApplication );
131
132
		$doctrineApplication = $this->getApplicationFromDatabase( $newApplication->getId() );
133
134
		$this->assertSame( '[email protected]', $doctrineApplication->getApplicantEmailAddress() );
135
	}
136
137
	public function testWriteAndReadRoundtrip() {
138
		$repository = $this->newRepository();
139
		$application = ValidMembershipApplication::newDomainEntity();
140
141
		$repository->storeApplication( $application );
142
143
		$this->assertEquals(
144
			$application,
145
			$repository->getApplicationById( self::MEMBERSHIP_APPLICATION_ID )
146
		);
147
	}
148
149
	public function testWhenPersistingDeletedApplication_exceptionIsThrown() {
150
		$application = ValidMembershipApplication::newDomainEntity();
151
		$application->assignId( self::ID_OF_APPLICATION_NOT_IN_DB );
152
153
		$repository = $this->newRepository();
154
155
		$this->expectException( StoreMembershipApplicationException::class );
156
		$repository->storeApplication( $application );
157
	}
158
159
	public function testWhenPersistingApplicationWithModerationFlag_doctrineApplicationHasFlag() {
160
		$application = ValidMembershipApplication::newDomainEntity();
161
		$application->markForModeration();
162
163
		$this->newRepository()->storeApplication( $application );
164
		$doctrineApplication = $this->getApplicationFromDatabase( $application->getId() );
165
166
		$this->assertTrue( $doctrineApplication->needsModeration() );
167
		$this->assertFalse( $doctrineApplication->isCancelled() );
168
	}
169
170
	public function testWhenPersistingApplicationWithCancelledFlag_doctrineApplicationHasFlag() {
171
		$application = ValidMembershipApplication::newDomainEntity();
172
		$application->cancel();
173
174
		$this->newRepository()->storeApplication( $application );
175
		$doctrineApplication = $this->getApplicationFromDatabase( $application->getId() );
176
177
		$this->assertFalse( $doctrineApplication->needsModeration() );
178
		$this->assertTrue( $doctrineApplication->isCancelled() );
179
	}
180
181
	public function testWhenPersistingCancelledModerationApplication_doctrineApplicationHasFlags() {
182
		$application = ValidMembershipApplication::newDomainEntity();
183
		$application->markForModeration();
184
		$application->cancel();
185
186
		$this->newRepository()->storeApplication( $application );
187
		$doctrineApplication = $this->getApplicationFromDatabase( $application->getId() );
188
189
		$this->assertTrue( $doctrineApplication->needsModeration() );
190
		$this->assertTrue( $doctrineApplication->isCancelled() );
191
	}
192
193
	public function testGivenDoctrineApplicationWithModerationAndCancelled_domainEntityHasFlags() {
194
		$doctrineApplication = ValidMembershipApplication::newDoctrineEntity();
195
		$doctrineApplication->setStatus( DoctrineApplication::STATUS_CANCELED + DoctrineApplication::STATUS_MODERATION );
196
197
		$this->storeDoctrineApplication( $doctrineApplication );
198
		$application = $this->newRepository()->getApplicationById( $doctrineApplication->getId() );
199
200
		$this->assertTrue( $application->needsModeration() );
201
		$this->assertTrue( $application->isCancelled() );
202
	}
203
204
	public function testGivenDoctrineApplicationWithModerationFlag_domainEntityHasFlag() {
205
		$doctrineApplication = ValidMembershipApplication::newDoctrineEntity();
206
		$doctrineApplication->setStatus( DoctrineApplication::STATUS_MODERATION );
207
208
		$this->storeDoctrineApplication( $doctrineApplication );
209
		$application = $this->newRepository()->getApplicationById( $doctrineApplication->getId() );
210
211
		$this->assertTrue( $application->needsModeration() );
212
		$this->assertFalse( $application->isCancelled() );
213
	}
214
215
	public function testGivenDoctrineApplicationWithCancelledFlag_domainEntityHasFlag() {
216
		$doctrineApplication = ValidMembershipApplication::newDoctrineEntity();
217
		$doctrineApplication->setStatus( DoctrineApplication::STATUS_CANCELED );
218
219
		$this->storeDoctrineApplication( $doctrineApplication );
220
		$application = $this->newRepository()->getApplicationById( $doctrineApplication->getId() );
221
222
		$this->assertFalse( $application->needsModeration() );
223
		$this->assertTrue( $application->isCancelled() );
224
	}
225
226
}
227