FunctionsTest.php 12.5 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
<?php

/**
 * @file
 * Definition of Drupal\system\Tests\Theme\FunctionsTest.
 */

namespace Drupal\system\Tests\Theme;

use Drupal\simpletest\WebTestBase;

/**
 * Tests for common theme functions.
 */
class FunctionsTest extends WebTestBase {
  public static function getInfo() {
    return array(
      'name' => 'Theme functions',
      'description' => 'Tests common theme functions.',
      'group' => 'Theme',
    );
  }

  /**
   * Tests theme_item_list().
   */
  function testItemList() {
28
    // Verify that empty items produce no output.
29 30 31 32
    $variables = array();
    $expected = '';
    $this->assertThemeOutput('item_list', $variables, $expected, 'Empty %callback generates no output.');

33
    // Verify that empty items with title produce no output.
34 35 36 37 38
    $variables = array();
    $variables['title'] = 'Some title';
    $expected = '';
    $this->assertThemeOutput('item_list', $variables, $expected, 'Empty %callback with title generates no output.');

39 40 41 42 43 44 45 46 47 48 49 50 51
    // Verify that empty items produce the empty string.
    $variables = array();
    $variables['empty'] = 'No items found.';
    $expected = '<div class="item-list">No items found.</div>';
    $this->assertThemeOutput('item_list', $variables, $expected, 'Empty %callback generates empty string.');

    // Verify that empty items produce the empty string with title.
    $variables = array();
    $variables['title'] = 'Some title';
    $variables['empty'] = 'No items found.';
    $expected = '<div class="item-list"><h3>Some title</h3>No items found.</div>';
    $this->assertThemeOutput('item_list', $variables, $expected, 'Empty %callback generates empty string with title.');

52 53 54 55 56 57 58
    // Verify nested item lists.
    $variables = array();
    $variables['title'] = 'Some title';
    $variables['attributes'] = array(
      'id' => 'parentlist',
    );
    $variables['items'] = array(
59
      // A plain string value forms an own item.
60
      'a',
61
      // Items can be fully-fledged render arrays with their own attributes.
62
      array(
63 64 65 66 67 68 69
        '#wrapper_attributes' => array(
          'id' => 'item-id-b',
        ),
        '#markup' => 'b',
        'childlist' => array(
          '#theme' => 'item_list',
          '#attributes' => array('id' => 'blist'),
70
          '#list_type' => 'ol',
71 72 73 74 75 76 77 78 79 80 81 82 83 84 85
          '#items' => array(
            'ba',
            array(
              '#markup' => 'bb',
              '#wrapper_attributes' => array('class' => array('item-class-bb')),
            ),
          ),
        ),
      ),
      // However, items can also be child #items.
      array(
        '#markup' => 'c',
        'childlist' => array(
          '#attributes' => array('id' => 'clist'),
          'ca',
86
          array(
87 88 89 90 91 92
            '#markup' => 'cb',
            '#wrapper_attributes' => array('class' => array('item-class-cb')),
            'children' => array(
              'cba',
              'cbb',
            ),
93
          ),
94
          'cc',
95 96
        ),
      ),
97
      // Use #markup to be able to specify #wrapper_attributes.
98
      array(
99 100
        '#markup' => 'd',
        '#wrapper_attributes' => array('id' => 'item-id-d'),
101
      ),
102 103 104 105 106 107
      // An empty item with attributes.
      array(
        '#wrapper_attributes' => array('id' => 'item-id-e'),
      ),
      // Lastly, another plain string item.
      'f',
108
    );
109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124

    $inner_b = '<div class="item-list"><ol id="blist">';
    $inner_b .= '<li class="odd first">ba</li>';
    $inner_b .= '<li class="item-class-bb even last">bb</li>';
    $inner_b .= '</ol></div>';

    $inner_cb = '<div class="item-list"><ul>';
    $inner_cb .= '<li class="odd first">cba</li>';
    $inner_cb .= '<li class="even last">cbb</li>';
    $inner_cb .= '</ul></div>';

    $inner_c = '<div class="item-list"><ul id="clist">';
    $inner_c .= '<li class="odd first">ca</li>';
    $inner_c .= '<li class="item-class-cb even">cb' . $inner_cb . '</li>';
    $inner_c .= '<li class="odd last">cc</li>';
    $inner_c .= '</ul></div>';
125 126 127 128 129

    $expected = '<div class="item-list">';
    $expected .= '<h3>Some title</h3>';
    $expected .= '<ul id="parentlist">';
    $expected .= '<li class="odd first">a</li>';
130 131 132 133 134
    $expected .= '<li id="item-id-b" class="even">b' . $inner_b . '</li>';
    $expected .= '<li class="odd">c' . $inner_c . '</li>';
    $expected .= '<li id="item-id-d" class="even">d</li>';
    $expected .= '<li id="item-id-e" class="odd"></li>';
    $expected .= '<li class="even last">f</li>';
135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157
    $expected .= '</ul></div>';

    $this->assertThemeOutput('item_list', $variables, $expected);
  }

