diff options
-rw-r--r-- | includes/menu.inc | 5 | ||||
-rw-r--r-- | modules/simpletest/tests/menu.test | 93 | ||||
-rw-r--r-- | modules/simpletest/tests/menu_test.module | 36 |
3 files changed, 133 insertions, 1 deletions
diff --git a/includes/menu.inc b/includes/menu.inc index 15978a32a..5c294c111 100644 --- a/includes/menu.inc +++ b/includes/menu.inc @@ -2313,6 +2313,9 @@ function menu_get_active_menu_names() { */ function menu_set_active_item($path) { $_GET['q'] = $path; + // Since the active item has changed, the active menu trail may also be out + // of date. + drupal_static_reset('menu_set_active_trail'); } /** @@ -2398,7 +2401,7 @@ function menu_set_active_trail($new_trail = NULL) { // appending either the preferred link or the menu router item for the // current page. Exclude it if we are on the front page. $last = end($trail); - if ($last['href'] != $preferred_link['href'] && !drupal_is_front_page()) { + if ($preferred_link && $last['href'] != $preferred_link['href'] && !drupal_is_front_page()) { $trail[] = $preferred_link; } } diff --git a/modules/simpletest/tests/menu.test b/modules/simpletest/tests/menu.test index 80324e63d..a7fb8a484 100644 --- a/modules/simpletest/tests/menu.test +++ b/modules/simpletest/tests/menu.test @@ -1644,4 +1644,97 @@ class MenuTrailTestCase extends MenuWebTestCase { variable_set('menu_test_menu_tree_set_path', $test_menu_path); $this->assertBreadcrumb('admin/config/development/menu-trail', $override_breadcrumb, t('Menu trail - Case 2'), $override_tree); } + + /** + * Tests that the active trail works correctly on custom 403 and 404 pages. + */ + function testCustom403And404Pages() { + // Set the custom 403 and 404 pages we will use. + variable_set('site_403', 'menu-test/custom-403-page'); + variable_set('site_404', 'menu-test/custom-404-page'); + + // Define the paths we'll visit to trigger 403 and 404 responses during + // this test, and the expected active trail for each case. + $paths = array( + 403 => 'admin/config', + 404 => $this->randomName(), + ); + // For the 403 page, the initial trail during the Drupal bootstrap should + // include the page that the user is trying to visit, while the final trail + // should reflect the custom 403 page that the user was redirected to. + $expected_trail[403]['initial'] = array( + '<front>' => 'Home', + 'admin/config' => 'Configuration', + ); + $expected_trail[403]['final'] = array( + '<front>' => 'Home', + 'menu-test' => 'Menu test root', + 'menu-test/custom-403-page' => 'Custom 403 page', + ); + // For the 404 page, the initial trail during the Drupal bootstrap should + // only contain the link back to "Home" (since the page the user is trying + // to visit doesn't have any menu items associated with it), while the + // final trail should reflect the custom 404 page that the user was + // redirected to. + $expected_trail[404]['initial'] = array( + '<front>' => 'Home', + ); + $expected_trail[404]['final'] = array( + '<front>' => 'Home', + 'menu-test' => 'Menu test root', + 'menu-test/custom-404-page' => 'Custom 404 page', + ); + + // Visit each path as an anonymous user so that we will actually get a 403 + // on admin/config. + $this->drupalLogout(); + foreach (array(403, 404) as $status_code) { + // Before visiting the page, trigger the code in the menu_test module + // that will record the active trail (so we can check it in this test). + variable_set('menu_test_record_active_trail', TRUE); + $this->drupalGet($paths[$status_code]); + $this->assertResponse($status_code); + + // Check that the initial trail (during the Drupal bootstrap) matches + // what we expect. + $initial_trail = variable_get('menu_test_active_trail_initial', array()); + $this->assertEqual(count($initial_trail), count($expected_trail[$status_code]['initial']), t('The initial active trail for a @status_code page contains the expected number of items (expected: @expected, found: @found).', array( + '@status_code' => $status_code, + '@expected' => count($expected_trail[$status_code]['initial']), + '@found' => count($initial_trail), + ))); + foreach (array_keys($expected_trail[$status_code]['initial']) as $index => $path) { + $this->assertEqual($initial_trail[$index]['href'], $path, t('Element number @number of the initial active trail for a @status_code page contains the correct path (expected: @expected, found: @found)', array( + '@number' => $index + 1, + '@status_code' => $status_code, + '@expected' => $path, + '@found' => $initial_trail[$index]['href'], + ))); + } + + // Check that the final trail (after the user has been redirected to the + // custom 403/404 page) matches what we expect. + $final_trail = variable_get('menu_test_active_trail_final', array()); + $this->assertEqual(count($final_trail), count($expected_trail[$status_code]['final']), t('The final active trail for a @status_code page contains the expected number of items (expected: @expected, found: @found).', array( + '@status_code' => $status_code, + '@expected' => count($expected_trail[$status_code]['final']), + '@found' => count($final_trail), + ))); + foreach (array_keys($expected_trail[$status_code]['final']) as $index => $path) { + $this->assertEqual($final_trail[$index]['href'], $path, t('Element number @number of the final active trail for a @status_code page contains the correct path (expected: @expected, found: @found)', array( + '@number' => $index + 1, + '@status_code' => $status_code, + '@expected' => $path, + '@found' => $final_trail[$index]['href'], + ))); + } + + // Check that the breadcrumb displayed on the final custom 403/404 page + // matches what we expect. (The last item of the active trail represents + // the current page, which is not supposed to appear in the breadcrumb, + // so we need to remove it from the array before checking.) + array_pop($expected_trail[$status_code]['final']); + $this->assertBreadcrumb(NULL, $expected_trail[$status_code]['final']); + } + } } diff --git a/modules/simpletest/tests/menu_test.module b/modules/simpletest/tests/menu_test.module index c42aca60f..0b954ae1c 100644 --- a/modules/simpletest/tests/menu_test.module +++ b/modules/simpletest/tests/menu_test.module @@ -230,6 +230,16 @@ function menu_test_menu() { 'page callback' => 'menu_test_menu_trail_callback', 'access arguments' => array('access administration pages'), ); + $items['menu-test/custom-403-page'] = array( + 'title' => 'Custom 403 page', + 'page callback' => 'menu_test_custom_403_404_callback', + 'access arguments' => array('access content'), + ); + $items['menu-test/custom-404-page'] = array( + 'title' => 'Custom 404 page', + 'page callback' => 'menu_test_custom_403_404_callback', + 'access arguments' => array('access content'), + ); // File inheritance tests. This menu item should inherit the page callback // system_admin_menu_block_page() and therefore render its children as links @@ -370,6 +380,32 @@ function menu_test_menu_trail_callback() { } /** + * Implements hook_init(). + */ +function menu_test_init() { + // When requested by one of the MenuTrailTestCase tests, record the initial + // active trail during Drupal's bootstrap (before the user is redirected to a + // custom 403 or 404 page). See menu_test_custom_403_404_callback(). + if (variable_get('menu_test_record_active_trail', FALSE)) { + variable_set('menu_test_active_trail_initial', menu_get_active_trail()); + } +} + +/** + * Callback for our custom 403 and 404 pages. + */ +function menu_test_custom_403_404_callback() { + // When requested by one of the MenuTrailTestCase tests, record the final + // active trail now that the user has been redirected to the custom 403 or + // 404 page. See menu_test_init(). + if (variable_get('menu_test_record_active_trail', FALSE)) { + variable_set('menu_test_active_trail_final', menu_get_active_trail()); + } + + return 'This is menu_test_custom_403_404_callback().'; +} + +/** * Page callback to use when testing the theme callback functionality. * * @param $inherited |