profile api test fixes (caching & case on entities)
[civicrm-core.git] / tests / phpunit / api / v3 / ProfileTest.php
index f84d71cf2c6012c2723d35351e0e121a0e250219..ee587565257f9ef7d47567aac3042c8566a6ee19 100644 (file)
@@ -38,6 +38,9 @@ require_once 'tests/phpunit/CiviTest/CiviUnitTestCase.php';
  */
 class api_v3_ProfileTest extends CiviUnitTestCase {
   protected $_apiversion;
+  protected $_profileID = 0;
+  protected $_membershipTypeID;
+  protected $_contactID;
   function get_info() {
     return array(
       'name' => 'Profile Test',
@@ -52,17 +55,22 @@ class api_v3_ProfileTest extends CiviUnitTestCase {
     $config = CRM_Core_Config::singleton();
     $config->countryLimit[1] = 1013;
     $config->stateLimit[1] = 1013;
+    $this->createLoggedInUser();
+    $this->_membershipTypeID = $this->membershipTypeCreate();
   }
 
   function tearDown() {
 
     $this->quickCleanup(array(
-        'civicrm_contact',
-        'civicrm_phone',
-        'civicrm_address',
-      ), TRUE);
+      'civicrm_contact',
+      'civicrm_phone',
+      'civicrm_address',
+      'civicrm_membership',
+      'civicrm_contribution',
+    ), TRUE);
+    $this->callAPISuccess('membership_type', 'delete', array('id' => $this->_membershipTypeID));
     // ok can't be bothered wring an api to do this & truncating is crazy
-    CRM_Core_DAO::executeQuery(' DELETE FROM civicrm_uf_group WHERE id IN (25, 26)');
+    CRM_Core_DAO::executeQuery(" DELETE FROM civicrm_uf_group WHERE id IN ($this->_profileID, 26)");
   }
 
   ////////////// test $this->callAPISuccess3_profile_get //////////////////
@@ -98,13 +106,12 @@ class api_v3_ProfileTest extends CiviUnitTestCase {
     $expected          = current($pofileFieldValues);
     $contactId         = key($pofileFieldValues);
     $params            = array(
-      'profile_id' => 25,
+      'profile_id' => $this->_profileID,
       'contact_id' => $contactId,
     );
     $result = $this->callAPISuccess('profile', 'get', $params);
     foreach ($expected as $profileField => $value) {
-      $this->assertEquals($value, CRM_Utils_Array::value($profileField, $result['values']), "In line " . __LINE__ . " error message: " . "missing/mismatching value for {$profileField}"
-      );
+      $this->assertEquals($value, CRM_Utils_Array::value($profileField, $result['values']));
     }
   }
 
@@ -113,13 +120,13 @@ class api_v3_ProfileTest extends CiviUnitTestCase {
     $expected          = current($pofileFieldValues);
     $contactId         = key($pofileFieldValues);
     $params            = array(
-      'profile_id' => array(25, 1, 'Billing'),
+      'profile_id' => array($this->_profileID, 1, 'Billing'),
       'contact_id' => $contactId,
     );
 
     $result = $this->callAPIAndDocument('profile', 'get', $params, __FUNCTION__, __FILE__);
     foreach ($expected as $profileField => $value) {
-      $this->assertEquals($value, CRM_Utils_Array::value($profileField, $result['values'][25]), " error message: " . "missing/mismatching value for {$profileField}");
+      $this->assertEquals($value, CRM_Utils_Array::value($profileField, $result['values'][$this->_profileID]), " error message: " . "missing/mismatching value for {$profileField}");
     }
     $this->assertEquals('abc1', $result['values'][1]['first_name'], " error message: " . "missing/mismatching value for {$profileField}");
     $this->assertFalse(array_key_exists('email-Primary', $result['values'][1]), 'profile 1 doesn not include email');
@@ -127,10 +134,10 @@ class api_v3_ProfileTest extends CiviUnitTestCase {
       'billing_first_name' => 'abc1',
       'billing_middle_name' => 'J.',
       'billing_last_name' => 'xyz1',
-      'billing_street_address-5' => '',
-      'billing_city-5' => '',
+      'billing_street_address-5' => '5 Saint Helier St',
+      'billing_city-5' => 'Gotham City',
       'billing_state_province_id-5' => '1021',
-      'billing_country_id-5' => '',
+      'billing_country_id-5' => '1228',
       'billing-email-5' => 'abc1.xyz1@yahoo.com',
       'billing_postal_code-5' => '90210',
       'billing-email-5' => 'abc1.xyz1@yahoo.com',
@@ -138,6 +145,39 @@ class api_v3_ProfileTest extends CiviUnitTestCase {
     ));
   }
 
+  function testProfileGetBillingUseIsBillingLocation() {
+    $individual = $this->_createIndividualContact();
+    $contactId  = key($individual);
+    $this->callAPISuccess('address', 'create', array(
+      'is_billing' => 1,
+      'street_address' => 'is billing st',
+      'location_type_id' => 2,
+      'contact_id' => $contactId,
+    ));
+
+    $expected = current($individual);
+
+    $params = array(
+      'profile_id' => array($this->_profileID, 1, 'Billing'),
+      'contact_id' => $contactId,
+    );
+
+    $result = $this->callAPISuccess('profile', 'get', $params);
+    $this->assertEquals('abc1', $result['values'][1]['first_name']);
+    $this->assertEquals(array(
+      'billing_first_name' => 'abc1',
+      'billing_middle_name' => 'J.',
+      'billing_last_name' => 'xyz1',
+      'billing_street_address-5' => 'is billing st',
+      'billing_city-5' => '',
+      'billing_state_province_id-5' => '',
+      'billing_country_id-5' => '',
+      'billing-email-5' => 'abc1.xyz1@yahoo.com',
+      'email-5' => 'abc1.xyz1@yahoo.com',
+      'billing_postal_code-5' => '',
+    ), $result['values']['Billing']);
+  }
+
   function testProfileGetMultipleHasBillingLocation() {
     $individual = $this->_createIndividualContact();
     $contactId  = key($individual);
@@ -147,7 +187,7 @@ class api_v3_ProfileTest extends CiviUnitTestCase {
     $expected = current($individual);
 
     $params = array(
-      'profile_id' => array(25, 1, 'Billing'),
+      'profile_id' => array($this->_profileID, 1, 'Billing'),
       'contact_id' => $contactId,
     );
 
@@ -166,6 +206,31 @@ class api_v3_ProfileTest extends CiviUnitTestCase {
       'billing_postal_code-5' => '',
     ));
   }
+
+  /**
+   * get Billing empty contact - this will return generic defaults
+   */
+  function testProfileGetBillingEmptyContact() {
+
+    $params = array(
+      'profile_id' => array('Billing'),
+    );
+
+    $result = $this->callAPISuccess('profile', 'get', $params);
+    $this->assertEquals(array(
+      'billing_first_name' => '',
+      'billing_middle_name' => '',
+      'billing_last_name' => '',
+      'billing_street_address-5' => '',
+      'billing_city-5' => '',
+      'billing_state_province_id-5' => '',
+      'billing_country_id-5' => '1228',
+      'billing_email-5' => '',
+      'email-5' => '',
+      'billing_postal_code-5' => '',
+    ), $result['values']['Billing']);
+  }
+
   /**
    * check contact activity profile without activity id
    */
@@ -185,7 +250,7 @@ class api_v3_ProfileTest extends CiviUnitTestCase {
 
     $params['activity_id'] = 100001;
     $result = $this->callAPIFailure('profile', 'get', $params,
-       'Invalid Activity Id (aid).');
+      'Invalid Activity Id (aid).');
   }
 
   /*
@@ -235,25 +300,73 @@ class api_v3_ProfileTest extends CiviUnitTestCase {
     }
   }
 
-  /////////////// test $this->callAPISuccess3_profile_set //////////////////
+  /**
+   * Check getfields works & gives us our fields
+   */
+  function testGetFields() {
+    $this->_createIndividualProfile();
+    $this->_addCustomFieldToProfile($this->_profileID);
+    $result = $this->callAPIAndDocument('profile', 'getfields', array('action' => 'submit', 'profile_id' => $this->_profileID), __FUNCTION__, __FILE__,
+      'demonstrates retrieving profile fields passing in an id');
+    $this->assertArrayKeyExists('first_name', $result['values']);
+    $this->assertEquals('2', $result['values']['first_name']['type']);
+    $this->assertEquals('Email', $result['values']['email-primary']['title']);
+    $this->assertEquals('civicrm_state_province', $result['values']['state_province-1']['pseudoconstant']['table']);
+    $this->assertEquals('defaultValue', $result['values']['custom_1']['default_value']);
+    $this->assertFalse(array_key_exists('participant_status', $result['values']));
+  }
+  /**
+   * Check getfields works & gives us our fields - partipant profile
+   */
+  function testGetFieldsParticipantProfile() {
+    $result = $this->callAPISuccess('profile', 'getfields', array(
+      'action' => 'submit',
+      'profile_id' => 'participant_status',
+      'get_options' => 'all')
+    );
+    $this->assertTrue(array_key_exists('participant_status', $result['values']));
+    $this->assertEquals('Attended', $result['values']['participant_status']['options'][2]);
+  }
 
   /**
-   * check with no array
+   * Check getfields works & gives us our fields - membership_batch_entry
+   * (getting to the end with no e-notices is pretty good evidence it's working)
    */
