Merge pull request #14897 from mattwire/membership_payment2
[civicrm-core.git] / tests / phpunit / api / v3 / ProfileTest.php
CommitLineData
6a488035 1<?php
b6708aeb 2/*
3 +--------------------------------------------------------------------+
2fe49090 4| CiviCRM version 5 |
b6708aeb 5+--------------------------------------------------------------------+
6b83d5bd 6| Copyright CiviCRM LLC (c) 2004-2019 |
b6708aeb 7+--------------------------------------------------------------------+
8| This file is a part of CiviCRM. |
9| |
10| CiviCRM is free software; you can copy, modify, and distribute it |
11| under the terms of the GNU Affero General Public License |
12| Version 3, 19 November 2007 and the CiviCRM Licensing Exception. |
13| |
14| CiviCRM is distributed in the hope that it will be useful, but |
15| WITHOUT ANY WARRANTY; without even the implied warranty of |
16| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
17| See the GNU Affero General Public License for more details. |
18| |
19| You should have received a copy of the GNU Affero General Public |
20| License and the CiviCRM Licensing Exception along |
21| with this program; if not, contact CiviCRM LLC |
22| at info[AT]civicrm[DOT]org. If you have questions about the |
23| GNU Affero General Public License or the licensing of CiviCRM, |
24| see the CiviCRM license FAQ at http://civicrm.org/licensing |
25+--------------------------------------------------------------------+
e70a7fc0 26 */
6a488035 27
6a488035
TO
28/**
29 * Test APIv3 civicrm_profile_* functions
30 *
6c6e6187 31 * @package CiviCRM
acb109b7 32 * @group headless
6a488035
TO
33 */
34class api_v3_ProfileTest extends CiviUnitTestCase {
3a38ae38 35
9da2e77c 36 protected $_profileID = 0;
3a38ae38 37
174dbdd5 38 protected $_membershipTypeID;
3a38ae38 39
174dbdd5 40 protected $_contactID;
4cbe18b8 41
3a38ae38 42 /**
43 * Set up for test.
44 */
00be9182 45 public function setUp() {
6a488035
TO
46 parent::setUp();
47 $config = CRM_Core_Config::singleton();
eefea86b
TO
48 $countryLimit = $config->countryLimit;
49 $countryLimit[1] = 1013;
50 $config->countryLimit = $countryLimit;
51
9da2e77c 52 $this->createLoggedInUser();
174dbdd5 53 $this->_membershipTypeID = $this->membershipTypeCreate();
6a488035
TO
54 }
55
3a38ae38 56 /**
57 * Cleanup after test.
58 *
59 * @throws \Exception
60 */
00be9182 61 public function tearDown() {
7fbb4198 62
3a38ae38 63 $this->quickCleanup([
21170390 64 'civicrm_contact',
65 'civicrm_phone',
66 'civicrm_address',
174dbdd5
E
67 'civicrm_membership',
68 'civicrm_contribution',
225d474b 69 'civicrm_uf_match',
3a38ae38 70 ], TRUE);
71 $this->callAPISuccess('membership_type', 'delete', ['id' => $this->_membershipTypeID]);
7f6a76d2 72 CRM_Core_DAO::executeQuery(" DELETE FROM civicrm_uf_group WHERE id = $this->_profileID OR name = 'test_contact_activity_profile'");
3a38ae38 73 parent::tearDown();
6a488035
TO
74 }
75
6a488035 76 /**
eceb18cc 77 * Check Without ProfileId.
6a488035 78 */
00be9182 79 public function testProfileGetWithoutProfileId() {
3a38ae38 80 $this->callAPIFailure('profile', 'get', ['contact_id' => 1],
7fbb4198 81 'Mandatory key(s) missing from params array: profile_id'
82 );
6a488035
TO
83 }
84
85 /**
eceb18cc 86 * Check with no invalid profile Id.
6a488035 87 */
00be9182 88 public function testProfileGetInvalidProfileId() {
3a38ae38 89 $this->callAPIFailure('profile', 'get', [
90 'contact_id' => 1,
91 'profile_id' => 1000,
92 ]);
6a488035
TO
93 }
94
95 /**
eceb18cc 96 * Check with success.
6a488035 97 */
00be9182 98 public function testProfileGet() {
363544d7 99 $profileFieldValues = $this->_createIndividualContact();
d9bbb948 100 $expected = reset($profileFieldValues);
363544d7 101 $contactId = key($profileFieldValues);
3a38ae38 102 $params = [
9da2e77c 103 'profile_id' => $this->_profileID,
6a488035 104 'contact_id' => $contactId,
3a38ae38 105 ];
106 $result = $this->callAPISuccess('profile', 'get', $params)['values'];
6a488035 107 foreach ($expected as $profileField => $value) {
3a38ae38 108 $this->assertEquals($value, CRM_Utils_Array::value($profileField, $result));
6a488035 109 }
6a488035
TO
110 }
111
3a38ae38 112 /**
113 * Test getting multiple profiles.
114 */
00be9182 115 public function testProfileGetMultiple() {
363544d7 116 $profileFieldValues = $this->_createIndividualContact();
d9bbb948 117 $expected = reset($profileFieldValues);
363544d7 118 $contactId = key($profileFieldValues);
3a38ae38 119 $params = [
120 'profile_id' => [$this->_profileID, 1, 'Billing'],
f01ce56b 121 'contact_id' => $contactId,
3a38ae38 122 ];
f01ce56b 123
3a38ae38 124 $result = $this->callAPIAndDocument('profile', 'get', $params, __FUNCTION__, __FILE__)['values'];
f01ce56b 125 foreach ($expected as $profileField => $value) {
3a38ae38 126 $this->assertEquals($value, CRM_Utils_Array::value($profileField, $result[$this->_profileID]), " error message: " . "missing/mismatching value for {$profileField}");
f01ce56b 127 }
3a38ae38 128 $this->assertEquals('abc1', $result[1]['first_name'], " error message: " . "missing/mismatching value for first name");
129 $this->assertFalse(array_key_exists('email-Primary', $result[1]), 'profile 1 does not include email');
130 $this->assertEquals($result['Billing'], [
f01ce56b 131 'billing_first_name' => 'abc1',
e0efd2d0 132 'billing_middle_name' => 'J.',
f01ce56b 133 'billing_last_name' => 'xyz1',
b29f74b6 134 'billing_street_address-5' => '5 Saint Helier St',
135 'billing_city-5' => 'Gotham City',
e0efd2d0 136 'billing_state_province_id-5' => '1021',
45c30250 137 'billing_country_id-5' => '1228',
e0efd2d0 138 'billing_postal_code-5' => '90210',
139 'billing-email-5' => 'abc1.xyz1@yahoo.com',
140 'email-5' => 'abc1.xyz1@yahoo.com',
3a38ae38 141 ]);
f01ce56b 142 }
143
3a38ae38 144 /**
145 * Test getting billing profile filled using is_billing.
146 */
00be9182 147 public function testProfileGetBillingUseIsBillingLocation() {
b29f74b6 148 $individual = $this->_createIndividualContact();
92915c55 149 $contactId = key($individual);
3a38ae38 150 $this->callAPISuccess('address', 'create', [
b29f74b6 151 'is_billing' => 1,
152 'street_address' => 'is billing st',
153 'location_type_id' => 2,
154 'contact_id' => $contactId,
3a38ae38 155 ]);
b29f74b6 156
3a38ae38 157 $params = [
158 'profile_id' => [$this->_profileID, 1, 'Billing'],
b29f74b6 159 'contact_id' => $contactId,
3a38ae38 160 ];
b29f74b6 161
3a38ae38 162 $result = $this->callAPISuccess('profile', 'get', $params)['values'];
163 $this->assertEquals('abc1', $result[1]['first_name']);
164 $this->assertEquals([
b29f74b6 165 'billing_first_name' => 'abc1',
166 'billing_middle_name' => 'J.',
167 'billing_last_name' => 'xyz1',
168 'billing_street_address-5' => 'is billing st',
169 'billing_city-5' => '',
170 'billing_state_province_id-5' => '',
171 'billing_country_id-5' => '',
172 'billing-email-5' => 'abc1.xyz1@yahoo.com',
173 'email-5' => 'abc1.xyz1@yahoo.com',
174 'billing_postal_code-5' => '',
3a38ae38 175 ], $result['Billing']);
b29f74b6 176 }
177
3a38ae38 178 /**
179 * Test getting multiple profiles, including billing.
180 */
00be9182 181 public function testProfileGetMultipleHasBillingLocation() {
f01ce56b 182 $individual = $this->_createIndividualContact();
92915c55 183 $contactId = key($individual);
3a38ae38 184 $this->callAPISuccess('address', 'create', [
39b959db
SL
185 'contact_id' => $contactId,
186 'street_address' => '25 Big Street',
187 'city' => 'big city',
188 'location_type_id' => 5,
3a38ae38 189 ]);
190 $this->callAPISuccess('email', 'create', [
39b959db
SL
191 'contact_id' => $contactId,
192 'email' => 'big@once.com',
193 'location_type_id' => 2,
194 'is_billing' => 1,
3a38ae38 195 ]);
f01ce56b 196
3a38ae38 197 $params = [
198 'profile_id' => [$this->_profileID, 1, 'Billing'],
f01ce56b 199 'contact_id' => $contactId,
3a38ae38 200 ];
f01ce56b 201
363544d7 202 $result = $this->callAPISuccess('profile', 'get', $params);
f01ce56b 203 $this->assertEquals('abc1', $result['values'][1]['first_name']);
3a38ae38 204 $this->assertEquals($result['values']['Billing'], [
f01ce56b 205 'billing_first_name' => 'abc1',
e0efd2d0 206 'billing_middle_name' => 'J.',
f01ce56b 207 'billing_last_name' => 'xyz1',
208 'billing_street_address-5' => '25 Big Street',
209 'billing_city-5' => 'big city',
210 'billing_state_province_id-5' => '',
211 'billing_country_id-5' => '',
212 'billing-email-5' => 'big@once.com',
e0efd2d0 213 'email-5' => 'big@once.com',
214 'billing_postal_code-5' => '',
3a38ae38 215 ]);
f01ce56b 216 }
b29f74b6 217
5a9e1452 218 /**
3a38ae38 219 * Get Billing empty contact - this will return generic defaults.
5a9e1452 220 */
00be9182 221 public function testProfileGetBillingEmptyContact() {
1c8738dd 222 $this->callAPISuccess('Setting', 'create', ['defaultContactCountry' => 1228]);
3a38ae38 223 $params = [
224 'profile_id' => ['Billing'],
225 ];
5a9e1452 226
3a38ae38 227 $result = $this->callAPISuccess('profile', 'get', $params)['values'];
228 $this->assertEquals([
5a9e1452 229 'billing_first_name' => '',
230 'billing_middle_name' => '',
231 'billing_last_name' => '',
232 'billing_street_address-5' => '',
233 'billing_city-5' => '',
234 'billing_state_province_id-5' => '',
235 'billing_country_id-5' => '1228',
236 'billing_email-5' => '',
237 'email-5' => '',
238 'billing_postal_code-5' => '',
3a38ae38 239 ], $result['Billing']);
5a9e1452 240 }
b29f74b6 241
7fbb4198 242 /**
eceb18cc 243 * Check contact activity profile without activity id.
7fbb4198 244 */
00be9182 245 public function testContactActivityGetWithoutActivityId() {
363544d7 246 list($params) = $this->_createContactWithActivity();
6a488035
TO
247
248 unset($params['activity_id']);
363544d7 249 $this->callAPIFailure('profile', 'get', $params, 'Mandatory key(s) missing from params array: activity_id');
6a488035
TO
250 }
251
7fbb4198 252 /**
eceb18cc 253 * Check contact activity profile wrong activity id.
7fbb4198 254 */
00be9182 255 public function testContactActivityGetWrongActivityId() {
363544d7 256 list($params) = $this->_createContactWithActivity();
6a488035 257 $params['activity_id'] = 100001;
363544d7 258 $this->callAPIFailure('profile', 'get', $params, 'Invalid Activity Id (aid).');
6a488035
TO
259 }
260
c490a46a 261 /**
eceb18cc 262 * Check contact activity profile with wrong activity type.
3a38ae38 263 *
264 * @throws \Exception
c490a46a 265 */
00be9182 266 public function testContactActivityGetWrongActivityType() {
7f6a76d2 267 $activity = $this->callAPISuccess('activity', 'create', [
268 'source_contact_id' => $this->householdCreate(),
6a488035
TO
269 'activity_type_id' => '2',
270 'subject' => 'Test activity',
271 'activity_date_time' => '20110316',
272 'duration' => '120',
3a38ae38 273 'location' => 'Pennsylvania',
6a488035
TO
274 'details' => 'a test activity',
275 'status_id' => '1',
6a488035 276 'priority_id' => '1',
7f6a76d2 277 ])['values'];
6a488035 278
3a38ae38 279 $activityValues = array_pop($activity);
6a488035 280
363544d7 281 list($params) = $this->_createContactWithActivity();
6a488035
TO
282
283 $params['activity_id'] = $activityValues['id'];
363544d7 284 $this->callAPIFailure('profile', 'get', $params, 'This activity cannot be edited or viewed via this profile.');
6a488035
TO
285 }
286
c490a46a 287 /**
eceb18cc 288 * Check contact activity profile with success.
c490a46a 289 */
00be9182 290 public function testContactActivityGetSuccess() {
6a488035
TO
291 list($params, $expected) = $this->_createContactWithActivity();
292
7fbb4198 293 $result = $this->callAPISuccess('profile', 'get', $params);
6a488035
TO
294
295 foreach ($expected as $profileField => $value) {
363544d7 296 $this->assertEquals($value, CRM_Utils_Array::value($profileField, $result['values']), " error message: " . "missing/mismatching value for {$profileField}"
6a488035
TO
297 );
298 }
6a488035
TO
299 }
300
6a488035 301 /**
9dec4e61 302 * Check getfields works & gives us our fields
303 */
00be9182 304 public function testGetFields() {
9dec4e61 305 $this->_createIndividualProfile();
306 $this->_addCustomFieldToProfile($this->_profileID);
3a38ae38 307 $result = $this->callAPIAndDocument('profile', 'getfields', [
39b959db
SL
308 'action' => 'submit',
309 'profile_id' => $this->_profileID,
3a38ae38 310 ], __FUNCTION__, __FILE__,
9dec4e61 311 'demonstrates retrieving profile fields passing in an id');
312 $this->assertArrayKeyExists('first_name', $result['values']);
313 $this->assertEquals('2', $result['values']['first_name']['type']);
9da2e77c 314 $this->assertEquals('Email', $result['values']['email-primary']['title']);
9dec4e61 315 $this->assertEquals('civicrm_state_province', $result['values']['state_province-1']['pseudoconstant']['table']);
316 $this->assertEquals('defaultValue', $result['values']['custom_1']['default_value']);
317 $this->assertFalse(array_key_exists('participant_status', $result['values']));
318 }
c490a46a 319
9dec4e61 320 /**
3a38ae38 321 * Check getfields works & gives us our fields - participant profile
6a488035 322 */
00be9182 323 public function testGetFieldsParticipantProfile() {
3a38ae38 324 $result = $this->callAPISuccess('profile', 'getfields', [
39b959db
SL
325 'action' => 'submit',
326 'profile_id' => 'participant_status',
327 'get_options' => 'all',
3a38ae38 328 ]);
29fbb90a
E
329 $this->assertTrue(array_key_exists('participant_status_id', $result['values']));
330 $this->assertEquals('Attended', $result['values']['participant_status_id']['options'][2]);
3a38ae38 331 $this->assertEquals(['participant_status'], $result['values']['participant_status_id']['api.aliases']);
6a488035 332 }
b0b44427 333
334 /**
335 * Check getfields works & gives us our fields - membership_batch_entry
336 * (getting to the end with no e-notices is pretty good evidence it's working)
337 */
00be9182 338 public function testGetFieldsMembershipBatchProfile() {
3a38ae38 339 $result = $this->callAPISuccess('profile', 'getfields', [
39b959db
SL
340 'action' => 'submit',
341 'profile_id' => 'membership_batch_entry',
342 'get_options' => 'all',
3a38ae38 343 ]);
b0b44427 344 $this->assertTrue(array_key_exists('total_amount', $result['values']));
7c3f2c03 345 $this->assertTrue(array_key_exists('financial_type_id', $result['values']));
3a38ae38 346 $this->assertEquals([
39b959db
SL
347 'contribution_type_id',
348 'contribution_type',
349 'financial_type',
3a38ae38 350 ], $result['values']['financial_type_id']['api.aliases']);
7c3f2c03 351 $this->assertTrue(!array_key_exists('financial_type', $result['values']));
b0b44427 352 $this->assertEquals(12, $result['values']['receive_date']['type']);
353 }
354
355 /**
356 * Check getfields works & gives us our fields - do them all
357 * (getting to the end with no e-notices is pretty good evidence it's working)
358 */
00be9182 359 public function testGetFieldsAllProfiles() {
3a38ae38 360 $result = $this->callAPISuccess('uf_group', 'get', ['return' => 'id'])['values'];
361 $profileIDs = array_keys($result);
b0b44427 362 foreach ($profileIDs as $profileID) {
3a38ae38 363 $this->callAPISuccess('profile', 'getfields', [
39b959db
SL
364 'action' => 'submit',
365 'profile_id' => $profileID,
366 'get_options' => 'all',
3a38ae38 367 ]);
b0b44427 368 }
369 }
6a488035
TO
370
371 /**
eceb18cc 372 * Check Without ProfileId.
6a488035 373 */
00be9182 374 public function testProfileSubmitWithoutProfileId() {
3a38ae38 375 $params = [
6a488035 376 'contact_id' => 1,
3a38ae38 377 ];
363544d7 378 $this->callAPIFailure('profile', 'submit', $params,
7fbb4198 379 'Mandatory key(s) missing from params array: profile_id'
380 );
6a488035
TO
381 }
382
383 /**
eceb18cc 384 * Check with no invalid profile Id.
6a488035 385 */
00be9182 386 public function testProfileSubmitInvalidProfileId() {
3a38ae38 387 $params = [
6a488035
TO
388 'contact_id' => 1,
389 'profile_id' => 1000,
3a38ae38 390 ];
391 $this->callAPIFailure('profile', 'submit', $params);
6a488035
TO
392 }
393
394 /**
eceb18cc 395 * Check with missing required field in profile.
6a488035 396 */
00be9182 397 public function testProfileSubmitCheckProfileRequired() {
d9bbb948
CW
398 $profileFieldValues = $this->_createIndividualContact();
399 $contactId = key($profileFieldValues);
3a38ae38 400 $updateParams = [
6a488035
TO
401 'first_name' => 'abc2',
402 'last_name' => 'xyz2',
403 'phone-1-1' => '022 321 826',
404 'country-1' => '1013',
405 'state_province-1' => '1000',
3a38ae38 406 ];
6a488035 407
3a38ae38 408 $params = array_merge([
409 'profile_id' => $this->_profileID,
410 'contact_id' => $contactId,
411 ],
6a488035
TO
412 $updateParams
413 );
414
d235daf6
MM
415 $this->callAPIFailure('profile', 'submit', $params,
416 "Mandatory key(s) missing from params array: email-primary"
7fbb4198 417 );
6a488035
TO
418 }
419
420 /**
eceb18cc 421 * Check with success.
6a488035 422 */
00be9182 423 public function testProfileSubmit() {
d9bbb948
CW
424 $profileFieldValues = $this->_createIndividualContact();
425 $contactId = key($profileFieldValues);
6a488035 426
3a38ae38 427 $updateParams = [
6a488035
TO
428 'first_name' => 'abc2',
429 'last_name' => 'xyz2',
5aa090ea 430 'email-primary' => 'abc2.xyz2@gmail.com',
6a488035
TO
431 'phone-1-1' => '022 321 826',
432 'country-1' => '1013',
433 'state_province-1' => '1000',
3a38ae38 434 ];
6a488035 435
3a38ae38 436 $params = array_merge([
9da2e77c 437 'profile_id' => $this->_profileID,
21170390 438 'contact_id' => $contactId,
3a38ae38 439 ], $updateParams);
6a488035 440
363544d7 441 $this->callAPIAndDocument('profile', 'submit', $params, __FUNCTION__, __FILE__);
6a488035 442
3a38ae38 443 $getParams = [
9da2e77c 444 'profile_id' => $this->_profileID,
6a488035 445 'contact_id' => $contactId,
3a38ae38 446 ];
7fbb4198 447 $profileDetails = $this->callAPISuccess('profile', 'get', $getParams);
6a488035
TO
448
449 foreach ($updateParams as $profileField => $value) {
f5bf5e4f 450 $this->assertEquals($value, CRM_Utils_Array::value($profileField, $profileDetails['values']), "missing/mismatching value for {$profileField}"
6a488035
TO
451 );
452 }
f5bf5e4f
E
453 unset($params['email-primary']);
454 $params['email-Primary'] = 'my@mail.com';
6c6e6187 455 $this->callAPISuccess('profile', 'submit', $params);
5aa090ea 456 $profileDetails = $this->callAPISuccess('profile', 'get', $getParams);
f5bf5e4f 457 $this->assertEquals('my@mail.com', $profileDetails['values']['email-Primary']);
6a488035
TO
458 }
459
7c3f2c03
E
460 /**
461 * Ensure caches are being cleared so we don't get into a debugging trap because of cached metadata
3a38ae38 462 * First we delete & create to increment the version & then check for caching problems.
7c3f2c03 463 */
00be9182 464 public function testProfileSubmitCheckCaching() {
3a38ae38 465 $this->callAPISuccess('membership_type', 'delete', ['id' => $this->_membershipTypeID]);
7c3f2c03
E
466 $this->_membershipTypeID = $this->membershipTypeCreate();
467
3a38ae38 468 $membershipTypes = $this->callAPISuccess('membership_type', 'get', []);
469 $profileFields = $this->callAPISuccess('profile', 'getfields', [
39b959db
SL
470 'get_options' => 'all',
471 'action' => 'submit',
472 'profile_id' => 'membership_batch_entry',
3a38ae38 473 ]);
474 $getoptions = $this->callAPISuccess('membership', 'getoptions', [
39b959db
SL
475 'field' => 'membership_type',
476 'context' => 'validate',
3a38ae38 477 ]);
7c3f2c03 478 $this->assertEquals(array_keys($membershipTypes['values']), array_keys($getoptions['values']));
f5c68f3c 479 $this->assertEquals(array_keys($membershipTypes['values']), array_keys($profileFields['values']['membership_type_id']['options']));
7c3f2c03 480
6c6e6187 481 }
f5c68f3c
E
482
483 /**
eceb18cc 484 * Test that the fields are returned in the right order despite the faffing around that goes on.
f5c68f3c 485 */
00be9182 486 public function testMembershipGetFieldsOrder() {
3a38ae38 487 $result = $this->callAPISuccess('profile', 'getfields', [
39b959db
SL
488 'action' => 'submit',
489 'profile_id' => 'membership_batch_entry',
3a38ae38 490 ])['values'];
f5c68f3c 491 $weight = 1;
3a38ae38 492 foreach ($result as $fieldName => $field) {
22e263ad 493 if ($fieldName == 'profile_id') {
f5c68f3c
E
494 continue;
495 }
496 $this->assertEquals($field['weight'], $weight);
497 $weight++;
498 }
499 }
92915c55 500
7c3f2c03
E
501 /**
502 * Check we can submit membership batch profiles (create mode)
503 */
00be9182 504 public function testProfileSubmitMembershipBatch() {
7c3f2c03 505 $this->_contactID = $this->individualCreate();
3a38ae38 506 $this->callAPISuccess('profile', 'submit', [
92915c55
TO
507 'profile_id' => 'membership_batch_entry',
508 'financial_type_id' => 1,
509 'membership_type' => $this->_membershipTypeID,
510 'join_date' => 'now',
511 'total_amount' => 10,
512 'contribution_status_id' => 1,
513 'receive_date' => 'now',
514 'contact_id' => $this->_contactID,
3a38ae38 515 ]);
7c3f2c03 516 }
92915c55 517
158d3e03 518 /**
eceb18cc 519 * Set is deprecated but we need to ensure it still works.
158d3e03 520 */
00be9182 521 public function testLegacySet() {
d9bbb948
CW
522 $profileFieldValues = $this->_createIndividualContact();
523 $contactId = key($profileFieldValues);
158d3e03 524
3a38ae38 525 $updateParams = [
158d3e03 526 'first_name' => 'abc2',
527 'last_name' => 'xyz2',
528 'email-Primary' => 'abc2.xyz2@gmail.com',
529 'phone-1-1' => '022 321 826',
530 'country-1' => '1013',
531 'state_province-1' => '1000',
3a38ae38 532 ];
158d3e03 533
3a38ae38 534 $params = array_merge([
9da2e77c 535 'profile_id' => $this->_profileID,
158d3e03 536 'contact_id' => $contactId,
3a38ae38 537 ], $updateParams);
158d3e03 538
539 $result = $this->callAPISuccess('profile', 'set', $params);
540 $this->assertArrayKeyExists('values', $result);
3a38ae38 541 $getParams = [
9da2e77c 542 'profile_id' => $this->_profileID,
158d3e03 543 'contact_id' => $contactId,
3a38ae38 544 ];
158d3e03 545 $profileDetails = $this->callAPISuccess('profile', 'get', $getParams);
546
547 foreach ($updateParams as $profileField => $value) {
548 $this->assertEquals($value, CRM_Utils_Array::value($profileField, $profileDetails['values']), "In line " . __LINE__ . " error message: " . "missing/mismatching value for {$profileField}"
549 );
550 }
551 }
c490a46a
CW
552
553 /**
eceb18cc 554 * Check contact activity profile without activity id.
c490a46a 555 */
00be9182 556 public function testContactActivitySubmitWithoutActivityId() {
6a488035
TO
557 list($params, $expected) = $this->_createContactWithActivity();
558
559 $params = array_merge($params, $expected);
560 unset($params['activity_id']);
3a38ae38 561 $this->callAPIFailure('profile', 'submit', $params, 'Mandatory key(s) missing from params array: activity_id');
6a488035
TO
562 }
563
c490a46a 564 /**
eceb18cc 565 * Check contact activity profile wrong activity id.
c490a46a 566 */
00be9182 567 public function testContactActivitySubmitWrongActivityId() {
6a488035 568 list($params, $expected) = $this->_createContactWithActivity();
6a488035
TO
569 $params = array_merge($params, $expected);
570 $params['activity_id'] = 100001;
3a38ae38 571 $this->callAPIFailure('profile', 'submit', $params, 'Invalid Activity Id (aid).');
6a488035
TO
572 }
573
c490a46a 574 /**
eceb18cc 575 * Check contact activity profile with wrong activity type.
3a38ae38 576 *
577 * @throws \Exception
c490a46a 578 */
00be9182 579 public function testContactActivitySubmitWrongActivityType() {
6a488035
TO
580
581 $sourceContactId = $this->householdCreate();
582
3a38ae38 583 $activityParams = [
6a488035
TO
584 'source_contact_id' => $sourceContactId,
585 'activity_type_id' => '2',
586 'subject' => 'Test activity',
587 'activity_date_time' => '20110316',
588 'duration' => '120',
3a38ae38 589 'location' => 'Pennsylvania',
6a488035
TO
590 'details' => 'a test activity',
591 'status_id' => '1',
6a488035 592 'priority_id' => '1',
3a38ae38 593 ];
6a488035 594
3a38ae38 595 $activity = $this->callAPISuccess('activity', 'create', $activityParams);
6a488035
TO
596
597 $activityValues = array_pop($activity['values']);
598
599 list($params, $expected) = $this->_createContactWithActivity();
600
601 $params = array_merge($params, $expected);
602 $params['activity_id'] = $activityValues['id'];
363544d7 603 $this->callAPIFailure('profile', 'submit', $params,
7fbb4198 604 'This activity cannot be edited or viewed via this profile.');
6a488035
TO
605 }
606
c490a46a 607 /**
eceb18cc 608 * Check contact activity profile with success.
c490a46a 609 */
00be9182 610 public function testContactActivitySubmitSuccess() {
363544d7 611 list($params) = $this->_createContactWithActivity();
6a488035 612
3a38ae38 613 $updateParams = [
6a488035
TO
614 'first_name' => 'abc2',
615 'last_name' => 'xyz2',
616 'email-Primary' => 'abc2.xyz2@yahoo.com',
617 'activity_subject' => 'Test Meeting',
618 'activity_details' => 'a test activity details',
619 'activity_duration' => '100',
2a66c165 620 'activity_date_time' => '2010-03-08 00:00:00',
6a488035 621 'activity_status_id' => '2',
3a38ae38 622 ];
6a488035 623 $profileParams = array_merge($params, $updateParams);
c3d3e837 624 $this->callAPISuccess('profile', 'submit', $profileParams);
3a38ae38 625 $result = $this->callAPISuccess('profile', 'get', $params)['values'];
6a488035
TO
626
627 foreach ($updateParams as $profileField => $value) {
3a38ae38 628 $this->assertEquals($value, CRM_Utils_Array::value($profileField, $result), " error message: " . "missing/mismatching value for {$profileField}"
6a488035
TO
629 );
630 }
6a488035
TO
631 }
632
6a488035 633 /**
eceb18cc 634 * Check profile apply Without ProfileId.
6a488035 635 */
00be9182 636 public function testProfileApplyWithoutProfileId() {
3a38ae38 637 $params = [
6a488035 638 'contact_id' => 1,
3a38ae38 639 ];
363544d7 640 $this->callAPIFailure('profile', 'apply', $params,
7fbb4198 641 'Mandatory key(s) missing from params array: profile_id');
6a488035
TO
642 }
643
644 /**
eceb18cc 645 * Check profile apply with no invalid profile Id.
6a488035 646 */
00be9182 647 public function testProfileApplyInvalidProfileId() {
3a38ae38 648 $params = [
6a488035
TO
649 'contact_id' => 1,
650 'profile_id' => 1000,
3a38ae38 651 ];
363544d7 652 $this->callAPIFailure('profile', 'apply', $params);
6a488035
TO
653 }
654
655 /**
eceb18cc 656 * Check with success.
6a488035 657 */
00be9182 658 public function testProfileApply() {
363544d7 659 $profileFieldValues = $this->_createIndividualContact();
660 current($profileFieldValues);
661 $contactId = key($profileFieldValues);
6a488035 662
3a38ae38 663 $params = [
9da2e77c 664 'profile_id' => $this->_profileID,
6a488035 665 'contact_id' => $contactId,
6a488035
TO
666 'first_name' => 'abc2',
667 'last_name' => 'xyz2',
668 'email-Primary' => 'abc2.xyz2@gmail.com',
669 'phone-1-1' => '022 321 826',
670 'country-1' => '1013',
671 'state_province-1' => '1000',
3a38ae38 672 ];
6a488035 673
7fbb4198 674 $result = $this->callAPIAndDocument('profile', 'apply', $params, __FUNCTION__, __FILE__);
6a488035
TO
675
676 // Expected field values
3a38ae38 677 $expected['contact'] = [
6a488035
TO
678 'contact_id' => $contactId,
679 'contact_type' => 'Individual',
680 'first_name' => 'abc2',
681 'last_name' => 'xyz2',
3a38ae38 682 ];
683 $expected['email'] = [
6a488035
TO
684 'location_type_id' => 1,
685 'is_primary' => 1,
686 'email' => 'abc2.xyz2@gmail.com',
3a38ae38 687 ];
6a488035 688
3a38ae38 689 $expected['phone'] = [
6a488035
TO
690 'location_type_id' => 1,
691 'is_primary' => 1,
692 'phone_type_id' => 1,
693 'phone' => '022 321 826',
3a38ae38 694 ];
695 $expected['address'] = [
6a488035
TO
696 'location_type_id' => 1,
697 'is_primary' => 1,
698 'country_id' => 1013,
699 'state_province_id' => 1000,
3a38ae38 700 ];
6a488035
TO
701
702 foreach ($expected['contact'] as $field => $value) {
3a38ae38 703 $this->assertEquals($value, CRM_Utils_Array::value($field, $result['values']), "missing/mismatching value for {$field}"
6a488035
TO
704 );
705 }
706
3a38ae38 707 foreach (['email', 'phone', 'address'] as $fieldType) {
6a488035
TO
708 $typeValues = array_pop($result['values'][$fieldType]);
709 foreach ($expected[$fieldType] as $field => $value) {
3a38ae38 710 $this->assertEquals($value, CRM_Utils_Array::value($field, $typeValues), "missing/mismatching value for {$field} ({$fieldType})"
6a488035
TO
711 );
712 }
713 }
714 }
715
d9bbb948
CW
716 /**
717 * Check success with tags.
718 */
719 public function testSubmitWithTags() {
720 $profileFieldValues = $this->_createIndividualContact();
721 $params = reset($profileFieldValues);
722 $contactId = key($profileFieldValues);
723 $params['profile_id'] = $this->_profileID;
724 $params['contact_id'] = $contactId;
725
3a38ae38 726 $this->callAPISuccess('ufField', 'create', [
d9bbb948
CW
727 'uf_group_id' => $this->_profileID,
728 'field_name' => 'tag',
729 'visibility' => 'Public Pages and Listings',
730 'field_type' => 'Contact',
731 'label' => 'Tags',
3a38ae38 732 ]);
d9bbb948
CW
733
734 $tag_1 = $this->callAPISuccess('tag', 'create', ['name' => 'abc'])['id'];
735 $tag_2 = $this->callAPISuccess('tag', 'create', ['name' => 'def'])['id'];
736
737 $params['tag'] = "$tag_1,$tag_2";
3a38ae38 738 $this->callAPISuccess('profile', 'submit', $params);
d9bbb948
CW
739
740 $tags = $this->callAPISuccess('entityTag', 'get', ['entity_id' => $contactId]);
741 $this->assertEquals(2, $tags['count']);
742
743 $params['tag'] = [$tag_1];
3a38ae38 744 $this->callAPISuccess('profile', 'submit', $params);
d9bbb948
CW
745
746 $tags = $this->callAPISuccess('entityTag', 'get', ['entity_id' => $contactId]);
747 $this->assertEquals(1, $tags['count']);
ab1a5ce2
CW
748
749 $params['tag'] = '';
3a38ae38 750 $this->callAPISuccess('profile', 'submit', $params);
ab1a5ce2
CW
751
752 $tags = $this->callAPISuccess('entityTag', 'get', ['entity_id' => $contactId]);
753 $this->assertEquals(0, $tags['count']);
4ffb408d 754
d9bbb948
CW
755 }
756
757 /**
758 * Check success with a note.
3a38ae38 759 *
760 * @throws \Exception
d9bbb948
CW
761 */
762 public function testSubmitWithNote() {
763 $profileFieldValues = $this->_createIndividualContact();
764 $params = reset($profileFieldValues);
765 $contactId = key($profileFieldValues);
766 $params['profile_id'] = $this->_profileID;
767 $params['contact_id'] = $contactId;
768
3a38ae38 769 $this->callAPISuccess('ufField', 'create', [
d9bbb948
CW
770 'uf_group_id' => $this->_profileID,
771 'field_name' => 'note',
772 'visibility' => 'Public Pages and Listings',
773 'field_type' => 'Contact',
774 'label' => 'Note',
3a38ae38 775 ]);
d9bbb948
CW
776
777 $params['note'] = "Hello 123";
778 $this->callAPISuccess('profile', 'submit', $params);
779
780 $note = $this->callAPISuccessGetSingle('note', ['entity_id' => $contactId]);
781 $this->assertEquals("Hello 123", $note['note']);
782 }
783
93878a99
CW
784 /**
785 * Check handling a custom greeting.
3a38ae38 786 *
787 * @throws \CiviCRM_API3_Exception
93878a99
CW
788 */
789 public function testSubmitGreetingFields() {
790 $profileFieldValues = $this->_createIndividualContact();
791 $params = reset($profileFieldValues);
792 $contactId = key($profileFieldValues);
793 $params['profile_id'] = $this->_profileID;
794 $params['contact_id'] = $contactId;
795
3a38ae38 796 $this->callAPISuccess('ufField', 'create', [
93878a99
CW
797 'uf_group_id' => $this->_profileID,
798 'field_name' => 'email_greeting',
799 'visibility' => 'Public Pages and Listings',
800 'field_type' => 'Contact',
801 'label' => 'Email Greeting',
3a38ae38 802 ]);
93878a99
CW
803
804 $emailGreetings = array_column(civicrm_api3('OptionValue', 'get', ['option_group_id' => "email_greeting"])['values'], NULL, 'name');
805
806 $params['email_greeting'] = $emailGreetings['Customized']['value'];
807 // Custom greeting should be required
808 $this->callAPIFailure('profile', 'submit', $params);
809
810 $params['email_greeting_custom'] = 'Hello fool!';
811 $this->callAPISuccess('profile', 'submit', $params);
812
813 // Api3 will not return custom greeting field so resorting to this
814 $greeting = CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_Contact', $contactId, 'email_greeting_custom');
815
816 $this->assertEquals("Hello fool!", $greeting);
817 }
818
4cbe18b8 819 /**
c490a46a 820 * Helper function to create an Individual with address/email/phone info. Import UF Group and UF Fields
3a38ae38 821 *
4cbe18b8
EM
822 * @param array $params
823 *
824 * @return mixed
825 */
3a38ae38 826 public function _createIndividualContact($params = []) {
827 $contactParams = array_merge([
39b959db
SL
828 'first_name' => 'abc1',
829 'last_name' => 'xyz1',
830 'email' => 'abc1.xyz1@yahoo.com',
3a38ae38 831 'api.address.create' => [
39b959db
SL
832 'location_type_id' => 1,
833 'is_primary' => 1,
834 'street_address' => '5 Saint Helier St',
835 'county' => 'Marin',
836 'country' => 'UNITED STATES',
837 'state_province' => 'Michigan',
838 'supplemental_address_1' => 'Hallmark Ct',
839 'supplemental_address_2' => 'Jersey Village',
840 'supplemental_address_3' => 'My Town',
841 'postal_code' => '90210',
842 'city' => 'Gotham City',
843 'is_billing' => 0,
3a38ae38 844 ],
845 'api.phone.create' => [
39b959db
SL
846 'location_type_id' => '1',
847 'phone' => '021 512 755',
848 'phone_type_id' => '1',
849 'is_primary' => '1',
3a38ae38 850 ],
851 ], $params);
6a488035 852
174dbdd5 853 $this->_contactID = $this->individualCreate($contactParams);
9dec4e61 854 $this->_createIndividualProfile();
6a488035 855 // expected result of above created profile with contact Id $contactId
3a38ae38 856 $profileData[$this->_contactID] = [
6a488035
TO
857 'first_name' => 'abc1',
858 'last_name' => 'xyz1',
9da2e77c 859 'email-primary' => 'abc1.xyz1@yahoo.com',
6a488035
TO
860 'phone-1-1' => '021 512 755',
861 'country-1' => '1228',
862 'state_province-1' => '1021',
3a38ae38 863 ];
6a488035
TO
864
865 return $profileData;
866 }
867
4cbe18b8
EM
868 /**
869 * @return array
870 */
00be9182 871 public function _createContactWithActivity() {
7f6a76d2 872 $ufGroupID = $this->callAPISuccess('UFGroup', 'create', [
873 'group_type' => 'Individual,Contact,Activity',
874 'title' => 'Test Contact-Activity Profile',
875 'name' => 'test_contact_activity_profile',
876 ])['id'];
877 $this->callAPISuccess('UFField', 'create', [
878 'uf_group_id' => $ufGroupID,
879 'field_name' => 'first_name',
880 'is_required' => TRUE,
881 'visibility' => 'Public Pages and Listings',
882 'label' => 'First Name',
883 'field_type' => 'Individual',
884 ]);
885 $this->callAPISuccess('UFField', 'create', [
886 'uf_group_id' => $ufGroupID,
887 'field_name' => 'last_name',
888 'is_required' => TRUE,
889 'visibility' => 'Public Pages and Listings',
890 'label' => 'Last Name',
891 'field_type' => 'Individual',
892 ]);
893 $this->callAPISuccess('UFField', 'create', [
894 'uf_group_id' => $ufGroupID,
895 'field_name' => 'email',
896 'is_required' => TRUE,
897 'visibility' => 'Public Pages and Listings',
898 'label' => 'Email',
899 'field_type' => 'Contact',
900 ]);
901 $this->callAPISuccess('UFField', 'create', [
902 'uf_group_id' => $ufGroupID,
903 'field_name' => 'activity_subject',
904 'is_required' => TRUE,
905 'visibility' => 'Public Pages and Listings',
906 'label' => 'Activity Subject',
907 'is_searchable' => TRUE,
908 'field_type' => 'Activity',
909 ]);
910 $this->callAPISuccess('UFField', 'create', [
911 'uf_group_id' => $ufGroupID,
912 'field_name' => 'activity_details',
913 'is_required' => TRUE,
914 'visibility' => 'Public Pages and Listings',
915 'label' => 'Activity Details',
916 'is_searchable' => TRUE,
917 'field_type' => 'Activity',
918 ]);
919 $this->callAPISuccess('UFField', 'create', [
920 'uf_group_id' => $ufGroupID,
921 'field_name' => 'activity_duration',
922 'is_required' => TRUE,
923 'visibility' => 'Public Pages and Listings',
924 'label' => 'Activity Duration',
925 'is_searchable' => TRUE,
926 'field_type' => 'Activity',
927 ]);
928 $this->callAPISuccess('UFField', 'create', [
929 'uf_group_id' => $ufGroupID,
930 'field_name' => 'activity_date_time',
931 'is_required' => TRUE,
932 'visibility' => 'Public Pages and Listings',
933 'label' => 'Activity Date',
934 'is_searchable' => TRUE,
935 'field_type' => 'Activity',
936 ]);
937 $this->callAPISuccess('UFField', 'create', [
938 'uf_group_id' => $ufGroupID,
939 'field_name' => 'activity_status_id',
940 'is_required' => TRUE,
941 'visibility' => 'Public Pages and Listings',
942 'label' => 'Activity Status',
943 'is_searchable' => TRUE,
944 'field_type' => 'Activity',
945 ]);
946
947 // hack: xml data set did not accept \ 1 (CRM_Core_DAO::VALUE_SEPARATOR) - should be possible
948 // to unhack now we use the api.
949 CRM_Core_DAO::setFieldValue('CRM_Core_DAO_UFGroup', $ufGroupID, 'group_type', 'Individual,Contact,Activity' . CRM_Core_DAO::VALUE_SEPARATOR . 'ActivityType:1');
6a488035
TO
950
951 $sourceContactId = $this->individualCreate();
3a38ae38 952 $contactParams = [
6a488035
TO
953 'first_name' => 'abc1',
954 'last_name' => 'xyz1',
955 'contact_type' => 'Individual',
956 'email' => 'abc1.xyz1@yahoo.com',
3a38ae38 957 'api.address.create' => [
6a488035
TO
958 'location_type_id' => 1,
959 'is_primary' => 1,
960 'name' => 'Saint Helier St',
961 'county' => 'Marin',
86797006 962 'country' => 'UNITED STATES',
6a488035
TO
963 'state_province' => 'Michigan',
964 'supplemental_address_1' => 'Hallmark Ct',
965 'supplemental_address_2' => 'Jersey Village',
207f62c6 966 'supplemental_address_3' => 'My Town',
3a38ae38 967 ],
968 ];
6a488035 969
7fbb4198 970 $contact = $this->callAPISuccess('contact', 'create', $contactParams);
6a488035
TO
971
972 $keys = array_keys($contact['values']);
973 $contactId = array_pop($keys);
974
363544d7 975 $this->assertEquals(0, $contact['values'][$contactId]['api.address.create']['is_error'], " error message: " . CRM_Utils_Array::value('error_message', $contact['values'][$contactId]['api.address.create'])
6a488035
TO
976 );
977
3a38ae38 978 $activityParams = [
6a488035
TO
979 'source_contact_id' => $sourceContactId,
980 'assignee_contact_id' => $contactId,
981 'activity_type_id' => '1',
982 'subject' => 'Make-it-Happen Meeting',
2a66c165 983 'activity_date_time' => '2011-03-16 00:00:00',
6a488035 984 'duration' => '120',
3a38ae38 985 'location' => 'Pennsylvania',
6a488035
TO
986 'details' => 'a test activity',
987 'status_id' => '1',
6a488035 988 'priority_id' => '1',
3a38ae38 989 ];
7fbb4198 990 $activity = $this->callAPISuccess('activity', 'create', $activityParams);
6a488035
TO
991
992 $activityValues = array_pop($activity['values']);
993
994 // valid parameters for above profile
3a38ae38 995 $profileParams = [
7f6a76d2 996 'profile_id' => $ufGroupID,
6a488035
TO
997 'contact_id' => $contactId,
998 'activity_id' => $activityValues['id'],
3a38ae38 999 ];
6a488035
TO
1000
1001 // expected result of above created profile
3a38ae38 1002 $expected = [
6a488035
TO
1003 'first_name' => 'abc1',
1004 'last_name' => 'xyz1',
1005 'email-Primary' => 'abc1.xyz1@yahoo.com',
1006 'activity_subject' => 'Make-it-Happen Meeting',
1007 'activity_details' => 'a test activity',
1008 'activity_duration' => '120',
2a66c165 1009 'activity_date_time' => '2011-03-16 00:00:00',
6a488035 1010 'activity_status_id' => '1',
3a38ae38 1011 ];
6a488035 1012
3a38ae38 1013 return [$profileParams, $expected];
6a488035 1014 }
92915c55 1015
9dec4e61 1016 /**
eceb18cc 1017 * Create a profile.
9dec4e61 1018 */
00be9182 1019 public function _createIndividualProfile() {
3a38ae38 1020 $ufGroupParams = [
363544d7 1021 'group_type' => 'Individual,Contact',
1022 // really we should remove this & test the ufField create sets it
9da2e77c
E
1023 'name' => 'test_individual_contact_profile',
1024 'title' => 'Flat Coffee',
3a38ae38 1025 'api.uf_field.create' => [
1026 [
9da2e77c
E
1027 'field_name' => 'first_name',
1028 'is_required' => 1,
1029 'visibility' => 'Public Pages and Listings',
1030 'field_type' => 'Individual',
91d8fc8a 1031 'label' => 'First Name',
3a38ae38 1032 ],
1033 [
9da2e77c
E
1034 'field_name' => 'last_name',
1035 'is_required' => 1,
1036 'visibility' => 'Public Pages and Listings',
1037 'field_type' => 'Individual',
91d8fc8a 1038 'label' => 'Last Name',
3a38ae38 1039 ],
1040 [
9da2e77c
E
1041 'field_name' => 'email',
1042 'is_required' => 1,
1043 'visibility' => 'Public Pages and Listings',
1044 'field_type' => 'Contact',
1045 'label' => 'Email',
3a38ae38 1046 ],
1047 [
9da2e77c
E
1048 'field_name' => 'phone',
1049 'is_required' => 1,
1050 'visibility' => 'Public Pages and Listings',
1051 'field_type' => 'Contact',
1052 'location_type_id' => 1,
1053 'phone_type_id' => 1,
21dfd5f5 1054 'label' => 'Phone',
3a38ae38 1055 ],
1056 [
9da2e77c
E
1057 'field_name' => 'country',
1058 'is_required' => 1,
1059 'visibility' => 'Public Pages and Listings',
1060 'field_type' => 'Contact',
1061 'location_type_id' => 1,
21dfd5f5 1062 'label' => 'Country',
3a38ae38 1063 ],
1064 [
9da2e77c
E
1065 'field_name' => 'state_province',
1066 'is_required' => 1,
1067 'visibility' => 'Public Pages and Listings',
1068 'field_type' => 'Contact',
1069 'location_type_id' => 1,
21dfd5f5 1070 'label' => 'State Province',
3a38ae38 1071 ],
1072 [
9da2e77c
E
1073 'field_name' => 'postal_code',
1074 'is_required' => 0,
1075 'field_type' => 'Contact',
1076 'location_type_id' => 1,
21dfd5f5 1077 'label' => 'State Province',
3a38ae38 1078 ],
1079 ],
1080 ];
9da2e77c
E
1081 $profile = $this->callAPISuccess('uf_group', 'create', $ufGroupParams);
1082 $this->_profileID = $profile['id'];
9dec4e61 1083 }
1084
4cbe18b8 1085 /**
100fef9d 1086 * @param int $profileID
4cbe18b8 1087 */
00be9182 1088 public function _addCustomFieldToProfile($profileID) {
9dec4e61 1089 $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__, '');
3a38ae38 1090 $this->uFFieldCreate([
39b959db
SL
1091 'uf_group_id' => $profileID,
1092 'field_name' => 'custom_' . $ids['custom_field_id'],
1093 'contact_type' => 'Contact',
3a38ae38 1094 ]);
9dec4e61 1095 }
96025800 1096
6a488035 1097}