View source
<?php
class BookAccessTestCase extends DrupalWebTestCase {
protected $profile = 'testing';
protected $books;
protected $nodes;
private $author;
private $adminRole;
public static function getInfo() {
return array(
'name' => 'Book Access tester',
'description' => 'Unit test cases for book access module.',
'group' => 'Book access',
);
}
function setUp() {
parent::setUp('book', 'book_access', 'book_access_ui');
$this
->resetTestData();
}
protected function resetTestData() {
$this->author = $this
->drupalCreateUser(array(
'administer access of own books',
'add content to books',
'create book content',
'create new books',
'edit own book content',
'access content',
));
$this->adminRole = $this
->drupalCreateRole(array(
'administer nodes',
'access content',
), 'administrator');
module_invoke('book_access', 'init');
$this->books = array();
$this->nodes = array();
$this
->createBook($this->books, $this->nodes, $this->author);
}
protected function createBook(&$books, &$nodes, $author, $pages = 2) {
static $mlid = 1;
static $counter = 1;
$firstNode = NULL;
while ($pages--) {
$node = new stdClass();
$node->title = "top-level book page #{$counter}";
$node->body = "dummy content {$counter}";
$node->uid = $author->uid;
$node->type = 'page';
$node->status = 1;
if ($firstNode === NULL) {
$node->book['bid'] = 'new';
}
else {
$node->book['bid'] = $firstNode;
}
node_save($node);
if ($firstNode === NULL) {
$books[] = $node;
$firstNode = $node->nid;
}
$nodes[] = $node;
++$counter;
}
}
function testCases() {
$this
->caseNoSpecialBookAccess();
$this
->caseAdministerBookAccess();
$this
->caseAdministerAnyBookAccess();
$this
->caseAdministerOwnBookAccess();
$this
->caseUpdatePreservesGrants();
$this
->caseAuthorVsAdminDefaults();
$this
->caseAuthorDefaultsPropagateToNewNode();
$this
->caseRoleDefaultsPropagateToNewNode();
$this
->caseChildDefaultsDoNotAffectParentBook();
$this
->caseAuthorDefaultsPropagateToUpdatedNode();
$this
->caseRoleWithIntentionalNoPermissionsAvoidsDefault();
$this
->caseDeletingBookDoesNotDeleteGrants();
$this
->caseResetToDefaults();
}
private function caseNoSpecialBookAccess() {
$user = $this
->drupalCreateUser(array(
'access content',
));
$this
->drupalLogin($user);
foreach ($this->nodes as $node) {
$nid = $node->nid;
$this
->drupalGet("node/{$nid}");
$this
->assertResponse('200', t('Can access content'));
$this
->drupalGet("book_access/delete/user_permission/{$nid}/{$this->author->uid}");
$this
->assertResponse('403', t('Cannot modify book_access permissions'));
$this
->drupalGet("node/{$nid}/book_access");
$this
->assertResponse('403', t('Cannot change book access'));
}
$this
->drupalLogout();
}
private function caseAdministerBookAccess() {
$user = $this
->drupalCreateUser(array(
'administer book access',
'access content',
));
$this
->drupalLogin($user);
foreach ($this->nodes as $node) {
$nid = $node->nid;
$this
->drupalGet("node/{$nid}");
$this
->assertResponse('200', t('Can access content'));
$this
->drupalGet("book_access/delete/user_permission/{$nid}/{$this->author->uid}");
$this
->assertResponse('200', t('Can modify book_access permissions'));
$this
->drupalGet("node/{$nid}/book_access");
$this
->assertResponse('200', t('Can change book access'));
}
$this
->drupalLogout();
}
private function caseAdministerAnyBookAccess() {
$user = $this
->drupalCreateUser(array(
'administer access of any book',
'access content',
));
$this
->drupalLogin($user);
foreach ($this->nodes as $node) {
$nid = $node->nid;
$this
->drupalGet("node/{$nid}");
$this
->assertResponse('200', t('Can access content'));
$this
->drupalGet("book_access/delete/user_permission/{$nid}/{$this->author->uid}");
$this
->assertResponse('403', t('Cannot modify book_access permissions'));
$this
->drupalGet("node/{$nid}/book_access");
$this
->assertResponse('200', t('Can change book access'));
}
$this
->drupalLogout();
}
private function caseAdministerOwnBookAccess() {
$user = $this
->drupalCreateUser(array(
'administer access of own books',
'access content',
));
$this
->drupalLogin($user);
$userBooks = array();
$userNodes = array();
$this
->createBook($userBooks, $userNodes, $user);
foreach ($this->nodes as $node) {
$nid = $node->nid;
$this
->drupalGet("node/{$nid}");
$this
->assertResponse('200', t('Can access content'));
$this
->drupalGet("book_access/delete/user_permission/{$nid}/{$this->author->uid}");
$this
->assertResponse('403', t('Cannot modify book_access permissions'));
$this
->drupalGet("node/{$nid}/book_access");
$this
->assertResponse('403', t('Cannot change book access'));
}
foreach ($userNodes as $node) {
$nid = $node->nid;
$this
->drupalGet("node/{$nid}/book_access");
$this
->assertResponse('200', t('Can change book access for own book'));
}
$this
->drupalLogout();
}
private function caseUpdatePreservesGrants() {
$user = $this
->drupalCreateUser(array(
'access content',
));
$grants = array(
'grant_update' => array(
$user->uid => 1,
),
'grant_delete' => array(
$user->uid => 1,
),
'grant_admin_access' => array(
$user->uid => 1,
),
'grant_add_child' => array(
$user->uid => 1,
),
'grant_edit_outline' => array(
$user->uid => 1,
),
);
foreach ($grants as $grant => $data) {
$this
->assertFalse(BookAccess::checkGrant($this->books[0]->nid, $grant, $user), t('Sanity check of initial state for "@grant" failed; should be false', array(
'@grant' => $grant,
)));
}
BookAccess::addUserGrants($this->books[0]->nid, array(
$user->uid,
), $grants);
foreach ($grants as $grant => $data) {
$this
->assertTrue(BookAccess::checkGrant($this->books[0]->nid, $grant, $user), t('Sanity check of "@grant" failed; should be true', array(
'@grant' => $grant,
)));
}
module_invoke('book_access', 'node_update', $this->books[0]);
foreach ($grants as $grant => $data) {
$this
->assertTrue(BookAccess::checkGrant($this->books[0]->nid, $grant, $user), t('"@grant" should stay true after node update', array(
'@grant' => $grant,
)));
}
}
private function caseAuthorVsAdminDefaults() {
$adminGrantsToCheck = drupal_map_assoc(BookAccess::grantIDs());
$authorGrantsToCheck = drupal_map_assoc(BookAccess::grantIDs());
$authorGrantsToCheck['grant_admin_access'] = FALSE;
$user = $this
->drupalCreateUser(array(
'access content',
));
$userBooks = array();
$userNodes = array();
$this
->createBook($userBooks, $userNodes, $user);
foreach ($authorGrantsToCheck as $grant => $value) {
$this
->assertEqual($value, BookAccess::checkGrant($userBooks[0]->nid, $grant, $user), t('Author (no admin role) should have @grant set to @value', array(
'@grant' => $grant,
'@value' => $value ? "TRUE" : "FALSE",
)));
}
$adminRole = user_role_load_by_name('administrator');
if ($adminRole === FALSE) {
$this
->fail(t('Couldn\'t load role \'administrator\''));
}
user_multiple_role_edit(array(
$user->uid,
), 'add_role', $adminRole->rid);
$user = user_load($user->uid);
foreach ($adminGrantsToCheck as $grant => $value) {
$this
->assertEqual($value, BookAccess::checkGrant($userBooks[0]->nid, $grant, $user), t('Author (with admin role) should have @grant set to @value', array(
'@grant' => $grant,
'@value' => $value ? "TRUE" : "FALSE",
)));
}
}
private function caseAuthorDefaultsPropagateToNewNode() {
$originalDefaults = variable_get("book_access_default_author_access");
$newDefaults = array(
'grant_view',
'grant_delete',
);
variable_set("book_access_default_author_access", $newDefaults);
$userBooks = array();
$userNodes = array();
$this
->createBook($userBooks, $userNodes, $this->author);
$resultSet = db_select('book_access_author', 'book_access_author')
->condition('uid', $this->author->uid, '=')
->condition('nid', $userBooks[0]->nid, '=')
->fields('book_access_author')
->execute();
$this
->assertTrue($resultSet
->rowCount() == 1, t('Exactly one entry in the database'));
$row = $resultSet
->fetchAssoc();
foreach ($originalDefaults as $grant) {
if (in_array($grant, $newDefaults)) {
$this
->assertTrue(BookAccess::checkGrant($userBooks[0]->nid, $grant, $this->author), t('New author default for grant "@grant" should be TRUE', array(
'@grant' => $grant,
)));
$this
->assertEqual(1, $row[$grant], t('DB entry for node @nid, author @uid, grant "@grant" should be 1', array(
'@nid' => $userBooks[0]->nid,
'@uid' => $this->author->uid,
'@grant' => $grant,
)));
}
else {
$this
->assertFalse(BookAccess::checkGrant($userBooks[0]->nid, $grant, $this->author), t('New author default for grant "@grant" should be FALSE', array(
'@grant' => $grant,
)));
$this
->assertEqual(0, $row[$grant], t('DB entry for node @nid, author @uid, grant "@grant" should be 0', array(
'@nid' => $userBooks[0]->nid,
'@uid' => $this->author->uid,
'@grant' => $grant,
)));
}
}
variable_set("book_access_default_author_access", $originalDefaults);
}
private function caseRoleDefaultsPropagateToNewNode() {
$enabledGrants = array(
'grant_view',
'grant_update',
);
$grantsToCheck = array(
'grant_delete' => FALSE,
'grant_view' => TRUE,
);
$rid = $this
->drupalCreateRole(array(
'access content',
));
if ($rid === FALSE) {
$this
->fail('Couldn\'t create test role');
}
$roles = array();
$roleGrants = BookAccess::getRoleGrants($this->books[0], $roles);
foreach ($grantsToCheck as $grant => $value) {
$this
->assertEqual($value, $roleGrants[$grant][$rid], t('Grant "@grant" should be @value', array(
'@grant' => $grant,
'@value' => $value ? "true" : "false",
)));
}
variable_set("book_access_default_role_{$rid}_access", $enabledGrants);
$roleBooks = array();
$roleNodes = array();
$roleUser = $this
->drupalCreateUser();
user_multiple_role_edit(array(
$roleUser->uid,
), 'add_role', $rid);
$this
->createBook($roleBooks, $roleNodes, $roleUser);
foreach ($enabledGrants as $grant) {
$this
->assertTrue(BookAccess::checkGrant($roleBooks[0]->nid, $grant, $roleUser), t('New book\'s grant "@grant" should be enabled', array(
'@grant' => $grant,
)));
}
}
private function caseChildDefaultsDoNotAffectParentBook() {
$originalDefaults = variable_get("book_access_default_author_access");
$userBooks = array();
$userNodes = array();
$this
->createBook($userBooks, $userNodes, $this->author);
$this
->assertTrue(BookAccess::checkGrant($userBooks[0]->nid, 'grant_delete', $this->author), t('Sanity checking that parent book does have grant_delete'));
$newDefaults = array(
'grant_view',
);
variable_set("book_access_default_author_access", $newDefaults);
$newNode = new stdClass();
$newNode->title = "child node";
$newNode->body = "dummy content";
$newNode->uid = $this->author->uid;
$newNode->type = 'page';
$newNode->stats = 1;
$newNode->book['bid'] = $userBooks[0]->nid;
node_save($newNode);
$this
->assertTrue(BookAccess::checkGrant($userBooks[0]->nid, 'grant_delete', $this->author), t('Parent must remain un-changed in its permissions'));
variable_set("book_access_default_author_access", $originalDefaults);
}
private function caseAuthorDefaultsPropagateToUpdatedNode() {
$newNode = new stdClass();
$newNode->title = "un-booked node";
$newNode->body = "dummy content";
$newNode->uid = $this->author->uid;
$newNode->type = 'page';
$newNode->stats = 1;
node_save($newNode);
$query = db_select('book_access_author', 'book_access_author')
->condition('nid', $newNode, '=')
->condition('uid', $this->author->uid)
->fields('book_access_author');
$resultSet = $query
->execute();
$this
->assertEqual(0, $resultSet
->rowCount(), t('There should not be any entry in the book_access_author table'));
$newNode->book['bid'] = 'new';
node_save($newNode);
$query = db_select('book_access_author', 'book_access_author')
->condition('nid', $newNode->book['bid'], '=')
->condition('uid', $this->author->uid, '=')
->fields('book_access_author');
$resultSet = $query
->execute();
$this
->assertEqual(1, $resultSet
->rowCount(), t('There should be an entry in the book_access_author table post-update'));
}
private function caseRoleWithIntentionalNoPermissionsAvoidsDefault() {
$rid = $this
->drupalCreateRole(array(
'access content',
));
if ($rid === FALSE) {
$this
->fail('Couldn\'t create test role');
}
$roleBooks = array();
$roleNodes = array();
$roleUser = $this
->drupalCreateUser();
user_multiple_role_edit(array(
$roleUser->uid,
), 'add_role', $rid);
$this
->createBook($roleBooks, $roleNodes, $roleUser);
$defaultRoleGrants = variable_get("book_access_default_role_{$rid}_access");
$this
->assertTrue(in_array('grant_view', $defaultRoleGrants), t('New book\'s grant_view should be on by default'));
variable_set("book_access_default_role_{$rid}_access", array());
$defaultRoleGrants = variable_get("book_access_default_role_{$rid}_access");
$this
->assertFalse(in_array('grant_view', $defaultRoleGrants), t('Sanity check to make sure grant_view is gone.'));
module_invoke('book_access', 'init');
$defaultRoleGrants = variable_get("book_access_default_role_{$rid}_access");
$this
->assertFalse(in_array('grant_view', $defaultRoleGrants), t('grant_view should not have come back'));
}
private function caseDeletingBookDoesNotDeleteGrants() {
$roleBooks = array();
$roleNodes = array();
$this
->createBook($roleBooks, $roleNodes, $this->author);
$this
->assertTrue(BookAccess::checkGrant($roleBooks[0]->nid, 'grant_view', $this->author), t('Sanity checking that newly-created book has grant_view'));
$this
->assertTrue(BookAccess::checkGrant($this->books[0]->nid, 'grant_view', $this->author), t('Sanity checking that base test-case book has grant_view'));
node_delete($roleBooks[0]->nid);
$this
->assertTrue(BookAccess::checkGrant($this->books[0]->nid, 'grant_view', $this->author), t('Base test-case book should maintain its permissions'));
}
private function caseResetToDefaults() {
$grantsToCheck = array(
'grant_delete',
'grant_view',
'grant_update',
);
$rid = $this
->drupalCreateRole(array(
'access content',
));
if ($rid === FALSE) {
$this
->fail('Couldn\'t create test role');
}
$roleBooks = array();
$roleNodes = array();
$roleUser = $this
->drupalCreateUser();
foreach ($roleUser->roles as $rid => $rname) {
user_multiple_role_edit(array(
$roleUser->uid,
), 'remove_role', $rid);
}
user_multiple_role_edit(array(
$roleUser->uid,
), 'add_role', $rid);
$roleUser = user_load($roleUser->uid);
variable_set("book_access_default_role_{$rid}_access", array());
$this
->createBook($roleBooks, $roleNodes, $this->author);
foreach ($grantsToCheck as $grant) {
$this
->assertFalse(BookAccess::checkGrant($roleBooks[0]->nid, $grant, $roleUser), t('New book\'s grant "@grant" should be disabled', array(
'@grant' => $grant,
)));
}
variable_set("book_access_default_role_{$rid}_access", $grantsToCheck);
BookAccess::resetToDefault($roleBooks[0]->nid);
foreach ($grantsToCheck as $grant) {
$this
->assertTrue(BookAccess::checkGrant($roleBooks[0]->nid, $grant, $roleUser), t('New book\'s grant "@grant" should be reset to the new default of enabled', array(
'@grant' => $grant,
)));
}
}
}