Commit | Line | Data |
---|---|---|
47c96854 RLAR |
1 | <?php |
2 | namespace Civi\Payment; | |
3 | ||
4 | use Civi\Test\HeadlessInterface; | |
5 | use Civi\Test\TransactionalInterface; | |
6 | ||
7 | /** | |
8 | * @group headless | |
9 | */ | |
10 | class PropertyBagTest extends \PHPUnit\Framework\TestCase implements HeadlessInterface, TransactionalInterface { | |
11 | ||
12 | public function setUpHeadless() { | |
13 | return \Civi\Test::headless()->apply(); | |
14 | } | |
15 | ||
16 | protected function setUp() { | |
17 | parent::setUp(); | |
18 | // $this->useTransaction(TRUE); | |
19 | } | |
20 | ||
21 | public function tearDown() { | |
22 | parent::tearDown(); | |
23 | } | |
24 | ||
25 | /** | |
26 | * Test we can set a contact ID. | |
27 | */ | |
28 | public function testSetContactID() { | |
29 | // Do things proper. | |
30 | $propertyBag = new PropertyBag(); | |
31 | $propertyBag->setContactID(123); | |
32 | $this->assertEquals(123, $propertyBag->getContactID()); | |
33 | ||
34 | // Same but this time set contact ID with string. | |
35 | // (php should throw its own warnings about this because of the signature) | |
36 | $propertyBag = new PropertyBag(); | |
37 | $propertyBag->setContactID('123'); | |
38 | $this->assertInternalType('int', $propertyBag->getContactID()); | |
39 | $this->assertEquals(123, $propertyBag->getContactID()); | |
40 | ||
41 | // Test we can have different labels | |
42 | $propertyBag = new PropertyBag(); | |
43 | $propertyBag->setContactID(123); | |
44 | $propertyBag->setContactID(456, 'new'); | |
45 | $this->assertEquals(123, $propertyBag->getContactID()); | |
46 | $this->assertEquals(456, $propertyBag->getContactID('new')); | |
47 | } | |
48 | ||
49 | /** | |
50 | * Test we cannot set an invalid contact ID. | |
51 | * | |
52 | * @expectedException \InvalidArgumentException | |
53 | */ | |
54 | public function testSetContactIDFailsIfInvalid() { | |
55 | $propertyBag = new PropertyBag(); | |
56 | $propertyBag->setContactID(0); | |
57 | } | |
58 | ||
59 | /** | |
60 | * Test we can set a contact ID the wrong way | |
61 | */ | |
62 | public function testSetContactIDLegacyWay() { | |
63 | $propertyBag = new PropertyBag(); | |
64 | $propertyBag['contactID'] = 123; | |
65 | $this->assertEquals(123, $propertyBag->getContactID()); | |
66 | $this->assertEquals(123, $propertyBag['contactID']); | |
67 | // There should not be any warnings yet. | |
68 | $this->assertEquals("", $propertyBag->lastWarning); | |
69 | ||
70 | // Now access via legacy name - should work but generate warning. | |
71 | $this->assertEquals(123, $propertyBag['contact_id']); | |
afbfe83c | 72 | $this->assertEquals("We have translated 'contact_id' to 'contactID' for you, but please update your code to use the propper setters and getters.", $propertyBag->lastWarning); |
47c96854 RLAR |
73 | |
74 | // Repeat but this time set the property using a legacy name, fetch by new name. | |
75 | $propertyBag = new PropertyBag(); | |
76 | $propertyBag['contact_id'] = 123; | |
afbfe83c | 77 | $this->assertEquals("We have translated 'contact_id' to 'contactID' for you, but please update your code to use the propper setters and getters.", $propertyBag->lastWarning); |
47c96854 RLAR |
78 | $this->assertEquals(123, $propertyBag->getContactID()); |
79 | $this->assertEquals(123, $propertyBag['contactID']); | |
80 | $this->assertEquals(123, $propertyBag['contact_id']); | |
81 | } | |
82 | ||
83 | /** | |
84 | */ | |
85 | public function testMergeInputs() { | |
86 | $propertyBag = new PropertyBag(); | |
87 | $propertyBag->mergeLegacyInputParams([ | |
88 | 'contactID' => 123, | |
89 | 'contributionRecurID' => 456, | |
90 | ]); | |
afbfe83c | 91 | $this->assertEquals("We have merged input params into the property bag for now but please rewrite code to not use this.", $propertyBag->lastWarning); |
47c96854 RLAR |
92 | $this->assertEquals(123, $propertyBag->getContactID()); |
93 | $this->assertEquals(456, $propertyBag->getContributionRecurID()); | |
94 | } | |
95 | ||
96 | /** | |
97 | * Test we can set and access custom props. | |
98 | */ | |
99 | public function testSetCustomProp() { | |
100 | $propertyBag = new PropertyBag(); | |
101 | $propertyBag->setCustomProperty('customThingForMyProcessor', 'fidget'); | |
102 | $this->assertEquals('fidget', $propertyBag->getCustomProperty('customThingForMyProcessor')); | |
103 | $this->assertEquals('', $propertyBag->lastWarning); | |
104 | ||
105 | // Test we can do this with array, although we should get a warning. | |
106 | $propertyBag = new PropertyBag(); | |
107 | $propertyBag['customThingForMyProcessor'] = 'fidget'; | |
108 | $this->assertEquals('fidget', $propertyBag->getCustomProperty('customThingForMyProcessor')); | |
afbfe83c | 109 | $this->assertEquals("Unknown property 'customThingForMyProcessor'. We have merged this in for now as a custom property. Please rewrite your code to use PropertyBag->setCustomProperty if it is a genuinely custom property, or a standardised setter like PropertyBag->setContactID for standard properties", $propertyBag->lastWarning); |
47c96854 RLAR |
110 | } |
111 | ||
112 | /** | |
113 | * Test we can't set a custom prop that we know about. | |
114 | * | |
115 | * @expectedException \InvalidArgumentException | |
116 | * @expectedExceptionMessage Attempted to set 'contactID' via setCustomProperty - must use using its setter. | |
117 | */ | |
118 | public function testSetCustomPropFails() { | |
119 | $propertyBag = new PropertyBag(); | |
120 | $propertyBag->setCustomProperty('contactID', 123); | |
121 | } | |
122 | ||
123 | /** | |
124 | * | |
125 | * @dataProvider otherParamsDataProvider | |
126 | */ | |
127 | public function testOtherParams($prop, $legacy_names, $valid_values, $invalid_values) { | |
128 | $setter = 'set' . ucfirst($prop); | |
129 | $getter = 'get' . ucfirst($prop); | |
130 | ||
131 | // Using the setter and getter, check we can pass stuff in and get expected out. | |
132 | foreach ($valid_values as $_) { | |
133 | list($given, $expect) = $_; | |
134 | $propertyBag = new PropertyBag(); | |
dea0d7b8 RLAR |
135 | try { |
136 | $propertyBag->$setter($given); | |
137 | } | |
138 | catch (\Exception $e) { | |
139 | $this->fail("Expected to be able to set '$prop' to '$given' but got " . get_class($e) . ": " . $e->getMessage()); | |
140 | } | |
141 | try { | |
142 | $this->assertEquals($expect, $propertyBag->$getter()); | |
143 | } | |
144 | catch (\Exception $e) { | |
145 | $this->fail("Expected to be able to call $getter, having called $setter with '$given' but got " . get_class($e) . ": " . $e->getMessage()); | |
146 | } | |
47c96854 RLAR |
147 | } |
148 | // Using the setter and getter, check we get an error for invalid data. | |
149 | foreach ($invalid_values as $given) { | |
150 | try { | |
151 | $propertyBag = new PropertyBag(); | |
152 | $propertyBag->$setter($given); | |
153 | } | |
154 | catch (\InvalidArgumentException $e) { | |
155 | // counts this assertion. | |
156 | $this->assertTrue(TRUE); | |
157 | continue; | |
158 | } | |
159 | $this->fail("Expected an error trying to set $prop to " . json_encode($given) . " but did not get one."); | |
160 | } | |
161 | ||
162 | // Check array access for the proper property name and any aliases. | |
163 | foreach (array_merge([$prop], $legacy_names) as $name) { | |
164 | // Check array access | |
165 | foreach ($valid_values as $_) { | |
166 | list($given, $expect) = $_; | |
167 | $propertyBag = new PropertyBag(); | |
168 | $propertyBag[$name] = $given; | |
169 | $this->assertEquals($expect, $propertyBag->$getter(), "Failed to set $prop via array access on $name"); | |
170 | // Nb. I don't feel the need to repeat all the checks above for every alias. | |
171 | // We only really need to test that the array access works for each alias. | |
172 | break; | |
173 | } | |
174 | } | |
175 | } | |
176 | ||
177 | /** | |
178 | * Test the require method works. | |
179 | */ | |
180 | public function testRequire() { | |
181 | $propertyBag = new PropertyBag(); | |
182 | $propertyBag->setContactID(123); | |
183 | $propertyBag->setDescription('foo'); | |
184 | // This one should not error. | |
185 | $propertyBag->require(['contactID', 'description']); | |
186 | try { | |
187 | $propertyBag->require(['contactID', 'description', 'contributionID', 'somethingthatdoesntexist']); | |
188 | } | |
189 | catch (\InvalidArgumentException $e) { | |
190 | $this->assertEquals('Required properties missing: contributionID, somethingthatdoesntexist', $e->getMessage()); | |
191 | } | |
192 | } | |
193 | ||
194 | /** | |
195 | * | |
196 | * Data provider for testOtherParams | |
197 | * | |
198 | */ | |
199 | public function otherParamsDataProvider() { | |
200 | $valid_bools = [['0' , FALSE], ['', FALSE], [0, FALSE], [FALSE, FALSE], [TRUE, TRUE], [1, TRUE], ['1', TRUE]]; | |
201 | $valid_strings = [['foo' , 'foo'], ['', '']]; | |
dea0d7b8 | 202 | $valid_strings_inc_null = [['foo' , 'foo'], ['', ''], [NULL, '']]; |
47c96854 RLAR |
203 | $valid_ints = [[123, 123], ['123', 123]]; |
204 | $invalid_ints = [-1, 0, NULL, '']; | |
205 | return [ | |
dea0d7b8 RLAR |
206 | ['billingStreetAddress', [], $valid_strings_inc_null, []], |
207 | ['billingSupplementalAddress1', [], $valid_strings_inc_null, []], | |
208 | ['billingSupplementalAddress2', [], $valid_strings_inc_null, []], | |
209 | ['billingSupplementalAddress3', [], $valid_strings_inc_null, []], | |
210 | ['billingCity', [], $valid_strings_inc_null, []], | |
211 | ['billingPostalCode', [], $valid_strings_inc_null, []], | |
212 | ['billingCounty', [], $valid_strings_inc_null, []], | |
213 | ['billingCountry', [], [['GB', 'GB'], ['NZ', 'NZ']], ['XX', '', NULL, 0]], | |
47c96854 RLAR |
214 | ['contributionID', ['contribution_id'], $valid_ints, $invalid_ints], |
215 | ['contributionRecurID', ['contribution_recur_id'], $valid_ints, $invalid_ints], | |
216 | ['description', [], [['foo' , 'foo'], ['', '']], []], | |
217 | ['feeAmount', ['fee_amount'], [[1.23, 1.23], ['4.56', 4.56]], [NULL]], | |
dea0d7b8 | 218 | ['firstName', [], $valid_strings_inc_null, []], |
47c96854 RLAR |
219 | ['invoiceID', ['invoice_id'], $valid_strings, []], |
220 | ['isBackOffice', ['is_back_office'], $valid_bools, [NULL]], | |
221 | ['isRecur', ['is_recur'], $valid_bools, [NULL]], | |
dea0d7b8 | 222 | ['lastName', [], $valid_strings_inc_null, []], |
47c96854 RLAR |
223 | ['paymentToken', [], $valid_strings, []], |
224 | ['recurFrequencyInterval', ['frequency_interval'], $valid_ints, $invalid_ints], | |
225 | ['recurFrequencyUnit', [], [['month', 'month'], ['day', 'day'], ['year', 'year']], ['', NULL, 0]], | |
dea0d7b8 | 226 | ['recurProcessorID', [], [['foo', 'foo']], [str_repeat('x', 256), NULL, '', 0]], |
47c96854 RLAR |
227 | ['transactionID', ['transaction_id'], $valid_strings, []], |
228 | ['trxnResultCode', [], $valid_strings, []], | |
229 | ]; | |
230 | } | |
231 | ||
a05bcbd4 RLAR |
232 | /** |
233 | * Test generic getter, setter methods. | |
234 | * | |
235 | */ | |
236 | public function testGetterAndSetter() { | |
237 | $propertyBag = new PropertyBag(); | |
238 | ||
239 | $propertyBag->setter('contactID', 123); | |
240 | $this->assertEquals(123, $propertyBag->getContactID(), "Failed testing that a valid property was set correctly"); | |
241 | ||
242 | $result = $propertyBag->getter('contactID'); | |
243 | $this->assertEquals(123, $result, "Failed testing the getter on a set property"); | |
244 | ||
245 | $result = $propertyBag->getter('contactID', TRUE, 456); | |
246 | $this->assertEquals(123, $result, "Failed testing the getter on a set property when providing a default"); | |
247 | ||
248 | $result = $propertyBag->getter('contributionRecurID', TRUE, 456); | |
249 | $this->assertEquals(456, $result, "Failed testing the getter on an unset property when providing a default"); | |
250 | ||
251 | try { | |
252 | $result = $propertyBag->getter('contributionRecurID', FALSE); | |
253 | $this->fail("getter called with unset property should throw exception but none was thrown"); | |
254 | } | |
255 | catch (\BadMethodCallException $e) { | |
256 | } | |
257 | ||
258 | $result = $propertyBag->getter('contribution_recur_id', TRUE, NULL); | |
259 | $this->assertNull($result, "Failed testing the getter on an invalid property when providing a default"); | |
260 | ||
261 | try { | |
262 | $result = $propertyBag->getter('contribution_recur_id'); | |
263 | } | |
264 | catch (\InvalidArgumentException $e) { | |
265 | $this->assertEquals("Attempted to get 'contribution_recur_id' via getCustomProperty - must use using its getter.", $e->getMessage()); | |
266 | } | |
267 | ||
268 | // Nb. hmmm. the custom property getter does not throw an exception if the property is unset, it just returns NULL. | |
269 | $result = $propertyBag->getter('something_custom'); | |
270 | $this->assertNull($result, "Failed testing the getter on an unset custom property when not providing a default"); | |
271 | ||
272 | try { | |
273 | $propertyBag->setter('some_custom_thing', 'foo'); | |
274 | $this->fail("Expected to get an exception when trying to use setter for a non-standard property."); | |
275 | } | |
276 | catch (\BadMethodCallException $e) { | |
277 | $this->assertEquals("Cannot use generic setter with non-standard properties; you must use setCustomProperty for custom properties.", $e->getMessage()); | |
278 | } | |
279 | ||
280 | // Test labels. | |
281 | $propertyBag->setter('contactID', '100', 'original'); | |
282 | $this->assertEquals(123, $propertyBag->getContactID(), "Looks like the setter did not respect the label."); | |
283 | $this->assertEquals(100, $propertyBag->getContactID('original'), "Failed to retrieve the labelled property"); | |
284 | $this->assertEquals(100, $propertyBag->getter('contactID', FALSE, NULL, 'original'), "Failed using the getter to retrieve the labelled property"); | |
285 | ||
286 | } | |
287 | ||
47c96854 | 288 | } |