You are here

abt.test in Access By Term 7

File

abt.test
View source
<?php

/*
* Test cases for abt.
*/
class ABTWebTestCase extends DrupalWebTestCase {
  protected $user;
  protected $vocabularies;
  protected $terms = array();
  protected $content_type;
  protected $fields = array();
  protected $field_instances = array();
  function setUp() {
    parent::setUp('abt');
  }

  /* Partial setup */
  function setUpTaxonomy() {
    $this->vocabularies = $this
      ->createVocabulary();
    $this->terms = $this
      ->populateVocabularies($this->vocabularies);
  }
  function setUpContentStructure($field_number = 3) {
    $this->content_type = $this
      ->createContentType();
    $this->fields = $this
      ->createFields($field_number);
    $this->field_instances = $this
      ->createFieldInstances($this->fields, $this->content_type);
  }

  /* Helpers */
  function tagUser(&$user, $field_name, $tids = array()) {
    for ($i = 0; $i < count($tids); $i++) {
      $user->{$field_name}['und'][]['tid'] = $tids[$i];
    }
    user_save($user);

    #$this->unauthorized_user->{$this->field_instances['user'][0]['field_name']}['und'][]['tid'] = $this->terms[0]->tid;
  }
  function createVocabulary($numberOfVocs = 1) {
    for ($i = 0; $i < $numberOfVocs; $i++) {
      $vocs[$i] = (object) array(
        'name' => $this
          ->randomName(),
        'machine_name' => drupal_strtolower($this
          ->randomName()),
      );
      taxonomy_vocabulary_save($vocs[$i]);
    }
    return $vocs;
  }
  function populateVocabularies($vocs, $numberOfTerms = 3) {
    $terms = array();
    for ($i = 0; $i < count($vocs); $i++) {
      $parent = 0;
      for ($j = 0; $j < $numberOfTerms; $j++) {
        $term = (object) array(
          'vid' => $vocs[$i]->vid,
          'name' => $this
            ->randomName(),
          'parent' => $parent,
        );
        taxonomy_term_save($term);
        $parent = $term->tid;
        $terms[$i][$j] = $term;
      }
    }
    return $terms;
  }
  function createContentType() {

    // Create a content type programmaticaly.
    return $this
      ->drupalCreateContentType();
  }
  function createFields($number_of_fields = 3) {
    $fields = array();
    $vocs = isset($this->vocabularies) ? $this->vocabularies : array(
      (object) array(
        'machine_name' => 'no_voc',
      ),
    );
    $voc_index = 0;
    for ($i = 0; $i < $number_of_fields; $i++) {
      if ($i >= count($vocs)) {
        $voc_index = 0;
      }
      $field = array(
        'field_name' => drupal_strtolower($this
          ->randomName() . '_field_name'),
        'type' => 'taxonomy_term_reference',
        'cardinality' => FIELD_CARDINALITY_UNLIMITED,
        'settings' => array(
          'allowed_values' => array(
            array(
              'vocabulary' => $vocs[$voc_index]->machine_name,
              'parent' => 0,
            ),
          ),
        ),
      );
      field_create_field($field);
      $fields[$i] = $field;
    }
    return $fields;
  }
  function createFieldInstances($field, $content_type, $entity_types = array(
    'node',
    'user',
  )) {
    $instances = $entity_types;
    for ($i = 0; $i < count($entity_types); $i++) {
      for ($j = 0; $j < count($field); $j++) {
        $instances[$entity_types[$i]][$j] = array(
          'field_name' => $field[$j]['field_name'],
          'entity_type' => $entity_types[$i],
          'bundle' => $entity_types[$i] == 'user' ? 'user' : $content_type->type,
          'label' => $field[$j]['field_name'] . '_fl_inst_label',
          'description' => $this
            ->randomName() . '_fl_inst_description',
          'weight' => mt_rand(0, 127),
          // test_field has no instance settings
          'widget' => array(
            'type' => 'test_field_widget',
            'settings' => array(
              'size' => mt_rand(0, 255),
            ),
          ),
        );
        field_create_instance($instances[$entity_types[$i]][$j]);
      }
    }
    return $instances;
  }
  function postFieldSettings($content_type, $field, $v, $u, $d) {
    $this
      ->drupalPost('admin/structure/types/manage/' . $content_type . '/fields/' . $field['field_name'], array(
      'abt_enable_view_control' => (int) $v,
      'abt_enable_update_control' => (int) $u,
      'abt_enable_delete_control' => (int) $d,
    ), 'Save settings');
    $this
      ->assertText(t('Saved ' . $field['label'] . ' configuration.'));
  }

}
class ABTEnviromentTestCase extends ABTWebTestCase {
  public static function getInfo() {
    return array(
      'name' => 'ABT environment test',
      'description' => 'Test if the environment is setup for the test (terms,fields,users,osv).',
      'group' => 'Access by Term (ABT)',
    );
  }
  function setUp() {
    parent::setUp();
    $this->user = $this
      ->drupalCreateUser(array(
      'assign view access control',
      'assign update access control',
      'assign delete access control',
      'administer content types',
      'administer permissions',
      'access user profiles',
      'administer site configuration',
      'administer modules',
      'administer users',
    ));
    $this
      ->drupalLogin($this->user);
    $this
      ->setUpTaxonomy();
    $this
      ->setUpContentStructure(5);
  }
  function testEnviroment() {
    $this
      ->envTestVocabularyCreation();
    $this
      ->envTestTermCreation();
    $this
      ->envTestContentTypeCreation();
    $this
      ->envTestFieldCreation();
    $this
      ->envTestFieldInstanceCreation();
    $this
      ->envTestUserData();
    $this
      ->envTestNodeData();
  }
  function envTestVocabularyCreation() {
    for ($i = 0; $i < count($this->vocabularies); $i++) {
      $loaded = taxonomy_vocabulary_load($this->vocabularies[$i]->vid);
      $this
        ->assertEqual($loaded->name, $this->vocabularies[$i]->name, t("Vocabulary %vid was created.", array(
        '%vid' => $loaded->vid,
      )));
    }
  }
  function envTestTermCreation() {
    foreach ($this->terms as $vid => $terms) {
      $parent_tid = 0;
      for ($i = 0; $i < count($terms); $i++) {
        $loaded = taxonomy_term_load($terms[$i]->tid);
        $this
          ->assertEqual($loaded->name, $terms[$i]->name, t('Taxonomy term @tid was created.', array(
          '@tid' => $loaded->tid . ' - ' . $loaded->name,
        )));
        $this
          ->assertEqual($parent_tid, $terms[$i]->parent[0], t('Taxonomy term hierarchy confirmed: @parent -> @child ', array(
          '@parent' => $parent_tid,
          '@child' => $terms[$i]->tid,
        )));
        $parent_tid = $loaded->tid;
      }
    }
  }
  function envTestContentTypeCreation() {
    $type_exists = db_query('SELECT 1 FROM {node_type} WHERE type = :type', array(
      ':type' => $this->content_type->type,
    ))
      ->fetchField();
    $this
      ->assertTrue($type_exists, 'The new content type has been created in the database: (' . $this->content_type->type . ')');
  }
  function envTestFieldCreation() {

    #$this->assertEqual(count($this->fields), 3, 'flds: '.$this->fields[0]['type']);
    for ($i = 0; $i < count($this->fields); $i++) {
      $loaded = field_info_field($this->fields[$i]['field_name']);
      $this
        ->assertEqual($loaded['field_name'] . $loaded['type'], $this->fields[$i]['field_name'] . $this->fields[$i]['type'], t('Field (@fname) was created.', array(
        '@fname' => $loaded['field_name'] . ', ' . $loaded['type'],
      )));
    }
  }
  function envTestFieldInstanceCreation($entity_types = array(
    'node',
    'user',
  )) {
    for ($i = 0; $i < count($entity_types); $i++) {
      for ($j = 0; $j < count($this->field_instances[$entity_types[$i]]); $j++) {
        $field_name = $this->field_instances[$entity_types[$i]][$j]['field_name'];
        $bundle = $this->field_instances[$entity_types[$i]][$j]['bundle'];
        $loaded = field_info_instance($entity_types[$i], $field_name, $bundle);
        $this
          ->assertTrue(isset($loaded['id']), t('Field instance created for field (@instname)', array(
          '@instname' => $field_name . ' - ' . $loaded['entity_type'],
        )));

        // Another way to check if field instances are created...
        // $info = _field_info_collate_fields();
        // $this->assertTrue(
        //   isset($info['instances'][$entity_types[$i]][$bundle][$field_name]),
        //   t('Field instance created: (@instname)', array('@instname' => $field_name.' - '.$this->field_instances[$entity_types[$i]][$j]['label']))
        // );
      }
    }
  }
  function envTestUserData() {
    $usr = user_load($this->user->uid);
    $this
      ->tagUser($usr, $this->fields[0]['field_name'], $tids = array(
      $this->terms[0][1]->tid,
      $this->terms[0][1]->tid,
    ));
    $usr = user_load($this->user->uid);
    $tid = $usr->{$this->fields[0]['field_name']}['und'][0]['tid'];
    $term = taxonomy_term_load($tid);
    $this
      ->assertTrue(isset($term->name), t('User tagged with term id (@var1)', array(
      '@var1' => $tid . ' - ' . $term->tid . ' - ' . $term->name . ' - ' . $this->field_instances['user'][0]['field_name'],
    )));
  }
  function envTestNodeData() {
    $node = $this
      ->drupalCreateNode(array(
      'type' => $this->content_type->type,
    ));
    $n = node_load($node->nid);
    $this
      ->assertTrue(isset($n->nid), 'Node created. (Nid:' . $n->nid . ')');
    $n->{$this->field_instances['node'][0]['field_name']}[$node->language][]['tid'] = $this->terms[0][1]->tid;
    node_save($n);
    $saved_tid = $n->{$this->field_instances['node'][0]['field_name']}[$node->language][0]['tid'];
    $n = node_load($n->nid);

    // just in case :)
    $this
      ->assertTrue(isset($n->nid) && $this->terms[0][1]->tid == $saved_tid, 'Term reference added. (Nid:' . $n->nid . ' - Tid:' . $saved_tid . ')');
  }

}
class ABTPermissionFieldTestCase extends ABTWebTestCase {
  public static function getInfo() {
    return array(
      'name' => 'ABT field settings test',
      'description' => 'Test ABT properties for fields (changing the field settings). If user can assign field as access-controlling.',
      'group' => 'Access by Term (ABT)',
    );
  }
  function setUp() {
    parent::setUp();
    $this
      ->setUpTaxonomy();
    $this
      ->setUpContentStructure(3);
  }
  function testEditFieldSettings() {
    $users = array(
      array(
        'assign view access control',
        'assign update access control',
        'assign delete access control',
        'administer content types',
      ),
    );
    $this->user = $this
      ->drupalCreateUser($users[0]);
    $this
      ->drupalLogin($this->user);
    $this
      ->runFieldSettingCombos();
    $this
      ->drupalLogout($this->user);
  }
  function runFieldSettingCombos() {
    $combos = array(
      array(
        'v' => ABT_CONTROL_DEFAULT_RESTRICT,
        'u' => ABT_NO_CONTROL,
        'd' => ABT_NO_CONTROL,
      ),
      array(
        'v' => ABT_NO_CONTROL,
        'u' => ABT_CONTROL_DEFAULT_RESTRICT,
        'd' => ABT_NO_CONTROL,
      ),
      array(
        'v' => ABT_NO_CONTROL,
        'u' => ABT_NO_CONTROL,
        'd' => ABT_CONTROL_DEFAULT_RESTRICT,
      ),
      array(
        'v' => ABT_CONTROL_DEFAULT_RESTRICT,
        'u' => ABT_CONTROL_DEFAULT_RESTRICT,
        'd' => ABT_NO_CONTROL,
      ),
      array(
        'v' => ABT_CONTROL_DEFAULT_RESTRICT,
        'u' => ABT_NO_CONTROL,
        'd' => ABT_CONTROL_DEFAULT_RESTRICT,
      ),
      array(
        'v' => ABT_NO_CONTROL,
        'u' => ABT_CONTROL_DEFAULT_RESTRICT,
        'd' => ABT_CONTROL_DEFAULT_RESTRICT,
      ),
      array(
        'v' => ABT_NO_CONTROL,
        'u' => ABT_NO_CONTROL,
        'd' => ABT_NO_CONTROL,
      ),
      /* this row should not be saved */
      array(
        'v' => ABT_CONTROL_DEFAULT_RESTRICT,
        'u' => ABT_CONTROL_DEFAULT_RESTRICT,
        'd' => ABT_CONTROL_DEFAULT_RESTRICT,
      ),
    );
    for ($j = 0, $i = 0; $i < count($combos); $i++, $j++) {
      $j = $j >= count($this->field_instances['node']) ? 0 : $j;

      // field counter
      $v = $combos[$i]['v'];
      $u = $combos[$i]['u'];
      $d = $combos[$i]['d'];
      $this
        ->postFieldSettings($this->content_type->type, $this->field_instances['node'][$j], $v, $u, $d);
      $expect = 1;
      $field = field_info_field($this->field_instances['node'][$j]['field_name']);
      $rowCount = 1;
      if (isset($field['settings']['abt_map'])) {
        if ($field['settings']['abt_map']['ctrl_view_access'] != $v) {
          $rowCount = 0;
        }
        if ($field['settings']['abt_map']['ctrl_update_access'] != $u) {
          $rowCount = 0;
        }
        if ($field['settings']['abt_map']['ctrl_delete_access'] != $d) {
          $rowCount = 0;
        }
      }
      $this
        ->assertTrue($rowCount == $expect, t('Field values changed as planned. (' . $v . $u . $d . ') = (' . $rowCount . ') Row was @not found.', array(
        '@not' => $expect ? '' : 'not',
      )));
    }
  }

}
class ABTPermissionGrantsTestCase extends ABTWebTestCase {
  public static function getInfo() {
    return array(
      'name' => 'ABT node access grants test',
      'description' => 'Test if ABT is restricting/allowing access as designed (takes a few minutes).',
      'group' => 'Access by Term (ABT)',
    );
  }
  function setUp() {
    parent::setUp();
    $this
      ->setUpTaxonomy();
    $this
      ->setUpContentStructure(5);
  }
  function testGrants() {
    $this
      ->accessGrants();

    // authenticated users
    $this
      ->accessGrants(false);

    // unauthenticated users
  }
  function accessGrants($authenticateUsers = true) {
    $flag_map[$this->fields[0]['field_name']] = array(
      'v' => 1,
      'u' => 1,
      'd' => 1,
    );
    $flag_map[$this->fields[1]['field_name']] = array(
      'v' => 1,
      'u' => 0,
      'd' => 0,
    );
    $flag_map[$this->fields[2]['field_name']] = array(
      'v' => 0,
      'u' => 1,
      'd' => 0,
    );
    $flag_map[$this->fields[3]['field_name']] = array(
      'v' => 0,
      'u' => 0,
      'd' => 1,
    );
    $flag_map[$this->fields[4]['field_name']] = array(
      'v' => 1,
      'u' => 0,
      'd' => 1,
    );
    for ($x = 0; $x < count($this->fields); $x++) {
      $field_name = $this->fields[$x]['field_name'];
      $v = $flag_map[$field_name]['v'];
      $u = $flag_map[$field_name]['u'];
      $d = $flag_map[$field_name]['d'];

      // loop trough terms and create users
      $user_map = array();
      $node_map = array();
      $expect_map = array();
      for ($i = 0; $i < count($this->terms); $i++) {
        $fields = field_read_fields();
        foreach ($fields as $field_name => $field) {
          unset($field['settings']['abt_map']);
          field_update_field($field);
        }

        // clean slate (for good measure)
        $field = field_info_field($field_name);
        $field_abt_map = array(
          'ctrl_view_access' => $v,
          'ctrl_update_access' => $u,
          'ctrl_delete_access' => $d,
        );
        $field['settings']['abt_map'] = $field_abt_map;
        field_update_field($field);
        node_access_rebuild();
        $term_list_ordered = $this->terms[$i];

        // Make sure we have some nodes and users without access flags.
        array_push($term_list_ordered, (object) array(
          'tid' => FALSE,
        ));
        array_unshift($term_list_ordered, (object) array(
          'tid' => FALSE,
        ));
        $term_list_reversed = array_reverse($term_list_ordered);
        for ($j = 0; $j < count($term_list_ordered); $j++) {
          $user_map[$i][$j] = $this
            ->drupalCreateUser();
          $node_map[$i][$j] = $this
            ->drupalCreateNode(array(
            'type' => $this->content_type->type,
          ));
          $usr = user_load($user_map[$i][$j]->uid);
          $nde = node_load($node_map[$i][$j]->nid);
          $term_list_ordered[$j]->tid !== FALSE && ($nde->{$field_name}['und'][0]['tid'] = $term_list_ordered[$j]->tid);
          $term_list_reversed[$j]->tid !== FALSE && ($usr->{$field_name}['und'][0]['tid'] = $term_list_reversed[$j]->tid);
          user_save($usr);
          node_save($nde);

          /*
           * Blocks bellow basicly say:
           * if either node or user lacks access flag = expect "access denied".
           */

          // User has no access tags && Node has access tags
          if ($term_list_reversed[$j]->tid === FALSE && $term_list_ordered[$j]->tid !== FALSE) {
            $expect_access[$i][$j] = FALSE;

            // User has no access tags && Node has no access tags
          }
          elseif ($term_list_reversed[$j]->tid === FALSE && $term_list_ordered[$j]->tid === FALSE) {
            $expect_access[$i][$j] = FALSE;

            // User has access tags && Node has no access tags
          }
          elseif ($term_list_reversed[$j]->tid !== FALSE && $term_list_ordered[$j]->tid === FALSE) {
            $expect_access[$i][$j] = FALSE;
          }
          else {
            $expect_access[$i][$j] = $term_list_reversed[$j]->tid <= $term_list_ordered[$j]->tid;
          }
          $authenticateUsers && $this
            ->drupalLogin($user_map[$i][$j]);
          $this
            ->drupalGet('node/' . $node_map[$i][$j]->nid);
          $text_to_expect = $authenticateUsers && $v == 1 && $expect_access[$i][$j] ? $nde->title : t('Access denied');
          $msg = $authenticateUsers && $v == 1 && $expect_access[$i][$j] ? t('View: access allowed') : t('View: access denied');
          $this
            ->assertText($text_to_expect, $msg . ' (' . $v . $u . $d . ') user-tid:' . ($term_list_reversed[$j]->tid === FALSE ? 'none' : $term_list_reversed[$j]->tid) . ' <= node-tid:' . ($term_list_ordered[$j]->tid === FALSE ? 'none' : $term_list_ordered[$j]->tid));
          $this
            ->drupalGet('node/' . $node_map[$i][$j]->nid . '/edit');
          $text_to_expect = $authenticateUsers && $u == 1 && $expect_access[$i][$j] ? $nde->title : t('Access denied');
          $msg = $authenticateUsers && $u == 1 && $expect_access[$i][$j] ? t('Update: access allowed') : t('Update: access denied');
          $this
            ->assertText($text_to_expect, $msg . ' (' . $v . $u . $d . ') user-tid:' . ($term_list_reversed[$j]->tid === FALSE ? 'none' : $term_list_reversed[$j]->tid) . ' <= node-tid:' . ($term_list_ordered[$j]->tid === FALSE ? 'none' : $term_list_ordered[$j]->tid));
          $this
            ->drupalGet('node/' . $node_map[$i][$j]->nid . '/delete');
          $text_to_expect = $authenticateUsers && $d == 1 && $expect_access[$i][$j] ? $nde->title : t('Access denied');
          $msg = $authenticateUsers && $d == 1 && $expect_access[$i][$j] ? t('Delete: access allowed') : t('Delete: access denied');
          $this
            ->assertText($text_to_expect, $msg . ' (' . $v . $u . $d . ') user-tid:' . ($term_list_reversed[$j]->tid === FALSE ? 'none' : $term_list_reversed[$j]->tid) . ' <= node-tid:' . ($term_list_ordered[$j]->tid === FALSE ? 'none' : $term_list_ordered[$j]->tid));
          $authenticateUsers && $this
            ->drupalLogout($user_map[$i][$j]);
        }
      }
    }
  }

}