CRM-17350 add unit test for tag api create permission
authoreileenmcnaughton <eileen@fuzion.co.nz>
Mon, 25 Jan 2016 01:08:06 +0000 (01:08 +0000)
committereileenmcnaughton <eileen@fuzion.co.nz>
Mon, 25 Jan 2016 04:04:40 +0000 (04:04 +0000)
tests/phpunit/api/v3/EntityTagACLTest.php [new file with mode: 0644]

diff --git a/tests/phpunit/api/v3/EntityTagACLTest.php b/tests/phpunit/api/v3/EntityTagACLTest.php
new file mode 100644 (file)
index 0000000..5787358
--- /dev/null
@@ -0,0 +1,234 @@
+<?php
+/*
+ +--------------------------------------------------------------------+
+ | CiviCRM version 4.7                                                |
+ +--------------------------------------------------------------------+
+ | Copyright CiviCRM LLC (c) 2004-2015                                |
+ +--------------------------------------------------------------------+
+ | This file is a part of CiviCRM.                                    |
+ |                                                                    |
+ | CiviCRM is free software; you can copy, modify, and distribute it  |
+ | under the terms of the GNU Affero General Public License           |
+ | Version 3, 19 November 2007 and the CiviCRM Licensing Exception.   |
+ |                                                                    |
+ | CiviCRM is distributed in the hope that it will be useful, but     |
+ | WITHOUT ANY WARRANTY; without even the implied warranty of         |
+ | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.               |
+ | See the GNU Affero General Public License for more details.        |
+ |                                                                    |
+ | You should have received a copy of the GNU Affero General Public   |
+ | License and the CiviCRM Licensing Exception along                  |
+ | with this program; if not, contact CiviCRM LLC                     |
+ | at info[AT]civicrm[DOT]org. If you have questions about the        |
+ | GNU Affero General Public License or the licensing of CiviCRM,     |
+ | see the CiviCRM license FAQ at http://civicrm.org/licensing        |
+ +--------------------------------------------------------------------+
+ */
+
+/**
+ *  Test APIv3 civicrm_entity_tag_* functions
+ *
+ * @package CiviCRM_APIv3
+ * @subpackage API_Core
+ */
+
+require_once 'CiviTest/CiviUnitTestCase.php';
+
+/**
+ * Class api_v3_EntityTagTest.
+ *
+ * This test class was introduced to ensure that the fix for CRM-17350 (reducing the required permission
+ * from edit all contacts to has right to edit this contact) would not result in inappropriate permission opening on
+ * other entities. Other entities are still too restricted but that is a larger job.
+ */
+class api_v3_EntityTagACLTest extends CiviUnitTestCase {
+
+  /**
+   * API Version in use.
+   *
+   * @var int
+   */
+  protected $_apiversion = 3;
+
+  /**
+   * Entity being tested.
+   *
+   * @var string
+   */
+  protected $_entity = 'entity_tag';
+
+  /**
+   * Set up permissions for test.
+   */
+  public function setUp() {
+    $this->useTransaction(TRUE);
+    parent::setUp();
+    $individualID = $this->individualCreate();
+    $daoObj = new CRM_Core_DAO();
+    $this->callAPISuccess('Attachment', 'create', array(
+      'entity_table' => 'civicrm_contact',
+      'entity_id' => $individualID,
+      'mime_type' => 'k',
+      'name' => 'p',
+      'content' => 'l',
+    ));
+    $daoObj->createTestObject('CRM_Activity_BAO_Activity', array(), 1, 0);
+    $daoObj->createTestObject('CRM_Case_BAO_Case', array(), 1, 0);
+    $entities = $this->getTagOptions();
+    foreach ($entities as $key => $entity) {
+      $this->callAPISuccess('Tag', 'create', array(
+        'used_for' => $key,
+        'name' => $entity,
+        'description' => $entity,
+        )
+      );
+    }
+    CRM_Core_Config::singleton()->userPermissionClass->permissions = array('access CiviCRM');
+  }
+
+  /**
+   * Get the options for the used_for fields.
+   *
+   * @return array
+   */
+  public function getTagOptions() {
+    $options = $this->callAPISuccess('Tag', 'getoptions', array('field' => 'used_for'));
+    return $options['values'];
+  }
+
+  /**
+   * Get the entity table for a tag label.
+   *
+   * @param string $entity
+   *
+   * @return string
+   */
+  protected function getTableForTag($entity) {
+    $options = $this->getTagOptions();
+    return array_search($entity, $options);
+  }
+  /**
+   * Get entities which can be tagged in data provider format.
+   */
+  public function taggableEntities() {
+    $return = array();
+    foreach ($this->getTagOptions() as $entity) {
+      $return[] = array($entity);
+    }
+    return $return;
+  }
+
+  /**
+   * This test checks that users with edit all contacts can edit all tags.
+   *
+   * @dataProvider taggableEntities
+   *
+   * We are looking to see that a contact with edit all contacts can still add all tags (for all
+   * tag entities since that was how it was historically and we are not fixing non-contact entities).
+   *
+   * @param string $entity
+   *   Entity to test
+   */
+  public function testThatForEntitiesEditAllContactsCanAddTags($entity) {
+
+    CRM_Core_Config::singleton()->userPermissionClass->permissions = array('edit all contacts');
+    $this->callAPISuccess('EntityTag', 'create', array(
+      'entity_id' => 1,
+      'tag_id' => $entity,
+      'check_permissions' => TRUE,
+      'entity_table' => $this->getTableForTag($entity),
+    ));
+    $this->callAPISuccessGetCount('EntityTag', array(
+      'entity_id' => 1,
+      'entity_table' => $this->getTableForTag($entity),
+    ), 1);
+  }
+
+  /**
+   * This test checks that an ACL or edit all contacts is required to be able to create a contact.
+   *
+   * @dataProvider taggableEntities
+   */
+  public function testThatForEntityWithoutACLOrEditAllThereIsNoAccess($entity) {
+
+    CRM_Core_Config::singleton()->userPermissionClass->permissions = array('access CiviCRM', 'view all contacts');
+    $this->callAPISuccess('EntityTag', 'create', array(
+      'entity_id' => 1,
+      'tag_id' => $entity,
+      'check_permissions' => TRUE,
+      'entity_table' => $this->getTableForTag($entity),
+    ));
+    $this->callAPISuccessGetCount('EntityTag', array(
+      'entity_id' => 1,
+      'entity_table' => $this->getTableForTag($entity),
+    ), 0);
+  }
+
+  /**
+   * This test checks that permissions are not applied when check_permissions is off.
+   *
+   * @dataProvider taggableEntities
+   *
+   * @param string $entity
+   *   Entity to test
+   */
+  public function testCheckPermissionsOffWorks($entity) {
+
+    CRM_Core_Config::singleton()->userPermissionClass->permissions = array('access CiviCRM', 'view all contacts');
+    $result = $this->callAPISuccess('EntityTag', 'create', array(
+      'entity_id' => 1,
+      'tag_id' => $entity,
+      'check_permissions' => 0,
+      'entity_table' => $this->getTableForTag($entity),
+    ));
+    $this->assertEquals(1, $result['added']);
+    $this->callAPISuccessGetCount('EntityTag', array(
+      'entity_id' => 1,
+      'entity_table' => $this->getTableForTag($entity),
+      'check_permissions' => 0,
+    ), 1);
+  }
+
+  /**
+   * This test checks ACLs can be used to control who can edit a contact.
+   *
+   * Note that for other entities this hook will not allow them to edit the entity_tag and they still need
+   * edit all contacts (pending a more extensive fix).
+   *
+   * @dataProvider taggableEntities
+   *
+   * @param string $entity
+   *   Entity to test
+   */
+  public function testThatForEntitiesACLApplies($entity) {
+
+    CRM_Core_Config::singleton()->userPermissionClass->permissions = array('access CiviCRM', 'view all contacts');
+    $this->hookClass->setHook('civicrm_aclWhereClause', array($this, 'aclWhereHookAllResults'));
+    $this->callAPISuccess('EntityTag', 'create', array(
+      'entity_id' => 1,
+      'tag_id' => $entity,
+      'entity_table' => $this->getTableForTag($entity),
+      'check_permissions' => TRUE,
+    ));
+    $this->callAPISuccessGetCount('EntityTag', array(
+      'entity_id' => 1,
+      'entity_table' => $this->getTableForTag($entity),
+    ), ($entity == 'Contacts' ? 1 : 0));
+  }
+
+  /**
+   * All results returned.
+   *
+   * @implements CRM_Utils_Hook::aclWhereClause
+   *
+   * @param string $type
+   * @param array $tables
+   * @param array $whereTables
+   * @param int $contactID
+   * @param string $where
+   */
+  public function aclWhereHookAllResults($type, &$tables, &$whereTables, &$contactID, &$where) {
+    $where = " (1) ";
+  }
+
+}