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