  /**
   * Tests theme_links().
   */
  function testLinks() {
    // Verify that empty variables produce no output.
    $variables = array();
    $expected = '';
    $this->assertThemeOutput('links', $variables, $expected, 'Empty %callback generates no output.');

    $variables = array();
    $variables['heading'] = 'Some title';
    $expected = '';
    $this->assertThemeOutput('links', $variables, $expected, 'Empty %callback with heading generates no output.');

    // Set the current path to the front page path.
    // Required to verify the "active" class in expected links below, and
    // because the current path is different when running tests manually via
    // simpletest.module ('batch') and via the testing framework ('').
158
    _current_path(\Drupal::config('system.site')->get('page.front'));
159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179

    // Verify that a list of links is properly rendered.
    $variables = array();
    $variables['attributes'] = array('id' => 'somelinks');
    $variables['links'] = array(
      'a link' => array(
        'title' => 'A <link>',
        'href' => 'a/link',
      ),
      'plain text' => array(
        'title' => 'Plain "text"',
      ),
      'front page' => array(
        'title' => 'Front page',
        'href' => '<front>',
      ),
    );

    $expected_links = '';
    $expected_links .= '<ul id="somelinks">';
    $expected_links .= '<li class="a-link odd first"><a href="' . url('a/link') . '">' . check_plain('A <link>') . '</a></li>';
180
    $expected_links .= '<li class="plain-text even">' . check_plain('Plain "text"') . '</li>';
181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200
    $expected_links .= '<li class="front-page odd last active"><a href="' . url('<front>') . '" class="active">' . check_plain('Front page') . '</a></li>';
    $expected_links .= '</ul>';

    // Verify that passing a string as heading works.
    $variables['heading'] = 'Links heading';
    $expected_heading = '<h2>Links heading</h2>';
    $expected = $expected_heading . $expected_links;
    $this->assertThemeOutput('links', $variables, $expected);

    // Verify that passing an array as heading works (core support).
    $variables['heading'] = array('text' => 'Links heading', 'level' => 'h3', 'class' => 'heading');
    $expected_heading = '<h3 class="heading">Links heading</h3>';
    $expected = $expected_heading . $expected_links;
    $this->assertThemeOutput('links', $variables, $expected);

    // Verify that passing attributes for the heading works.
    $variables['heading'] = array('text' => 'Links heading', 'level' => 'h3', 'attributes' => array('id' => 'heading'));
    $expected_heading = '<h3 id="heading">Links heading</h3>';
    $expected = $expected_heading . $expected_links;
    $this->assertThemeOutput('links', $variables, $expected);
201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216

    // Verify that passing attributes for the links work.
    $variables['links']['a link']['attributes'] = array(
      'class' => array('a/class'),
    );
    $variables['links']['plain text']['attributes'] = array(
      'class' => array('a/class'),
    );
    $expected_links = '';
    $expected_links .= '<ul id="somelinks">';
    $expected_links .= '<li class="a-link odd first"><a href="' . url('a/link') . '" class="a/class">' . check_plain('A <link>') . '</a></li>';
    $expected_links .= '<li class="plain-text even"><span class="a/class">' . check_plain('Plain "text"') . '</span></li>';
    $expected_links .= '<li class="front-page odd last active"><a href="' . url('<front>') . '" class="active">' . check_plain('Front page') . '</a></li>';
    $expected_links .= '</ul>';
    $expected = $expected_heading . $expected_links;
    $this->assertThemeOutput('links', $variables, $expected);
217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279
  }

