t('Book Access'), 'description' => t('Test access control to Books and Book Pages'), 'group' => t('Book Access') ); } function setUp() { // @ to supress all the stupid errors from SimpleTest @parent::setUp('book', 'book_access'); } function tearDown() { parent::tearDown(); } /** * Exercise basic functionality of Book Access module. Note: this is NOT a * complete test of Book module itself, so it is reccommended that you run the * Book module test at the same time. */ function testBasicOperation() { // ======================================================================== // Create book content and check the owner has full access to it. $book_author = $this->drupalCreateUser( array( // Node permissions 'create book content', 'edit own book content', 'delete own book content', // Book permissions 'create new books', 'add content to books', ) ); $this->drupalLogin($book_author); // Create a book with some nested pages. $book = $this->createBookPage('BOOK', 'new'); $bookpage1 = $this->createBookPage('PAGE1', $book); $booksubpage1 = $this->createBookPage('SUBPAGE1', $bookpage1); $booksubpage2 = $this->createBookPage('SUBPAGE2', $bookpage1); $bookpage2 = $this->createBookPage('PAGE2', $book); $this->checkBookAccess($book); $this->checkBookAccess($bookpage1); $this->checkBookAccess($booksubpage1); $this->checkBookAccess($booksubpage2); $this->checkBookAccess($bookpage2); // ======================================================================== // Check anonymous user can read, but not write/delete this (using the // default permissions) $this->drupalLogout(); $this->checkBookAccess($book, TRUE, FALSE, FALSE); $this->checkBookAccess($bookpage1, TRUE, FALSE, FALSE); $this->checkBookAccess($booksubpage1, TRUE, FALSE, FALSE); $this->checkBookAccess($booksubpage2, TRUE, FALSE, FALSE); $this->checkBookAccess($bookpage2, TRUE, FALSE, FALSE); // ======================================================================== // Remove all permissions for the book from Anonymous User, and check it // can no longer read/write/delete the book $admin_user = $this->drupalCreateUser( array( // Book Access permissions 'administer book access' ) ); $this->drupalLogin($admin_user); $nid = $book['nid']; $rid = DRUPAL_ANONYMOUS_RID; $edit = array( "access[$nid][view][$rid]" => FALSE, "access[$nid][update][$rid]" => FALSE, "access[$nid][delete][$rid]" => FALSE, ); $this->drupalPost('admin/content/book/access', $edit, 'Save configuration'); $this->drupalLogout(); $this->checkBookAccess($book, FALSE, FALSE, FALSE); $this->checkBookAccess($bookpage1, FALSE, FALSE, FALSE); $this->checkBookAccess($booksubpage1, FALSE, FALSE, FALSE); $this->checkBookAccess($booksubpage2, FALSE, FALSE, FALSE); $this->checkBookAccess($bookpage2, FALSE, FALSE, FALSE); // ======================================================================== // Remove all permissions for the book to Anonymous User, and check it // can now read/write/delete the book $admin_user = $this->drupalCreateUser( array( // Book Access permissions 'administer book access' ) ); $this->drupalLogin($admin_user); $nid = $book['nid']; $rid = DRUPAL_ANONYMOUS_RID; $edit = array( "access[$nid][view][$rid]" => TRUE, "access[$nid][update][$rid]" => TRUE, "access[$nid][delete][$rid]" => TRUE, ); $this->drupalPost('admin/content/book/access', $edit, 'Save configuration'); $this->drupalLogout(); $this->checkBookAccess($book); $this->checkBookAccess($bookpage1); $this->checkBookAccess($booksubpage1); $this->checkBookAccess($booksubpage2); $this->checkBookAccess($bookpage2); } /** * Create a book page, optionally with parent book. * * @param $prefix * (Optional) A string prefix to use on the Book title and body. Defaults to * "BOOK". * @param $book * (Optional) If $book is NULL (default) then create a book page without * naming a book. If $book is 'new' then create a book page and a new book. * If $book is an array (as returned from this function) use it as the * parent for a new book page. * @return * An array of information about the new book created, including 'nid', * 'url', 'bid', and 'plid'. */ function createBookPage($prefix = 'BOOK', $book = NULL) { $edit = array( 'title' => $this->randomName(10, $prefix . '_TITLE_'), 'body' => $this->randomName(20, $prefix . '_BODY_'), ); $options = array(); if ($book == 'new') { // Create a new Book. $edit['book[bid]'] = 'new'; } elseif (is_array($book)) { // Name the given Book as parent. $options['query'] = array('parent' => $book['mlid']); // Need to load a different form. $edit['book[bid]'] = $book['bid']; $edit['book[plid]'] = $book['mlid']; } else { // No Book. $edit['book[bid]'] = 0; } // Create the book, and parse for NID $this->drupalPost('node/add/book', $edit, 'Save', $options); $edit['url'] = $this->getUrl(); $bits = explode('/', $this->getUrl()); $node = node_load(array_pop($bits)); $edit['mlid'] = $node->book['mlid']; $edit['nid'] = $node->book['nid']; $edit['bid'] = $node->book['bid']; return $edit; } /** * Check that the current user can/cannot view/update/delete the given book. * @param $book * A book-array as returned by createBookPage() * @param $view * If TRUE, then check that the current user CAN view the given book * (default), otherwise check that the current CANNOT view the given book. * @param $update * If TRUE, then check that the current user CAN edit the given book * (default), otherwise check that the current CANNOT editthe given book. * @param $delete * If TRUE, then check that the current user CAN delete the given book * (default), otherwise check that the current CANNOT delete the given book. */ function checkBookAccess($book, $view = TRUE, $update = TRUE, $delete = TRUE) { $node = node_load($book['nid']); $this->drupalGet($book['url']); if ($view) { $this->assertText($node->name); $this->assertText($book['title']); $this->assertText($book['body']); } else { $this->drupalGet($book['url']); $this->assertText('Access denied'); } if ($update) { $this->assertLink('Edit'); $this->drupalGet($book['url'] . '/edit'); $this->assertNoText('Access denied'); } else { $this->assertNoLink('Edit'); $this->drupalGet($book['url'] . '/edit'); $this->assertText('Access denied'); } if ($delete) { $this->drupalGet($book['url'] . '/delete'); $this->assertNoText('Access denied'); $this->assertText('Are you sure you want to delete'); } else { $this->drupalGet($book['url'] . '/delete'); $this->assertText('Access denied'); $this->assertNoText('Are you sure you want to delete'); } } /** * Write the given data to the given filename, relative to the Drupal * temporary directory. This method is really useful for determining what was * in the HTML page that DrupalWebTestCase actually saw. * * @param $filename * The filename to write (defaults to out.html). * @param $data * The data that will be written to the above file (defaults to the content * of the current page). */ function writeFile($filename = 'out.html', $data = NULL) { $data = ($data == NULL) ? $this->drupalGetContent() : $data; $filename = file_directory_temp() . '/' . $filename; $this->assertTrue(file_put_contents($filename, $data), t('Wrote content to %filename', array('%filename' => $filename))); drupal_set_message("Wrote content to $filename"); } }