Projet

Général

Profil

Paste
Télécharger (38,3 ko) Statistiques
| Branche: | Révision:

root / drupal7 / modules / block / block.test @ 76597ebf

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->assertNotNull($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->assertNotNull($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
}