array( 'access content', 'access site reports', 'access administration pages', 'administer permissions', 'create article content', 'edit any article content', 'create page content', 'edit any page content', ), 'tax_admin' => array( 'access content', 'administer taxonomy', ), 'editor' => array( 'access content', 'create article content', 'create page content', ), 'regular_user' => array( 'access content', ), ); public function setUp() { // Enable module and dependencies. parent::setUp('taxonomy_access'); // Rebuild node access on installation. node_access_rebuild(); // Configure users with base permission patterns. foreach ($this->user_config as $user => $permissions) { $this->users[$user] = $this->drupalCreateUser($permissions); // Save the role ID separately so it's easy to retrieve. foreach ($this->users[$user]->roles as $rid => $role) { if ($rid != DRUPAL_AUTHENTICATED_RID) { $this->user_roles[$user] = user_role_load($rid); } } } // Give the anonymous and authenticated roles ignore grants. $rows = array(); foreach (array(DRUPAL_ANONYMOUS_RID, DRUPAL_AUTHENTICATED_RID) as $rid) { $ignore = array( 'view' => TAXONOMY_ACCESS_NODE_IGNORE, 'update' => TAXONOMY_ACCESS_NODE_IGNORE, 'delete' => TAXONOMY_ACCESS_NODE_IGNORE, ); $rows[] = _taxonomy_access_format_grant_record(TAXONOMY_ACCESS_GLOBAL_DEFAULT, $rid, $ignore, TRUE); } taxonomy_access_set_default_grants($rows); foreach (array(DRUPAL_ANONYMOUS_RID, DRUPAL_AUTHENTICATED_RID) as $rid) { $r = db_query( 'SELECT grant_view FROM {taxonomy_access_default} WHERE vid = :vid AND rid = :rid', array(':vid' => TAXONOMY_ACCESS_GLOBAL_DEFAULT, ':rid' => $rid) ) ->fetchField(); $this->assertTrue(is_numeric($r) && $r == 0, t("Set global default for role %rid to Ignore", array('%rid' => $rid))); } } /** * Creates a vocabulary with a certain name. * * @param string $machine_name * A machine-safe name. * * @return object * The vocabulary object. */ function createVocab($machine_name) { $vocabulary = new stdClass(); $vocabulary->name = $machine_name; $vocabulary->description = $this->randomName(); $vocabulary->machine_name = $machine_name; $vocabulary->help = ''; $vocabulary->weight = mt_rand(0, 10); taxonomy_vocabulary_save($vocabulary); return $vocabulary; } /** * Creates a new term in the specified vocabulary. * * @param string $machine_name * A machine-safe name. * @param object $vocab * A vocabulary object. * @param int|null $parent * (optional) The tid of the parent term, if any. Defaults to NULL. * * @return object * The taxonomy term object. */ function createTerm($machine_name, $vocab, $parent = NULL) { $term = new stdClass(); $term->name = $machine_name; $term->description = $machine_name; // Use the first available text format. $term->format = db_query_range('SELECT format FROM {filter_format}', 0, 1)->fetchField(); $term->vid = $vocab->vid; $term->vocabulary_machine_name = $vocab->machine_name; if (!is_null($parent)) { $term->parent = $parent; } taxonomy_term_save($term); return $term; } /** * Creates a taxonomy field and adds it to the page content type. * * @param string $machine_name * The machine name of the vocabulary to use. * @param string $widget * (optional) The name of the widget to use. Defaults to 'options_select'. * @param int $count * (optional) The allowed number of values. Defaults to unlimited. * * @return array * Array of instance data. */ function createField($machine_name, $widget = 'options_select', $count = FIELD_CARDINALITY_UNLIMITED) { $field = array( 'field_name' => $machine_name, 'type' => 'taxonomy_term_reference', 'cardinality' => $count, 'settings' => array( 'allowed_values' => array( array( 'vocabulary' => $machine_name, 'parent' => 0, ), ), ), ); $field = field_create_field($field); $instance = array( 'field_name' => $machine_name, 'bundle' => 'page', 'entity_type' => 'node', 'widget' => array( 'type' => $widget, ), 'display' => array( 'default' => array( 'type' => 'taxonomy_term_reference_link', ), ), ); return field_create_instance($instance); } /** * Creates an article with the specified terms. * * @param array $autocreate * (optional) An array of term names to autocreate. Defaults to array(). * @param array $existing * (optional) An array of existing term IDs to add. * * @return object * The node object. */ function createArticle($autocreate = array(), $existing = array()) { $values = array(); foreach ($autocreate as $name) { $values[] = array('tid' => 'autocreate', 'vid' => 1, 'name' => $name, 'vocabulary_machine_name' => 'tags'); } foreach ($existing as $tid) { $values[] = array('tid' => $tid, 'vid' => 1, 'vocabulary_machine_name' => 'tags'); } // Bloody $langcodes. $values = array(LANGUAGE_NONE => $values); $settings = array( 'type' => 'article', 'field_tags' => $values, ); return $this->drupalCreateNode($settings); } /** * Submits the node access rebuild form. */ function rebuild() { $this->drupalPost('admin/reports/status/rebuild', array(), t('Rebuild permissions')); $this->assertText(t('The content access permissions have been rebuilt.')); } /** * Asserts that a status column and "Configure" link is found for the role. * * @param array $statuses * An associative array of role statuses, keyed by role ID. Each item * should be TRUE if the role is enabled, and FALSE otherwise. */ function checkRoleConfig(array $statuses) { $roles = _taxonomy_access_user_roles(); // Log in as the administrator. $this->drupalLogout(); $this->drupalLogin($this->users['site_admin']); $this->drupalGet(TAXONOMY_ACCESS_CONFIG); foreach ($statuses as $rid => $status) { // Assert that a "Configure" link is available for the role. $this->assertLinkByHref( TAXONOMY_ACCESS_CONFIG . "/role/$rid/edit", 0, t('"Configure" link is available for role %rid.', array('%rid' => $rid))); } // Retrieve the grant status table. $shown = array(); $table = $this->xpath('//table/tbody'); $table = reset($table); // SimpleXML has fake arrays so we have to do this to get the data out. foreach ($table->tr as $row) { $tds = array(); foreach ($row->td as $value) { $tds[] = (string) $value; } $shown[$tds[0]] = $tds[1]; } foreach ($statuses as $rid => $status) { // Assert that the form shows the passed status. if ($status) { $this->assertTrue( $shown[$roles[$rid]] == t('Enabled'), format_string('Role %role is enabled.', array('%role' => $rid))); } else { $this->assertTrue( $shown[$roles[$rid]] == t('Disabled'), format_string('Role %role is disabled.', array('%role' => $rid))); } // Assert that a "Configure" link is available for the role. $this->assertLinkByHref( TAXONOMY_ACCESS_CONFIG . "/role/$rid/edit", 0, t('"Configure" link is available for role %rid.', array('%rid' => $rid))); } } /** * Asserts that an enable link is or is not found for the role. * * @param int $rid * The role ID to check. * @param bool $found * Whether the link should be found, or not. */ function checkRoleEnableLink($rid, $found) { if ($found) { $this->assertLinkByHref( TAXONOMY_ACCESS_CONFIG . "/role/$rid/enable", 0, t('Enable link is available for role %rid.', array('%rid' => $rid)) ); } else { $this->assertNoLinkByHref( TAXONOMY_ACCESS_CONFIG . "/role/$rid/enable", t('Enable link is not available for role %rid.', array('%rid' => $rid)) ); } } /** * Asserts that a disable link is or is not found for the role. * * @param int $rid * The role ID to check. * @param bool $found * Whether the link should be found, or not. */ function checkRoleDisableLink($rid, $found) { if ($found) { $this->assertLinkByHref( TAXONOMY_ACCESS_CONFIG . "/role/$rid/delete", 0, t('Disable link is available for role %rid.', array('%rid' => $rid)) ); } else { $this->assertNoLinkByHref( TAXONOMY_ACCESS_CONFIG . "/role/$rid/delete", t('Disable link is not available for role %rid.', array('%rid' => $rid)) ); } } /** * Adds a term row on the role configuration form. * * @param array &$edit * The form data to post. * @param int $vid * (optional) The vocabulary ID. Defaults to * TAXONOMY_ACCESS_GLOBAL_DEFAULT. * @param $int tid * (optional) The term ID. Defaults to TAXONOMY_ACCESS_VOCABULARY_DEFAULT. * @param int $view * (optional) The view grant value. Defaults to * TAXONOMY_ACCESS_NODE_IGNORE. * @param int $update * (optional) The update grant value. Defaults to * @param int $delete * (optional) The delete grant value. Defaults to * TAXONOMY_ACCESS_NODE_IGNORE. * @param int $create * (optional) The create grant value. Defaults to * TAXONOMY_ACCESS_TERM_DENY. * @param int $list * (optional) The list grant value. Defaults to TAXONOMY_ACCESS_TERM_DENY. */ function addFormRow(&$edit, $vid = TAXONOMY_ACCESS_GLOBAL_DEFAULT, $tid = TAXONOMY_ACCESS_VOCABULARY_DEFAULT, $view = TAXONOMY_ACCESS_NODE_IGNORE, $update = TAXONOMY_ACCESS_NODE_IGNORE, $delete = TAXONOMY_ACCESS_NODE_IGNORE, $create = TAXONOMY_ACCESS_TERM_DENY, $list = TAXONOMY_ACCESS_TERM_DENY) { $new_value = $tid ? "term $tid" : "default $vid"; $edit["new[$vid][item]"] = $new_value; $edit["new[$vid][grants][$vid][0][view]"] = $view; $edit["new[$vid][grants][$vid][0][update]"] = $update; $edit["new[$vid][grants][$vid][0][delete]"] = $delete; $edit["new[$vid][grants][$vid][0][create]"] = $create; $edit["new[$vid][grants][$vid][0][list]"] = $list; } /** * Configures a row on the TAC configuration form. * * @param array &$edit * The form data to post. * @param int $vid * (optional) The vocabulary ID. Defaults to * TAXONOMY_ACCESS_GLOBAL_DEFAULT. * @param $int tid * (optional) The term ID. Defaults to TAXONOMY_ACCESS_VOCABULARY_DEFAULT. * @param int $view * (optional) The view grant value. Defaults to * TAXONOMY_ACCESS_NODE_IGNORE. * @param int $update * (optional) The update grant value. Defaults to * @param int $delete * (optional) The delete grant value. Defaults to * TAXONOMY_ACCESS_NODE_IGNORE. * @param int $create * (optional) The create grant value. Defaults to * TAXONOMY_ACCESS_TERM_DENY. * @param int $list * (optional) The list grant value. Defaults to TAXONOMY_ACCESS_TERM_DENY. */ function configureFormRow(&$edit, $vid = TAXONOMY_ACCESS_GLOBAL_DEFAULT, $tid = TAXONOMY_ACCESS_VOCABULARY_DEFAULT, $view = TAXONOMY_ACCESS_NODE_IGNORE, $update = TAXONOMY_ACCESS_NODE_IGNORE, $delete = TAXONOMY_ACCESS_NODE_IGNORE, $create = TAXONOMY_ACCESS_TERM_DENY, $list = TAXONOMY_ACCESS_TERM_DENY) { $edit["grants[$vid][$tid][view]"] = $view; $edit["grants[$vid][$tid][update]"] = $update; $edit["grants[$vid][$tid][delete]"] = $delete; $edit["grants[$vid][$tid][create]"] = $create; $edit["grants[$vid][$tid][list]"] = $list; } } /** * Tests the module's response to changes from other modules. */ class TaxonomyAccessExternalChanges extends TaxonomyAccessTestCase { public static function getInfo() { return array( 'name' => 'External changes', 'description' => "Test the module's response to changes from other modules.", 'group' => 'Taxonomy Access Control', ); } public function setUp() { parent::setUp(); } /* 1. delete a term 2. delete a role 3. delete a field attachment 4. modify a field attachment 5. delete a vocabulary 6. add terms to node 7. remove terms from node */ } /** * Tests the module's configuration forms. */ class TaxonomyAccessConfigTest extends TaxonomyAccessTestCase { protected $articles = array(); protected $pages = array(); protected $vocabs = array(); protected $terms = array(); public static function getInfo() { return array( 'name' => 'Configuration forms', 'description' => 'Test module configuration forms.', 'group' => 'Taxonomy Access Control', ); } public function setUp() { parent::setUp(); // Add two taxonomy fields to pages. foreach (array('v1', 'v2') as $vocab) { $this->vocabs[$vocab] = $this->createVocab($vocab); $this->createField($vocab); $this->terms[$vocab . 't1'] = $this->createTerm($vocab . 't1', $this->vocabs[$vocab]); $this->terms[$vocab . 't2'] = $this->createTerm($vocab . 't2', $this->vocabs[$vocab]); } // Set up a variety of nodes with different term combinations. $this->articles['no_tags'] = $this->createArticle(); $this->articles['one_tag'] = $this->createArticle(array($this->randomName())); $this->articles['two_tags'] = $this->createArticle(array($this->randomName(), $this->randomName())); $this->pages['no_tags'] = $this->createPage(); foreach ($this->terms as $t1) { $this->pages[$t1->name] = $this->createPage(array($t1->name)); foreach ($this->terms as $t2) { $this->pages[$t1->name . '_' . $t2->name] = $this->createPage(array($t1->name, $t2->name)); } } } /** * Creates a page with the specified terms. * * @param array $terms * (optional) An array of term names to tag the page. Defaults to array(). * * @return object * The node object. */ function createPage($tags = array()) { $v1 = array(); $v2 = array(); foreach ($tags as $name) { switch ($this->terms[$name]->vid) { case ($this->vocabs['v1']->vid): $v1[] = array('tid' => $this->terms[$name]->tid); break; case ($this->vocabs['v2']->vid): $v2[] = array('tid' => $this->terms[$name]->tid); break; } } // Bloody $langcodes. $v1 = array(LANGUAGE_NONE => $v1); $v2 = array(LANGUAGE_NONE => $v2); $settings = array( 'type' => 'page', 'v1' => $v1, 'v2' => $v2, ); return $this->drupalCreateNode($settings); } /* @todo - check anon and auth forms - add recursive for vocab and for term - change multiple - delete multiple - configure create and list */ /** * Tests the initial state of the test environment. * * Verifies that: * - Access to all nodes is denied for anonymous users. * - The main admin page provides the correct configuration links. */ public function testSetUpCheck() { // Visit all nodes as anonymous and verify that access is denied. foreach ($this->articles as $key => $article) { $this->drupalGet('node/' . $article->nid); $this->assertResponse(403, t("Access to %name article (nid %nid) is denied.", array('%name' => $key, '%nid' => $article->nid))); } foreach ($this->pages as $key => $page) { $this->drupalGet('node/' . $page->nid); $this->assertResponse(403, t("Access to %name page (nid %nid) is denied.", array('%name' => $key, '%nid' => $page->nid))); } // Log in as the regular_user. $this->drupalLogin($this->users['regular_user']); // Visit all nodes and verify that access is denied. foreach ($this->articles as $key => $article) { $this->drupalGet('node/' . $article->nid); $this->assertResponse(403, t("Access to %name article (nid %nid) is denied.", array('%name' => $key, '%nid' => $article->nid))); } foreach ($this->pages as $key => $page) { $this->drupalGet('node/' . $page->nid); $this->assertResponse(403, t("Access to %name page (nid %nid) is denied.", array('%name' => $key, '%nid' => $page->nid))); } // Log in as the administrator. $this->drupalLogin($this->users['site_admin']); // Confirm that only edit links are available for anon. and auth. $this->checkRoleConfig(array( DRUPAL_ANONYMOUS_RID => TRUE, DRUPAL_AUTHENTICATED_RID => TRUE, )); } /** * Tests configuring a global default. * * Verifies that: * - Access is updated for all nodes when there are no other configurations. * - Access is updated for the correct nodes when there are specific term * and vocabulary configurations. */ public function testGlobalDefaultConfig() { // Log in as the administrator. $this->drupalLogin($this->users['site_admin']); // Use the admin form to give anonymous view allow in the global default. $this->drupalGet(TAXONOMY_ACCESS_CONFIG . '/role/' . DRUPAL_ANONYMOUS_RID . '/edit'); $edit = array(); $this->configureFormRow($edit, TAXONOMY_ACCESS_GLOBAL_DEFAULT, TAXONOMY_ACCESS_VOCABULARY_DEFAULT, TAXONOMY_ACCESS_NODE_ALLOW); $this->drupalPost(NULL, $edit, 'Save all'); // Log out. $this->drupalLogout(); // Visit each node and verify that access is allowed. foreach ($this->articles as $key => $article) { $this->drupalGet('node/' . $article->nid); $this->assertResponse(200, t("Access to %name article (nid %nid) is allowed.", array('%name' => $key, '%nid' => $article->nid))); } foreach ($this->pages as $key => $page) { $this->drupalGet('node/' . $page->nid); $this->assertResponse(200, t("Access to %name page (nid %nid) is allowed.", array('%name' => $key, '%nid' => $page->nid))); } // Add some specific configurations programmatically. // Set the v1 default to view allow. $default_config = _taxonomy_access_format_grant_record( $this->vocabs['v1']->vid, DRUPAL_ANONYMOUS_RID, array('view' => TAXONOMY_ACCESS_NODE_ALLOW), TRUE ); taxonomy_access_set_default_grants(array($default_config)); // Set v1t1 and v2t1 to view allow. $term_configs = array(); foreach (array('v1t1', 'v2t1') as $name) { $term_configs[] = _taxonomy_access_format_grant_record( $this->terms[$name]->vid, DRUPAL_ANONYMOUS_RID, array('view' => TAXONOMY_ACCESS_NODE_ALLOW) ); } taxonomy_access_set_term_grants($term_configs); // This leaves articles and the v2t2 page controlled by the global default. // Log in as the administrator. $this->drupalLogin($this->users['site_admin']); // Use the admin form to give anonymous view deny in the global default. $this->drupalGet(TAXONOMY_ACCESS_CONFIG . '/role/' . DRUPAL_ANONYMOUS_RID . '/edit'); $edit = array(); $this->configureFormRow($edit, TAXONOMY_ACCESS_GLOBAL_DEFAULT, TAXONOMY_ACCESS_VOCABULARY_DEFAULT, TAXONOMY_ACCESS_NODE_DENY); $this->drupalPost(NULL, $edit, 'Save all'); // Log out. $this->drupalLogout(); // Visit each artile and verify that access is denied. foreach ($this->articles as $key => $article) { $this->drupalGet('node/' . $article->nid); $this->assertResponse(403, t("Access to %name article (nid %nid) is denied.", array('%name' => $key, '%nid' => $article->nid))); } // Visit each page. foreach ($this->pages as $key => $page) { $this->drupalGet('node/' . $page->nid); switch (TRUE) { // If the page has no tags, access should be denied. case ($key == 'no_tags'): // If the page is tagged with v2t2, access should be denied. case (strpos($key, 'v2t2') !== FALSE): $this->assertResponse(403, t("Access to %name page (nid %nid) is denied.", array('%name' => $key, '%nid' => $page->nid))); break; // Otherwise, access should be allowed. default: $this->assertResponse(200, t("Access to %name page (nid %nid) is allowed.", array('%name' => $key, '%nid' => $page->nid))); break; } } } /** * Tests configuring vocabulary defaults. * * Verifies that: * - Access is updated correctly when the vocabulary default is added and * configured. * - Access is updated correctly when there is a specific term configuration * in the vocabulary. * - Access is updated correctly when multiple defaults are changed. * - Access is updated correctly when the vocabulary default is deleted. */ public function testVocabularyDefaultConfig() { // Log in as the administrator. $this->drupalLogin($this->users['site_admin']); // Enable the vocabulary. $this->drupalGet(TAXONOMY_ACCESS_CONFIG . '/role/' . DRUPAL_ANONYMOUS_RID . '/edit'); // @todo // - Ensure that all vocabularies are options in the "Add" fieldset. $edit = array(); $edit['enable_vocab'] = $this->vocabs['v1']->vid; $this->drupalPost(NULL, $edit, t('Add')); // @todo // - Ensure that the vocabulary is removed from the "Add" fieldset. // - Ensure that the fieldset for the vocabulary appears. // - Ensure that no other fieldsets or rows appear. // Give anonymous view allow for the v1 default. $edit = array(); $this->configureFormRow($edit, $this->vocabs['v1']->vid, TAXONOMY_ACCESS_VOCABULARY_DEFAULT, TAXONOMY_ACCESS_NODE_ALLOW); $this->drupalPost(NULL, $edit, 'Save all'); // Log out. $this->drupalLogout(); // Visit each page and verify whether access is allowed or denied. foreach ($this->pages as $key => $page) { $this->drupalGet('node/' . $page->nid); // If the page is tagged with a v1 term, access should be allowed. if (strpos($key, 'v1') !== FALSE) { $this->assertResponse(200, t("Access to %name page (nid %nid) is allowed.", array('%name' => $key, '%nid' => $page->nid))); } // Otherwise, access should be denied. else { $this->assertResponse(403, t("Access to %name page (nid %nid) is denied.", array('%name' => $key, '%nid' => $page->nid))); } } // Programmatically enable v2 and add a specific configuration for v2t1. taxonomy_access_enable_vocab($this->vocabs['v2']->vid, DRUPAL_ANONYMOUS_RID); $term_config = _taxonomy_access_format_grant_record( $this->terms['v2t1']->tid, DRUPAL_ANONYMOUS_RID, array('view' => TAXONOMY_ACCESS_NODE_IGNORE) ); taxonomy_access_set_term_grants(array($term_config)); // Log in as the administrator. $this->drupalLogin($this->users['site_admin']); // Use the admin form to give anonymous view deny for the v2 default. $this->drupalGet(TAXONOMY_ACCESS_CONFIG . '/role/' . DRUPAL_ANONYMOUS_RID . '/edit'); $edit = array(); $this->configureFormRow($edit, $this->vocabs['v2']->vid, TAXONOMY_ACCESS_VOCABULARY_DEFAULT, TAXONOMY_ACCESS_NODE_DENY); $this->drupalPost(NULL, $edit, 'Save all'); $this->drupalGet(TAXONOMY_ACCESS_CONFIG . '/role/' . DRUPAL_ANONYMOUS_RID . '/edit'); // Log out. $this->drupalLogout(); // Visit each page and verify whether access is allowed or denied. foreach ($this->pages as $key => $page) { $this->drupalGet('node/' . $page->nid); switch (TRUE) { // If the page is tagged with v2t2, the v2 default is inherited: Deny. case (strpos($key, 'v2t2') !== FALSE): $this->assertResponse(403, t("Access to %name page (nid %nid) is denied.", array('%name' => $key, '%nid' => $page->nid))); break; // Otherwise, if the page is tagged with v1, it's allowed. case (strpos($key, 'v1') !== FALSE): $this->assertResponse(200, t("Access to %name page (nid %nid) is allowed.", array('%name' => $key, '%nid' => $page->nid))); break; // Access should be denied by default. default: $this->assertResponse(403, t("Access to %name page (nid %nid) is denied.", array('%name' => $key, '%nid' => $page->nid))); break; } } // Log in as the administrator. $this->drupalLogin($this->users['site_admin']); // Use the form to change the configuration: Allow for v2; Deny for v1. $this->drupalGet(TAXONOMY_ACCESS_CONFIG . '/role/' . DRUPAL_ANONYMOUS_RID . '/edit'); $edit = array(); $this->configureFormRow($edit, $this->vocabs['v2']->vid, TAXONOMY_ACCESS_VOCABULARY_DEFAULT, TAXONOMY_ACCESS_NODE_ALLOW); $this->configureFormRow($edit, $this->vocabs['v1']->vid, TAXONOMY_ACCESS_VOCABULARY_DEFAULT, TAXONOMY_ACCESS_NODE_DENY); $this->drupalPost(NULL, $edit, 'Save all'); // Log out. $this->drupalLogout(); // Visit each page and verify whether access is allowed or denied. foreach ($this->pages as $key => $page) { $this->drupalGet('node/' . $page->nid); switch (TRUE) { // If the page is tagged with a v1 term, access should be denied. case (strpos($key, 'v1') !== FALSE): $this->assertResponse(403, t("Access to %name page (nid %nid) is denied.", array('%name' => $key, '%nid' => $page->nid))); break; // Otherwise, if the page is tagged with v2t2, the default is // inherited and access should be allowed. case (strpos($key, 'v2t2') !== FALSE): $this->assertResponse(200, t("Access to %name page (nid %nid) is allowed.", array('%name' => $key, '%nid' => $page->nid))); break; // Access should be denied by default. default: $this->assertResponse(403, t("Access to %name page (nid %nid) is denied.", array('%name' => $key, '%nid' => $page->nid))); break; } } // Log in as the administrator. $this->drupalLogin($this->users['site_admin']); // Use the admin form to disable v1. $this->drupalGet(TAXONOMY_ACCESS_CONFIG . '/role/' . DRUPAL_ANONYMOUS_RID . '/edit'); $this->clickLink(t('delete all v1 access rules')); $this->assertText("Are you sure you want to delete all Taxonomy access rules for v1", t('Disable form for vocabulary loaded.')); $this->drupalPost(NULL, array(), 'Delete all'); // Log out. $this->drupalLogout(); // Visit each page and verify whether access is allowed or denied. foreach ($this->pages as $key => $page) { $this->drupalGet('node/' . $page->nid); // If the page is tagged with v2t2, access should be allowed. if (strpos($key, 'v2t2') !== FALSE) { $this->assertResponse(200, t("Access to %name page (nid %nid) is allowed.", array('%name' => $key, '%nid' => $page->nid))); } // Otherwise, access should be denied. else { $this->assertResponse(403, t("Access to %name page (nid %nid) is denied.", array('%name' => $key, '%nid' => $page->nid))); } } } /** * Tests configuring specific terms. * * Verifies that: * - Access is updated correctly when the term configuration is added. * - Access is updated correctly when there is a vocabulary default. * - Access is updated correctly when multiple configurations are changed. * - Access is updated correctly when the term configuration is deleted. */ public function testTermConfig() { // Log in as the administrator. $this->drupalLogin($this->users['site_admin']); // Use the admin form to enable v1 and give anonymous view allow for v1t1. $this->drupalGet(TAXONOMY_ACCESS_CONFIG . '/role/' . DRUPAL_ANONYMOUS_RID . '/edit'); $edit = array(); $edit['enable_vocab'] = $this->vocabs['v1']->vid; $this->drupalPost(NULL, $edit, t('Add')); $edit = array(); $this->addFormRow($edit, $this->vocabs['v1']->vid, $this->terms['v1t1']->tid, TAXONOMY_ACCESS_NODE_ALLOW); $this->drupalPost(NULL, $edit, 'Add'); // Log out. $this->drupalLogout(); // Visit each page and verify whether access is allowed or denied. foreach ($this->pages as $key => $page) { $this->drupalGet('node/' . $page->nid); // If the page is tagged with v1t1, access should be allowed. if (strpos($key, 'v1t1') !== FALSE) { $this->assertResponse(200, t("Access to %name page (nid %nid) is allowed.", array('%name' => $key, '%nid' => $page->nid))); } // Otherwise, access should be denied. else { $this->assertResponse(403, t("Access to %name page (nid %nid) is denied.", array('%name' => $key, '%nid' => $page->nid))); } } // Enable v2 programmatically. taxonomy_access_enable_vocab($this->vocabs['v2']->vid, DRUPAL_ANONYMOUS_RID); // Log in as the administrator. $this->drupalLogin($this->users['site_admin']); // Use the admin form to give anonymous view deny for v2t1. $this->drupalGet(TAXONOMY_ACCESS_CONFIG . '/role/' . DRUPAL_ANONYMOUS_RID . '/edit'); $edit = array(); $this->addFormRow($edit, $this->vocabs['v2']->vid, $this->terms['v2t1']->tid, TAXONOMY_ACCESS_NODE_DENY); $this->drupalPost(NULL, $edit, 'Add'); // Log out. $this->drupalLogout(); // Visit each page and verify whether access is allowed or denied. foreach ($this->pages as $key => $page) { $this->drupalGet('node/' . $page->nid); switch (TRUE) { // If the page is tagged with v2t1, access should be denied. case (strpos($key, 'v2t1') !== FALSE): $this->assertResponse(403, t("Access to %name page (nid %nid) is denied.", array('%name' => $key, '%nid' => $page->nid))); break; // Otherwise, if the page is tagged with v1t1, it's allowed. case (strpos($key, 'v1t1') !== FALSE): $this->assertResponse(200, t("Access to %name page (nid %nid) is allowed.", array('%name' => $key, '%nid' => $page->nid))); break; // Access should be denied by default. default: $this->assertResponse(403, t("Access to %name page (nid %nid) is denied.", array('%name' => $key, '%nid' => $page->nid))); break; } } // Log in as the administrator. $this->drupalLogin($this->users['site_admin']); // Use the form to change the configuration: Allow for v2t1; Deny for v1t1. $this->drupalGet(TAXONOMY_ACCESS_CONFIG . '/role/' . DRUPAL_ANONYMOUS_RID . '/edit'); $edit = array(); $this->configureFormRow( $edit, $this->vocabs['v2']->vid, $this->terms['v2t1']->tid, TAXONOMY_ACCESS_NODE_ALLOW ); $this->configureFormRow( $edit, $this->vocabs['v1']->vid, $this->terms['v1t1']->tid, TAXONOMY_ACCESS_NODE_DENY ); $this->drupalPost(NULL, $edit, 'Save all'); // Log out. $this->drupalLogout(); // Visit each page and verify whether access is allowed or denied. foreach ($this->pages as $key => $page) { $this->drupalGet('node/' . $page->nid); switch (TRUE) { // If the page is tagged with v1t1, access should be denied. case (strpos($key, 'v1t1') !== FALSE): $this->assertResponse(403, t("Access to %name page (nid %nid) is denied.", array('%name' => $key, '%nid' => $page->nid))); break; // Otherwise, if the page is tagged with v2t1, it's allowed. case (strpos($key, 'v2t1') !== FALSE): $this->assertResponse(200, t("Access to %name page (nid %nid) is allowed.", array('%name' => $key, '%nid' => $page->nid))); break; // Access should be denied by default. default: $this->assertResponse(403, t("Access to %name page (nid %nid) is denied.", array('%name' => $key, '%nid' => $page->nid))); break; } } // Log in as the administrator. $this->drupalLogin($this->users['site_admin']); // Use the form to delete the v2t1 configuration. $this->drupalGet(TAXONOMY_ACCESS_CONFIG . '/role/' . DRUPAL_ANONYMOUS_RID . '/edit'); $edit = array(); $edit["grants[{$this->vocabs['v2']->vid}][{$this->terms['v2t1']->tid}][remove]"] = 1; $this->drupalPost(NULL, $edit, 'Delete selected'); // Log out. $this->drupalLogout(); // Visit each page and verify whether access is allowed or denied. foreach ($this->pages as $key => $page) { $this->drupalGet('node/' . $page->nid); // Access to all pages should be denied. $this->assertResponse(403, t("Access to %name page (nid %nid) is denied.", array('%name' => $key, '%nid' => $page->nid))); } } /** * Tests adding a term configuration with children. * * @todo * Check that node access is updated for these as well. */ public function testTermWithChildren() { // Create some additional taxonomy terms in a hierarchy: // v1 // - v1t1 // - - v1t1c1 // - - - v1t1c1g1 // - - - v1t1c1g2 // - - v1t1c2 // - - v1t2 $this->terms['v1t1c1'] = $this->createTerm( 'v1t1c1', $this->vocabs['v1'], $this->terms['v1t1']->tid ); $this->terms['v1t1c2'] = $this->createTerm( 'v1t1c2', $this->vocabs['v1'], $this->terms['v1t1']->tid ); $this->terms['v1t1c1g1'] = $this->createTerm( 'v1t1c1g1', $this->vocabs['v1'], $this->terms['v1t1c1']->tid ); $this->terms['v1t1c1g2'] = $this->createTerm( 'v1t1c1g2', $this->vocabs['v1'], $this->terms['v1t1c1']->tid ); // Add pages tagged with each. foreach (array('v1t1c1', 'v1t1c2', 'v1t1c1g1', 'v1t1c1g2') as $name) { $this->pages[$name] = $this->createPage(array($name)); } // Log in as the administrator. $this->drupalLogin($this->users['site_admin']); // Enable v1 programmatically. taxonomy_access_enable_vocab($this->vocabs['v1']->vid, DRUPAL_ANONYMOUS_RID); // Use the admin form to give anonymous view allow for v1t1 and children. $this->drupalGet(TAXONOMY_ACCESS_CONFIG . '/role/' . DRUPAL_ANONYMOUS_RID . '/edit'); $edit = array(); $edit["new[{$this->vocabs['v1']->vid}][recursive]"] = 1; $this->addFormRow($edit, $this->vocabs['v1']->vid, $this->terms['v1t1']->tid, TAXONOMY_ACCESS_NODE_ALLOW); $this->drupalPost(NULL, $edit, 'Add'); } /** * Tests enabling and disabling TAC for a custom role. */ public function testRoleEnableDisable() { // Save some typing. $rid = $this->user_roles['regular_user']->rid; $name = $this->user_roles['regular_user']->name; // Check that the role is disabled by default. $this->checkRoleConfig(array( DRUPAL_ANONYMOUS_RID => TRUE, DRUPAL_AUTHENTICATED_RID => TRUE, $rid => FALSE, )); // Test enabling the role. $this->drupalGet(TAXONOMY_ACCESS_CONFIG . "/role/$rid/edit"); // Check that there is: // - An enable link // - No disable link // @todo // - No grant tables. $this->checkRoleEnableLink($rid, TRUE); $this->checkRoleDisableLink($rid, FALSE); // Enable the role and check that there is: // - A disable link // - No enable link // @todo // - A global default table (with correct values?) // - An "Add vocabulary" fieldset. // - No vocabulary fieldsets or term data. $this->clickLink(format_string('Enable @name', array('@name' => $name))); $this->checkRoleEnableLink($rid, FALSE); $this->checkRoleDisableLink($rid, TRUE); // Update the global default to allow view. $edit = array(); $this->configureFormRow($edit, TAXONOMY_ACCESS_GLOBAL_DEFAULT, TAXONOMY_ACCESS_VOCABULARY_DEFAULT, TAXONOMY_ACCESS_NODE_ALLOW); $this->drupalPost(NULL, $edit, 'Save all'); // Confirm that all three roles are enabled. $this->checkRoleConfig(array( DRUPAL_ANONYMOUS_RID => TRUE, DRUPAL_AUTHENTICATED_RID => TRUE, $rid => TRUE, )); // Check that the role is configured. $r = db_query( 'SELECT grant_view FROM {taxonomy_access_default} WHERE vid = :vid AND rid = :rid', array(':vid' => TAXONOMY_ACCESS_GLOBAL_DEFAULT, ':rid' => $rid) ) ->fetchField(); $this->assertTrue($r == TAXONOMY_ACCESS_NODE_ALLOW, t('Used form to grant the role %role view in the global default.', array('%role' => $name))); // Log in as the regular_user. $this->drupalLogout(); $this->drupalLogin($this->users['regular_user']); // Visit each node and verify that access is allowed. foreach ($this->articles as $key => $article) { $this->drupalGet('node/' . $article->nid); $this->assertResponse(200, t("Access to %name article (nid %nid) is allowed.", array('%name' => $key, '%nid' => $article->nid))); } foreach ($this->pages as $key => $page) { $this->drupalGet('node/' . $page->nid); $this->assertResponse(200, t("Access to %name page (nid %nid) is allowed.", array('%name' => $key, '%nid' => $page->nid))); } // Log in as the administrator. $this->drupalLogout(); $this->drupalLogin($this->users['site_admin']); // Test disabling the role. $this->drupalGet(TAXONOMY_ACCESS_CONFIG . "/role/$rid/edit"); $this->clickLink(t('Disable @name', array('@name' => $name))); $this->assertText("Are you sure you want to delete all taxonomy access rules for the role $name", t('Disable form for role loaded.')); $this->drupalPost(NULL, array(), 'Delete all'); // Confirm that a confirmation message appears. $this->assertText("All taxonomy access rules deleted for role $name", t('Confirmation message found.')); // Check that there is: // - An enable link // - No disable link // @todo // - No grant tables. $this->checkRoleEnableLink($rid, TRUE); $this->checkRoleDisableLink($rid, FALSE); // Confirm edit/enable/disable links are in their original state. $this->checkRoleConfig(array( DRUPAL_ANONYMOUS_RID => TRUE, DRUPAL_AUTHENTICATED_RID => TRUE, $rid => FALSE, )); // Check that the role is no longer configured. $r = db_query( 'SELECT grant_view FROM {taxonomy_access_default} WHERE rid = :rid', array(':rid' => $rid) ) ->fetchAll(); $this->assertTrue(empty($r), t('All records removed for role %role.', array('%role' => $name))); // @todo // - Add a term configuration and make sure that gets deleted too. // Log in as the regular_user. $this->drupalLogout(); $this->drupalLogin($this->users['regular_user']); // Visit all nodes and verify that access is again denied. foreach ($this->articles as $key => $article) { $this->drupalGet('node/' . $article->nid); $this->assertResponse(403, t("Access to %name article (nid %nid) is denied.", array('%name' => $key, '%nid' => $article->nid))); } foreach ($this->pages as $key => $page) { $this->drupalGet('node/' . $page->nid); $this->assertResponse(403, t("Access to %name page (nid %nid) is denied.", array('%name' => $key, '%nid' => $page->nid))); } } } /** * Tests node access for all possible grant combinations. */ class TaxonomyAccessNodeGrantTest extends TaxonomyAccessTestCase { // There are three roles for node access testing: // global_allow Receives "Allow" in the global default. // global_ignore Receives "Ignore" in the global default. // global_deny Receives "Deny" in the global default. // All roles receive the same permissions for terms and vocab defaults. protected $roles = array(); protected $role_config = array( 'global_allow' => array(), 'global_ignore' => array(), 'global_deny' => array(), ); protected $vocabs = array(); public static function getInfo() { return array( 'name' => 'Node access', 'description' => 'Test node access for various grant configurations.', 'group' => 'Taxonomy Access Control', ); } public function setUp() { parent::setUp(); // Configure roles with no additional permissions. foreach ($this->role_config as $role_name => $permissions) { $this->roles[$role_name] = $this->drupalCreateRole(array(), $role_name); } $node_grants = array('view', 'update', 'delete'); // Set up our testing taxonomy. // We will create 4 vocabularies: a, i, d, and nc // These names indicate what grant the vocab. default will have for view. // (NC means the vocab default is not configured.) $grant_types = array( 'a' => array(), 'i' => array(), 'd' => array(), 'nc' => array(), ); // View alone can be used to test V/U/D because the logic is identical. foreach ($node_grants as $grant) { $grant_types['a'][$grant] = TAXONOMY_ACCESS_NODE_ALLOW; $grant_types['i'][$grant] = TAXONOMY_ACCESS_NODE_IGNORE; $grant_types['d'][$grant] = TAXONOMY_ACCESS_NODE_DENY; } // Each vocabulary will have four parent terms in the same fashion: // a_parent, i_parent, d_parent, and nc_parent. // Each of these_parent terms will have children in each class, as well: // a_child, i_child, d_child, and nc_child. // So, each vocab looks something like: // - a_parent // - - a_child // - - i_child // - - d_child // - - nc_child // - i_parent // - - a_child // - - i_child // - - d_child // - - nc_child // - d_parent // - - a_child // - - i_child // - - d_child // - - nc_child // - nc_parent // - - a_child // - - i_child // - - d_child // - - nc_child $term_rows = array(); $default_rows = array(); $this->setUpAssertions = array(); // Configure terms, vocabularies, and grants. foreach ($grant_types as $vocab_name => $default_grants) { // Create the vocabulary. $vocab_name = "v" . $vocab_name; $this->vocabs[$vocab_name] = array(); $this->vocabs[$vocab_name]['vocab'] = parent::createVocab($vocab_name); $this->vocabs[$vocab_name]['terms'] = array(); $vocab = $this->vocabs[$vocab_name]['vocab']; // Add a field for the vocabulary to pages. $this->createField($vocab_name); // Configure default grants for the vocabulary for each role. if (!empty($default_grants)) { foreach ($this->roles as $name => $role) { $default_rows[] = _taxonomy_access_format_grant_record($vocab->vid, $role, $default_grants, TRUE); $this->setUpAssertions[] = array( 'grant' => $default_grants['view'], 'query' => 'SELECT grant_view FROM {taxonomy_access_default} WHERE vid = :vid AND rid = :rid', 'args' => array(':vid' => $vocab->vid, ':rid' => $role), 'message' => t('Configured default grants for vocab %vocab, role %role', array('%vocab' => $vocab->machine_name, '%role' => $name)), ); } } // Create terms. foreach ($grant_types as $parent_name => $parent_grants) { // Create parent term. $parent_name = $vocab_name . "__" . $parent_name . "_parent"; $this->vocabs[$vocab_name]['terms'][$parent_name] = parent::createTerm($parent_name, $vocab); $parent_id = $this->vocabs[$vocab_name]['terms'][$parent_name]->tid; // Configure grants for the parent term for each role. if (!empty($parent_grants)) { foreach ($this->roles as $name => $role) { $term_rows[] = _taxonomy_access_format_grant_record($parent_id, $role, $parent_grants); $this->setUpAssertions[] = array( 'grant' => $parent_grants['view'], 'query' => 'SELECT grant_view FROM {taxonomy_access_term} WHERE tid = :tid AND rid = :rid', 'args' => array(':tid' => $parent_id, ':rid' => $role), 'message' => t('Configured grants for term %term, role %role', array('%term' => $parent_name, '%role' => $name)), ); } } // Create child terms. foreach ($grant_types as $child_name => $child_grants) { $child_name = $parent_name . "__" . $child_name . "_child"; $this->vocabs[$vocab_name]['terms'][$child_name] = parent::createTerm($child_name, $vocab, $parent_id); $child_id = $this->vocabs[$vocab_name]['terms'][$child_name]->tid; // Configure grants for the child term for each role. if (!empty($child_grants)) { foreach ($this->roles as $name => $role) { $term_rows[] = _taxonomy_access_format_grant_record($child_id, $role, $child_grants); $this->setUpAssertions[] = array( 'grant' => $child_grants['view'], 'query' => 'SELECT grant_view FROM {taxonomy_access_term} WHERE tid = :tid AND rid = :rid', 'args' => array(':tid' => $child_id, ':rid' => $role), 'message' => t('Configured grants for term %term, role %role', array('%term' => $child_name, '%role' => $name)), ); } } } } } // Set the grants. taxonomy_access_set_default_grants($default_rows); taxonomy_access_set_term_grants($term_rows); } /** * Verifies that all grants were properly stored during setup. */ public function testSetUpCheck() { // Check that all records were properly stored. foreach ($this->setUpAssertions as $assertion) { $r = db_query($assertion['query'], $assertion['args'])->fetchField(); $this->assertTrue( (is_numeric($r) && $r == $assertion['grant']), $assertion['message'] ); } } // Role config tests: // Create a role // Create a user with the role // Configure role grants via form // Add, with children, delete // Confirm records stored // Confirm node access properly updated // Go back and edit, repeat. // Disable role. // Confirm form. // Update node access if prompted. // Confirm records deleted. // Confirm node access updated. // 1. delete a term // 2. change a grant config // 3. delete a grant config // 4. change a vocab default // 5. delete a voacb default // 6. disable a role // 7. delete a role // 8. delete a field attachment // 9. delete a vocabulary } /** * Tests term grants for all possible grant combinations. */ class TaxonomyAccessTermGrantTest extends TaxonomyAccessTestCase { // There are four roles for term access testing: // ctlt Receives both "Create" and "List" in the global default. // ctlf Receives "Create" but not "List" in the global default. // cflt Receives "List" but not "Create" in the global default. // cflf Receives neither "Create" nor "List" in the global default. // All roles receive the same permissions for terms and vocab defaults. protected $roles = array(); protected $role_config = array( 'ctlt' => array(), 'ctlf' => array(), 'cflt' => array(), 'cflf' => array(), ); protected $vocabs = array(); public static function getInfo() { return array( 'name' => 'Term grants', 'description' => 'Test node access for View tag (create) and Add tag (list) grants.', 'group' => 'Taxonomy Access Control', ); } public function setUp() { parent::setUp(); // Configure roles with no additional permissions. foreach ($this->role_config as $role_name => $permissions) { $this->roles[$role_name] = $this->drupalCreateRole(array(), $role_name); } // Set up our testing taxonomy. // We will create four vocabularies: // vctlt Receives both "Create" and "List" in the vocabulary default. // vctlf Receives "Create" but not "List" in the vocabulary default. // vcflt Receives "List" but not "Create" in the vocabulary default. // vcflf Receives neither "Create" nor "List" in the vocabulary default. $grant_combos = array( 'ctlt' => array('create' => TAXONOMY_ACCESS_TERM_ALLOW, 'list' => TAXONOMY_ACCESS_TERM_ALLOW), 'ctlf' => array('create' => TAXONOMY_ACCESS_TERM_ALLOW, 'list' => TAXONOMY_ACCESS_TERM_DENY), 'cflt' => array('create' => TAXONOMY_ACCESS_TERM_DENY, 'list' => TAXONOMY_ACCESS_TERM_ALLOW), 'cflf' => array('create' => TAXONOMY_ACCESS_TERM_DENY, 'list' => TAXONOMY_ACCESS_TERM_DENY), ); // Grant all rows view, update, and delete. foreach ($grant_combos as $combo) { $combo['view'] = TAXONOMY_ACCESS_NODE_ALLOW; $combo['update'] = TAXONOMY_ACCESS_NODE_ALLOW; $combo['delete'] = TAXONOMY_ACCESS_NODE_ALLOW; } // Each vocabulary will have four parent terms in the same fashion: // ctlt_parent, ctlf_parent, cflt_parent, and cflf_parent. // Each of these_parent terms will have children in each class, as well: // ctlt_child, ctlf_child, cflt_child, and cflf_child. // So, each vocab looks something like: // - ctlt_parent // - - ctlt_child // - - ctlf_child // - - cflt_child // - - cflf_child // - ctlf_parent // - - ctlt_child // - - ctlf_child // - - cflt_child // - - cfl_fchild // - cflt_parent // - - ctlt_child // - - ctlf_child // - - cflt_child // - - cflf_child // - cflf_parent // - - ctlt_child // - - ctlf_child // - - cflt_child // - - cflf_child // Configure terms, vocabularies, and grants. foreach ($grant_combos as $vocab_name => $default_grants) { // Create the vocabulary. $vocab_name = "v" . $vocab_name; $this->vocabs[$vocab_name] = array(); $this->vocabs[$vocab_name]['vocab'] = parent::createVocab($vocab_name); $this->vocabs[$vocab_name]['terms'] = array(); $vocab = $this->vocabs[$vocab_name]['vocab']; // Add a field for the vocabulary to pages. $this->createField($vocab_name); // Configure default grants for the vocabulary for each role. if (!empty($default_grants)) { foreach ($this->roles as $name => $role) { $default_rows[] = _taxonomy_access_format_grant_record($vocab->vid, $role, $default_grants, TRUE); $this->setUpAssertions[] = array( 'create' => $default_grants['create'], 'list' => $default_grants['list'], 'query' => 'SELECT grant_create, grant_list FROM {taxonomy_access_default} WHERE vid = :vid AND rid = :rid', 'args' => array(':vid' => $vocab->vid, ':rid' => $role), 'message' => t('Configured default grants for vocab %vocab, role %role', array('%vocab' => $vocab->machine_name, '%role' => $name)), ); } } // Create terms. foreach ($grant_combos as $parent_name => $parent_grants) { // Create parent term. $parent_name = $vocab_name . "__" . $parent_name . "_parent"; $this->vocabs[$vocab_name]['terms'][$parent_name] = parent::createTerm($parent_name, $vocab); $parent_id = $this->vocabs[$vocab_name]['terms'][$parent_name]->tid; // Configure grants for the parent term for each role. if (!empty($parent_grants)) { foreach ($this->roles as $name => $role) { $term_rows[] = _taxonomy_access_format_grant_record($parent_id, $role, $parent_grants); $this->setUpAssertions[] = array( 'create' => $parent_grants['create'], 'list' => $parent_grants['list'], 'query' => 'SELECT grant_create, grant_list FROM {taxonomy_access_term} WHERE tid = :tid AND rid = :rid', 'args' => array(':tid' => $parent_id, ':rid' => $role), 'message' => t('Configured grants for term %term, role %role', array('%term' => $parent_name, '%role' => $name)), ); } } // Create child terms. foreach ($grant_combos as $child_name => $child_grants) { $child_name = $parent_name . "__" . $child_name . "_child"; $this->vocabs[$vocab_name]['terms'][$child_name] = parent::createTerm($child_name, $vocab, $parent_id); $child_id = $this->vocabs[$vocab_name]['terms'][$child_name]->tid; // Configure grants for the child term for each role. if (!empty($child_grants)) { foreach ($this->roles as $name => $role) { $term_rows[] = _taxonomy_access_format_grant_record($child_id, $role, $child_grants); $this->setUpAssertions[] = array( 'create' => $child_grants['create'], 'list' => $child_grants['list'], 'query' => 'SELECT grant_create, grant_list FROM {taxonomy_access_term} WHERE tid = :tid AND rid = :rid', 'args' => array(':tid' => $child_id, ':rid' => $role), 'message' => t('Configured grants for term %term, role %role', array('%term' => $child_name, '%role' => $name)), ); } } } } } // Set the grants. taxonomy_access_set_default_grants($default_rows); taxonomy_access_set_term_grants($term_rows); } /** * Verifies that all grants were properly stored during setup. */ public function testSetUpCheck() { // Check that all records were properly stored. foreach ($this->setUpAssertions as $assertion) { $r = db_query($assertion['query'], $assertion['args'])->fetchAssoc(); $this->assertTrue( (is_array($r) && $r['grant_create'] == $assertion['create'] && $r['grant_list'] == $assertion['list']), $assertion['message'] ); } } } class TaxonomyAccessWeightTest extends DrupalWebTestCase { public static function getInfo() { return array( 'name' => 'Weight', 'description' => 'Test module weight.', 'group' => 'Taxonomy Access Control', ); } public function setUp() { parent::setUp('taxonomy_access'); } /** * Verifies that this module is weighted below the Taxonomy module. */ public function testWeight() { // Verify weight. $tax_weight = db_query( "SELECT weight FROM {system} WHERE name = 'taxonomy'") ->fetchField(); $tax_access_weight = db_query( "SELECT weight FROM {system} WHERE name = 'taxonomy_access'") ->fetchField(); $this->assertTrue( $tax_access_weight > $tax_weight, t("Weight of this module is @tax_access_weight. Weight of the Taxonomy module is @tax_weight.", array('@tax_access_weight' => $tax_access_weight, '@tax_weight' => $tax_weight)) ); // Disable module and set weight of the Taxonomy module to a high number. module_disable(array('taxonomy_access'), TRUE); db_update('system') ->fields(array('weight' => rand(5000, 9000))) ->condition('name', 'taxonomy') ->execute(); // Re-enable module and re-verify weight. module_enable(array('taxonomy_access'), TRUE); $tax_weight = db_query( "SELECT weight FROM {system} WHERE name = 'taxonomy'") ->fetchField(); $tax_access_weight = db_query( "SELECT weight FROM {system} WHERE name = 'taxonomy_access'") ->fetchField(); $this->assertTrue( $tax_access_weight > $tax_weight, t("Weight of this module is @tax_access_weight. Weight of the Taxonomy module is @tax_weight.", array('@tax_access_weight' => $tax_access_weight, '@tax_weight' => $tax_weight)) ); } } /** * Tests that callbacks are cleaned up when the module is disabled. */ class TaxonomyAccessCallbackCleanupTest extends DrupalWebTestCase { public static function getInfo() { return array( 'name' => 'Callback Cleanup', 'description' => 'Test callback cleanup during disabling of module works.', 'group' => 'Taxonomy Access Control', ); } public function setUp() { parent::setUp('taxonomy_access'); } /** * Verifies that the module's callbacks are cleaned up during disable. */ public function testCallbackCleanup() { // The problem only happens on new fields after the module is installed. $content_type = $this->drupalCreateContentType(); // Create a new field with type taxonomy_term_reference. $field_name = drupal_strtolower($this->randomName() . '_field_name'); $field_type = array( 'field_name' => $field_name, 'type' => 'taxonomy_term_reference', 'cardinality' => 1, ); $field_type = field_create_field($field_type); // Add an instance of the field to content type. $field_instance = array( 'field_name' => $field_name, 'entity_type' => 'node', 'bundle' => $content_type->name ); $field_instance = field_create_instance($field_instance); // Trigger hook_disable to see if the callbacks are cleaned up. module_disable(array('taxonomy_access'), TRUE); // Create a user so that we can check if we can access the node add pages. $this->privileged_user = $this->drupalCreateUser(array('bypass node access')); $this->drupalLogin($this->privileged_user); // If the callbacks are not cleaned up we would get a fatal error. $this->drupalGet('node/add/' . $content_type->name); $this->assertText(t('Create @name', array('@name' => $content_type->name)), t('New content can be added')); } }