  /**
   * Test the use of drupal_pre_render_links() on a nested array of links.
   */
  function testDrupalPreRenderLinks() {
    // Define the base array to be rendered, containing a variety of different
    // kinds of links.
    $base_array = array(
      '#theme' => 'links',
      '#pre_render' => array('drupal_pre_render_links'),
      '#links' => array(
        'parent_link' => array(
          'title' => 'Parent link original',
          'href' => 'parent-link-original',
        ),
      ),
      'first_child' => array(
        '#theme' => 'links',
        '#links' => array(
          // This should be rendered if 'first_child' is rendered separately,
          // but ignored if the parent is being rendered (since it duplicates
          // one of the parent's links).
          'parent_link' => array(
            'title' => 'Parent link copy',
            'href' => 'parent-link-copy',
          ),
          // This should always be rendered.
          'first_child_link' => array(
            'title' => 'First child link',
            'href' => 'first-child-link',
          ),
        ),
      ),
      // This should always be rendered as part of the parent.
      'second_child' => array(
        '#theme' => 'links',
        '#links' => array(
          'second_child_link' => array(
            'title' => 'Second child link',
            'href' => 'second-child-link',
          ),
        ),
      ),
      // This should never be rendered, since the user does not have access to
      // it.
      'third_child' => array(
        '#theme' => 'links',
        '#links' => array(
          'third_child_link' => array(
            'title' => 'Third child link',
            'href' => 'third-child-link',
          ),
        ),
        '#access' => FALSE,
      ),
    );

    // Start with a fresh copy of the base array, and try rendering the entire
    // thing. We expect a single <ul> with appropriate links contained within
    // it.
    $render_array = $base_array;
    $html = drupal_render($render_array);
280
    $dom = new \DOMDocument();
281
    $dom->loadHTML($html);
282
    $this->assertEqual($dom->getElementsByTagName('ul')->length, 1, 'One "ul" tag found in the rendered HTML.');
283
    $list_elements = $dom->getElementsByTagName('li');
284 285 286 287 288 289
    $this->assertEqual($list_elements->length, 3, 'Three "li" tags found in the rendered HTML.');
    $this->assertEqual($list_elements->item(0)->nodeValue, 'Parent link original', 'First expected link found.');
    $this->assertEqual($list_elements->item(1)->nodeValue, 'First child link', 'Second expected link found.');
    $this->assertEqual($list_elements->item(2)->nodeValue, 'Second child link', 'Third expected link found.');
    $this->assertIdentical(strpos($html, 'Parent link copy'), FALSE, '"Parent link copy" link not found.');
    $this->assertIdentical(strpos($html, 'Third child link'), FALSE, '"Third child link" link not found.');
290 291 292 293 294 295 296 297

    // Now render 'first_child', followed by the rest of the links, and make
    // sure we get two separate <ul>'s with the appropriate links contained
    // within each.
    $render_array = $base_array;
    $child_html = drupal_render($render_array['first_child']);
    $parent_html = drupal_render($render_array);
    // First check the child HTML.
298
    $dom = new \DOMDocument();
299
    $dom->loadHTML($child_html);
300
    $this->assertEqual($dom->getElementsByTagName('ul')->length, 1, 'One "ul" tag found in the rendered child HTML.');
301
    $list_elements = $dom->getElementsByTagName('li');
302 303 304
    $this->assertEqual($list_elements->length, 2, 'Two "li" tags found in the rendered child HTML.');
    $this->assertEqual($list_elements->item(0)->nodeValue, 'Parent link copy', 'First expected link found.');
    $this->assertEqual($list_elements->item(1)->nodeValue, 'First child link', 'Second expected link found.');
305
    // Then check the parent HTML.
306
    $dom = new \DOMDocument();
307
    $dom->loadHTML($parent_html);
308
    $this->assertEqual($dom->getElementsByTagName('ul')->length, 1, 'One "ul" tag found in the rendered parent HTML.');
309
    $list_elements = $dom->getElementsByTagName('li');
310 311 312 313 314
    $this->assertEqual($list_elements->length, 2, 'Two "li" tags found in the rendered parent HTML.');
    $this->assertEqual($list_elements->item(0)->nodeValue, 'Parent link original', 'First expected link found.');
    $this->assertEqual($list_elements->item(1)->nodeValue, 'Second child link', 'Second expected link found.');
    $this->assertIdentical(strpos($parent_html, 'First child link'), FALSE, '"First child link" link not found.');
    $this->assertIdentical(strpos($parent_html, 'Third child link'), FALSE, '"Third child link" link not found.');
315 316
  }
}