-  function testProfileSetNoArray() {
-    $params = NULL;
-    $result = $this->callAPIFailure('profile', 'set', $params);
-    $this->assertEquals($result['error_message'], 'Input variable `params` is not an array');
+  function testGetFieldsMembershipBatchProfile() {
+    $result = $this->callAPISuccess('profile', 'getfields', array(
+      'action' => 'submit',
+      'profile_id' => 'membership_batch_entry',
+      'get_options' => 'all')
+    );
+    $this->assertTrue(array_key_exists('total_amount', $result['values']));
+    $this->assertEquals(12, $result['values']['receive_date']['type']);
   }
 
+  /**
+   * Check getfields works & gives us our fields - do them all
+   * (getting to the end with no e-notices is pretty good evidence it's working)
+   */
+  function testGetFieldsAllProfiles() {
+    $result = $this->callAPISuccess('uf_group', 'get', array('return' => 'id'));
+    $profileIDs = array_keys($result['values']);
+    foreach ($profileIDs as $profileID) {
+      $result = $this->callAPISuccess('profile', 'getfields', array(
+        'action' => 'submit',
+        'profile_id' => $profileID,
+        'get_options' => 'all')
+      );
+    }
+  }
+  /////////////// test $this->callAPISuccess3_profile_set //////////////////
+
   /**
    * check Without ProfileId
    */
-  function testProfileSetWithoutProfileId() {
+  function testProfileSubmitWithoutProfileId() {
     $params = array(
       'contact_id' => 1,
     );
-    $result = $this->callAPIFailure('profile', 'set', $params,
+    $result = $this->callAPIFailure('profile', 'submit', $params,
       'Mandatory key(s) missing from params array: profile_id'
     );
   }
@@ -261,18 +374,18 @@ class api_v3_ProfileTest extends CiviUnitTestCase {
   /**
    * check with no invalid profile Id
    */
-  function testProfileSetInvalidProfileId() {
+  function testProfileSubmitInvalidProfileId() {
     $params = array(
       'contact_id' => 1,
       'profile_id' => 1000,
     );
-    $result = $this->callAPIFailure('profile', 'set', $params);
+    $result = $this->callAPIFailure('profile', 'submit', $params);
   }
 
   /**
    * check with missing required field in profile
    */
-  function testProfileSetCheckProfileRequired() {
+  function testProfileSubmitCheckProfileRequired() {
     $pofileFieldValues = $this->_createIndividualContact();
     current($pofileFieldValues);
     $contactId = key($pofileFieldValues);
@@ -284,19 +397,19 @@ class api_v3_ProfileTest extends CiviUnitTestCase {
       'state_province-1' => '1000',
     );
 
-    $params = array_merge(array('profile_id' => 25, 'contact_id' => $contactId),
+    $params = array_merge(array('profile_id' => $this->_profileID, 'contact_id' => $contactId),
       $updateParams
     );
 
-    $result = $this->callAPIFailure('profile', 'set', $params,
-      'Missing required parameters for profile id 25: email-Primary'
+    $result = $this->callAPIFailure('profile', 'submit', $params,
+      "Missing required parameters for profile id $this->_profileID: email-Primary"
     );
   }
 
   /**
    * check with success
    */
-  function testProfileSet() {
+  function testProfileSubmit() {
     $pofileFieldValues = $this->_createIndividualContact();
     current($pofileFieldValues);
     $contactId = key($pofileFieldValues);
@@ -304,63 +417,98 @@ class api_v3_ProfileTest extends CiviUnitTestCase {
     $updateParams = array(
       'first_name' => 'abc2',
       'last_name' => 'xyz2',
-      'email-Primary' => 'abc2.xyz2@gmail.com',
+      'email-primary' => 'abc2.xyz2@gmail.com',
       'phone-1-1' => '022 321 826',
       'country-1' => '1013',
       'state_province-1' => '1000',
     );
 
     $params = array_merge(array(
-        'profile_id' => 25,
-        'contact_id' => $contactId,
-      ), $updateParams);
+      'profile_id' => $this->_profileID,
+      'contact_id' => $contactId,
+    ), $updateParams);
 
-    $result = $this->callAPIAndDocument('profile', 'set', $params, __FUNCTION__, __FILE__);
+    $result = $this->callAPIAndDocument('profile', 'submit', $params, __FUNCTION__, __FILE__);
 
     $getParams = array(
-      'profile_id' => 25,
+      'profile_id' => $this->_profileID,
       'contact_id' => $contactId,
     );
     $profileDetails = $this->callAPISuccess('profile', 'get', $getParams);
 
     foreach ($updateParams as $profileField => $value) {
-      $this->assertEquals($value, CRM_Utils_Array::value($profileField, $profileDetails['values']), "In line " . __LINE__ . " error message: " . "missing/mismatching value for {$profileField}"
+      $this->assertEquals($value, CRM_Utils_Array::value($profileField, $profileDetails['values']), "missing/mismatching value for {$profileField}"
       );
     }
+    unset($params['email-primary']);
+    $params['email-Primary'] = 'my@mail.com';
+    $this->callAPISuccess('profile', 'submit',  $params);
+    $profileDetails = $this->callAPISuccess('profile', 'get', $getParams);
+    $this->assertEquals('my@mail.com', $profileDetails['values']['email-Primary']);
   }
 
+  /**
+   * set is deprecated but we need to ensure it still works
+   */
+  function testLegacySet() {
+    $pofileFieldValues = $this->_createIndividualContact();
+    current($pofileFieldValues);
+    $contactId = key($pofileFieldValues);
+
+    $updateParams = array(
+      'first_name' => 'abc2',
+      'last_name' => 'xyz2',
+      'email-Primary' => 'abc2.xyz2@gmail.com',
+      'phone-1-1' => '022 321 826',
+      'country-1' => '1013',
+      'state_province-1' => '1000',
+    );
+
+    $params = array_merge(array(
+      'profile_id' => $this->_profileID,
+      'contact_id' => $contactId,
+    ), $updateParams);
+
+    $result = $this->callAPISuccess('profile', 'set', $params);
+    $this->assertArrayKeyExists('values', $result);
+    $getParams = array(
+      'profile_id' => $this->_profileID,
+      'contact_id' => $contactId,
+    );
+    $profileDetails = $this->callAPISuccess('profile', 'get', $getParams);
+
+    foreach ($updateParams as $profileField => $value) {
+      $this->assertEquals($value, CRM_Utils_Array::value($profileField, $profileDetails['values']), "In line " . __LINE__ . " error message: " . "missing/mismatching value for {$profileField}"
+      );
+    }
+  }
   /*
      * check contact activity profile without activity id
      */
-  function testContactActivitySetWithoutActivityId() {
+  function testContactActivitySubmitWithoutActivityId() {
     list($params, $expected) = $this->_createContactWithActivity();
 
     $params = array_merge($params, $expected);
     unset($params['activity_id']);
-    $result = $this->callAPIFailure('profile', 'set', $params);
+    $result = $this->callAPIFailure('profile', 'submit', $params);
     $this->assertEquals($result['error_message'], 'Mandatory key(s) missing from params array: activity_id');
-
-    $this->quickCleanup(array('civicrm_uf_field', 'civicrm_uf_join', 'civicrm_uf_group', 'civicrm_custom_field', 'civicrm_custom_group', 'civicrm_contact'));
   }
 
   /*
      * check contact activity profile wrong activity id
      */
-  function testContactActivitySetWrongActivityId() {
+  function testContactActivitySubmitWrongActivityId() {
     list($params, $expected) = $this->_createContactWithActivity();
-
     $params = array_merge($params, $expected);
     $params['activity_id'] = 100001;
-    $result = $this->callAPIFailure('profile', 'set', $params);
+    $result = $this->callAPIFailure('profile', 'submit', $params);
     $this->assertEquals($result['error_message'], 'Invalid Activity Id (aid).');
-
-    $this->quickCleanup(array('civicrm_uf_field', 'civicrm_uf_join', 'civicrm_uf_group', 'civicrm_custom_field', 'civicrm_custom_group', 'civicrm_contact'));
   }
 
   /*
      * check contact activity profile with wrong activity type
      */
-  function testContactActivitySetWrongActivityType() {
+  function testContactActivitySubmitWrongActivityType() {
     //flush cache by calling with reset
     $activityTypes = CRM_Core_PseudoConstant::activityType(TRUE, TRUE, TRUE, 'name', TRUE);
 
@@ -386,14 +534,14 @@ class api_v3_ProfileTest extends CiviUnitTestCase {
 
     $params = array_merge($params, $expected);
     $params['activity_id'] = $activityValues['id'];
-    $result = $this->callAPIFailure('profile', 'set', $params,
+    $result = $this->callAPIFailure('profile', 'submit', $params,
       'This activity cannot be edited or viewed via this profile.');
   }
 
   /*
      * check contact activity profile with success
      */
-  function testContactActivitySetSuccess() {
+  function testContactActivitySubmitSuccess() {
     list($params, $expected) = $this->_createContactWithActivity();
 
     $updateParams = array(
@@ -407,8 +555,8 @@ class api_v3_ProfileTest extends CiviUnitTestCase {
       'activity_status_id' => '2',
     );
     $profileParams = array_merge($params, $updateParams);
-    $profile       = $this->callAPISuccess('profile', 'set', $profileParams);
-    $result        = $this->callAPISuccess('profile', 'get', $params);
+    $this->callAPISuccess('profile', 'submit', $profileParams);
+    $result = $this->callAPISuccess('profile', 'get', $params);
 
     foreach ($updateParams as $profileField => $value) {
       $this->assertEquals($value, CRM_Utils_Array::value($profileField, $result['values']), "In line " . __LINE__ . " error message: " . "missing/mismatching value for {$profileField}"
@@ -447,7 +595,7 @@ class api_v3_ProfileTest extends CiviUnitTestCase {
     $contactId = key($pofileFieldValues);
 
     $params = array(
-      'profile_id' => 25,
+      'profile_id' => $this->_profileID,
       'contact_id' => $contactId,
       'first_name' => 'abc2',
       'last_name' => 'xyz2',
@@ -511,13 +659,15 @@ class api_v3_ProfileTest extends CiviUnitTestCase {
       'api.address.create' => array(
         'location_type_id' => 1,
         'is_primary' => 1,
-        'name' => 'Saint Helier St',
+        'street_address' => '5 Saint Helier St',
         'county' => 'Marin',
         'country' => 'United States',
         'state_province' => 'Michigan',
         'supplemental_address_1' => 'Hallmark Ct',
         'supplemental_address_2' => 'Jersey Village',
         'postal_code' => '90210',
+        'city' => 'Gotham City',
+        'is_billing' => 0,
       ),
       'api.phone.create' => array(
         'location_type_id' => '1',
@@ -528,29 +678,13 @@ class api_v3_ProfileTest extends CiviUnitTestCase {
      ), $params
     );
 
-    $contactID = $this->individualCreate($contactParams);
-
-    // Create new profile having group_type: Contact,Individual
-    $op = new PHPUnit_Extensions_Database_Operation_Insert();
-    $op->execute($this->_dbconn,
-      new PHPUnit_Extensions_Database_DataSet_XMLDataSet(
-        dirname(__FILE__) . "/dataset/uf_group_25.xml"
-      )
-    );
-    // Create Contact + Idividual fields for profile
-    $op = new PHPUnit_Extensions_Database_Operation_Insert();
-    $op->execute($this->_dbconn,
-      new PHPUnit_Extensions_Database_DataSet_XMLDataSet(
-        dirname(__FILE__) . "/dataset/uf_field_uf_group_25.xml"
-      )
-    );
-
-
+    $this->_contactID = $this->individualCreate($contactParams);
+    $this->_createIndividualProfile();
     // expected result of above created profile with contact Id $contactId
-    $profileData[$contactID] = array(
+    $profileData[$this->_contactID] = array(
       'first_name' => 'abc1',
       'last_name' => 'xyz1',
-      'email-Primary' => 'abc1.xyz1@yahoo.com',
+      'email-primary' => 'abc1.xyz1@yahoo.com',
       'phone-1-1' => '021 512 755',
       'country-1' => '1228',
       'state_province-1' => '1021',
@@ -617,7 +751,7 @@ class api_v3_ProfileTest extends CiviUnitTestCase {
       'profile_id' => 26,
       'contact_id' => $contactId,
       'activity_id' => $activityValues['id'],
-         );
+    );
 
     // expected result of above created profile
     $expected = array(
@@ -634,5 +768,81 @@ class api_v3_ProfileTest extends CiviUnitTestCase {
 
     return array($profileParams, $expected);
   }
+  /**
+   * Create a profile
+   */
+  function _createIndividualProfile() {
+
+    // creating these via the api as we want to utilise & test the flushing of caches when fields created
+    // via the api
+
+    $ufGroupParams = array(
+      'group_type' => 'Individual,Contact',// really we should remove this & test the ufField create sets it
+      'name' => 'test_individual_contact_profile',
+      'title' => 'Flat Coffee',
+      'api.uf_field.create' => array(
+        array(
+          'field_name' => 'first_name',
+          'is_required' => 1,
+          'visibility' => 'Public Pages and Listings',
+          'field_type' => 'Individual',
+          'label' => 'First Name',
+        ),
+        array(
+          'field_name' => 'last_name',
+          'is_required' => 1,
+          'visibility' => 'Public Pages and Listings',
+          'field_type' => 'Individual',
+          'label' => 'Last Name',
+        ),
+        array(
+          'field_name' => 'email',
+          'is_required' => 1,
+          'visibility' => 'Public Pages and Listings',
+          'field_type' => 'Contact',
+          'label' => 'Email',
+        ),
+        array(
+          'field_name' => 'phone',
+          'is_required' => 1,
+          'visibility' => 'Public Pages and Listings',
+          'field_type' => 'Contact',
+          'location_type_id' => 1,
+          'phone_type_id' => 1,
+          'label' => 'Phone'
+        ),
+        array(
+          'field_name' => 'country',
+          'is_required' => 1,
+          'visibility' => 'Public Pages and Listings',
+          'field_type' => 'Contact',
+          'location_type_id' => 1,
+          'label' => 'Country'
+        ),
+        array(
+          'field_name' => 'state_province',
+          'is_required' => 1,
+          'visibility' => 'Public Pages and Listings',
+          'field_type' => 'Contact',
+          'location_type_id' => 1,
+          'label' => 'State Province'
+        ),
+        array(
+          'field_name' => 'postal_code',
+          'is_required' => 0,
+          'field_type' => 'Contact',
+          'location_type_id' => 1,
+          'label' => 'State Province'
+         ),
+      ),
+    );
+    $profile = $this->callAPISuccess('uf_group', 'create', $ufGroupParams);
+    $this->_profileID = $profile['id'];
+  }
+
+  function _addCustomFieldToProfile($profileID) {
+    $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__, '');
+    $this->uFFieldCreate(array('uf_group_id' => $profileID, 'field_name' => 'custom_' . $ids['custom_field_id'], 'contact_type' => 'Contact'));
+  }
 }