View source
<?php
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');
}
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);
}
function tagUser(&$user, $field_name, $tids = array()) {
for ($i = 0; $i < count($tids); $i++) {
$user->{$field_name}['und'][]['tid'] = $tids[$i];
}
user_save($user);
}
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() {
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),
'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() {
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'],
)));
}
}
}
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);
$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,
),
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;
$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();
$this
->accessGrants(false);
}
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'];
$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);
}
$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];
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);
if ($term_list_reversed[$j]->tid === FALSE && $term_list_ordered[$j]->tid !== FALSE) {
$expect_access[$i][$j] = FALSE;
}
elseif ($term_list_reversed[$j]->tid === FALSE && $term_list_ordered[$j]->tid === FALSE) {
$expect_access[$i][$j] = FALSE;
}
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]);
}
}
}
}
}