Commit af474609 authored by Dries's avatar Dries

- Added a test framework to Drupal along with a first batch of tests for

  Drupal core!  This is an important milestone for the project so enable
  the module and check it out ... :)

  Thanks to Rok Žlender, Károly Négyesi, Jimmy Berry, Kevin Bridges, Charlie
  Gordon, Douglas Hubler, Miglius Alaburda, Andy Kirkham, Dimitri13, Kieran
  Lal, Moshe Weitzman, and the many other people that helped with testing
  over the past years and that drove this home.

  It all works but it is still rough around the edges (i.e. documentation
  is still being written, the coding style is not 100% yet, a number of
  tests still fail) but we spent the entire weekend working on it in Paris
  and made a ton of progress.  The best way to help and to get up to speed,
  is to start writing and contributing some tests ... as well as fixing
  some of the failures.

  For those willing to help with improving the test framework, here are
  some next steps and issues to resolve:

    - How to best approach unit tests and mock functions?
    - How to test drupal_mail() and drupal_http_request()?
    - How to improve the admin UI so we have a nice progress bar?
    - How best to do code coverage?
    - See http://g.d.o/node/10099 for more ...
parent fe7b9baf
......@@ -14,6 +14,8 @@ Drupal 7.0, xxxx-xx-xx (development version)
* Provide descriptions for permissions on the administration page.
- Search:
* Made it possible to language-aware searches.
- Testing:
* Added test framework and tests.
- Removed ping module:
* This module has been removed from the core download. Contributed
alternatives are available.
......
......@@ -122,7 +122,7 @@ function db_prefix_tables($sql) {
* @return the name of the previously active database or FALSE if non was found.
*/
function db_set_active($name = 'default') {
global $db_url, $db_type, $active_db;
global $db_url, $db_type, $active_db, $db_prefix;
static $db_conns, $active_name = FALSE;
if (empty($db_url)) {
......@@ -150,6 +150,12 @@ function db_set_active($name = 'default') {
}
$db_conns[$name] = db_connect($connect_url);
// We need to pass around the simpletest database prefix in the request
// and we put that in the user_agent header.
if (preg_match("/^simpletest\d+$/", $_SERVER['HTTP_USER_AGENT'])) {
$db_prefix = $_SERVER['HTTP_USER_AGENT'];
}
}
$previous_name = $active_name;
......
<?php
// $Id$
class XMLRPCValidator1Test extends DrupalUnitTestCase {
function getInfo() {
return array('name' => t('XML-RPC validator1'),
'description' => t('See !validator-link. note: simpletest_xmlrpc.module must be enabled', array('!validator-link' => l('the xmlrpc validator1 specification', 'http://www.xmlrpc.com/validator1Docs'))),
'group' => t('XML-RPC'));
}
function test_run_all_tests() {
if (!$this->drupalModuleEnable('simpletest_xmlrpc')) {
return FALSE;
}
$xml_url = url(NULL, array('absolute' => TRUE)) . 'xmlrpc.php';
srand();
mt_srand();
$array_1 = array(array('curly' => mt_rand(-100,100)),
array('curly' => mt_rand(-100,100)),
array('larry' => mt_rand(-100,100)),
array('larry' => mt_rand(-100,100)),
array('moe' => mt_rand(-100,100)),
array('moe' => mt_rand(-100,100)),
array('larry' => mt_rand(-100,100)));
shuffle($array_1);
$l_res_1 = simpletest_xmlrpc_arrayOfStructsTest($array_1);
$r_res_1 = xmlrpc($xml_url, 'validator1.arrayOfStructsTest', $array_1);
$this->assertIdentical($l_res_1, $r_res_1, 'array of structs test: %s');
$string_2 = 't\'&>>zf"md>yr>xlcev<h<"k&j<og"w&&>">>uai"np&s>>q\'&b<>"&&&';
$l_res_2 = simpletest_xmlrpc_countTheEntities($string_2);
$r_res_2 = xmlrpc($xml_url, 'validator1.countTheEntities', $string_2);
$this->assertIdentical($l_res_2, $r_res_2, 'count the entities test: %s');
$struct_3 = array('moe' => mt_rand(-100,100), 'larry' => mt_rand(-100,100), 'curly' => mt_rand(-100,100), 'homer' => mt_rand(-100,100));
$l_res_3 = simpletest_xmlrpc_easyStructTest($struct_3);
$r_res_3 = xmlrpc($xml_url, 'validator1.easyStructTest', $struct_3);
$this->assertIdentical($l_res_3, $r_res_3, 'easy struct test: %s');
$struct_4 = array('sub1' => array('bar' => 13),
'sub2' => 14,
'sub3' => array('foo' => 1, 'baz' => 2),
'sub4' => array('ss' => array('sss' => array('ssss' => 'sssss'))));
$l_res_4 = simpletest_xmlrpc_echoStructTest($struct_4);
$r_res_4 = xmlrpc($xml_url, 'validator1.echoStructTest', $struct_4);
$this->assertIdentical($l_res_4, $r_res_4, 'echo struct test: %s');
$int_5 = mt_rand(-100,100);
$bool_5 = (($int_5 % 2) == 0);
$string_5 = $this->randomName();
$double_5 = (double)(mt_rand(-1000,1000) / 100);
$time_5 = time();
$base64_5 = $this->randomName(100);
$l_res_5 = simpletest_xmlrpc_manyTypesTest($int_5, $bool_5, $string_5, $double_5, xmlrpc_date($time_5), $base64_5);
$l_res_5[5] = $l_res_5[5]->data; /* override warpping */
$r_res_5 = xmlrpc($xml_url, 'validator1.manyTypesTest', $int_5, $bool_5, $string_5, $double_5, xmlrpc_date($time_5), xmlrpc_base64($base64_5));
/* Contains objects, objects are not equal */
// See http://drupal.org/node/37766 why this currnetly fails
$this->assertEqual($l_res_5, $r_res_5, 'many types test: %s');
$size = mt_rand(100,200);
$array_6 = array();
for ($i = 0; $i < $size; $i++) {
$array_6[] = $this->randomName(mt_rand(8,12));
}
$l_res_6 = simpletest_xmlrpc_moderateSizeArrayCheck($array_6);
$r_res_6 = xmlrpc($xml_url, 'validator1.moderateSizeArrayCheck', $array_6);
$this->assertIdentical($l_res_6, $r_res_6, 'moderate size array check: %s');
$struct_7 = array();
for ($y = 2000; $y < 2002; $y++) {
for ($m = 3; $m < 5; $m++) {
for ($d = 1; $d < 6; $d++) {
$ys = (string)$y;
$ms = sprintf('%02d', $m);
$ds = sprintf('%02d', $d);
$struct_7[$ys][$ms][$ds]['moe'] = mt_rand(-100,100);
$struct_7[$ys][$ms][$ds]['larry'] = mt_rand(-100,100);
$struct_7[$ys][$ms][$ds]['curly'] = mt_rand(-100,100);
}
}
}
$l_res_7 = simpletest_xmlrpc_nestedStructTest($struct_7);
$r_res_7 = xmlrpc($xml_url, 'validator1.nestedStructTest', $struct_7);
$this->assertIdentical($l_res_7, $r_res_7, 'nested struct test: %s');
$int_8 = mt_rand(-100,100);
$l_res_8 = simpletest_xmlrpc_simpleStructReturnTest($int_8);
$r_res_8 = xmlrpc($xml_url, 'validator1.simpleStructReturnTest', $int_8);
$this->assertIdentical($l_res_8, $r_res_8, 'nested struct test: %s');
/* Now test multicall */
$x = array();
$x[] = array('validator1.arrayOfStructsTest', $array_1);
$x[] = array('validator1.countTheEntities', $string_2);
$x[] = array('validator1.easyStructTest', $struct_3);
$x[] = array('validator1.echoStructTest', $struct_4);
$x[] = array('validator1.manyTypesTest', $int_5, $bool_5, $string_5, $double_5, xmlrpc_date($time_5), xmlrpc_base64($base64_5));
$x[] = array('validator1.moderateSizeArrayCheck', $array_6);
$x[] = array('validator1.nestedStructTest', $struct_7);
$x[] = array('validator1.simpleStructReturnTest', $int_8);
$a_l_res = array($l_res_1, $l_res_2, $l_res_3, $l_res_4, $l_res_5, $l_res_6, $l_res_7, $l_res_8);
$a_r_res = xmlrpc($xml_url, $x);
$this->assertEqual($a_l_res, $a_r_res, 'multicall equals result');
}
}
?>
\ No newline at end of file
This diff is collapsed.
<?php
// $Id$
class BlockTestCase extends DrupalWebTestCase {
/**
* Implementation of getInfo().
*/
function getInfo() {
return array(
'name' => t('Block functionality'),
'description' => t('Add, edit and delete custom block. Configure and move a module-defined block.'),
'group' => t('Block'),
);
}
/**
* Implementation of setUp().
*/
function setUp() {
parent::setUp();
// Create and login user
$admin_user = $this->drupalCreateUser(array('administer blocks'));
$this->drupalLogin($admin_user);
}
/**
* Test creating custom block (i.e. box), moving it to a specific region and then deleting it.
*/
function testBox() {
// Add a new box by filling out the input form on the admin/build/block/add page.
$box = array();
$box['info'] = $this->randomName(8);
$box['title'] = $this->randomName(8);
$box['body'] = $this->randomName(32);
$this->drupalPost('admin/build/block/add', $box, t('Save block'));
// Confirm that the box has been created, and then query the created bid.
$this->assertText(t('The block has been created.'), t('Box successfully created.'));
$bid = db_result(db_query("SELECT bid FROM {boxes} WHERE info = '%s'", array($box['info'])));
// Check to see if the box was created by checking that it's in the database..
$this->assertNotNull($bid, t('Box found in database'));
// Set the created box to a specific region.
// TODO: Implement full region checking.
$edit = array();
$edit['block_'. $bid .'[region]'] = 'left';
$this->drupalPost('admin/build/block', $edit, t('Save blocks'));
// Confirm that the box was moved to the proper region.
$this->assertText(t('The block settings have been updated.'), t('Box successfully moved to left region.'));
// Confirm that the box is being displayed.
$this->assertText(t($box['title']), t('Box successfully being displayed on the page.'));
// Delete the created box & verify that it's been deleted and no longer appearing on the page.
$this->drupalPost('admin/build/block/delete/'. $bid, array(), t('Delete'));
$this->assertRaw(t('The block %title has been removed.', array('%title' => $box['info'])), t('Box successfully deleted.'));
$this->assertNoText(t($box['title']), t('Box no longer appears on page.'));
}
/**
* Test configuring and moving a module-define block to specific regions.
*/
function testBlock() {
// Select the Navigation block to be configured and moved.
$block = array();
$block['module'] = 'user';
$block['delta'] = 'navigation';
$block['title'] = $this->randomName(8);
// Set block title to confirm that interface works and override any custom titles.
$this->drupalPost('admin/build/block/configure/'. $block['module'] .'/'. $block['delta'], array('title' => $block['title']), t('Save block'));
$this->assertText(t('The block configuration has been saved.'), t('Block title set.'));
$bid = db_result(db_query("SELECT bid FROM {blocks} WHERE module = '%s' AND delta = %d", array($block['module'], $block['delta'])));
// Check to see if the block was created by checking that it's in the database.
$this->assertNotNull($bid, t('Block found in database'));
// Set the created block to a specific region.
$edit = array();
$edit[$block['module'] .'_'. $block['delta'] .'[region]'] = 'left';
$this->drupalPost('admin/build/block', $edit, t('Save blocks'));
// Confirm that the block was moved to the proper region.
// TODO: Implement full region checking.
$this->assertText(t('The block settings have been updated.'), t('Block successfully moved to left region.'));
// Confirm that the block is being displayed.
$this->assertText(t($block['title']), t('Block successfully being displayed on the page.'));
// Set the block to the disabled region.
$edit = array();
$edit[$block['module'] .'_'. $block['delta'] .'[region]'] = '-1';
$this->drupalPost('admin/build/block', $edit, t('Save blocks'));
// Confirm that the block was moved to the proper region.
$this->assertText(t('The block settings have been updated.'), t('Block successfully move to disabled region.'));
$this->assertNoText(t($block['title']), t('Block no longer appears on page.'));
// For convenience of developers, put the navigation block back.
$edit = array();
$edit[$block['module'] .'_'. $block['delta'] .'[region]'] = 'left';
$this->drupalPost('admin/build/block', $edit, t('Save blocks'));
$this->assertText(t('The block settings have been updated.'), t('Block successfully move to disabled region.'));
$this->drupalPost('admin/build/block/configure/'. $block['module'] .'/'. $block['delta'], array('title' => 'Navigation'), t('Save block'));
$this->assertText(t('The block configuration has been saved.'), t('Block title set.'));
}
}
<?php
// $Id$
class BlogTestCase extends DrupalWebTestCase {
protected $big_user;
protected $own_user;
protected $any_user;
/**
* Implementation of getInfo().
*/
function getInfo() {
return array(
'name' => t('Blog functionality'),
'description' => t('Create, view, edit, delete, and change blog entries and verify its consistency in the database.'),
'group' => t('Blog'),
);
}
/**
* Enable modules and create users with specific permissions.
*/
function setUp() {
parent::setUp('blog');
// Create users.
$this->big_user = $this->drupalCreateUser(array('administer blocks'));
$this->own_user = $this->drupalCreateUser(array('create blog content', 'edit own blog content', 'delete own blog content'));
$this->any_user = $this->drupalCreateUser(array('create blog content', 'edit any blog content', 'delete any blog content', 'access administration pages'));
}
/**
* Login users, create blog nodes, and test blog functionality through the admin and user interfaces.
*/
function testBlog() {
// Login the admin user.
$this->drupalLogin($this->big_user);
// Enable the recent blog block.
$edit = array();
$edit['blog_recent[region]'] = 'right';
$this->drupalPost('admin/build/block', $edit, t('Save blocks'));
$this->assertResponse(200);
// Do basic tests for each user.
$this->doBasicTests($this->any_user, TRUE);
$this->doBasicTests($this->own_user, FALSE);
// Create another blog node for the any blog user.
$node = $this->drupalCreateNode(array('type' => 'blog', 'uid' => $this->any_user->uid));
// Verify the own blog user only has access to the blog view node.
$this->verifyBlogs($this->any_user, $node, FALSE, 403);
// Create another blog node for the own blog user.
$node = $this->drupalCreateNode(array('type' => 'blog', 'uid' => $this->own_user->uid));
// Login the any blog user.
$this->drupalLogin($this->any_user);
// Verify the any blog user has access to all the blog nodes.
$this->verifyBlogs($this->own_user, $node, TRUE);
}
/**
* Run basic tests on the indicated user.
*
* @param object $user The logged in user.
* @param boolean $admin User has 'access administration pages' privilege.
*/
private function doBasicTests($user, $admin) {
// Login the user.
$this->drupalLogin($user);
// Create blog node.
$node = $this->drupalCreateNode(array('type' => 'blog', 'uid' => $user->uid));
// Verify the user has access to all the blog nodes.
$this->verifyBlogs($user, $node, $admin);
// Verify the blog links are displayed.
$this->verifyBlogLinks($user);
}
/**
* Verify the logged in user has the desired access to the various blog nodes.
*
* @param object $node_user The user who creates the node.
* @param object $node Node.
* @param boolean $admin User has 'access administration pages' privilege.
* @param integer $response HTTP response code.
*/
private function verifyBlogs($node_user, $node, $admin, $response = 200) {
$crumb = '›';
$quote = '&#039;';
$response2 = ($admin) ? 200 : 403;
// View blog help node.
$this->drupalGet('admin/help/blog');
$this->assertResponse($response2);
// NOTE: The two commented asserts fail because the get returns the 'admin/help' node instead of the indicated node???
if ($response2 == 200) {
// $this->assertTitle(t('Blog | Drupal'), t('Blog help node was displayed'));
$this->assertText(t('Blog'), t('Blog help node was displayed'));
// $this->assertText(t('Home '. $crumb .' Administer '. $crumb .' Help'), t('Breadcrumbs were displayed'));
}
// Verify the blog block was displayed.
$this->drupalGet('');
$this->assertResponse(200);
$this->assertText(t('Recent blog posts'), t('Blog block was displayed'));
// View blog node.
$this->drupalGet('node/'. $node->nid);
$this->assertResponse(200);
$this->assertTitle($node->title. ' | Drupal', t('Blog node was displayed'));
$this->assertText(t('Home '. $crumb .' Blogs '. $crumb .' @name'. $quote .'s blog', array('@name' => $node_user->name)), t('Breadcrumbs were displayed'));
// View blog edit node.
$this->drupalGet('node/'. $node->nid .'/edit');
$this->assertResponse($response);
if ($response == 200) {
$this->assertTitle($node->title. ' | Drupal', t('Blog edit node was displayed'));
$this->assertText(t('Home '. $crumb .' @title', array('@title' => $node->title)), t('Breadcrumbs were displayed'));
}
if ($response == 200) {
// Edit blog node.
$edit = array();
$edit['title'] = 'node/' . $node->nid;
$edit['body'] = $this->randomName(256);
$this->drupalPost('node/'. $node->nid .'/edit', $edit, t('Save'));
$this->assertRaw(t('Blog entry %title has been updated.', array('%title' => $edit['title'])), t('Blog node was edited'));
// Delete blog node.
$this->drupalPost('node/'. $node->nid .'/delete', array(), t('Delete'));
$this->assertResponse($response);
$this->assertRaw(t('Blog entry %title has been deleted.', array('%title' => $edit['title'])), t('Blog node was deleted'));
}
}
/**
* Verify the blog links are displayed to the logged in user.
*
* @param object $user The logged in user.
*/
private function verifyBlogLinks($user) {
$crumb = '›';
// Confirm blog entries link exists on the user page.
$this->drupalGet('user/'. $user->uid);
$this->assertResponse(200);
$this->assertText(t('View recent blog entries'), t('View recent blog entries link was displayed'));
// Confirm the recent blog entries link links to the user's blog page.
$this->clickLink('View recent blog entries');
$this->assertTitle(t("@name's blog | Drupal", array('@name' => $user->name)), t('View recent blog entries link target was correct'));
// Confirm a blog page was displayed.
$this->drupalGet('blog');
$this->assertResponse(200);
$this->assertTitle('Blogs | Drupal', t('Blog page was displayed'));
$this->assertText(t('Home'), t('Breadcrumbs were displayed'));
// Confirm a blog page was displayed per user.
$this->drupalGet('blog/'. $user->uid);
$this->assertTitle(t("@name's blog | Drupal", array('@name' => $user->name)), t('User blog node was displayed'));
$this->assertText(t('Home '. $crumb .' Blogs'), t('Breadcrumbs were displayed'));
// Confirm a blog feed was displayed.
$this->drupalGet('blog/feed');
$this->assertTitle(t('Drupal blogs'), t('Blog feed was displayed'));
// Confirm a blog feed was displayed per user.
$this->drupalGet('blog/'. $user->uid .'/feed');
$this->assertTitle(t("@name's blog", array('@name' => $user->name)), t('User blog feed was displayed'));
}
}
<?php
// $Id$
class BlogAPITestCase extends DrupalWebTestCase {
/**
* Implementation of getInfo().
*/
function getInfo() {
return array(
'name' => t('Blog API functionality'),
'description' => t('Create, edit, and delete post; upload file; and set/get categories.'),
'group' => t('Blog API'),
);
}
/**
* Implementation of setUp().
*/
function setUp() {
parent::setUp('blog', 'blogapi', 'taxonomy');
}
/**
* Create, edit, and delete post; upload file; and set/get categories.
*/
function testBlogAPI() {
// Create admin user and taxononmy for later use.
$admin_user = $this->drupalCreateUser(array('administer taxonomy'));
$this->drupalLogin($admin_user);
$vid = $this->addVocabulary('simpletest_vocab');
$term = $this->addTerm($vid, 'simpletest_term1');
$this->drupalLogout();
// Create user.
$web_user = $this->drupalCreateUser(array('create blog content', 'delete own blog content', 'edit own blog content', 'administer content with blog api'));
$this->drupalLogin($web_user);
// Init common variables.
$local = url('xmlrpc.php', array('absolute' => TRUE));
$appid = 'simpletest';
// Get user's blog.
$result = xmlrpc($local, 'blogger.getUsersBlogs', $appid, $web_user->name, $web_user->pass_raw);
$this->assertTrue($result, t('Request for user\'s blogs returned correctly.'));
if ($result !== FALSE) {
if ($this->assertTrue(array_key_exists('blogid', $result[0]), t('Blog found.'))) {
$blog_id = $result[0]['blogid'];
}
}
// Create post.
$content = $this->randomName(32);
$result = xmlrpc($local, 'blogger.newPost', $appid, $blog_id, $web_user->name, $web_user->pass_raw, $content, TRUE);
$this->assertTrue($result, t('Post created.'));
$nid = $result;
// Check recent posts.
$result = xmlrpc($local, 'blogger.getRecentPosts', $appid, $blog_id, $web_user->name, $web_user->pass_raw, 5);
$this->assertTrue($result, t('Recent post list retreived.'));
if ($result !== FALSE && array_key_exists('title', $result[0])) {
$this->assertEqual($content, $result[0]['title'], t('Post found.'));
}
else
$this->assertTrue(false, 'Post found.');
// Edit post.
$content_new = $this->randomName(10);
$result = xmlrpc($local, 'blogger.editPost', $appid, $nid, $web_user->name, $web_user->pass_raw, $content_new, TRUE);
$this->assertTrue($result, t('Post successfully modified.'));
// Upload file.
$file = current($this->drupalGetTestFiles('text'));
$file_contents = file_get_contents($file->filename);
$file = array();
$file['name'] = $this->randomName() .'.txt';
$file['type'] = 'text';
$file['bits'] = xmlrpc_base64($file_contents);
$result = xmlrpc($local, 'metaWeblog.newMediaObject', $blog_id, $web_user->name, $web_user->pass_raw, $file);
$this->assertTrue($result, t('File successfully uploaded.'));
$url = (array_key_exists('url', $result) ? $result['url'] : '');
// Check uploaded file.
$this->drupalGet($url);
$this->assertEqual($this->drupalGetContent(), $file_contents, t('Uploaded contents verified.'));
// Set post categories.
$categories = array(array('categoryId' => $term));
$result = xmlrpc($local, 'mt.setPostCategories', $nid, $web_user->name, $web_user->pass_raw, $categories);
$this->assertTrue($result, t('Post categories set.'));
// Get post categories.
$result = xmlrpc($local, 'mt.getPostCategories', $nid, $web_user->name, $web_user->pass_raw);
$this->assertTrue($result, t('Category list successfully retreived.'));
if ($result !== FALSE && array_key_exists('categoryId', $result[0])) {
$this->assertEqual($term, $result[0]['categoryId'], t('Category list verified.'));
}
// Delete post.
$result = xmlrpc($local, 'blogger.deletePost', $appid, $nid, $web_user->name, $web_user->pass_raw, TRUE);
$this->assertTrue($result, t('Post successfully deleted.'));
}
/**
* Add taxonomy vocabulary.
*
* @param string $vocab Vocabulary name.
* @return interger Vocab id.
*/
function addVocabulary($vocab) {
$edit = array();
$edit['name'] = $vocab;
$edit['nodes[blog]'] = TRUE;
$this->drupalPost('admin/content/taxonomy/add/vocabulary', $edit, t('Save'));
$this->assertRaw(t('Created new vocabulary %vocab.', array('%vocab' => $edit['name'])), t('Taxonomy vocabulary added.'));
$vocab_arr = taxonomy_get_vocabularies();
$vid = NULL;
foreach ($vocab_arr as $vocab_item) {
if ($vocab_item->name == $vocab) {
$vid = $vocab_item->vid;
break;
}
}
$this->assertNotNull($vid, t('Vocabulary found in database.'));
return $vid;
}
/**
* Add a taxonomy term to vocabulary.
*
* @param integer $vid Vocabulary id.
* @param string $term Term name.
* @return interger Term id.
*/
function addTerm($vid, $term) {
$edit = array();
$edit['name'] = $term;
$this->drupalPost('admin/content/taxonomy/'. $vid .'/add/term', $edit, t('Save'));
$this->assertRaw(t('Created new term %term.', array('%term' => $edit['name'])), t('Taxonomy term added.'));
$tree = taxonomy_get_tree($vid);
$tid = NULL;
foreach ($tree as $tree_term) {
if ($tree_term->name == $term) {
$tid = $tree_term->tid;
break;
}
}
$this->assertNotNull($tid, t('Term found in database.'));
return $tid;
}
}
<?php
// $Id$
class BookTestCase extends DrupalWebTestCase {
protected $book;
/**
* Implementation of getInfo().
*/
function getInfo() {
return array(
'name' => t('Book functionality'),
'description' => t('Create a book, add pages, and test book interface.'),
'group' => t('Book'),
);
}
/**
* Implementation of setUp().
*/
function setUp() {
parent::setUp('book');
}
/**
* Test book funcitonality through node interfaces.
*/
function testBook() {
// Create users.
$book_author = $this->drupalCreateUser(array('create new books', 'create book content', 'add content to books'));
$web_user = $this->drupalCreateUser(array('access printer-friendly version'));
// Create new book.
$this->drupalLogin($book_author);
$this->book = $this->createBookNode('new');
$book = $this->book;
/*
* Add page hiearchy to book.
* Book
* |- Node 0
* |- Node 1
* |- Node 2
* |- Node 3
* |- Node 4
*/
$nodes = array();
$nodes[] = $this->createBookNode($book->nid); // Node 0.
$nodes[] = $this->createBookNode($book->nid, $nodes[0]->book['mlid']); // Node 1.
$nodes[] = $this->createBookNode($book->nid, $nodes[0]->book['mlid']); // Node 2.
$nodes[] = $this->createBookNode($book->nid); // Node 3.
$nodes[] = $this->createBookNode($book->nid); // Node 4.
$this->drupalLogout();