diff options
Diffstat (limited to 'www/crm/wp-content/plugins/civicrm/civicrm/ext/api4/tests/phpunit/Action')
21 files changed, 1971 insertions, 0 deletions
diff --git a/www/crm/wp-content/plugins/civicrm/civicrm/ext/api4/tests/phpunit/Action/BaseCustomValueTest.php b/www/crm/wp-content/plugins/civicrm/civicrm/ext/api4/tests/phpunit/Action/BaseCustomValueTest.php new file mode 100644 index 00000000..41fe7281 --- /dev/null +++ b/www/crm/wp-content/plugins/civicrm/civicrm/ext/api4/tests/phpunit/Action/BaseCustomValueTest.php @@ -0,0 +1,31 @@ +<?php + +namespace Civi\Test\Api4\Action; + +use Civi\Test\Api4\UnitTestCase; +use Civi\Test\Api4\Traits\TableDropperTrait; + +abstract class BaseCustomValueTest extends UnitTestCase { + + use \Civi\Test\Api4\Traits\OptionCleanupTrait { + setUp as setUpOptionCleanup; + } + use TableDropperTrait; + + /** + * Set up baseline for testing + */ + public function setUp() { + $this->setUpOptionCleanup(); + $cleanup_params = [ + 'tablesToTruncate' => [ + 'civicrm_custom_group', + 'civicrm_custom_field', + ], + ]; + + $this->dropByPrefix('civicrm_value_mycontact'); + $this->cleanup($cleanup_params); + } + +} diff --git a/www/crm/wp-content/plugins/civicrm/civicrm/ext/api4/tests/phpunit/Action/BasicActionsTest.php b/www/crm/wp-content/plugins/civicrm/civicrm/ext/api4/tests/phpunit/Action/BasicActionsTest.php new file mode 100644 index 00000000..29523389 --- /dev/null +++ b/www/crm/wp-content/plugins/civicrm/civicrm/ext/api4/tests/phpunit/Action/BasicActionsTest.php @@ -0,0 +1,154 @@ +<?php + +namespace Civi\Test\Api4\Action; + +use Civi\Test\Api4\UnitTestCase; +use Civi\Api4\MockBasicEntity; + +/** + * @group headless + */ +class BasicActionsTest extends UnitTestCase { + + public function testCrud() { + MockBasicEntity::delete()->addWhere('id', '>', 0)->execute(); + + $id1 = MockBasicEntity::create()->addValue('foo', 'one')->execute()->first()['id']; + + $result = MockBasicEntity::get()->execute(); + $this->assertCount(1, $result); + + $id2 = MockBasicEntity::create()->addValue('foo', 'two')->execute()->first()['id']; + + $result = MockBasicEntity::get()->execute(); + $this->assertCount(2, $result); + + MockBasicEntity::update()->addWhere('id', '=', $id2)->addValue('foo', 'new')->execute(); + + $result = MockBasicEntity::get()->addOrderBy('id', 'DESC')->setLimit(1)->execute(); + $this->assertCount(1, $result); + $this->assertEquals('new', $result->first()['foo']); + + MockBasicEntity::delete()->addWhere('id', '=', $id2); + $result = MockBasicEntity::get()->execute(); + $this->assertEquals('one', $result->first()['foo']); + } + + public function testReplace() { + MockBasicEntity::delete()->addWhere('id', '>', 0)->execute(); + + $objects = [ + ['group' => 'one', 'color' => 'red'], + ['group' => 'one', 'color' => 'blue'], + ['group' => 'one', 'color' => 'green'], + ['group' => 'two', 'color' => 'orange'], + ]; + + foreach ($objects as &$object) { + $object['id'] = MockBasicEntity::create()->setValues($object)->execute()->first()['id']; + } + + // Keep red, change blue, delete green, and add yellow + $replacements = [ + ['color' => 'red', 'id' => $objects[0]['id']], + ['color' => 'not blue', 'id' => $objects[1]['id']], + ['color' => 'yellow'] + ]; + + MockBasicEntity::replace()->addWhere('group', '=', 'one')->setRecords($replacements)->execute(); + + $newObjects = MockBasicEntity::get()->addOrderBy('id', 'DESC')->execute()->indexBy('id'); + + $this->assertCount(4, $newObjects); + + $this->assertEquals('yellow', $newObjects->first()['color']); + + $this->assertEquals('not blue', $newObjects[$objects[1]['id']]['color']); + + // Ensure group two hasn't been altered + $this->assertEquals('orange', $newObjects[$objects[3]['id']]['color']); + $this->assertEquals('two', $newObjects[$objects[3]['id']]['group']); + } + + public function testBatchFrobnicate() { + MockBasicEntity::delete()->addWhere('id', '>', 0)->execute(); + + $objects = [ + ['group' => 'one', 'color' => 'red', 'number' => 10], + ['group' => 'one', 'color' => 'blue', 'number' => 20], + ['group' => 'one', 'color' => 'green', 'number' => 30], + ['group' => 'two', 'color' => 'blue', 'number' => 40], + ]; + foreach ($objects as &$object) { + $object['id'] = MockBasicEntity::create()->setValues($object)->execute()->first()['id']; + } + + $result = MockBasicEntity::batchFrobnicate()->addWhere('color', '=', 'blue')->execute(); + $this->assertEquals(2, count($result)); + $this->assertEquals([400, 1600], \CRM_Utils_Array::collect('frobnication', (array) $result)); + } + + public function testGetFields() { + $getFields = MockBasicEntity::getFields()->execute()->indexBy('name'); + + $this->assertCount(6, $getFields); + $this->assertEquals('Id', $getFields['id']['title']); + // Ensure default data type is "String" when not specified + $this->assertEquals('String', $getFields['color']['data_type']); + + // Getfields should default to loadOptions = false and reduce them to bool + $this->assertTrue($getFields['group']['options']); + $this->assertFalse($getFields['id']['options']); + + // Now load options + $getFields = MockBasicEntity::getFields() + ->addWhere('name', '=', 'group') + ->setLoadOptions(TRUE) + ->execute()->indexBy('name'); + + $this->assertCount(1, $getFields); + $this->assertArrayHasKey('one', $getFields['group']['options']); + } + + public function testItemsToGet() { + $get = MockBasicEntity::get() + ->addWhere('color', 'NOT IN', ['yellow']) + ->addWhere('color', 'IN', ['red', 'blue']) + ->addWhere('color', '!=', 'green') + ->addWhere('group', '=', 'one'); + + $this->assertEquals(['red', 'blue'], $get->_itemsToGet('color')); + $this->assertEquals(['one'], $get->_itemsToGet('group')); + } + + public function testFieldsToGet() { + $get = MockBasicEntity::get() + ->addWhere('color', '!=', 'green'); + + // If no "select" is set, should always return true + $this->assertTrue($get->_isFieldSelected('color')); + $this->assertTrue($get->_isFieldSelected('shape')); + $this->assertTrue($get->_isFieldSelected('size')); + + // With a non-empty "select" fieldsToSelect() will return fields needed to evaluate each clause. + $get->addSelect('id'); + $this->assertTrue($get->_isFieldSelected('color')); + $this->assertTrue($get->_isFieldSelected('id')); + $this->assertFalse($get->_isFieldSelected('shape')); + $this->assertFalse($get->_isFieldSelected('size')); + $this->assertFalse($get->_isFieldSelected('weight')); + $this->assertFalse($get->_isFieldSelected('group')); + + $get->addClause('OR', ['shape', '=', 'round'], ['AND', [['size', '=', 'big'], ['weight', '!=', 'small']]]); + $this->assertTrue($get->_isFieldSelected('color')); + $this->assertTrue($get->_isFieldSelected('id')); + $this->assertTrue($get->_isFieldSelected('shape')); + $this->assertTrue($get->_isFieldSelected('size')); + $this->assertTrue($get->_isFieldSelected('weight')); + $this->assertFalse($get->_isFieldSelected('group')); + + $get->addOrderBy('group'); + $this->assertTrue($get->_isFieldSelected('group')); + } + +} diff --git a/www/crm/wp-content/plugins/civicrm/civicrm/ext/api4/tests/phpunit/Action/BasicCustomFieldTest.php b/www/crm/wp-content/plugins/civicrm/civicrm/ext/api4/tests/phpunit/Action/BasicCustomFieldTest.php new file mode 100644 index 00000000..85687a08 --- /dev/null +++ b/www/crm/wp-content/plugins/civicrm/civicrm/ext/api4/tests/phpunit/Action/BasicCustomFieldTest.php @@ -0,0 +1,187 @@ +<?php + +namespace Civi\Test\Api4\Action; + +use Civi\Api4\Contact; +use Civi\Api4\CustomField; +use Civi\Api4\CustomGroup; + +/** + * @group headless + */ +class BasicCustomFieldTest extends BaseCustomValueTest { + + public function testWithSingleField() { + + $customGroup = CustomGroup::create() + ->setCheckPermissions(FALSE) + ->addValue('name', 'MyContactFields') + ->addValue('extends', 'Contact') + ->execute() + ->first(); + + CustomField::create() + ->setCheckPermissions(FALSE) + ->addValue('label', 'FavColor') + ->addValue('custom_group_id', $customGroup['id']) + ->addValue('html_type', 'Text') + ->addValue('data_type', 'String') + ->execute(); + + $contactId = Contact::create() + ->setCheckPermissions(FALSE) + ->addValue('first_name', 'Johann') + ->addValue('last_name', 'Tester') + ->addValue('contact_type', 'Individual') + ->addValue('MyContactFields.FavColor', 'Red') + ->execute() + ->first()['id']; + + $contact = Contact::get() + ->setCheckPermissions(FALSE) + ->addSelect('first_name') + ->addSelect('MyContactFields.FavColor') + ->addWhere('id', '=', $contactId) + ->addWhere('MyContactFields.FavColor', '=', 'Red') + ->execute() + ->first(); + + $this->assertArrayHasKey('MyContactFields', $contact); + $contactFields = $contact['MyContactFields']; + $this->assertArrayHasKey('FavColor', $contactFields); + $this->assertEquals('Red', $contactFields['FavColor']); + + Contact::update() + ->addWhere('id', '=', $contactId) + ->addValue('MyContactFields.FavColor', 'Blue') + ->execute(); + + $contact = Contact::get() + ->setCheckPermissions(FALSE) + ->addSelect('MyContactFields.FavColor') + ->addWhere('id', '=', $contactId) + ->execute() + ->first(); + + $contactFields = $contact['MyContactFields']; + $this->assertEquals('Blue', $contactFields['FavColor']); + } + + public function testWithTwoFields() { + + $customGroup = CustomGroup::create() + ->setCheckPermissions(FALSE) + ->addValue('name', 'MyContactFields') + ->addValue('extends', 'Contact') + ->execute() + ->first(); + + CustomField::create() + ->setCheckPermissions(FALSE) + ->addValue('label', 'FavColor') + ->addValue('custom_group_id', $customGroup['id']) + ->addValue('html_type', 'Text') + ->addValue('data_type', 'String') + ->execute(); + + CustomField::create() + ->setCheckPermissions(FALSE) + ->addValue('label', 'FavFood') + ->addValue('custom_group_id', $customGroup['id']) + ->addValue('html_type', 'Text') + ->addValue('data_type', 'String') + ->execute(); + + $contactId1 = Contact::create() + ->setCheckPermissions(FALSE) + ->addValue('first_name', 'Johann') + ->addValue('last_name', 'Tester') + ->addValue('MyContactFields.FavColor', 'Red') + ->addValue('MyContactFields.FavFood', 'Cherry') + ->execute() + ->first()['id']; + + $contactId2 = Contact::create() + ->setCheckPermissions(FALSE) + ->addValue('first_name', 'MaryLou') + ->addValue('last_name', 'Tester') + ->addValue('MyContactFields.FavColor', 'Purple') + ->addValue('MyContactFields.FavFood', 'Grapes') + ->execute() + ->first()['id']; + + $contact = Contact::get() + ->setCheckPermissions(FALSE) + ->addSelect('first_name') + ->addSelect('MyContactFields.FavColor') + ->addSelect('MyContactFields.FavFood') + ->addWhere('id', '=', $contactId1) + ->addWhere('MyContactFields.FavColor', '=', 'Red') + ->addWhere('MyContactFields.FavFood', '=', 'Cherry') + ->execute() + ->first(); + + $this->assertArrayHasKey('MyContactFields', $contact); + $contactFields = $contact['MyContactFields']; + $this->assertArrayHasKey('FavColor', $contactFields); + $this->assertEquals('Red', $contactFields['FavColor']); + + Contact::update() + ->addWhere('id', '=', $contactId1) + ->addValue('MyContactFields.FavColor', 'Blue') + ->execute(); + + $contact = Contact::get() + ->setCheckPermissions(FALSE) + ->addSelect('MyContactFields.FavColor') + ->addWhere('id', '=', $contactId1) + ->execute() + ->first(); + + $contactFields = $contact['MyContactFields']; + $this->assertEquals('Blue', $contactFields['FavColor']); + + $search = Contact::get() + ->setCheckPermissions(FALSE) + ->addClause('OR', ['MyContactFields.FavColor', '=', 'Blue'], ['MyContactFields.FavFood', '=', 'Grapes']) + ->addSelect('id') + ->addOrderBy('id') + ->execute() + ->indexBy('id'); + + $this->assertEquals([$contactId1, $contactId2], array_keys((array) $search)); + + $search = Contact::get() + ->setCheckPermissions(FALSE) + ->addClause('NOT', ['MyContactFields.FavColor', '=', 'Purple'], ['MyContactFields.FavFood', '=', 'Grapes']) + ->addSelect('id') + ->addOrderBy('id') + ->execute() + ->indexBy('id'); + + $this->assertNotContains($contactId2, array_keys((array) $search)); + + $search = Contact::get() + ->setCheckPermissions(FALSE) + ->addClause('NOT', ['MyContactFields.FavColor', '=', 'Purple'], ['MyContactFields.FavFood', '=', 'Grapes']) + ->addSelect('id') + ->addOrderBy('id') + ->execute() + ->indexBy('id'); + + $this->assertContains($contactId1, array_keys((array) $search)); + $this->assertNotContains($contactId2, array_keys((array) $search)); + + $search = Contact::get() + ->setCheckPermissions(FALSE) + ->setWhere([['NOT', ['OR', [['MyContactFields.FavColor', '=', 'Blue'], ['MyContactFields.FavFood', '=', 'Grapes']]]]]) + ->addSelect('id') + ->addOrderBy('id') + ->execute() + ->indexBy('id'); + + $this->assertNotContains($contactId1, array_keys((array) $search)); + $this->assertNotContains($contactId2, array_keys((array) $search)); + } + +} diff --git a/www/crm/wp-content/plugins/civicrm/civicrm/ext/api4/tests/phpunit/Action/ChainTest.php b/www/crm/wp-content/plugins/civicrm/civicrm/ext/api4/tests/phpunit/Action/ChainTest.php new file mode 100644 index 00000000..bbd6a092 --- /dev/null +++ b/www/crm/wp-content/plugins/civicrm/civicrm/ext/api4/tests/phpunit/Action/ChainTest.php @@ -0,0 +1,53 @@ +<?php + +namespace Civi\Test\Api4\Action; + +use Civi\Test\Api4\UnitTestCase; + +/** + * @group headless + */ +class ChainTest extends UnitTestCase { + + public function testGetActionsWithFields() { + $actions = \Civi\Api4\Activity::getActions() + ->addChain('fields', \Civi\Api4\Activity::getFields()->setAction('$name'), 'name') + ->execute() + ->indexBy('name'); + + $this->assertEquals('Array', $actions['getActions']['fields']['params']['data_type']); + } + + public function testGetEntityWithActions() { + $entities = \Civi\Api4\Entity::get() + ->addSelect('name') + ->setChain([ + 'actions' => ['$name', 'getActions', ['select' => ['name']], 'name'] + ]) + ->execute() + ->indexBy('name'); + + $this->assertArrayHasKey('replace', $entities['Contact']['actions']); + $this->assertArrayHasKey('getLinks', $entities['Entity']['actions']); + $this->assertArrayNotHasKey('replace', $entities['Entity']['actions']); + } + + public function testContactCreateWithGroup() { + $firstName = uniqid('cwtf'); + $lastName = uniqid('cwtl'); + + $contact = \Civi\Api4\Contact::create() + ->addValue('first_name', $firstName) + ->addValue('last_name', $lastName) + ->addChain('group', \Civi\Api4\Group::create()->addValue('title', '$display_name'), 0) + ->addChain('add_to_group', \Civi\Api4\GroupContact::create()->addValue('contact_id', '$id')->addValue('group_id', '$group.id'), 0) + ->addChain('check_group', \Civi\Api4\GroupContact::get()->addWhere('group_id', '=', '$group.id')) + ->execute() + ->first(); + + $this->assertCount(1, $contact['check_group']); + $this->assertEquals($contact['id'], $contact['check_group'][0]['contact_id']); + $this->assertEquals($contact['group']['id'], $contact['check_group'][0]['group_id']); + } + +} diff --git a/www/crm/wp-content/plugins/civicrm/civicrm/ext/api4/tests/phpunit/Action/ComplexQueryTest.php b/www/crm/wp-content/plugins/civicrm/civicrm/ext/api4/tests/phpunit/Action/ComplexQueryTest.php new file mode 100644 index 00000000..0a320100 --- /dev/null +++ b/www/crm/wp-content/plugins/civicrm/civicrm/ext/api4/tests/phpunit/Action/ComplexQueryTest.php @@ -0,0 +1,87 @@ +<?php + +namespace Civi\Test\Api4\Action; + +use Civi\Test\Api4\UnitTestCase; +use Civi\Api4\Activity; + +/** + * @group headless + * + * This class tests a series of complex query situations described in the + * initial APIv4 specification + */ +class ComplexQueryTest extends UnitTestCase { + + public function setUpHeadless() { + $relatedTables = [ + 'civicrm_activity', + 'civicrm_activity_contact', + ]; + $this->cleanup(['tablesToTruncate' => $relatedTables]); + $this->loadDataSet('DefaultDataSet'); + + return parent::setUpHeadless(); + } + + /** + * Fetch all phone call activities + * Expects at least one activity loaded from the data set. + */ + public function testGetAllHousingSupportActivities() { + $results = Activity::get() + ->setCheckPermissions(FALSE) + ->addWhere('activity_type.name', '=', 'Phone Call') + ->execute(); + + $this->assertGreaterThan(0, count($results)); + } + + /** + * Fetch all activities with a blue tag; and return all tags on the activities + */ + public function testGetAllTagsForBlueTaggedActivities() { + + } + + /** + * Fetch contacts named 'Bob' and all of their blue activities + */ + public function testGetAllBlueActivitiesForBobs() { + + } + + /** + * Get all contacts in a zipcode and return their Home or Work email addresses + */ + public function testGetHomeOrWorkEmailsForContactsWithZipcode() { + + } + + /** + * Fetch all activities where Bob is the assignee or source + */ + public function testGetActivitiesWithBobAsAssigneeOrSource() { + + } + + /** + * Get all contacts which + * (a) have address in zipcode 94117 or 94118 or in city "San Francisco","LA" + * and + * (b) are not deceased and + * (c) have a custom-field "most_important_issue=Environment". + */ + public function testAWholeLotOfConditions() { + + } + + /** + * Get participants who attended CiviCon 2012 but not CiviCon 2013. + * Return their name and email. + */ + public function testGettingNameAndEmailOfAttendeesOfCiviCon2012Only() { + + } + +} diff --git a/www/crm/wp-content/plugins/civicrm/civicrm/ext/api4/tests/phpunit/Action/ContactApiKeyTest.php b/www/crm/wp-content/plugins/civicrm/civicrm/ext/api4/tests/phpunit/Action/ContactApiKeyTest.php new file mode 100644 index 00000000..63d85d55 --- /dev/null +++ b/www/crm/wp-content/plugins/civicrm/civicrm/ext/api4/tests/phpunit/Action/ContactApiKeyTest.php @@ -0,0 +1,170 @@ +<?php + +namespace Civi\Test\Api4\Action; + +use Civi\Api4\Contact; + +/** + * @group headless + */ +class ContactApiKeyTest extends \Civi\Test\Api4\UnitTestCase { + + public function testGetApiKey() { + \CRM_Core_Config::singleton()->userPermissionClass->permissions = ['access CiviCRM']; + $key = uniqid(); + + $contact = Contact::create() + ->setCheckPermissions(FALSE) + ->addValue('first_name', 'Api') + ->addValue('last_name', 'Key0') + ->addValue('api_key', $key) + ->execute() + ->first(); + + $result = Contact::get() + ->setCheckPermissions(FALSE) + ->addWhere('id', '=', $contact['id']) + ->addSelect('api_key') + ->execute() + ->first(); + + $this->assertEquals($result['api_key'], $key); + + $result = Contact::get() + ->addWhere('id', '=', $contact['id']) + ->addSelect('api_key') + ->execute() + ->first(); + + $this->assertTrue(empty($result['api_key'])); + } + + public function testCreateWithApiKey() { + \CRM_Core_Config::singleton()->userPermissionClass->permissions = ['access CiviCRM', 'add contacts']; + $key = uniqid(); + + $error = ''; + try { + Contact::create() + ->addValue('first_name', 'Api') + ->addValue('last_name', 'Key1') + ->addValue('api_key', $key) + ->execute() + ->first(); + } + catch (\Exception $e) { + $error = $e->getMessage(); + } + $this->assertContains('key', $error); + } + + public function testUpdateApiKey() { + \CRM_Core_Config::singleton()->userPermissionClass->permissions = ['access CiviCRM']; + $key = uniqid(); + + $contact = Contact::create() + ->setCheckPermissions(FALSE) + ->addValue('first_name', 'Api') + ->addValue('last_name', 'Key2') + ->addValue('api_key', $key) + ->execute() + ->first(); + + $error = ''; + try { + // Try to update the key without permissions; nothing should happen + Contact::update() + ->addWhere('id', '=', $contact['id']) + ->addValue('api_key', "NotAllowed") + ->execute(); + } + catch (\Exception $e) { + $error = $e->getMessage(); + } + + $result = Contact::get() + ->setCheckPermissions(FALSE) + ->addWhere('id', '=', $contact['id']) + ->addSelect('api_key') + ->execute() + ->first(); + + $this->assertContains('key', $error); + + // Assert key is still the same + $this->assertEquals($result['api_key'], $key); + + // Now we can update the key + \CRM_Core_Config::singleton()->userPermissionClass->permissions = ['access CiviCRM', 'administer CiviCRM', 'edit all contacts']; + + Contact::update() + ->addWhere('id', '=', $contact['id']) + ->addValue('api_key', "IGotThePower!") + ->execute(); + + $result = Contact::get() + ->addWhere('id', '=', $contact['id']) + ->addSelect('api_key') + ->execute() + ->first(); + + // Assert key was updated + $this->assertEquals($result['api_key'], "IGotThePower!"); + } + + public function testUpdateOwnApiKey() { + \CRM_Core_Config::singleton()->userPermissionClass->permissions = ['access CiviCRM', 'edit own api keys', 'edit my contact']; + $key = uniqid(); + + $contact = Contact::create() + ->setCheckPermissions(FALSE) + ->addValue('first_name', 'Api') + ->addValue('last_name', 'Key3') + ->addValue('api_key', $key) + ->execute() + ->first(); + + $error = ''; + try { + // Try to update the key without permissions; nothing should happen + Contact::update() + ->addWhere('id', '=', $contact['id']) + ->addValue('api_key', "NotAllowed") + ->execute(); + } + catch (\Exception $e) { + $error = $e->getMessage(); + } + + $this->assertContains('key', $error); + + $result = Contact::get() + ->setCheckPermissions(FALSE) + ->addWhere('id', '=', $contact['id']) + ->addSelect('api_key') + ->execute() + ->first(); + + // Assert key is still the same + $this->assertEquals($result['api_key'], $key); + + // Now we can update the key + \CRM_Core_Session::singleton()->set('userID', $contact['id']); + + Contact::update() + ->addWhere('id', '=', $contact['id']) + ->addValue('api_key', "MyId!") + ->execute(); + + $result = Contact::get() + ->setCheckPermissions(FALSE) + ->addWhere('id', '=', $contact['id']) + ->addSelect('api_key') + ->execute() + ->first(); + + // Assert key was updated + $this->assertEquals($result['api_key'], "MyId!"); + } + +} diff --git a/www/crm/wp-content/plugins/civicrm/civicrm/ext/api4/tests/phpunit/Action/CreateCustomValueTest.php b/www/crm/wp-content/plugins/civicrm/civicrm/ext/api4/tests/phpunit/Action/CreateCustomValueTest.php new file mode 100644 index 00000000..762b4617 --- /dev/null +++ b/www/crm/wp-content/plugins/civicrm/civicrm/ext/api4/tests/phpunit/Action/CreateCustomValueTest.php @@ -0,0 +1,64 @@ +<?php + +namespace Civi\Test\Api4\Action; + +use Civi\Api4\CustomField; +use Civi\Api4\CustomGroup; +use Civi\Api4\OptionGroup; +use Civi\Api4\OptionValue; + +/** + * @group headless + */ +class CreateCustomValueTest extends BaseCustomValueTest { + + public function testGetWithCustomData() { + $optionValues = ['r' => 'Red', 'g' => 'Green', 'b' => 'Blue']; + + $customGroup = CustomGroup::create() + ->setCheckPermissions(FALSE) + ->addValue('name', 'MyContactFields') + ->addValue('extends', 'Contact') + ->execute() + ->first(); + + CustomField::create() + ->setCheckPermissions(FALSE) + ->addValue('label', 'Color') + ->addValue('options', $optionValues) + ->addValue('custom_group_id', $customGroup['id']) + ->addValue('html_type', 'Select') + ->addValue('data_type', 'String') + ->execute(); + + $customField = CustomField::get() + ->setCheckPermissions(FALSE) + ->addWhere('label', '=', 'Color') + ->execute() + ->first(); + + $this->assertNotNull($customField['option_group_id']); + $optionGroupId = $customField['option_group_id']; + + $optionGroup = OptionGroup::get() + ->setCheckPermissions(FALSE) + ->addWhere('id', '=', $optionGroupId) + ->execute() + ->first(); + + $this->assertEquals('Color', $optionGroup['title']); + + $createdOptionValues = OptionValue::get() + ->setCheckPermissions(FALSE) + ->addWhere('option_group_id', '=', $optionGroupId) + ->execute() + ->getArrayCopy(); + + $values = array_column($createdOptionValues, 'value'); + $labels = array_column($createdOptionValues, 'label'); + $createdOptionValues = array_combine($values, $labels); + + $this->assertEquals($optionValues, $createdOptionValues); + } + +} diff --git a/www/crm/wp-content/plugins/civicrm/civicrm/ext/api4/tests/phpunit/Action/CreateWithOptionGroupTest.php b/www/crm/wp-content/plugins/civicrm/civicrm/ext/api4/tests/phpunit/Action/CreateWithOptionGroupTest.php new file mode 100644 index 00000000..b4d0af85 --- /dev/null +++ b/www/crm/wp-content/plugins/civicrm/civicrm/ext/api4/tests/phpunit/Action/CreateWithOptionGroupTest.php @@ -0,0 +1,190 @@ +<?php + +namespace Civi\Test\Api4\Action; + +use Civi\Api4\CustomField; +use Civi\Api4\CustomGroup; +use Civi\Api4\Contact; + +/** + * @group headless + */ +class CreateWithOptionGroupTest extends BaseCustomValueTest { + + /** + * Remove the custom tables + */ + public function setUp() { + $this->dropByPrefix('civicrm_value_financial'); + $this->dropByPrefix('civicrm_value_favorite'); + parent::setUp(); + } + + public function testGetWithCustomData() { + $group = uniqid('fava'); + $colorField = uniqid('colora'); + $foodField = uniqid('fooda'); + + $customGroupId = CustomGroup::create() + ->setCheckPermissions(FALSE) + ->addValue('name', $group) + ->addValue('extends', 'Contact') + ->execute() + ->first()['id']; + + CustomField::create() + ->setCheckPermissions(FALSE) + ->addValue('label', $colorField) + ->addValue('name', $colorField) + ->addValue('options', ['r' => 'Red', 'g' => 'Green', 'b' => 'Blue']) + ->addValue('custom_group_id', $customGroupId) + ->addValue('html_type', 'Select') + ->addValue('data_type', 'String') + ->execute(); + + CustomField::create() + ->setCheckPermissions(FALSE) + ->addValue('label', $foodField) + ->addValue('name', $foodField) + ->addValue('options', ['1' => 'Corn', '2' => 'Potatoes', '3' => 'Cheese']) + ->addValue('custom_group_id', $customGroupId) + ->addValue('html_type', 'Select') + ->addValue('data_type', 'String') + ->execute(); + + $customGroupId = CustomGroup::create() + ->setCheckPermissions(FALSE) + ->addValue('name', 'FinancialStuff') + ->addValue('extends', 'Contact') + ->execute() + ->first()['id']; + + CustomField::create() + ->setCheckPermissions(FALSE) + ->addValue('label', 'Salary') + ->addValue('custom_group_id', $customGroupId) + ->addValue('html_type', 'Number') + ->addValue('data_type', 'Money') + ->execute(); + + Contact::create() + ->setCheckPermissions(FALSE) + ->addValue('first_name', 'Jerome') + ->addValue('last_name', 'Tester') + ->addValue('contact_type', 'Individual') + ->addValue("$group.$colorField", 'r') + ->addValue("$group.$foodField", '1') + ->addValue('FinancialStuff.Salary', 50000) + ->execute(); + + $result = Contact::get() + ->setCheckPermissions(FALSE) + ->addSelect('first_name') + ->addSelect("$group.$colorField.label") + ->addSelect("$group.$foodField.label") + ->addSelect('FinancialStuff.Salary') + ->addWhere("$group.$foodField.label", 'IN', ['Corn', 'Potatoes']) + ->addWhere('FinancialStuff.Salary', '>', '10000') + ->execute() + ->first(); + + $this->assertArrayHasKey($group, $result); + $favoriteThings = $result[$group]; + $favoriteFood = $favoriteThings[$foodField]; + $favoriteColor = $favoriteThings[$colorField]; + $financialStuff = $result['FinancialStuff']; + $this->assertEquals('Red', $favoriteColor['label']); + $this->assertEquals('Corn', $favoriteFood['label']); + $this->assertEquals(50000, $financialStuff['Salary']); + } + + public function testWithCustomDataForMultipleContacts() { + $group = uniqid('favb'); + $colorField = uniqid('colorb'); + $foodField = uniqid('foodb'); + + $customGroupId = CustomGroup::create() + ->setCheckPermissions(FALSE) + ->addValue('name', $group) + ->addValue('extends', 'Contact') + ->execute() + ->first()['id']; + + CustomField::create() + ->setCheckPermissions(FALSE) + ->addValue('label', $colorField) + ->addValue('name', $colorField) + ->addValue('options', ['r' => 'Red', 'g' => 'Green', 'b' => 'Blue']) + ->addValue('custom_group_id', $customGroupId) + ->addValue('html_type', 'Select') + ->addValue('data_type', 'String') + ->execute(); + + CustomField::create() + ->setCheckPermissions(FALSE) + ->addValue('label', $foodField) + ->addValue('name', $foodField) + ->addValue('options', ['1' => 'Corn', '2' => 'Potatoes', '3' => 'Cheese']) + ->addValue('custom_group_id', $customGroupId) + ->addValue('html_type', 'Select') + ->addValue('data_type', 'String') + ->execute(); + + $customGroupId = CustomGroup::create() + ->setCheckPermissions(FALSE) + ->addValue('name', 'FinancialStuff') + ->addValue('extends', 'Contact') + ->execute() + ->first()['id']; + + CustomField::create() + ->setCheckPermissions(FALSE) + ->addValue('label', 'Salary') + ->addValue('custom_group_id', $customGroupId) + ->addValue('html_type', 'Number') + ->addValue('data_type', 'Money') + ->execute(); + + Contact::create() + ->setCheckPermissions(FALSE) + ->addValue('first_name', 'Red') + ->addValue('last_name', 'Corn') + ->addValue('contact_type', 'Individual') + ->addValue("$group.$colorField", 'r') + ->addValue("$group.$foodField", '1') + ->addValue('FinancialStuff.Salary', 10000) + ->execute(); + + Contact::create() + ->setCheckPermissions(FALSE) + ->addValue('first_name', 'Blue') + ->addValue('last_name', 'Cheese') + ->addValue('contact_type', 'Individual') + ->addValue("$group.$colorField", 'b') + ->addValue("$group.$foodField", '3') + ->addValue('FinancialStuff.Salary', 500000) + ->execute(); + + $result = Contact::get() + ->setCheckPermissions(FALSE) + ->addSelect('first_name') + ->addSelect('last_name') + ->addSelect("$group.$colorField.label") + ->addSelect("$group.$foodField.label") + ->addSelect('FinancialStuff.Salary') + ->addWhere("$group.$foodField.label", 'IN', ['Corn', 'Cheese']) + ->execute(); + + $blueCheese = NULL; + foreach ($result as $contact) { + if ($contact['first_name'] === 'Blue') { + $blueCheese = $contact; + } + } + + $this->assertEquals('Blue', $blueCheese[$group][$colorField]['label']); + $this->assertEquals('Cheese', $blueCheese[$group][$foodField]['label']); + $this->assertEquals(500000, $blueCheese['FinancialStuff']['Salary']); + } + +} diff --git a/www/crm/wp-content/plugins/civicrm/civicrm/ext/api4/tests/phpunit/Action/CustomValuePerformanceTest.php b/www/crm/wp-content/plugins/civicrm/civicrm/ext/api4/tests/phpunit/Action/CustomValuePerformanceTest.php new file mode 100644 index 00000000..3fa59ef4 --- /dev/null +++ b/www/crm/wp-content/plugins/civicrm/civicrm/ext/api4/tests/phpunit/Action/CustomValuePerformanceTest.php @@ -0,0 +1,95 @@ +<?php + +namespace Civi\Test\Api4\Action; + +use Civi\Api4\Contact; +use Civi\Api4\CustomField; +use Civi\Api4\CustomGroup; +use Civi\Test\Api4\Traits\QueryCounterTrait; + +/** + * @group headless + */ +class CustomValuePerformanceTest extends BaseCustomValueTest { + + use QueryCounterTrait; + + public function testQueryCount() { + + $this->markTestIncomplete(); + + $customGroupId = CustomGroup::create() + ->setCheckPermissions(FALSE) + ->addValue('name', 'MyContactFields') + ->addValue('title', 'MyContactFields') + ->addValue('extends', 'Contact') + ->execute() + ->first()['id']; + + CustomField::create() + ->setCheckPermissions(FALSE) + ->addValue('label', 'FavColor') + ->addValue('custom_group_id', $customGroupId) + ->addValue('options', ['r' => 'Red', 'g' => 'Green', 'b' => 'Blue']) + ->addValue('html_type', 'Select') + ->addValue('data_type', 'String') + ->execute(); + + CustomField::create() + ->setCheckPermissions(FALSE) + ->addValue('label', 'FavAnimal') + ->addValue('custom_group_id', $customGroupId) + ->addValue('html_type', 'Text') + ->addValue('data_type', 'String') + ->execute(); + + CustomField::create() + ->setCheckPermissions(FALSE) + ->addValue('label', 'FavLetter') + ->addValue('custom_group_id', $customGroupId) + ->addValue('html_type', 'Text') + ->addValue('data_type', 'String') + ->execute(); + + CustomField::create() + ->setCheckPermissions(FALSE) + ->addValue('label', 'FavFood') + ->addValue('custom_group_id', $customGroupId) + ->addValue('html_type', 'Text') + ->addValue('data_type', 'String') + ->execute(); + + $this->beginQueryCount(); + + Contact::create() + ->setCheckPermissions(FALSE) + ->addValue('first_name', 'Red') + ->addValue('last_name', 'Tester') + ->addValue('contact_type', 'Individual') + ->addValue('MyContactFields.FavColor', 'r') + ->addValue('MyContactFields.FavAnimal', 'Sheep') + ->addValue('MyContactFields.FavLetter', 'z') + ->addValue('MyContactFields.FavFood', 'Coconuts') + ->execute(); + + Contact::get() + ->setCheckPermissions(FALSE) + ->addSelect('display_name') + ->addSelect('MyContactFields.FavColor.label') + ->addSelect('MyContactFields.FavColor.weight') + ->addSelect('MyContactFields.FavColor.is_default') + ->addSelect('MyContactFields.FavAnimal') + ->addSelect('MyContactFields.FavLetter') + ->addWhere('MyContactFields.FavColor', '=', 'r') + ->addWhere('MyContactFields.FavFood', '=', 'Coconuts') + ->addWhere('MyContactFields.FavAnimal', '=', 'Sheep') + ->addWhere('MyContactFields.FavLetter', '=', 'z') + ->execute() + ->first(); + + // FIXME: This count is artificially high due to the line + // $this->entity = Tables::getBriefName(Tables::getClassForTable($targetTable)); + // In class Joinable. TODO: Investigate why. + } + +} diff --git a/www/crm/wp-content/plugins/civicrm/civicrm/ext/api4/tests/phpunit/Action/CustomValueTest.php b/www/crm/wp-content/plugins/civicrm/civicrm/ext/api4/tests/phpunit/Action/CustomValueTest.php new file mode 100644 index 00000000..da954bc7 --- /dev/null +++ b/www/crm/wp-content/plugins/civicrm/civicrm/ext/api4/tests/phpunit/Action/CustomValueTest.php @@ -0,0 +1,174 @@ +<?php + +namespace Civi\Test\Api4\Action; + +use Civi\Api4\CustomField; +use Civi\Api4\CustomGroup; +use Civi\Api4\CustomValue; +use Civi\Api4\Contact; + +/** + * @group headless + */ +class CustomValueTest extends BaseCustomValueTest { + + protected $contactID; + + /** + * Test CustomValue::GetFields/Get/Create/Update/Replace/Delete + */ + public function testCRUD() { + $optionValues = ['r' => 'Red', 'g' => 'Green', 'b' => 'Blue']; + + $group = uniqid('groupc'); + $colorField = uniqid('colorc'); + + $customGroup = CustomGroup::create() + ->setCheckPermissions(FALSE) + ->addValue('name', $group) + ->addValue('extends', 'Contact') + ->addValue('is_multiple', TRUE) + ->execute() + ->first(); + + CustomField::create() + ->setCheckPermissions(FALSE) + ->addValue('label', $colorField) + ->addValue('options', $optionValues) + ->addValue('custom_group_id', $customGroup['id']) + ->addValue('html_type', 'Select') + ->addValue('data_type', 'String') + ->execute(); + + $this->contactID = Contact::create() + ->setCheckPermissions(FALSE) + ->addValue('first_name', 'Johann') + ->addValue('last_name', 'Tester') + ->addValue('contact_type', 'Individual') + ->execute() + ->first()['id']; + + // Retrieve and check the fields of CustomValue = Custom_$group + $fields = CustomValue::getFields($group)->execute(); + $expectedResult = [ + [ + 'custom_field_id' => 1, + 'custom_group' => $group, + 'name' => $colorField, + 'title' => ts($colorField), + 'entity' => "Custom_$group", + 'data_type' => 'String', + 'fk_entity' => NULL, + ], + [ + 'name' => 'id', + 'title' => ts('Custom Value ID'), + 'entity' => "Custom_$group", + 'data_type' => 'Integer', + 'fk_entity' => NULL, + ], + [ + 'name' => 'entity_id', + 'title' => ts('Entity ID'), + 'entity' => "Custom_$group", + 'data_type' => 'Integer', + 'fk_entity' => 'Contact', + ], + ]; + + foreach ($expectedResult as $key => $field) { + foreach ($field as $attr => $value) { + $this->assertEquals($expectedResult[$key][$attr], $fields[$key][$attr]); + } + } + + // CASE 1: Test CustomValue::create + // Create two records for a single contact and using CustomValue::get ensure that two records are created + CustomValue::create($group) + ->addValue($colorField, 'Green') + ->addValue("entity_id", $this->contactID) + ->execute(); + CustomValue::create($group) + ->addValue($colorField, 'Red') + ->addValue("entity_id", $this->contactID) + ->execute(); + // fetch custom values using API4 CustomValue::get + $result = CustomValue::get($group)->execute(); + + // check if two custom values are created + $this->assertEquals(2, count($result)); + $expectedResult = [ + [ + 'id' => 1, + $colorField => 'Green', + 'entity_id' => $this->contactID, + ], + [ + 'id' => 2, + $colorField => 'Red', + 'entity_id' => $this->contactID, + ], + ]; + // match the data + foreach ($expectedResult as $key => $field) { + foreach ($field as $attr => $value) { + $this->assertEquals($expectedResult[$key][$attr], $result[$key][$attr]); + } + } + + // CASE 2: Test CustomValue::update + // Update a records whose id is 1 and change the custom field (name = Color) value to 'White' from 'Green' + CustomValue::update($group) + ->addWhere("id", "=", 1) + ->addValue($colorField, 'White') + ->execute(); + + // ensure that the value is changed for id = 1 + $color = CustomValue::get($group) + ->addWhere("id", "=", 1) + ->execute() + ->first()[$colorField]; + $this->assertEquals('White', $color); + + // CASE 3: Test CustomValue::replace + // create a second contact which will be used to replace the custom values, created earlier + $secondContactID = Contact::create() + ->setCheckPermissions(FALSE) + ->addValue('first_name', 'Adam') + ->addValue('last_name', 'Tester') + ->addValue('contact_type', 'Individual') + ->execute() + ->first()['id']; + // Replace all the records which was created earlier with entity_id = first contact + // with custom record [$colorField => 'Rainbow', 'entity_id' => $secondContactID] + CustomValue::replace($group) + ->setRecords([[$colorField => 'Rainbow', 'entity_id' => $secondContactID]]) + ->addWhere('entity_id', '=', $this->contactID) + ->execute(); + + // Check the two records created earlier is replaced by new contact + $result = CustomValue::get($group)->execute(); + $this->assertEquals(1, count($result)); + + $expectedResult = [ + [ + 'id' => 3, + $colorField => 'Rainbow', + 'entity_id' => $secondContactID, + ], + ]; + foreach ($expectedResult as $key => $field) { + foreach ($field as $attr => $value) { + $this->assertEquals($expectedResult[$key][$attr], $result[$key][$attr]); + } + } + + // CASE 4: Test CustomValue::delete + // There is only record left whose id = 3, delete that record on basis of criteria id = 3 + CustomValue::delete($group)->addWhere("id", "=", 3)->execute(); + $result = CustomValue::get($group)->execute(); + // check that there are no custom values present + $this->assertEquals(0, count($result)); + } + +} diff --git a/www/crm/wp-content/plugins/civicrm/civicrm/ext/api4/tests/phpunit/Action/DateTest.php b/www/crm/wp-content/plugins/civicrm/civicrm/ext/api4/tests/phpunit/Action/DateTest.php new file mode 100644 index 00000000..8cdbfc7c --- /dev/null +++ b/www/crm/wp-content/plugins/civicrm/civicrm/ext/api4/tests/phpunit/Action/DateTest.php @@ -0,0 +1,46 @@ +<?php + +namespace Civi\Test\Api4\Action; + +use Civi\Api4\Contact; +use Civi\Api4\Relationship; +use Civi\Test\Api4\UnitTestCase; + +/** + * @group headless + */ +class DateTest extends UnitTestCase { + + public function testRelationshipDate() { + $c1 = Contact::create() + ->addValue('first_name', 'c') + ->addValue('last_name', 'one') + ->execute() + ->first()['id']; + $c2 = Contact::create() + ->addValue('first_name', 'c') + ->addValue('last_name', 'two') + ->execute() + ->first()['id']; + $r = Relationship::create() + ->addValue('contact_id_a', $c1) + ->addValue('contact_id_b', $c2) + ->addValue('relationship_type_id', 1) + ->addValue('start_date', 'now') + ->addValue('end_date', 'now + 1 week') + ->execute() + ->first()['id']; + $result = Relationship::get() + ->addWhere('start_date', '=', 'now') + ->addWhere('end_date', '>', 'now + 1 day') + ->execute() + ->indexBy('id'); + $this->assertArrayHasKey($r, $result); + $result = Relationship::get() + ->addWhere('start_date', '<', 'now') + ->execute() + ->indexBy('id'); + $this->assertArrayNotHasKey($r, $result); + } + +} diff --git a/www/crm/wp-content/plugins/civicrm/civicrm/ext/api4/tests/phpunit/Action/EvaluateConditionTest.php b/www/crm/wp-content/plugins/civicrm/civicrm/ext/api4/tests/phpunit/Action/EvaluateConditionTest.php new file mode 100644 index 00000000..3726042f --- /dev/null +++ b/www/crm/wp-content/plugins/civicrm/civicrm/ext/api4/tests/phpunit/Action/EvaluateConditionTest.php @@ -0,0 +1,38 @@ +<?php + +namespace Civi\Test\Api4\Action; + +use Civi\Api4\MockBasicEntity; +use Civi\Test\Api4\UnitTestCase; + +/** + * @group headless + */ +class EvaluateConditionTest extends UnitTestCase { + + public function testEvaluateCondition() { + $action = MockBasicEntity::get(); + $reflection = new \ReflectionClass($action); + $method = $reflection->getMethod('evaluateCondition'); + $method->setAccessible(TRUE); + + $data = [ + 'nada' => 0, + 'uno' => 1, + 'dos' => 2, + 'apple' => 'red', + 'banana' => 'yellow', + 'values' => ['one' => 1, 'two' => 2, 'three' => 3], + ]; + + $this->assertFalse($method->invoke($action, '$uno > $dos', $data)); + $this->assertTrue($method->invoke($action, '$uno < $dos', $data)); + $this->assertTrue($method->invoke($action, '$apple == "red" && $banana != "red"', $data)); + $this->assertFalse($method->invoke($action, '$apple == "red" && $banana != "yellow"', $data)); + $this->assertTrue($method->invoke($action, '$values.one == $uno', $data)); + $this->assertTrue($method->invoke($action, '$values.one + $dos == $values.three', $data)); + $this->assertTrue($method->invoke($action, 'empty($nada)', $data)); + $this->assertFalse($method->invoke($action, 'empty($values)', $data)); + } + +} diff --git a/www/crm/wp-content/plugins/civicrm/civicrm/ext/api4/tests/phpunit/Action/ExtendFromIndividualTest.php b/www/crm/wp-content/plugins/civicrm/civicrm/ext/api4/tests/phpunit/Action/ExtendFromIndividualTest.php new file mode 100644 index 00000000..2d3be50c --- /dev/null +++ b/www/crm/wp-content/plugins/civicrm/civicrm/ext/api4/tests/phpunit/Action/ExtendFromIndividualTest.php @@ -0,0 +1,54 @@ +<?php + +namespace Civi\Test\Api4\Action; + +use Civi\Api4\Contact; +use Civi\Api4\CustomField; +use Civi\Api4\CustomGroup; + +/** + * @group headless + */ +class ExtendFromIndividualTest extends BaseCustomValueTest { + + public function testGetWithNonStandardExtends() { + + $customGroup = CustomGroup::create() + ->setCheckPermissions(FALSE) + ->addValue('name', 'MyContactFields') + ->addValue('extends', 'Individual') // not Contact + ->execute() + ->first(); + + CustomField::create() + ->setCheckPermissions(FALSE) + ->addValue('label', 'FavColor') + ->addValue('custom_group_id', $customGroup['id']) + ->addValue('html_type', 'Text') + ->addValue('data_type', 'String') + ->execute(); + + $contactId = Contact::create() + ->setCheckPermissions(FALSE) + ->addValue('first_name', 'Johann') + ->addValue('last_name', 'Tester') + ->addValue('contact_type', 'Individual') + ->addValue('MyContactFields.FavColor', 'Red') + ->execute() + ->first()['id']; + + $contact = Contact::get() + ->setCheckPermissions(FALSE) + ->addSelect('display_name') + ->addSelect('MyContactFields.FavColor') + ->addWhere('id', '=', $contactId) + ->execute() + ->first(); + + $this->assertArrayHasKey('MyContactFields', $contact); + $contactFields = $contact['MyContactFields']; + $favColor = $contactFields['FavColor']; + $this->assertEquals('Red', $favColor); + } + +} diff --git a/www/crm/wp-content/plugins/civicrm/civicrm/ext/api4/tests/phpunit/Action/FkJoinTest.php b/www/crm/wp-content/plugins/civicrm/civicrm/ext/api4/tests/phpunit/Action/FkJoinTest.php new file mode 100644 index 00000000..c2b044e5 --- /dev/null +++ b/www/crm/wp-content/plugins/civicrm/civicrm/ext/api4/tests/phpunit/Action/FkJoinTest.php @@ -0,0 +1,75 @@ +<?php + +namespace Civi\Test\Api4\Action; + +use Civi\Test\Api4\UnitTestCase; +use Civi\Api4\Activity; +use Civi\Api4\Contact; + +/** + * @group headless + */ +class FkJoinTest extends UnitTestCase { + + public function setUpHeadless() { + $relatedTables = [ + 'civicrm_activity', + 'civicrm_phone', + 'civicrm_activity_contact', + ]; + $this->cleanup(['tablesToTruncate' => $relatedTables]); + $this->loadDataSet('DefaultDataSet'); + + return parent::setUpHeadless(); + } + + /** + * Fetch all phone call activities. Expects a single activity + * loaded from the data set. + */ + public function testThreeLevelJoin() { + $results = Activity::get() + ->setCheckPermissions(FALSE) + ->addWhere('activity_type.name', '=', 'Phone Call') + ->execute(); + + $this->assertCount(1, $results); + } + + public function testActivityContactJoin() { + $results = Activity::get() + ->setCheckPermissions(FALSE) + ->addSelect('assignees.id') + ->addSelect('assignees.first_name') + ->addSelect('assignees.display_name') + ->addWhere('assignees.first_name', '=', 'Phoney') + ->execute(); + + $firstResult = $results->first(); + + $this->assertCount(1, $results); + $this->assertTrue(is_array($firstResult['assignees'])); + + $firstAssignee = array_shift($firstResult['assignees']); + $this->assertEquals($firstAssignee['first_name'], 'Phoney'); + } + + public function testContactPhonesJoin() { + $testContact = $this->getReference('test_contact_1'); + $testPhone = $this->getReference('test_phone_1'); + + $results = Contact::get() + ->setCheckPermissions(FALSE) + ->addSelect('phones.phone') + ->addWhere('id', '=', $testContact['id']) + ->addWhere('phones.location_type.name', '=', 'Home') + ->execute() + ->first(); + + $this->assertArrayHasKey('phones', $results); + $this->assertCount(1, $results['phones']); + $firstPhone = array_shift($results['phones']); + $this->assertEquals($testPhone['phone'], $firstPhone['phone']); + } + +} diff --git a/www/crm/wp-content/plugins/civicrm/civicrm/ext/api4/tests/phpunit/Action/GetExtraFieldsTest.php b/www/crm/wp-content/plugins/civicrm/civicrm/ext/api4/tests/phpunit/Action/GetExtraFieldsTest.php new file mode 100644 index 00000000..bc9b10e7 --- /dev/null +++ b/www/crm/wp-content/plugins/civicrm/civicrm/ext/api4/tests/phpunit/Action/GetExtraFieldsTest.php @@ -0,0 +1,26 @@ +<?php + +namespace Civi\Test\Api4\Action; + +use Civi\Test\Api4\UnitTestCase; +use Civi\Api4\Contact; + +/** + * @group headless + */ +class GetExtraFieldsTest extends UnitTestCase { + + public function testBAOFieldsWillBeReturned() { + $returnedFields = Contact::getFields() + ->execute() + ->getArrayCopy(); + + $baseFields = \CRM_Contact_BAO_Contact::fields(); + $baseFieldNames = array_column($baseFields, 'name'); + $returnedFieldNames = array_column($returnedFields, 'name'); + $notReturned = array_diff($baseFieldNames, $returnedFieldNames); + + $this->assertEmpty($notReturned); + } + +} diff --git a/www/crm/wp-content/plugins/civicrm/civicrm/ext/api4/tests/phpunit/Action/GetFromArrayTest.php b/www/crm/wp-content/plugins/civicrm/civicrm/ext/api4/tests/phpunit/Action/GetFromArrayTest.php new file mode 100644 index 00000000..bee6fbf3 --- /dev/null +++ b/www/crm/wp-content/plugins/civicrm/civicrm/ext/api4/tests/phpunit/Action/GetFromArrayTest.php @@ -0,0 +1,163 @@ +<?php + +namespace Civi\Test\Api4\Action; + +use Civi\Test\Api4\UnitTestCase; +use Civi\Api4\MockArrayEntity; + +/** + * @group headless + */ +class GetFromArrayTest extends UnitTestCase { + + public function testArrayGetWithLimit() { + $result = MockArrayEntity::get() + ->setOffset(2) + ->setLimit(2) + ->execute(); + $this->assertEquals(3, $result[0]['field1']); + $this->assertEquals(4, $result[1]['field1']); + $this->assertEquals(2, count($result)); + } + + public function testArrayGetWithSort() { + $result = MockArrayEntity::get() + ->addOrderBy('field1', 'DESC') + ->execute(); + $this->assertEquals([5, 4, 3, 2, 1], array_column((array) $result, 'field1')); + + $result = MockArrayEntity::get() + ->addOrderBy('field5', 'DESC') + ->addOrderBy('field2', 'ASC') + ->execute(); + $this->assertEquals([3, 2, 5, 4, 1], array_column((array) $result, 'field1')); + + $result = MockArrayEntity::get() + ->addOrderBy('field3', 'ASC') + ->addOrderBy('field2', 'ASC') + ->execute(); + $this->assertEquals([3, 1, 2, 5, 4], array_column((array) $result, 'field1')); + } + + public function testArrayGetWithSelect() { + $result = MockArrayEntity::get() + ->addSelect('field1') + ->addSelect('field3') + ->setLimit(4) + ->execute(); + $this->assertEquals([ + [ + 'field1' => 1, + 'field3' => NULL, + ], + [ + 'field1' => 2, + 'field3' => 0, + ], + [ + 'field1' => 3, + ], + [ + 'field1' => 4, + 'field3' => 1, + ], + ], (array) $result); + } + + public function testArrayGetWithWhere() { + $result = MockArrayEntity::get() + ->addWhere('field2', '=', 'yack') + ->execute(); + $this->assertEquals([2], array_column((array) $result, 'field1')); + + $result = MockArrayEntity::get() + ->addWhere('field5', '!=', 'banana') + ->addWhere('field3', 'IS NOT NULL') + ->execute(); + $this->assertEquals([4, 5], array_column((array) $result, 'field1')); + + $result = MockArrayEntity::get() + ->addWhere('field1', '>=', '4') + ->execute(); + $this->assertEquals([4, 5], array_column((array) $result, 'field1')); + + $result = MockArrayEntity::get() + ->addWhere('field1', '<', '2') + ->execute(); + $this->assertEquals([1], array_column((array) $result, 'field1')); + + $result = MockArrayEntity::get() + ->addWhere('field2', 'LIKE', '%ra%') + ->execute(); + $this->assertEquals([1, 3], array_column((array) $result, 'field1')); + + $result = MockArrayEntity::get() + ->addWhere('field3', 'IS NULL') + ->execute(); + $this->assertEquals([1, 3], array_column((array) $result, 'field1')); + + $result = MockArrayEntity::get() + ->addWhere('field3', '=', '0') + ->execute(); + $this->assertEquals([2], array_column((array) $result, 'field1')); + + $result = MockArrayEntity::get() + ->addWhere('field2', 'LIKE', '%ra') + ->execute(); + $this->assertEquals([1], array_column((array) $result, 'field1')); + + $result = MockArrayEntity::get() + ->addWhere('field2', 'LIKE', 'ra') + ->execute(); + $this->assertEquals(0, count($result)); + + $result = MockArrayEntity::get() + ->addWhere('field2', 'NOT LIKE', '%ra%') + ->execute(); + $this->assertEquals([2, 4, 5], array_column((array) $result, 'field1')); + + $result = MockArrayEntity::get() + ->addWhere('field6', '=', '0') + ->execute(); + $this->assertEquals([3, 4, 5], array_column((array) $result, 'field1')); + + $result = MockArrayEntity::get() + ->addWhere('field6', '=', 0) + ->execute(); + $this->assertEquals([3, 4, 5], array_column((array) $result, 'field1')); + + $result = MockArrayEntity::get() + ->addWhere('field1', 'BETWEEN', [3, 5]) + ->execute(); + $this->assertEquals([3, 4, 5], array_column((array) $result, 'field1')); + + $result = MockArrayEntity::get() + ->addWhere('field1', 'NOT BETWEEN', [3, 4]) + ->execute(); + $this->assertEquals([1, 2, 5], array_column((array) $result, 'field1')); + } + + public function testArrayGetWithNestedWhereClauses() { + $result = MockArrayEntity::get() + ->addClause('OR', ['field2', 'LIKE', '%ra'], ['field2', 'LIKE', 'x ray']) + ->execute(); + $this->assertEquals([1, 3], array_column((array) $result, 'field1')); + + $result = MockArrayEntity::get() + ->addClause('OR', ['field2', '=', 'zebra'], ['field2', '=', 'yack']) + ->addClause('OR', ['field5', '!=', 'apple'], ['field3', 'IS NULL']) + ->execute(); + $this->assertEquals([1, 2], array_column((array) $result, 'field1')); + + $result = MockArrayEntity::get() + ->addClause('NOT', ['field2', '!=', 'yack']) + ->execute(); + $this->assertEquals([2], array_column((array) $result, 'field1')); + + $result = MockArrayEntity::get() + ->addClause('OR', ['field1', '=', 2], ['AND', [['field5', '=', 'apple'], ['field3', '=', 1]]]) + ->execute(); + $this->assertEquals([2, 4, 5], array_column((array) $result, 'field1')); + } + +} diff --git a/www/crm/wp-content/plugins/civicrm/civicrm/ext/api4/tests/phpunit/Action/IndexTest.php b/www/crm/wp-content/plugins/civicrm/civicrm/ext/api4/tests/phpunit/Action/IndexTest.php new file mode 100644 index 00000000..17356c92 --- /dev/null +++ b/www/crm/wp-content/plugins/civicrm/civicrm/ext/api4/tests/phpunit/Action/IndexTest.php @@ -0,0 +1,48 @@ +<?php + +namespace Civi\Test\Api4\Action; + +use Civi\Test\Api4\UnitTestCase; + +/** + * @group headless + */ +class IndexTest extends UnitTestCase { + + public function testIndex() { + // Results indexed by name + $resultByName = civicrm_api4('Activity', 'getActions', [], 'name'); + $this->assertInstanceOf('Civi\Api4\Generic\Result', $resultByName); + $this->assertEquals('get', $resultByName['get']['name']); + + // Get result at index 0 + $firstResult = civicrm_api4('Activity', 'getActions', [], 0); + $this->assertInstanceOf('Civi\Api4\Generic\Result', $firstResult); + $this->assertArrayHasKey('name', $firstResult); + + $this->assertEquals($resultByName->first(), (array) $firstResult); + } + + public function testBadIndexInt() { + $error = ''; + try { + civicrm_api4('Activity', 'getActions', [], 99); + } + catch (\API_Exception $e) { + $error = $e->getMessage(); + } + $this->assertContains('not found', $error); + } + + public function testBadIndexString() { + $error = ''; + try { + civicrm_api4('Activity', 'getActions', [], 'xyz'); + } + catch (\API_Exception $e) { + $error = $e->getMessage(); + } + $this->assertContains('not found', $error); + } + +} diff --git a/www/crm/wp-content/plugins/civicrm/civicrm/ext/api4/tests/phpunit/Action/NullValueTest.php b/www/crm/wp-content/plugins/civicrm/civicrm/ext/api4/tests/phpunit/Action/NullValueTest.php new file mode 100644 index 00000000..dc4f656a --- /dev/null +++ b/www/crm/wp-content/plugins/civicrm/civicrm/ext/api4/tests/phpunit/Action/NullValueTest.php @@ -0,0 +1,55 @@ +<?php + +namespace Civi\Test\Api4\Action; + +use Civi\Api4\Contact; +use Civi\Test\Api4\UnitTestCase; + +/** + * @group headless + */ +class NullValueTest extends UnitTestCase { + + public function setUpHeadless() { + $format = '{contact.first_name}{ }{contact.last_name}'; + \Civi::settings()->set('display_name_format', $format); + return parent::setUpHeadless(); + } + + public function testStringNull() { + $contact = Contact::create() + ->setCheckPermissions(FALSE) + ->addValue('first_name', 'Joseph') + ->addValue('last_name', 'null') + ->addValue('contact_type', 'Individual') + ->execute() + ->first(); + + $this->assertSame('Null', $contact['last_name']); + $this->assertSame('Joseph Null', $contact['display_name']); + } + + public function testSettingToNull() { + $contact = Contact::create() + ->setCheckPermissions(FALSE) + ->addValue('first_name', 'ILoveMy') + ->addValue('last_name', 'LastName') + ->addValue('contact_type', 'Individual') + ->execute() + ->first(); + + $this->assertSame('ILoveMy LastName', $contact['display_name']); + $contactId = $contact['id']; + + $contact = Contact::update() + ->setCheckPermissions(FALSE) + ->addWhere('id', '=', $contactId) + ->addValue('last_name', NULL) + ->execute() + ->first(); + + $this->assertSame(NULL, $contact['last_name']); + $this->assertSame('ILoveMy', $contact['display_name']); + } + +} diff --git a/www/crm/wp-content/plugins/civicrm/civicrm/ext/api4/tests/phpunit/Action/ReplaceTest.php b/www/crm/wp-content/plugins/civicrm/civicrm/ext/api4/tests/phpunit/Action/ReplaceTest.php new file mode 100644 index 00000000..097e12b0 --- /dev/null +++ b/www/crm/wp-content/plugins/civicrm/civicrm/ext/api4/tests/phpunit/Action/ReplaceTest.php @@ -0,0 +1,171 @@ +<?php + +namespace Civi\Test\Api4\Action; + +use Civi\Api4\CustomField; +use Civi\Api4\CustomGroup; +use Civi\Api4\CustomValue; +use Civi\Api4\Email; +use Civi\Test\Api4\Traits\TableDropperTrait; +use Civi\Test\Api4\UnitTestCase; +use Civi\Api4\Contact; + +/** + * @group headless + */ +class ReplaceTest extends UnitTestCase { + use TableDropperTrait; + + /** + * Set up baseline for testing + */ + public function setUp() { + $tablesToTruncate = [ + 'civicrm_custom_group', + 'civicrm_custom_field', + 'civicrm_email', + ]; + $this->dropByPrefix('civicrm_value_replacetest'); + $this->cleanup(['tablesToTruncate' => $tablesToTruncate]); + parent::setUp(); + } + + public function testEmailReplace() { + $cid1 = Contact::create() + ->addValue('first_name', 'Lotsa') + ->addValue('last_name', 'Emails') + ->execute() + ->first()['id']; + $cid2 = Contact::create() + ->addValue('first_name', 'Notso') + ->addValue('last_name', 'Many') + ->execute() + ->first()['id']; + $e0 = Email::create() + ->setValues(['contact_id' => $cid2, 'email' => 'nosomany@example.com', 'location_type_id' => 1]) + ->execute() + ->first()['id']; + $e1 = Email::create() + ->setValues(['contact_id' => $cid1, 'email' => 'first@example.com', 'location_type_id' => 1]) + ->execute() + ->first()['id']; + $e2 = Email::create() + ->setValues(['contact_id' => $cid1, 'email' => 'second@example.com', 'location_type_id' => 1]) + ->execute() + ->first()['id']; + $replacement = [ + ['email' => 'firstedited@example.com', 'id' => $e1], + ['contact_id' => $cid1, 'email' => 'third@example.com', 'location_type_id' => 1] + ]; + $replaced = Email::replace() + ->setRecords($replacement) + ->addWhere('contact_id', '=', $cid1) + ->execute(); + // Should have saved 2 records + $this->assertEquals(2, $replaced->count()); + // Should have deleted email2 + $this->assertEquals([$e2], $replaced->deleted); + // Verify contact now has the new email records + $results = Email::get() + ->addWhere('contact_id', '=', $cid1) + ->execute() + ->indexBy('id'); + $this->assertEquals('firstedited@example.com', $results[$e1]['email']); + $this->assertEquals(2, $results->count()); + $this->assertArrayNotHasKey($e2, (array) $results); + $this->assertArrayNotHasKey($e0, (array) $results); + unset($results[$e1]); + foreach ($results as $result) { + $this->assertEquals('third@example.com', $result['email']); + } + // Validate our other contact's email did not get deleted + $c2email = Email::get() + ->addWhere('contact_id', '=', $cid2) + ->execute() + ->first(); + $this->assertEquals('nosomany@example.com', $c2email['email']); + } + + public function testCustomValueReplace() { + $customGroup = CustomGroup::create() + ->setCheckPermissions(FALSE) + ->addValue('name', 'replaceTest') + ->addValue('extends', 'Contact') + ->addValue('is_multiple', TRUE) + ->execute() + ->first(); + + CustomField::create() + ->addValue('label', 'Custom1') + ->addValue('custom_group_id', $customGroup['id']) + ->addValue('html_type', 'String') + ->addValue('data_type', 'String') + ->execute(); + + CustomField::create() + ->setCheckPermissions(FALSE) + ->addValue('label', 'Custom2') + ->addValue('custom_group_id', $customGroup['id']) + ->addValue('html_type', 'String') + ->addValue('data_type', 'String') + ->execute(); + + $cid1 = Contact::create() + ->addValue('first_name', 'Lotsa') + ->addValue('last_name', 'Data') + ->execute() + ->first()['id']; + $cid2 = Contact::create() + ->addValue('first_name', 'Notso') + ->addValue('last_name', 'Much') + ->execute() + ->first()['id']; + + // Contact 2 gets one row + CustomValue::create('replaceTest') + ->setCheckPermissions(FALSE) + ->addValue('Custom1', "2 1") + ->addValue('Custom2', "2 1") + ->addValue('entity_id', $cid2) + ->execute(); + + // Create 3 rows for contact 1 + foreach ([1, 2, 3] as $i) { + CustomValue::create('replaceTest') + ->setCheckPermissions(FALSE) + ->addValue('Custom1', "1 $i") + ->addValue('Custom2', "1 $i") + ->addValue('entity_id', $cid1) + ->execute(); + } + + $cid1Records = CustomValue::get('replaceTest') + ->setCheckPermissions(FALSE) + ->addWhere('entity_id', '=', $cid1) + ->execute(); + + $this->assertCount(3, $cid1Records); + $this->assertCount(1, CustomValue::get('replaceTest')->setCheckPermissions(FALSE)->addWhere('entity_id', '=', $cid2)->execute()); + + $result = CustomValue::replace('replaceTest') + ->addWhere('entity_id', '=', $cid1) + ->addRecord(['Custom1' => 'new one', 'Custom2' => 'new two']) + ->addRecord(['id' => $cid1Records[0]['id'], 'Custom1' => 'changed one', 'Custom2' => 'changed two']) + ->execute(); + + $this->assertCount(2, $result); + $this->assertCount(2, $result->deleted); + + $newRecords = CustomValue::get('replaceTest') + ->setCheckPermissions(FALSE) + ->addWhere('entity_id', '=', $cid1) + ->execute() + ->indexBy('id'); + + $this->assertEquals('new one', $newRecords->last()['Custom1']); + $this->assertEquals('new two', $newRecords->last()['Custom2']); + $this->assertEquals('changed one', $newRecords[$cid1Records[0]['id']]['Custom1']); + $this->assertEquals('changed two', $newRecords[$cid1Records[0]['id']]['Custom2']); + } + +} diff --git a/www/crm/wp-content/plugins/civicrm/civicrm/ext/api4/tests/phpunit/Action/UpdateContactTest.php b/www/crm/wp-content/plugins/civicrm/civicrm/ext/api4/tests/phpunit/Action/UpdateContactTest.php new file mode 100644 index 00000000..71265598 --- /dev/null +++ b/www/crm/wp-content/plugins/civicrm/civicrm/ext/api4/tests/phpunit/Action/UpdateContactTest.php @@ -0,0 +1,34 @@ +<?php + +namespace Civi\Test\Api4\Action; + +use Civi\Api4\Contact; +use Civi\Test\Api4\UnitTestCase; + +/** + * Class UpdateContactTest + * @package Civi\Test\Api4\Action + * @group headless + */ +class UpdateContactTest extends UnitTestCase { + + public function testUpdateWillWork() { + $contactId = Contact::create() + ->setCheckPermissions(FALSE) + ->addValue('first_name', 'Johann') + ->addValue('last_name', 'Tester') + ->addValue('contact_type', 'Individual') + ->execute() + ->first()['id']; + + $contact = Contact::update() + ->setCheckPermissions(FALSE) + ->addWhere('id', '=', $contactId) + ->addValue('first_name', 'Testy') + ->execute() + ->first(); + $this->assertEquals('Testy', $contact['first_name']); + $this->assertEquals('Tester', $contact['last_name']); + } + +} diff --git a/www/crm/wp-content/plugins/civicrm/civicrm/ext/api4/tests/phpunit/Action/UpdateCustomValueTest.php b/www/crm/wp-content/plugins/civicrm/civicrm/ext/api4/tests/phpunit/Action/UpdateCustomValueTest.php new file mode 100644 index 00000000..99a9f011 --- /dev/null +++ b/www/crm/wp-content/plugins/civicrm/civicrm/ext/api4/tests/phpunit/Action/UpdateCustomValueTest.php @@ -0,0 +1,56 @@ +<?php + +namespace Civi\Test\Api4\Action; + +use Civi\Api4\Contact; +use Civi\Api4\CustomField; +use Civi\Api4\CustomGroup; +use \CRM_Core_BAO_CustomValueTable as CustomValueTable; + +/** + * @group headless + */ +class UpdateCustomValueTest extends BaseCustomValueTest { + + public function testGetWithCustomData() { + + $customGroup = CustomGroup::create() + ->setCheckPermissions(FALSE) + ->addValue('name', 'MyContactFields') + ->addValue('extends', 'Contact') + ->execute() + ->first(); + + CustomField::create() + ->setCheckPermissions(FALSE) + ->addValue('label', 'FavColor') + ->addValue('custom_group_id', $customGroup['id']) + ->addValue('html_type', 'Text') + ->addValue('data_type', 'String') + ->execute(); + + $contactId = Contact::create() + ->setCheckPermissions(FALSE) + ->addValue('first_name', 'Red') + ->addValue('last_name', 'Tester') + ->addValue('contact_type', 'Individual') + ->addValue('MyContactFields.FavColor', 'Red') + ->execute() + ->first()['id']; + + Contact::update() + ->setCheckPermissions(FALSE) + ->addWhere('id', '=', $contactId) + ->addValue('first_name', 'Red') + ->addValue('last_name', 'Tester') + ->addValue('contact_type', 'Individual') + ->addValue('MyContactFields.FavColor', 'Blue') + ->execute(); + + $result = CustomValueTable::getEntityValues($contactId, 'Contact'); + + $this->assertEquals(1, count($result)); + $this->assertContains('Blue', $result); + } + +} |