cms/drupal/modules/block/block.test
changeset 541 e756a8c72c3d
equal deleted inserted replaced
540:07239de796bb 541:e756a8c72c3d
       
     1 <?php
       
     2 
       
     3 /**
       
     4  * @file
       
     5  * Tests for block.module.
       
     6  */
       
     7 
       
     8 class BlockTestCase extends DrupalWebTestCase {
       
     9   protected $regions;
       
    10   protected $admin_user;
       
    11 
       
    12   public static function getInfo() {
       
    13     return array(
       
    14       'name' => 'Block functionality',
       
    15       'description' => 'Add, edit and delete custom block. Configure and move a module-defined block.',
       
    16       'group' => 'Block',
       
    17     );
       
    18   }
       
    19 
       
    20   function setUp() {
       
    21     parent::setUp();
       
    22 
       
    23     // Create and log in an administrative user having access to the Full HTML
       
    24     // text format.
       
    25     $full_html_format = filter_format_load('full_html');
       
    26     $this->admin_user = $this->drupalCreateUser(array(
       
    27       'administer blocks',
       
    28       filter_permission_name($full_html_format),
       
    29       'access administration pages',
       
    30     ));
       
    31     $this->drupalLogin($this->admin_user);
       
    32 
       
    33     // Define the existing regions
       
    34     $this->regions = array();
       
    35     $this->regions[] = 'header';
       
    36     $this->regions[] = 'sidebar_first';
       
    37     $this->regions[] = 'content';
       
    38     $this->regions[] = 'sidebar_second';
       
    39     $this->regions[] = 'footer';
       
    40   }
       
    41 
       
    42   /**
       
    43    * Test creating custom block, moving it to a specific region and then deleting it.
       
    44    */
       
    45   function testCustomBlock() {
       
    46     // Confirm that the add block link appears on block overview pages.
       
    47     $this->drupalGet('admin/structure/block');
       
    48     $this->assertRaw(l('Add block', 'admin/structure/block/add'), 'Add block link is present on block overview page for default theme.');
       
    49     $this->drupalGet('admin/structure/block/list/seven');
       
    50     $this->assertRaw(l('Add block', 'admin/structure/block/list/seven/add'), 'Add block link is present on block overview page for non-default theme.');
       
    51 
       
    52     // Confirm that hidden regions are not shown as options for block placement
       
    53     // when adding a new block.
       
    54     theme_enable(array('stark'));
       
    55     $themes = list_themes();
       
    56     $this->drupalGet('admin/structure/block/add');
       
    57     foreach ($themes as $key => $theme) {
       
    58       if ($theme->status) {
       
    59         foreach ($theme->info['regions_hidden'] as $hidden_region) {
       
    60           $elements = $this->xpath('//select[@id=:id]//option[@value=:value]', array(':id' => 'edit-regions-' . $key, ':value' => $hidden_region));
       
    61           $this->assertFalse(isset($elements[0]), format_string('The hidden region @region is not available for @theme.', array('@region' => $hidden_region, '@theme' => $key)));
       
    62         }
       
    63       }
       
    64     }
       
    65 
       
    66     // Add a new custom block by filling out the input form on the admin/structure/block/add page.
       
    67     $custom_block = array();
       
    68     $custom_block['info'] = $this->randomName(8);
       
    69     $custom_block['title'] = $this->randomName(8);
       
    70     $custom_block['body[value]'] = $this->randomName(32);
       
    71     $this->drupalPost('admin/structure/block/add', $custom_block, t('Save block'));
       
    72 
       
    73     // Confirm that the custom block has been created, and then query the created bid.
       
    74     $this->assertText(t('The block has been created.'), 'Custom block successfully created.');
       
    75     $bid = db_query("SELECT bid FROM {block_custom} WHERE info = :info", array(':info' => $custom_block['info']))->fetchField();
       
    76 
       
    77     // Check to see if the custom block was created by checking that it's in the database.
       
    78     $this->assertTrue($bid, 'Custom block found in database');
       
    79 
       
    80     // Check that block_block_view() returns the correct title and content.
       
    81     $data = block_block_view($bid);
       
    82     $format = db_query("SELECT format FROM {block_custom} WHERE bid = :bid", array(':bid' => $bid))->fetchField();
       
    83     $this->assertTrue(array_key_exists('subject', $data) && empty($data['subject']), 'block_block_view() provides an empty block subject, since custom blocks do not have default titles.');
       
    84     $this->assertEqual(check_markup($custom_block['body[value]'], $format), $data['content'], 'block_block_view() provides correct block content.');
       
    85 
       
    86     // Check whether the block can be moved to all available regions.
       
    87     $custom_block['module'] = 'block';
       
    88     $custom_block['delta'] = $bid;
       
    89     foreach ($this->regions as $region) {
       
    90       $this->moveBlockToRegion($custom_block, $region);
       
    91     }
       
    92 
       
    93     // Verify presence of configure and delete links for custom block.
       
    94     $this->drupalGet('admin/structure/block');
       
    95     $this->assertLinkByHref('admin/structure/block/manage/block/' . $bid . '/configure', 0, 'Custom block configure link found.');
       
    96     $this->assertLinkByHref('admin/structure/block/manage/block/' . $bid . '/delete', 0, 'Custom block delete link found.');
       
    97 
       
    98     // Set visibility only for authenticated users, to verify delete functionality.
       
    99     $edit = array();
       
   100     $edit['roles[' . DRUPAL_AUTHENTICATED_RID . ']'] = TRUE;
       
   101     $this->drupalPost('admin/structure/block/manage/block/' . $bid . '/configure', $edit, t('Save block'));
       
   102 
       
   103     // Delete the created custom block & verify that it's been deleted and no longer appearing on the page.
       
   104     $this->clickLink(t('delete'));
       
   105     $this->drupalPost('admin/structure/block/manage/block/' . $bid . '/delete', array(), t('Delete'));
       
   106     $this->assertRaw(t('The block %title has been removed.', array('%title' => $custom_block['info'])), 'Custom block successfully deleted.');
       
   107     $this->assertNoText(t($custom_block['title']), 'Custom block no longer appears on page.');
       
   108     $count = db_query("SELECT 1 FROM {block_role} WHERE module = :module AND delta = :delta", array(':module' => $custom_block['module'], ':delta' => $custom_block['delta']))->fetchField();
       
   109     $this->assertFalse($count, 'Table block_role being cleaned.');
       
   110   }
       
   111 
       
   112   /**
       
   113    * Test creating custom block using Full HTML.
       
   114    */
       
   115   function testCustomBlockFormat() {
       
   116     // Add a new custom block by filling out the input form on the admin/structure/block/add page.
       
   117     $custom_block = array();
       
   118     $custom_block['info'] = $this->randomName(8);
       
   119     $custom_block['title'] = $this->randomName(8);
       
   120     $custom_block['body[value]'] = '<h1>Full HTML</h1>';
       
   121     $full_html_format = filter_format_load('full_html');
       
   122     $custom_block['body[format]'] = $full_html_format->format;
       
   123     $this->drupalPost('admin/structure/block/add', $custom_block, t('Save block'));
       
   124 
       
   125     // Set the created custom block to a specific region.
       
   126     $bid = db_query("SELECT bid FROM {block_custom} WHERE info = :info", array(':info' => $custom_block['info']))->fetchField();
       
   127     $edit = array();
       
   128     $edit['blocks[block_' . $bid . '][region]'] = $this->regions[1];
       
   129     $this->drupalPost('admin/structure/block', $edit, t('Save blocks'));
       
   130 
       
   131     // Confirm that the custom block is being displayed using configured text format.
       
   132     $this->drupalGet('node');
       
   133     $this->assertRaw('<h1>Full HTML</h1>', 'Custom block successfully being displayed using Full HTML.');
       
   134 
       
   135     // Confirm that a user without access to Full HTML can not see the body field,
       
   136     // but can still submit the form without errors.
       
   137     $block_admin = $this->drupalCreateUser(array('administer blocks'));
       
   138     $this->drupalLogin($block_admin);
       
   139     $this->drupalGet('admin/structure/block/manage/block/' . $bid . '/configure');
       
   140     $this->assertFieldByXPath("//textarea[@name='body[value]' and @disabled='disabled']", t('This field has been disabled because you do not have sufficient permissions to edit it.'), 'Body field contains denied message');
       
   141     $this->drupalPost('admin/structure/block/manage/block/' . $bid . '/configure', array(), t('Save block'));
       
   142     $this->assertNoText(t('Ensure that each block description is unique.'));
       
   143 
       
   144     // Confirm that the custom block is still being displayed using configured text format.
       
   145     $this->drupalGet('node');
       
   146     $this->assertRaw('<h1>Full HTML</h1>', 'Custom block successfully being displayed using Full HTML.');
       
   147   }
       
   148 
       
   149   /**
       
   150    * Test block visibility.
       
   151    */
       
   152   function testBlockVisibility() {
       
   153     $block = array();
       
   154 
       
   155     // Create a random title for the block
       
   156     $title = $this->randomName(8);
       
   157 
       
   158     // Create the custom block
       
   159     $custom_block = array();
       
   160     $custom_block['info'] = $this->randomName(8);
       
   161     $custom_block['title'] = $title;
       
   162     $custom_block['body[value]'] = $this->randomName(32);
       
   163     $this->drupalPost('admin/structure/block/add', $custom_block, t('Save block'));
       
   164 
       
   165     $bid = db_query("SELECT bid FROM {block_custom} WHERE info = :info", array(':info' => $custom_block['info']))->fetchField();
       
   166     $block['module'] = 'block';
       
   167     $block['delta'] = $bid;
       
   168     $block['title'] = $title;
       
   169 
       
   170     // Set the block to be hidden on any user path, and to be shown only to
       
   171     // authenticated users.
       
   172     $edit = array();
       
   173     $edit['pages'] = 'user*';
       
   174     $edit['roles[' . DRUPAL_AUTHENTICATED_RID . ']'] = TRUE;
       
   175     $this->drupalPost('admin/structure/block/manage/' . $block['module'] . '/' . $block['delta'] . '/configure', $edit, t('Save block'));
       
   176 
       
   177     // Move block to the first sidebar.
       
   178     $this->moveBlockToRegion($block, $this->regions[1]);
       
   179 
       
   180     $this->drupalGet('');
       
   181     $this->assertText($title, 'Block was displayed on the front page.');
       
   182 
       
   183     $this->drupalGet('user');
       
   184     $this->assertNoText($title, 'Block was not displayed according to block visibility rules.');
       
   185 
       
   186     $this->drupalGet('USER/' . $this->admin_user->uid);
       
   187     $this->assertNoText($title, 'Block was not displayed according to block visibility rules regardless of path case.');
       
   188 
       
   189     // Confirm that the block is not displayed to anonymous users.
       
   190     $this->drupalLogout();
       
   191     $this->drupalGet('');
       
   192     $this->assertNoText($title, 'Block was not displayed to anonymous users.');
       
   193   }
       
   194 
       
   195   /**
       
   196    * Test block visibility when using "pages" restriction but leaving
       
   197    * "pages" textarea empty
       
   198    */
       
   199   function testBlockVisibilityListedEmpty() {
       
   200     $block = array();
       
   201 
       
   202     // Create a random title for the block
       
   203     $title = $this->randomName(8);
       
   204 
       
   205     // Create the custom block
       
   206     $custom_block = array();
       
   207     $custom_block['info'] = $this->randomName(8);
       
   208     $custom_block['title'] = $title;
       
   209     $custom_block['body[value]'] = $this->randomName(32);
       
   210     $this->drupalPost('admin/structure/block/add', $custom_block, t('Save block'));
       
   211 
       
   212     $bid = db_query("SELECT bid FROM {block_custom} WHERE info = :info", array(':info' => $custom_block['info']))->fetchField();
       
   213     $block['module'] = 'block';
       
   214     $block['delta'] = $bid;
       
   215     $block['title'] = $title;
       
   216 
       
   217     // Move block to the first sidebar.
       
   218     $this->moveBlockToRegion($block, $this->regions[1]);
       
   219 
       
   220     // Set the block to be hidden on any user path, and to be shown only to
       
   221     // authenticated users.
       
   222     $edit = array();
       
   223     $edit['visibility'] = BLOCK_VISIBILITY_LISTED;
       
   224     $this->drupalPost('admin/structure/block/manage/' . $block['module'] . '/' . $block['delta'] . '/configure', $edit, t('Save block'));
       
   225 
       
   226     $this->drupalGet('');
       
   227     $this->assertNoText($title, 'Block was not displayed according to block visibility rules.');
       
   228 
       
   229     $this->drupalGet('user');
       
   230     $this->assertNoText($title, 'Block was not displayed according to block visibility rules regardless of path case.');
       
   231 
       
   232     // Confirm that the block is not displayed to anonymous users.
       
   233     $this->drupalLogout();
       
   234     $this->drupalGet('');
       
   235     $this->assertNoText($title, 'Block was not displayed to anonymous users.');
       
   236   }
       
   237 
       
   238   /**
       
   239    * Test user customization of block visibility.
       
   240    */
       
   241   function testBlockVisibilityPerUser() {
       
   242     $block = array();
       
   243 
       
   244     // Create a random title for the block.
       
   245     $title = $this->randomName(8);
       
   246 
       
   247     // Create our custom test block.
       
   248     $custom_block = array();
       
   249     $custom_block['info'] = $this->randomName(8);
       
   250     $custom_block['title'] = $title;
       
   251     $custom_block['body[value]'] = $this->randomName(32);
       
   252     $this->drupalPost('admin/structure/block/add', $custom_block, t('Save block'));
       
   253 
       
   254     $bid = db_query("SELECT bid FROM {block_custom} WHERE info = :info", array(':info' => $custom_block['info']))->fetchField();
       
   255     $block['module'] = 'block';
       
   256     $block['delta'] = $bid;
       
   257     $block['title'] = $title;
       
   258 
       
   259     // Move block to the first sidebar.
       
   260     $this->moveBlockToRegion($block, $this->regions[1]);
       
   261 
       
   262     // Set the block to be customizable per user, visible by default.
       
   263     $edit = array();
       
   264     $edit['custom'] = BLOCK_CUSTOM_ENABLED;
       
   265     $this->drupalPost('admin/structure/block/manage/' . $block['module'] . '/' . $block['delta'] . '/configure', $edit, t('Save block'));
       
   266 
       
   267     // Disable block visibility for the admin user.
       
   268     $edit = array();
       
   269     $edit['block[' . $block['module'] . '][' . $block['delta'] . ']'] = FALSE;
       
   270     $this->drupalPost('user/' . $this->admin_user->uid . '/edit', $edit, t('Save'));
       
   271 
       
   272     $this->drupalGet('');
       
   273     $this->assertNoText($block['title'], 'Block was not displayed according to per user block visibility setting.');
       
   274 
       
   275     // Set the block to be customizable per user, hidden by default.
       
   276     $edit = array();
       
   277     $edit['custom'] = BLOCK_CUSTOM_DISABLED;
       
   278     $this->drupalPost('admin/structure/block/manage/' . $block['module'] . '/' . $block['delta'] . '/configure', $edit, t('Save block'));
       
   279 
       
   280     // Enable block visibility for the admin user.
       
   281     $edit = array();
       
   282     $edit['block[' . $block['module'] . '][' . $block['delta'] . ']'] = TRUE;
       
   283     $this->drupalPost('user/' . $this->admin_user->uid . '/edit', $edit, t('Save'));
       
   284 
       
   285     $this->drupalGet('');
       
   286     $this->assertText($block['title'], 'Block was displayed according to per user block visibility setting.');
       
   287   }
       
   288 
       
   289   /**
       
   290    * Test configuring and moving a module-define block to specific regions.
       
   291    */
       
   292   function testBlock() {
       
   293     // Select the Navigation block to be configured and moved.
       
   294     $block = array();
       
   295     $block['module'] = 'system';
       
   296     $block['delta'] = 'management';
       
   297     $block['title'] = $this->randomName(8);
       
   298 
       
   299     // Set block title to confirm that interface works and override any custom titles.
       
   300     $this->drupalPost('admin/structure/block/manage/' . $block['module'] . '/' . $block['delta'] . '/configure', array('title' => $block['title']), t('Save block'));
       
   301     $this->assertText(t('The block configuration has been saved.'), 'Block title set.');
       
   302     $bid = db_query("SELECT bid FROM {block} WHERE module = :module AND delta = :delta", array(
       
   303       ':module' => $block['module'],
       
   304       ':delta' => $block['delta'],
       
   305     ))->fetchField();
       
   306 
       
   307     // Check to see if the block was created by checking that it's in the database.
       
   308     $this->assertTrue($bid, 'Block found in database');
       
   309 
       
   310     // Check whether the block can be moved to all available regions.
       
   311     foreach ($this->regions as $region) {
       
   312       $this->moveBlockToRegion($block, $region);
       
   313     }
       
   314 
       
   315     // Set the block to the disabled region.
       
   316     $edit = array();
       
   317     $edit['blocks[' . $block['module'] . '_' . $block['delta'] . '][region]'] = '-1';
       
   318     $this->drupalPost('admin/structure/block', $edit, t('Save blocks'));
       
   319 
       
   320     // Confirm that the block was moved to the proper region.
       
   321     $this->assertText(t('The block settings have been updated.'), 'Block successfully move to disabled region.');
       
   322     $this->assertNoText(t($block['title']), 'Block no longer appears on page.');
       
   323 
       
   324     // Confirm that the region's xpath is not available.
       
   325     $xpath = $this->buildXPathQuery('//div[@id=:id]/*', array(':id' => 'block-block-' . $bid));
       
   326     $this->assertNoFieldByXPath($xpath, FALSE, 'Custom block found in no regions.');
       
   327 
       
   328     // For convenience of developers, put the navigation block back.
       
   329     $edit = array();
       
   330     $edit['blocks[' . $block['module'] . '_' . $block['delta'] . '][region]'] = $this->regions[1];
       
   331     $this->drupalPost('admin/structure/block', $edit, t('Save blocks'));
       
   332     $this->assertText(t('The block settings have been updated.'), 'Block successfully move to first sidebar region.');
       
   333 
       
   334     $this->drupalPost('admin/structure/block/manage/' . $block['module'] . '/' . $block['delta'] . '/configure', array('title' => 'Navigation'), t('Save block'));
       
   335     $this->assertText(t('The block configuration has been saved.'), 'Block title set.');
       
   336   }
       
   337 
       
   338   function moveBlockToRegion($block, $region) {
       
   339     // Set the created block to a specific region.
       
   340     $edit = array();
       
   341     $edit['blocks[' . $block['module'] . '_' . $block['delta'] . '][region]'] = $region;
       
   342     $this->drupalPost('admin/structure/block', $edit, t('Save blocks'));
       
   343 
       
   344     // Confirm that the block was moved to the proper region.
       
   345     $this->assertText(t('The block settings have been updated.'), format_string('Block successfully moved to %region_name region.', array( '%region_name' => $region)));
       
   346 
       
   347     // Confirm that the block is being displayed.
       
   348     $this->drupalGet('node');
       
   349     $this->assertText(t($block['title']), 'Block successfully being displayed on the page.');
       
   350 
       
   351     // Confirm that the custom block was found at the proper region.
       
   352     $xpath = $this->buildXPathQuery('//div[@class=:region-class]//div[@id=:block-id]/*', array(
       
   353       ':region-class' => 'region region-' . str_replace('_', '-', $region),
       
   354       ':block-id' => 'block-' . $block['module'] . '-' . $block['delta'],
       
   355     ));
       
   356     $this->assertFieldByXPath($xpath, NULL, format_string('Custom block found in %region_name region.', array('%region_name' => $region)));
       
   357   }
       
   358 
       
   359   /**
       
   360    * Test _block_rehash().
       
   361    */
       
   362   function testBlockRehash() {
       
   363     module_enable(array('block_test'));
       
   364     $this->assertTrue(module_exists('block_test'), 'Test block module enabled.');
       
   365 
       
   366     // Our new block should be inserted in the database when we visit the
       
   367     // block management page.
       
   368     $this->drupalGet('admin/structure/block');
       
   369     // Our test block's caching should default to DRUPAL_CACHE_PER_ROLE.
       
   370     $current_caching = db_query("SELECT cache FROM {block} WHERE module = 'block_test' AND delta = 'test_cache'")->fetchField();
       
   371     $this->assertEqual($current_caching, DRUPAL_CACHE_PER_ROLE, 'Test block cache mode defaults to DRUPAL_CACHE_PER_ROLE.');
       
   372 
       
   373     // Disable caching for this block.
       
   374     variable_set('block_test_caching', DRUPAL_NO_CACHE);
       
   375     // Flushing all caches should call _block_rehash().
       
   376     drupal_flush_all_caches();
       
   377     // Verify that the database is updated with the new caching mode.
       
   378     $current_caching = db_query("SELECT cache FROM {block} WHERE module = 'block_test' AND delta = 'test_cache'")->fetchField();
       
   379     $this->assertEqual($current_caching, DRUPAL_NO_CACHE, "Test block's database entry updated to DRUPAL_NO_CACHE.");
       
   380   }
       
   381 }
       
   382 
       
   383 class NonDefaultBlockAdmin extends DrupalWebTestCase {
       
   384   public static function getInfo() {
       
   385     return array(
       
   386       'name' => 'Non default theme admin',
       
   387       'description' => 'Check the administer page for non default theme.',
       
   388       'group' => 'Block',
       
   389     );
       
   390   }
       
   391 
       
   392   /**
       
   393    * Test non-default theme admin.
       
   394    */
       
   395   function testNonDefaultBlockAdmin() {
       
   396     $admin_user = $this->drupalCreateUser(array('administer blocks', 'administer themes'));
       
   397     $this->drupalLogin($admin_user);
       
   398     theme_enable(array('stark'));
       
   399     $this->drupalGet('admin/structure/block/list/stark');
       
   400   }
       
   401 }
       
   402 
       
   403 /**
       
   404  * Test blocks correctly initialized when picking a new default theme.
       
   405  */
       
   406 class NewDefaultThemeBlocks extends DrupalWebTestCase {
       
   407   public static function getInfo() {
       
   408     return array(
       
   409       'name' => 'New default theme blocks',
       
   410       'description' => 'Checks that the new default theme gets blocks.',
       
   411       'group' => 'Block',
       
   412     );
       
   413   }
       
   414 
       
   415   /**
       
   416    * Check the enabled Bartik blocks are correctly copied over.
       
   417    */
       
   418   function testNewDefaultThemeBlocks() {
       
   419     // Create administrative user.
       
   420     $admin_user = $this->drupalCreateUser(array('administer themes'));
       
   421     $this->drupalLogin($admin_user);
       
   422 
       
   423     // Ensure no other theme's blocks are in the block table yet.
       
   424     $themes = array();
       
   425     $themes['default'] = variable_get('theme_default', 'bartik');
       
   426     if ($admin_theme = variable_get('admin_theme')) {
       
   427       $themes['admin'] = $admin_theme;
       
   428     }
       
   429     $count = db_query_range('SELECT 1 FROM {block} WHERE theme NOT IN (:themes)', 0, 1, array(':themes' => $themes))->fetchField();
       
   430     $this->assertFalse($count, 'Only the default theme and the admin theme have blocks.');
       
   431 
       
   432     // Populate list of all blocks for matching against new theme.
       
   433     $blocks = array();
       
   434     $result = db_query('SELECT * FROM {block} WHERE theme = :theme', array(':theme' => $themes['default']));
       
   435     foreach ($result as $block) {
       
   436       // $block->theme and $block->bid will not match, so remove them.
       
   437       unset($block->theme, $block->bid);
       
   438       $blocks[$block->module][$block->delta] = $block;
       
   439     }
       
   440 
       
   441     // Turn on the Stark theme and ensure that it contains all of the blocks
       
   442     // the default theme had.
       
   443     theme_enable(array('stark'));
       
   444     variable_set('theme_default', 'stark');
       
   445     $result = db_query('SELECT * FROM {block} WHERE theme = :theme', array(':theme' => 'stark'));
       
   446     foreach ($result as $block) {
       
   447       unset($block->theme, $block->bid);
       
   448       $this->assertEqual($blocks[$block->module][$block->delta], $block, format_string('Block %name matched', array('%name' => $block->module . '-' . $block->delta)));
       
   449     }
       
   450   }
       
   451 }
       
   452 
       
   453 /**
       
   454  * Test the block system with admin themes.
       
   455  */
       
   456 class BlockAdminThemeTestCase extends DrupalWebTestCase {
       
   457   public static function getInfo() {
       
   458     return array(
       
   459       'name' => 'Admin theme block admin accessibility',
       
   460       'description' => "Check whether the block administer page for a disabled theme accessible if and only if it's the admin theme.",
       
   461       'group' => 'Block',
       
   462     );
       
   463   }
       
   464 
       
   465   /**
       
   466    * Check for the accessibility of the admin theme on the  block admin page.
       
   467    */
       
   468   function testAdminTheme() {
       
   469     // Create administrative user.
       
   470     $admin_user = $this->drupalCreateUser(array('administer blocks', 'administer themes'));
       
   471     $this->drupalLogin($admin_user);
       
   472 
       
   473     // Ensure that access to block admin page is denied when theme is disabled.
       
   474     $this->drupalGet('admin/structure/block/list/stark');
       
   475     $this->assertResponse(403, 'The block admin page for a disabled theme can not be accessed');
       
   476 
       
   477     // Enable admin theme and confirm that tab is accessible.
       
   478     $edit['admin_theme'] = 'stark';
       
   479     $this->drupalPost('admin/appearance', $edit, t('Save configuration'));
       
   480     $this->drupalGet('admin/structure/block/list/stark');
       
   481     $this->assertResponse(200, 'The block admin page for the admin theme can be accessed');
       
   482   }
       
   483 }
       
   484 
       
   485 /**
       
   486  * Test block caching.
       
   487  */
       
   488 class BlockCacheTestCase extends DrupalWebTestCase {
       
   489   protected $admin_user;
       
   490   protected $normal_user;
       
   491   protected $normal_user_alt;
       
   492 
       
   493   public static function getInfo() {
       
   494     return array(
       
   495       'name' => 'Block caching',
       
   496       'description' => 'Test block caching.',
       
   497       'group' => 'Block',
       
   498     );
       
   499   }
       
   500 
       
   501   function setUp() {
       
   502     parent::setUp('block_test');
       
   503 
       
   504     // Create an admin user, log in and enable test blocks.
       
   505     $this->admin_user = $this->drupalCreateUser(array('administer blocks', 'access administration pages'));
       
   506     $this->drupalLogin($this->admin_user);
       
   507 
       
   508     // Create additional users to test caching modes.
       
   509     $this->normal_user = $this->drupalCreateUser();
       
   510     $this->normal_user_alt = $this->drupalCreateUser();
       
   511     // Sync the roles, since drupalCreateUser() creates separate roles for
       
   512     // the same permission sets.
       
   513     user_save($this->normal_user_alt, array('roles' => $this->normal_user->roles));
       
   514     $this->normal_user_alt->roles = $this->normal_user->roles;
       
   515 
       
   516     // Enable block caching.
       
   517     variable_set('block_cache', TRUE);
       
   518 
       
   519     // Enable our test block.
       
   520     $edit['blocks[block_test_test_cache][region]'] = 'sidebar_first';
       
   521     $this->drupalPost('admin/structure/block', $edit, t('Save blocks'));
       
   522   }
       
   523 
       
   524   /**
       
   525    * Test DRUPAL_CACHE_PER_ROLE.
       
   526    */
       
   527   function testCachePerRole() {
       
   528     $this->setCacheMode(DRUPAL_CACHE_PER_ROLE);
       
   529 
       
   530     // Enable our test block. Set some content for it to display.
       
   531     $current_content = $this->randomName();
       
   532     variable_set('block_test_content', $current_content);
       
   533     $this->drupalLogin($this->normal_user);
       
   534     $this->drupalGet('');
       
   535     $this->assertText($current_content, 'Block content displays.');
       
   536 
       
   537     // Change the content, but the cached copy should still be served.
       
   538     $old_content = $current_content;
       
   539     $current_content = $this->randomName();
       
   540     variable_set('block_test_content', $current_content);
       
   541     $this->drupalGet('');
       
   542     $this->assertText($old_content, 'Block is served from the cache.');
       
   543 
       
   544     // Clear the cache and verify that the stale data is no longer there.
       
   545     cache_clear_all();
       
   546     $this->drupalGet('');
       
   547     $this->assertNoText($old_content, 'Block cache clear removes stale cache data.');
       
   548     $this->assertText($current_content, 'Fresh block content is displayed after clearing the cache.');
       
   549 
       
   550     // Test whether the cached data is served for the correct users.
       
   551     $old_content = $current_content;
       
   552     $current_content = $this->randomName();
       
   553     variable_set('block_test_content', $current_content);
       
   554     $this->drupalLogout();
       
   555     $this->drupalGet('');
       
   556     $this->assertNoText($old_content, 'Anonymous user does not see content cached per-role for normal user.');
       
   557 
       
   558     $this->drupalLogin($this->normal_user_alt);
       
   559     $this->drupalGet('');
       
   560     $this->assertText($old_content, 'User with the same roles sees per-role cached content.');
       
   561 
       
   562     $this->drupalLogin($this->admin_user);
       
   563     $this->drupalGet('');
       
   564     $this->assertNoText($old_content, 'Admin user does not see content cached per-role for normal user.');
       
   565 
       
   566     $this->drupalLogin($this->normal_user);
       
   567     $this->drupalGet('');
       
   568     $this->assertText($old_content, 'Block is served from the per-role cache.');
       
   569   }
       
   570 
       
   571   /**
       
   572    * Test DRUPAL_CACHE_GLOBAL.
       
   573    */
       
   574   function testCacheGlobal() {
       
   575     $this->setCacheMode(DRUPAL_CACHE_GLOBAL);
       
   576     $current_content = $this->randomName();
       
   577     variable_set('block_test_content', $current_content);
       
   578 
       
   579     $this->drupalGet('');
       
   580     $this->assertText($current_content, 'Block content displays.');
       
   581 
       
   582     $old_content = $current_content;
       
   583     $current_content = $this->randomName();
       
   584     variable_set('block_test_content', $current_content);
       
   585 
       
   586     $this->drupalLogout();
       
   587     $this->drupalGet('user');
       
   588     $this->assertText($old_content, 'Block content served from global cache.');
       
   589   }
       
   590 
       
   591   /**
       
   592    * Test DRUPAL_NO_CACHE.
       
   593    */
       
   594   function testNoCache() {
       
   595     $this->setCacheMode(DRUPAL_NO_CACHE);
       
   596     $current_content = $this->randomName();
       
   597     variable_set('block_test_content', $current_content);
       
   598 
       
   599     // If DRUPAL_NO_CACHE has no effect, the next request would be cached.
       
   600     $this->drupalGet('');
       
   601     $this->assertText($current_content, 'Block content displays.');
       
   602 
       
   603     // A cached copy should not be served.
       
   604     $current_content = $this->randomName();
       
   605     variable_set('block_test_content', $current_content);
       
   606     $this->drupalGet('');
       
   607     $this->assertText($current_content, 'DRUPAL_NO_CACHE prevents blocks from being cached.');
       
   608   }
       
   609 
       
   610   /**
       
   611    * Test DRUPAL_CACHE_PER_USER.
       
   612    */
       
   613   function testCachePerUser() {
       
   614     $this->setCacheMode(DRUPAL_CACHE_PER_USER);
       
   615     $current_content = $this->randomName();
       
   616     variable_set('block_test_content', $current_content);
       
   617     $this->drupalLogin($this->normal_user);
       
   618 
       
   619     $this->drupalGet('');
       
   620     $this->assertText($current_content, 'Block content displays.');
       
   621 
       
   622     $old_content = $current_content;
       
   623     $current_content = $this->randomName();
       
   624     variable_set('block_test_content', $current_content);
       
   625 
       
   626     $this->drupalGet('');
       
   627     $this->assertText($old_content, 'Block is served from per-user cache.');
       
   628 
       
   629     $this->drupalLogin($this->normal_user_alt);
       
   630     $this->drupalGet('');
       
   631     $this->assertText($current_content, 'Per-user block cache is not served for other users.');
       
   632 
       
   633     $this->drupalLogin($this->normal_user);
       
   634     $this->drupalGet('');
       
   635     $this->assertText($old_content, 'Per-user block cache is persistent.');
       
   636   }
       
   637 
       
   638   /**
       
   639    * Test DRUPAL_CACHE_PER_PAGE.
       
   640    */
       
   641   function testCachePerPage() {
       
   642     $this->setCacheMode(DRUPAL_CACHE_PER_PAGE);
       
   643     $current_content = $this->randomName();
       
   644     variable_set('block_test_content', $current_content);
       
   645 
       
   646     $this->drupalGet('node');
       
   647     $this->assertText($current_content, 'Block content displays on the node page.');
       
   648 
       
   649     $old_content = $current_content;
       
   650     $current_content = $this->randomName();
       
   651     variable_set('block_test_content', $current_content);
       
   652 
       
   653     $this->drupalGet('user');
       
   654     $this->assertNoText($old_content, 'Block content cached for the node page does not show up for the user page.');
       
   655     $this->drupalGet('node');
       
   656     $this->assertText($old_content, 'Block content cached for the node page.');
       
   657   }
       
   658 
       
   659   /**
       
   660    * Private helper method to set the test block's cache mode.
       
   661    */
       
   662   private function setCacheMode($cache_mode) {
       
   663     db_update('block')
       
   664       ->fields(array('cache' => $cache_mode))
       
   665       ->condition('module', 'block_test')
       
   666       ->execute();
       
   667 
       
   668     $current_mode = db_query("SELECT cache FROM {block} WHERE module = 'block_test'")->fetchField();
       
   669     if ($current_mode != $cache_mode) {
       
   670       $this->fail(t('Unable to set cache mode to %mode. Current mode: %current_mode', array('%mode' => $cache_mode, '%current_mode' => $current_mode)));
       
   671     }
       
   672   }
       
   673 }
       
   674 
       
   675 /**
       
   676  * Test block HTML id validity.
       
   677  */
       
   678 class BlockHTMLIdTestCase extends DrupalWebTestCase {
       
   679 
       
   680   public static function getInfo() {
       
   681     return array(
       
   682       'name' => 'Block HTML id',
       
   683       'description' => 'Test block HTML id validity.',
       
   684       'group' => 'Block',
       
   685     );
       
   686   }
       
   687 
       
   688   function setUp() {
       
   689     parent::setUp('block_test');
       
   690 
       
   691     // Create an admin user, log in and enable test blocks.
       
   692     $this->admin_user = $this->drupalCreateUser(array('administer blocks', 'access administration pages'));
       
   693     $this->drupalLogin($this->admin_user);
       
   694 
       
   695     // Enable our test block.
       
   696     $edit['blocks[block_test_test_html_id][region]'] = 'sidebar_first';
       
   697     $this->drupalPost('admin/structure/block', $edit, t('Save blocks'));
       
   698 
       
   699     // Make sure the block has some content so it will appear
       
   700     $current_content = $this->randomName();
       
   701     variable_set('block_test_content', $current_content);
       
   702   }
       
   703 
       
   704   /**
       
   705    * Test valid HTML id.
       
   706    */
       
   707   function testHTMLId() {
       
   708     $this->drupalGet('');
       
   709     $this->assertRaw('block-block-test-test-html-id', 'HTML id for test block is valid.');
       
   710   }
       
   711 }
       
   712 
       
   713 
       
   714 /**
       
   715  * Unit tests for template_preprocess_block().
       
   716  */
       
   717 class BlockTemplateSuggestionsUnitTest extends DrupalUnitTestCase {
       
   718   public static function getInfo() {
       
   719     return array(
       
   720       'name' => 'Block template suggestions',
       
   721       'description' => 'Test the template_preprocess_block() function.',
       
   722       'group' => 'Block',
       
   723     );
       
   724   }
       
   725 
       
   726   /**
       
   727    * Test if template_preprocess_block() handles the suggestions right.
       
   728    */
       
   729   function testBlockThemeHookSuggestions() {
       
   730     // Define block delta with underscore to be preprocessed
       
   731     $block1 = new stdClass();
       
   732     $block1->module = 'block';
       
   733     $block1->delta = 'underscore_test';
       
   734     $block1->region = 'footer';
       
   735     $variables1 = array();
       
   736     $variables1['elements']['#block'] = $block1;
       
   737     $variables1['elements']['#children'] = '';
       
   738     template_preprocess_block($variables1);
       
   739     $this->assertEqual($variables1['theme_hook_suggestions'], array('block__footer', 'block__block', 'block__block__underscore_test'), 'Found expected block suggestions for delta with underscore');
       
   740 
       
   741     // Define block delta with hyphens to be preprocessed. Hyphens should be
       
   742     // replaced with underscores.
       
   743     $block2 = new stdClass();
       
   744     $block2->module = 'block';
       
   745     $block2->delta = 'hyphen-test';
       
   746     $block2->region = 'footer';
       
   747     $variables2 = array();
       
   748     $variables2['elements']['#block'] = $block2;
       
   749     $variables2['elements']['#children'] = '';
       
   750     template_preprocess_block($variables2);
       
   751     $this->assertEqual($variables2['theme_hook_suggestions'], array('block__footer', 'block__block', 'block__block__hyphen_test'), 'Hyphens (-) in block delta were replaced by underscore (_)');
       
   752   }
       
   753 }
       
   754 
       
   755 /**
       
   756  * Tests for hook_block_view_MODULE_DELTA_alter().
       
   757  */
       
   758 class BlockViewModuleDeltaAlterWebTest extends DrupalWebTestCase {
       
   759 
       
   760   public static function getInfo() {
       
   761     return array(
       
   762       'name' => 'Block view module delta alter',
       
   763       'description' => 'Test the hook_block_view_MODULE_DELTA_alter() hook.',
       
   764       'group' => 'Block',
       
   765     );
       
   766   }
       
   767 
       
   768   public function setUp() {
       
   769     parent::setUp(array('block_test'));
       
   770   }
       
   771 
       
   772   /**
       
   773    * Tests that the alter hook is called, even if the delta contains a hyphen.
       
   774    */
       
   775   public function testBlockViewModuleDeltaAlter() {
       
   776     $block = new stdClass;
       
   777     $block->module = 'block_test';
       
   778     $block->delta = 'test_underscore';
       
   779     $block->title = '';
       
   780     $render_array = _block_render_blocks(array('region' => $block));
       
   781     $render = array_pop($render_array);
       
   782     $test_underscore = $render->content['#markup'];
       
   783     $this->assertEqual($test_underscore, 'hook_block_view_MODULE_DELTA_alter', 'Found expected altered block content for delta with underscore');
       
   784 
       
   785     $block = new stdClass;
       
   786     $block->module = 'block_test';
       
   787     $block->delta = 'test-hyphen';
       
   788     $block->title = '';
       
   789     $render_array = _block_render_blocks(array('region' => $block));
       
   790     $render = array_pop($render_array);
       
   791     $test_hyphen = $render->content['#markup'];
       
   792     $this->assertEqual($test_hyphen, 'hook_block_view_MODULE_DELTA_alter', 'Hyphens (-) in block delta were replaced by underscore (_)');
       
   793   }
       
   794 
       
   795 }
       
   796 
       
   797 /**
       
   798  * Tests that hidden regions do not inherit blocks when a theme is enabled.
       
   799  */
       
   800 class BlockHiddenRegionTestCase extends DrupalWebTestCase {
       
   801   public static function getInfo() {
       
   802     return array(
       
   803       'name' => 'Blocks not in hidden region',
       
   804       'description' => 'Checks that a newly enabled theme does not inherit blocks to its hidden regions.',
       
   805       'group' => 'Block',
       
   806     );
       
   807   }
       
   808 
       
   809   function setUp() {
       
   810     parent::setUp(array('block_test'));
       
   811   }
       
   812 
       
   813   /**
       
   814    * Tests that hidden regions do not inherit blocks when a theme is enabled.
       
   815    */
       
   816   function testBlockNotInHiddenRegion() {
       
   817     // Create administrative user.
       
   818     $admin_user = $this->drupalCreateUser(array('administer blocks', 'administer themes', 'search content'));
       
   819     $this->drupalLogin($admin_user);
       
   820 
       
   821     // Enable "block_test_theme" and set it as the default theme.
       
   822     $theme = 'block_test_theme';
       
   823     theme_enable(array($theme));
       
   824     variable_set('theme_default', $theme);
       
   825     menu_rebuild();
       
   826 
       
   827     // Ensure that "block_test_theme" is set as the default theme.
       
   828     $this->drupalGet('admin/structure/block');
       
   829     $this->assertText('Block test theme(' . t('active tab') . ')', 'Default local task on blocks admin page is the block test theme.');
       
   830 
       
   831     // Ensure that the search form block is displayed.
       
   832     $this->drupalGet('');
       
   833     $this->assertText('Search form', 'Block was displayed on the front page.');
       
   834   }
       
   835 }
       
   836 
       
   837 /**
       
   838  * Tests that a block assigned to an invalid region triggers the warning.
       
   839  */
       
   840 class BlockInvalidRegionTestCase extends DrupalWebTestCase {
       
   841   public static function getInfo() {
       
   842     return array(
       
   843       'name' => 'Blocks in invalid regions',
       
   844       'description' => 'Checks that an active block assigned to a non-existing region triggers the warning message and is disabled.',
       
   845       'group' => 'Block',
       
   846     );
       
   847   }
       
   848 
       
   849   function setUp() {
       
   850     parent::setUp(array('block', 'block_test'));
       
   851     // Create an admin user.
       
   852     $admin_user = $this->drupalCreateUser(array('administer site configuration', 'access administration pages'));
       
   853     $this->drupalLogin($admin_user);
       
   854   }
       
   855 
       
   856   /**
       
   857    * Tests that blocks assigned to invalid regions work correctly.
       
   858    */
       
   859   function testBlockInInvalidRegion() {
       
   860     // Enable a test block in the default theme and place it in an invalid region.
       
   861     db_merge('block')
       
   862       ->key(array(
       
   863         'module' => 'block_test',
       
   864         'delta' => 'test_html_id',
       
   865         'theme' => variable_get('theme_default', 'stark'),
       
   866       ))
       
   867       ->fields(array(
       
   868         'status' => 1,
       
   869         'region' => 'invalid_region',
       
   870         'cache' => DRUPAL_NO_CACHE,
       
   871       ))
       
   872       ->execute();
       
   873 
       
   874     $warning_message = t('The block %info was assigned to the invalid region %region and has been disabled.', array('%info' => t('Test block html id'), '%region' => 'invalid_region'));
       
   875 
       
   876     // Clearing the cache should disable the test block placed in the invalid region.
       
   877     $this->drupalPost('admin/config/development/performance', array(), 'Clear all caches');
       
   878     $this->assertRaw($warning_message, 'Enabled block was in the invalid region and has been disabled.');
       
   879 
       
   880     // Clear the cache to check if the warning message is not triggered.
       
   881     $this->drupalPost('admin/config/development/performance', array(), 'Clear all caches');
       
   882     $this->assertNoRaw($warning_message, 'Disabled block in the invalid region will not trigger the warning.');
       
   883 
       
   884     // Place disabled test block in the invalid region of the default theme.
       
   885     db_merge('block')
       
   886       ->key(array(
       
   887         'module' => 'block_test',
       
   888         'delta' => 'test_html_id',
       
   889         'theme' => variable_get('theme_default', 'stark'),
       
   890       ))
       
   891       ->fields(array(
       
   892         'region' => 'invalid_region',
       
   893         'cache' => DRUPAL_NO_CACHE,
       
   894       ))
       
   895       ->execute();
       
   896 
       
   897     // Clear the cache to check if the warning message is not triggered.
       
   898     $this->drupalPost('admin/config/development/performance', array(), 'Clear all caches');
       
   899     $this->assertNoRaw($warning_message, 'Disabled block in the invalid region will not trigger the warning.');
       
   900   }
       
   901 }
       
   902 
       
   903 /**
       
   904  * Tests that block rehashing works correctly.
       
   905  */
       
   906 class BlockHashTestCase extends DrupalWebTestCase {
       
   907   public static function getInfo() {
       
   908     return array(
       
   909       'name' => 'Block rehash',
       
   910       'description' => 'Checks _block_rehash() functionality.',
       
   911       'group' => 'Block',
       
   912     );
       
   913   }
       
   914 
       
   915   function setUp() {
       
   916     parent::setUp(array('block'));
       
   917   }
       
   918 
       
   919   /**
       
   920    * Tests that block rehashing does not write to the database too often.
       
   921    */
       
   922   function testBlockRehash() {
       
   923     // No hook_block_info_alter(), no save.
       
   924     $this->doRehash();
       
   925     module_enable(array('block_test'), FALSE);
       
   926     // Save the new blocks, check that the new blocks exist by checking weight.
       
   927     _block_rehash();
       
   928     $this->assertWeight(0);
       
   929     // Now hook_block_info_alter() exists but no blocks are saved on a second
       
   930     // rehash.
       
   931     $this->doRehash();
       
   932     $this->assertWeight(0);
       
   933     // Now hook_block_info_alter() exists and is changing one block which
       
   934     // should be saved.
       
   935     $GLOBALS['conf']['block_test_info_alter'] = 1;
       
   936     $this->doRehash(TRUE);
       
   937     $this->assertWeight(10000);
       
   938     // Now hook_block_info_alter() exists but already changed the block's
       
   939     // weight before, so it should not be saved again.
       
   940     $this->doRehash();
       
   941     $this->assertWeight(10000);
       
   942   }
       
   943 
       
   944   /**
       
   945    * Performs a block rehash and checks several related assertions.
       
   946    *
       
   947    * @param $alter_active
       
   948    *   Set to TRUE if the block_test module's hook_block_info_alter()
       
   949    *   implementation is expected to make a change that results in an existing
       
   950    *   block needing to be resaved to the database. Defaults to FALSE.
       
   951    */
       
   952   function doRehash($alter_active = FALSE) {
       
   953     $saves = 0;
       
   954     foreach (_block_rehash() as $block) {
       
   955       $module = $block['module'];
       
   956       $delta = $block['delta'];
       
   957       if ($alter_active && $module == 'block_test' && $delta == 'test_html_id') {
       
   958         $this->assertFalse(empty($block['saved']), "$module $delta saved");
       
   959         $saves++;
       
   960       }
       
   961       else {
       
   962         $this->assertTrue(empty($block['saved']), "$module $delta not saved");
       
   963       }
       
   964     }
       
   965     $this->assertEqual($alter_active, $saves);
       
   966   }
       
   967 
       
   968   /**
       
   969    * Asserts that the block_test module's block has a given weight.
       
   970    *
       
   971    * @param $weight
       
   972    *   The expected weight.
       
   973    */
       
   974   function assertWeight($weight) {
       
   975     $db_weight = db_query('SELECT weight FROM {block} WHERE module = :module AND delta = :delta', array(':module' => 'block_test', ':delta' => 'test_html_id'))->fetchField();
       
   976     // By casting to string the assert fails on FALSE.
       
   977     $this->assertIdentical((string) $db_weight, (string) $weight);
       
   978   }
       
   979 }