Test Setup Failed
Pull Request — master (#7)
by Gabriel
64:20
created

testGivenAddressChangeWithReceiptOptIn_optInIsStoredCorrectly()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 8
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 6
nc 1
nop 0
dl 0
loc 8
rs 10
c 1
b 0
f 0
1
<?php
2
3
declare( strict_types = 1 );
4
5
namespace WMDE\Fundraising\AddressChangeContext\Tests\Unit\DataAccess;
6
7
use Doctrine\ORM\EntityManager;
8
use PHPUnit\Framework\TestCase;
9
use WMDE\Fundraising\AddressChange\DataAccess\DoctrineAddressChangeRepository;
10
use WMDE\Fundraising\AddressChange\Domain\Model\Address;
11
use WMDE\Fundraising\AddressChange\Domain\Model\AddressChange;
12
use WMDE\Fundraising\AddressChangeContext\Tests\TestEnvironment;
13
14
/**
15
 * @covers \WMDE\Fundraising\AddressChange\DataAccess\DoctrineAddressChangeRepository
16
 */
17
class DoctrineAddressChangeRepositoryTest extends TestCase {
18
19
	const VALID_UPDATE_TOKEN_PERSONAL_DONATION = '2a54c0a1-fc94-4ef8-8b0a-7c2ed8565521';
20
	const VALID_UPDATE_TOKEN_PERSONAL_MEMBERSHIP = 'ce4449f9-8317-41fa-acc3-4a878e26845d';
21
	const VALID_UPDATE_TOKEN_COMPANY_DONATION = 'c52258ba-fed1-476a-a7e5-c721df087c12';
22
	const VALID_UPDATE_TOKEN_COMPANY_MEMBERSHIP = '8d11d2ba-5ec5-4ec8-a08c-0ac7b8654b59';
23
	const INVALID_UPDATE_TOKEN = '72dfed91-fa40-4af0-9e80-c6010ab29cd1';
24
25
	/** @var EntityManager */
26
	private $em;
27
28
	public function setUp(): void {
29
		$this->em = TestEnvironment::newInstance()->getFactory()->getEntityManager();
30
		parent::setUp();
31
	}
32
33
	public function testGivenValidPersonalDonationUuid_addressChangeIsReturned(): void {
34
		$this->storeAddressChange( self::VALID_UPDATE_TOKEN_PERSONAL_DONATION, true );
35
		$retrievedAddressChange = $this->retrieveAddressChangeByUuid( self::VALID_UPDATE_TOKEN_PERSONAL_DONATION );
36
37
		$this->assertNotNull( $retrievedAddressChange );
38
		$this->assertSame(
39
			self::VALID_UPDATE_TOKEN_PERSONAL_DONATION,
40
			$retrievedAddressChange->getCurrentIdentifier()
41
		);
42
		$this->assertTrue( $retrievedAddressChange->isPersonalAddress() );
43
	}
44
45
	public function testGivenValidCompanyDonationUuid_addressChangeIsReturned(): void {
46
		$this->storeAddressChange( self::VALID_UPDATE_TOKEN_COMPANY_DONATION, false );
47
		$retrievedAddressChange = $this->retrieveAddressChangeByUuid( self::VALID_UPDATE_TOKEN_COMPANY_DONATION );
48
49
		$this->assertNotNull( $retrievedAddressChange );
50
		$this->assertSame(
51
			self::VALID_UPDATE_TOKEN_COMPANY_DONATION,
52
			$retrievedAddressChange->getCurrentIdentifier()
53
		);
54
		$this->assertTrue( $retrievedAddressChange->isCompanyAddress() );
55
	}
56
57
	public function testGivenInvalidDonationUuid_nullIsReturned(): void {
58
		$addressChangeRepository = new DoctrineAddressChangeRepository( $this->em );
59
		$addressChange = $addressChangeRepository->getAddressChangeByUuid( self::INVALID_UPDATE_TOKEN );
60
		$this->assertNull( $addressChange );
61
	}
62
63
	public function testGivenAddressChangeWithAddress_itIsStoredCorrectly(): void {
64
		$addressChangeRepository = new DoctrineAddressChangeRepository( $this->em );
65
		$addressChange = AddressChange::createNewPersonAddressChange( null, $this->newPersonalAddress() );
66
		$addressChangeRepository->storeAddressChange( $addressChange );
67
		$now = new \DateTime();
68
69
		$this->em->clear( AddressChange::class );
70
		$retrievedAddressChange = $addressChangeRepository->getAddressChangeByUuid( $addressChange->getCurrentIdentifier() );
71
		$this->assertNotNull( $retrievedAddressChange );
72
		$this->assertNotNull( $retrievedAddressChange->getAddress() );
73
		$this->assertNotNull( $addressChange->getAddress() ); // avoid PHPStan errors when accessing address later
74
		$this->assertFalse( $retrievedAddressChange->isExported() );
75
		$this->assertDatePropertyIsSet( $now, $retrievedAddressChange, 'createdAt' );
0 ignored issues
show
Bug introduced by
It seems like $retrievedAddressChange can also be of type null; however, parameter $addressChange of WMDE\Fundraising\Address...sertDatePropertyIsSet() does only seem to accept WMDE\Fundraising\Address...ain\Model\AddressChange, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

75
		$this->assertDatePropertyIsSet( $now, /** @scrutinizer ignore-type */ $retrievedAddressChange, 'createdAt' );
Loading history...
76
		$this->assertDatePropertyIsSet( $now, $retrievedAddressChange, 'modifiedAt' );
77
		$this->assertSame( $addressChange->getCurrentIdentifier(), $retrievedAddressChange->getCurrentIdentifier() );
78
		$this->assertSame( $addressChange->getAddress()->isPersonalAddress(), $retrievedAddressChange->getAddress()->isPersonalAddress() );
79
	}
80
81
	public function testGivenAddressChangeWithReceiptOptIn_optInIsStoredCorrectly(): void {
82
		$addressChangeRepository = new DoctrineAddressChangeRepository( $this->em );
83
		$addressChange = AddressChange::createNewCompanyAddressChange();
84
		$addressChangeRepository->storeAddressChange( $addressChange );
85
86
		$this->em->clear( AddressChange::class );
87
		$retrievedAddressChange = $addressChangeRepository->getAddressChangeByUuid( $addressChange->getCurrentIdentifier() );
88
		$this->assertTrue( $retrievedAddressChange->isOptedIntoDonationReceipt() );
89
	}
90
91
	public function testGivenAddressChangeWithReceiptOptOut_optOutIsStoredCorrectly(): void {
92
		$addressChangeRepository = new DoctrineAddressChangeRepository( $this->em );
93
		$addressChange = AddressChange::createNewCompanyAddressChange();
94
		$addressChange->optOutOfDonationReceipt();
95
		$addressChangeRepository->storeAddressChange( $addressChange );
96
97
		$this->em->clear( AddressChange::class );
98
		$retrievedAddressChange = $addressChangeRepository->getAddressChangeByUuid( $addressChange->getCurrentIdentifier() );
99
		$this->assertFalse( $retrievedAddressChange->isOptedIntoDonationReceipt() );
100
	}
101
102
	public function testGivenExportedAddressChange_itsStateIsStoredCorrectly(): void {
103
		$addressChangeRepository = new DoctrineAddressChangeRepository( $this->em );
104
		$addressChange = AddressChange::createNewPersonAddressChange( null, $this->newPersonalAddress() );
105
		$addressChange->markAsExported();
106
		$addressChangeRepository->storeAddressChange( $addressChange );
107
		$now = new \DateTime();
108
109
		$this->em->clear( AddressChange::class );
110
		$retrievedAddressChange = $addressChangeRepository->getAddressChangeByUuid( $addressChange->getCurrentIdentifier() );
111
		$this->assertNotNull( $retrievedAddressChange );
112
		$this->assertTrue( $retrievedAddressChange->isExported() );
113
		$this->assertDatePropertyIsSet( $now, $retrievedAddressChange, 'exportDate' );
0 ignored issues
show
Bug introduced by
It seems like $retrievedAddressChange can also be of type null; however, parameter $addressChange of WMDE\Fundraising\Address...sertDatePropertyIsSet() does only seem to accept WMDE\Fundraising\Address...ain\Model\AddressChange, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

113
		$this->assertDatePropertyIsSet( $now, /** @scrutinizer ignore-type */ $retrievedAddressChange, 'exportDate' );
Loading history...
114
	}
115
116
	private function storeAddressChange( string $uuid, bool $isPersonal = true ): void {
117
		if ( $isPersonal ) {
118
			$addressChange = AddressChange::createNewPersonAddressChange(
119
				$uuid,
120
				$this->newPersonalAddress()
121
			);
122
		} else {
123
			$addressChange = AddressChange::createNewCompanyAddressChange(
124
				$uuid,
125
				$this->newCompanyAddress()
126
			);
127
		}
128
		$this->em->persist( $addressChange );
129
		$this->em->flush();
130
		$this->em->clear( AddressChange::class );
131
	}
132
133
	private function retrieveAddressChangeByUuid( string $uuid ): ?AddressChange {
134
		$addressChangeRepository = new DoctrineAddressChangeRepository( $this->em );
135
		return $addressChangeRepository->getAddressChangeByUuid(
136
			$uuid
137
		);
138
	}
139
140
	private function newPersonalAddress(): Address {
141
		return Address::newPersonalAddress(
142
			'Herr',
143
			'Prof. Dr.',
144
			'Test',
145
			'User',
146
			'Teststreet 12345',
147
			'98765',
148
			'Berlin',
149
			'Germany'
150
		);
151
	}
152
153
	private function newCompanyAddress(): Address {
154
		return Address::newCompanyAddress(
155
			'Test Company',
156
			'Teststreet 123',
157
			'324324',
158
			'Not Berlin',
159
			'Somewhere'
160
		);
161
	}
162
163
	private function assertDatePropertyIsSet( \DateTime $expectedDate, AddressChange $addressChange, string $propertyName, float $delta = 1.0 ): void {
164
		// We're peeking into private properties to make sure the dates, which are not exposed through getters at the domain level,
165
		// are properly written at the DB level
166
		$dateField = new \ReflectionProperty( AddressChange::class, $propertyName );
167
		$dateField->setAccessible( true );
168
		$actualDate = $dateField->getValue( $addressChange );
169
		$this->assertEqualsWithDelta( $actualDate->getTimestamp(), $expectedDate->getTimestamp(), $delta, 'Dates do not match.' );
170
	}
171
}
172