1 layout.test LayoutFlexibleTemplateTest::testLayoutFlexibleTemplates()

Test that layout templates may be enabled and disabled.

File

core/modules/layout/tests/layout.test, line 3293
Tests for the Layout module.

Class

LayoutFlexibleTemplateTest
Tests the interface for flexible layouts.

Code

function testLayoutFlexibleTemplates() {
  $this->backdropGet('admin/structure/layouts/settings');
  $this->clickLink(t('Add flexible layout template'));

  // Test creating a new flexible layout.
  $template_name1 = $this->randomName();
  $template_machine_name1 = strtolower($template_name1);
  $template_description1 = $this->randomName();

  $edit = array(
    'name' => $template_name1,
    'machine_name' => $template_machine_name1,
    'description' => $template_description1,
  );
  $this->backdropPost(NULL, $edit, t('Save and configure'));
  $this->assertText(t('Layout template "@title" saved.', array('@title' => $template_name1)));

  // Check that the new template is found in the cached list of templates.
  $all_templates = layout_get_layout_template_info();
  $this->assertTrue(isset($all_templates[$template_machine_name1]), 'The flexible template is found in the cache of templates.');

  // Check that its in the list of templates.
  $this->backdropGet('admin/structure/layouts/settings');
  $title = $this->xpath("//td//div[text()=:name]", array(':name' => $template_name1));
  $this->assertTrue($title, 'The flexible template is found in the UI list of templates.');

  // Add another, edit it, then delete it.
  $this->clickLink(t('Add flexible layout template'));
  $template_name2 = $this->randomName();
  $template_machine_name2 = strtolower($template_name2);
  $template_description2 = $this->randomName();

  $edit = array(
    'name' => $template_name2,
    'machine_name' => $template_machine_name2,
    'description' => $template_description2,
  );
  $this->backdropPost(NULL, $edit, t('Save and configure'));
  $this->assertText(t('Layout template "@title" saved.', array('@title' => $template_name2)));
  $this->backdropGet('admin/structure/layouts/settings');
  $flexible_layout_edit_link = 'admin/structure/layouts/settings/flexible-template/' . $template_machine_name2 . '/edit';
  $edit = array(
    'name' => 'To be deleted',
    'description' => $template_description2,
  );
  $this->backdropPost($flexible_layout_edit_link, $edit, t('Save and configure'));
  $this->backdropGet('admin/structure/layouts/settings');
  $title = $this->xpath("//td//div[text()=:name]", array(':name' => 'To be deleted'));
  $this->assertTrue($title, 'The flexible template is found in the UI list of templates with the new name.');
  $flexible_layout_delete_link = 'admin/structure/layouts/settings/flexible-template/' . $template_machine_name2 . '/delete';
  $edit = array();
  $this->backdropPost($flexible_layout_delete_link, $edit, t('Delete template'));
  $this->backdropGet('admin/structure/layouts/settings');
  $title = $this->xpath("//td//div[text()=:name]", array(':name' => 'To be deleted'));
  $this->assertFalse($title, 'The flexible template is not found in the UI list of templates with the new name.');

  $this->backdropGet('admin/structure/layouts');
  $this->clickLink(t('Add layout'));

  // Create a new layout at a new path using the new template.
  $layout_title = $this->randomName();
  $layout_name = strtolower($layout_title);
  $layout_url = 'layout-test-path';
  $edit = array(
    'title' => $layout_title,
    'name' => $layout_name,
    'layout_template' => $template_machine_name1,
    'path' => $layout_url,
  );
  $this->backdropPost(NULL, $edit, t('Create layout'));

  // We should be taken to the layout content page next.
  $this->assertText(t('Layout created. Blocks may now be added to this layout.'));

  // Add a block to the first row.
  $this->clickLink(t('Add block'), 0);
  $this->assertText(t('A testing block for layouts.'));
  $this->clickLink(t('Layout foo block'));
  $edit = array(
    'block_settings[count]' => 30,
  );
  $this->backdropPost(NULL, $edit, t('Add block'));

  // Add a block to the second row.
  $this->clickLink(t('Add block'), 1);
  $this->assertText(t('A testing block for layouts.'));
  $this->clickLink(t('Layout foo block'));
  $edit = array(
    'block_settings[count]' => 15,
  );
  $this->backdropPost(NULL, $edit, t('Add block'));

  // Add a block to the third row.
  $this->clickLink(t('Add block'), 2);
  $this->assertText(t('A testing block for layouts.'));
  $this->clickLink(t('Layout foo block'));
  $edit = array(
    'block_settings[count]' => 5,
  );
  $this->backdropPost(NULL, $edit, t('Add block'));

  // Save the layout.
  $this->backdropPost(NULL, array(), t('Save layout'));

  // Check that the layout is in the listing of layouts.
  $this->backdropGet('admin/structure/layouts');
  $this->assertText(check_plain($layout_title));

  // Go to the the layout path and confirm the blocks exist, have the right
  // setting, and are in the right place.
  $this->backdropGet($layout_url);
  $layout_template = layout_flexible_template_load($template_machine_name1);
  $layout_region_names = array_keys($layout_template->rows);
  $region_block_settings = array(
    $layout_region_names[0] => 30,
    $layout_region_names[1] => 15,
    $layout_region_names[2] => 5,
  );
  foreach ($region_block_settings as $region_name => $setting) {
    $string = format_string('The setting of count is @setting.', array('@setting' => $setting));
    $elements = $this->xpath('//*[contains(@class,:region)]//*[contains(text(),:string)]', array(
      ':region' => 'l-' . $region_name,
      ':string' => $string,
    ));
    $this->assertEqual(count($elements), 1, "The sample block was found in the $region_name region.");
  }

  // Configure the first template.
  $flexible_layout_configure_link = 'admin/structure/layouts/settings/flexible-template/' . $template_machine_name1 . '/configure';
  $this->backdropGet($flexible_layout_configure_link);
  // Check for the default three rows.
  $rows = $this->xpath("//*[@id=:id]//*[contains(@id, :row_id)]", array(':id' => 'layout-flexible-content', ':row_id' => 'flexible-row'));
  $this->assertEqual(count($rows), 3, 'Three rows are found in the template');

  // Edit the header row and check that the changes are reflected on the
  // template editor page and the layout path.
  $this->clickLink(t('Configure'), 0);
  $edit = array(
    'region_names[region_0][label]' => 'New header',
    'region_names[region_0][name]' => 'new-header-new',
    'region_names[region_0][classes]' => 'blue-blue',
    'region_names[region_0][region_class_enable]' => TRUE,
    'row_classes' => 'new-class another-class',
    'element' => 'main',
    'container' => 'no_container',
  );
  $this->backdropPost(NULL, $edit, t('Save configuration'));

  $header_row = $this->xpath("//main[contains(@id, :row_id)]//h2[text()=:row_title]", array(':row_id' => 'flexible-row--' . $layout_region_names[0], ':row_title' => 'New header'));
  $this->assertEqual(count($header_row), 1, 'The header row has been renamed in the template editor.');

  $this->backdropPost(NULL, array(), t('Save layout template'));

  // Go to the block add page and check that the header region was renamed.
  $this->backdropGet('admin/structure/layouts/manage/' . $layout_name);
  $header_row = $this->xpath("//main[contains(@class, :row_class)]//h2[text()=:row_title]", array(':row_class' => 'l-' . $layout_region_names[0], ':row_title' => 'New header'));
  $this->assertEqual(count($header_row), 1, 'The header row has been renamed in the block add page.');

  // Check that header region class has changed.
  $rows = $this->xpath("//div[contains(@class, :region_class)]", array(':region_class' => 'l-region--new-header-new blue-blue'));
  $this->assertEqual(count($rows), 1, 'The header region class has been renamed in the block add page.');

  // Disable the additional CSS classes.
  $this->backdropGet($flexible_layout_configure_link);
  $this->clickLink(t('Configure'), 0);
  $edit = array(
    'region_names[region_0][region_class_enable]' => FALSE,
  );
  $this->backdropPost(NULL, $edit, t('Save configuration'));
  $this->backdropPost(NULL, array(), t('Save layout template'));

  // Go to the block add page and check that the header region class does not
  // have additional classes.
  $this->backdropGet('admin/structure/layouts/manage/' . $layout_name);
  $rows = $this->xpath("//div[contains(@class, :region_class)]", array(':region_class' => 'l-region--1 blue-blue'));
  $this->assertNotEqual(count($rows), 1, 'The header region class has no additional classes.');

  // Go to the layout path and check that the header region was renamed and
  // the block is still in the header region.
  $this->backdropGet($layout_url);

  $string = format_string('The setting of count is @setting.', array('@setting' => 30));
  $elements = $this->xpath('//main[contains(@class,:region)]/div[contains(@class, :container_class)]//*[contains(text(),:string)]', array(
    ':region' => 'l-' . $layout_region_names[0],
    ':container_class' => 'no-container',
    ':string' => $string,
  ));
  $this->assertEqual(count($elements), 1, "The header element has been changed to 'main'");

  // Go to the template editor and add a new row.
  $flexible_layout_configure_link = 'admin/structure/layouts/settings/flexible-template/' . $template_machine_name1 . '/configure';
  $this->backdropGet($flexible_layout_configure_link);
  $this->backdropPost(NULL, array(), t('Add row'));
  $edit = array(
    'region_count' => 3,
  );
  $this->backdropPost(NULL, $edit, t('Choose region widths'));
  $edit = array(
    'region_style' => 'region_4_4_4',
  );
  $this->backdropPost(NULL, $edit, t('Continue'));
  // Rename just the first region.
  $edit = array(
    'region_names[region_0][label]' => 'First region',
    // Machine names have to be set manually.
    'region_names[region_0][name]' => 'first-region',
    'region_names[region_1][name]' => 'region-2',
    'region_names[region_2][name]' => 'region-3',
  );
  $this->backdropPost(NULL, $edit, t('Save configuration'));
  $this->backdropPost(NULL, array(), t('Save layout template'));

  $row_count = $this->xpath("//*[@id=:id]//*[contains(@id, :row_id)]", array(':id' => 'layout-flexible-content', ':row_id' => 'flexible-row'));
  $this->assertEqual(count($row_count), 4, 'Four rows are found in the template');

  // Get the id of the last (new) row.
  $last_row_attr = $this->xpath('//div[contains(@class, :class)]/*[4]/@data-row-id', array(
    ':class' => 'layout-flexible-content',
  ));
  $data_row_id = (string) $last_row_attr[0][0];
  $last_row_id = 'flexible-row--' . $last_row_attr[0][0];

  // The last row has 3 regions.
  $row_count = $this->xpath('//div[contains(@id, :id)]//div[contains(@class, :class)]/div', array(
    ':id' => $last_row_id,
    ':class' => 'l-flexible-row row',
  ));
  $this->assertEqual(count($row_count), 3, 'The last row has 3 regions.');

  // Check that the first region has the expected title.
  $fourth_row_first_region_title = $this->xpath('//div[contains(@id, :id)]//div[contains(@class, :class)]/div[1]//h2[text()=:region_title]', array(
    ':id' => $last_row_id,
    ':class' => 'l-flexible-row row',
    ':region_title' => 'First region',
  ));
  $this->assertTrue($fourth_row_first_region_title, 'The region has the correct title.');

  // Go to the block add page and check that the new row shows correctly.
  $this->backdropGet('admin/structure/layouts/manage/' . $layout_name);

  // The last row has 3 regions.
  $row_count = $this->xpath('//div[contains(@data-row-id, :id)]//div[contains(@class, :class)]/div', array(
    ':id' => $data_row_id,
    ':class' => 'l-flexible-row row',
  ));
  $this->assertEqual(count($row_count), 3, 'The last row has 3 regions.');

  // Check that the first region has the expected title.
  $fourth_row_first_region_title = $this->xpath('//div[contains(@data-row-id, :id)]//div[contains(@class, :class)]/div[1]//h2[text()=:region_title]', array(
    ':id' => $data_row_id,
    ':class' => 'l-flexible-row row',
    ':region_title' => 'First region',
  ));
  $this->assertTrue($fourth_row_first_region_title, 'The region has the correct title.');

  // Add a block to the new row first region.
  $this->clickLink(t('Add block'), 3);
  $this->assertText(t('A testing block for layouts.'));
  $this->clickLink(t('Layout foo block'));
  $edit = array(
    'block_settings[count]' => 19,
  );
  $this->backdropPost(NULL, $edit, t('Add block'));

  // Add a block to the new row first region.
  $this->clickLink(t('Add block'), 4);
  $this->assertText(t('A testing block for layouts.'));
  $this->clickLink(t('Layout foo block'));
  $edit = array(
    'block_settings[count]' => 18,
  );
  $this->backdropPost(NULL, $edit, t('Add block'));

  // Add a block to the new row first region.
  $this->clickLink(t('Add block'), 5);
  $this->assertText(t('A testing block for layouts.'));
  $this->clickLink(t('Layout foo block'));
  $edit = array(
    'block_settings[count]' => 17,
  );
  $this->backdropPost(NULL, $edit, t('Add block'));

  // Save the layout.
  $this->backdropPost(NULL, array(), t('Save layout'));

  // Go to the the layout path and confirm the blocks exist, have the right
  // setting, and are in the right place.
  $this->backdropGet($layout_url);
  $region_block_settings = array('19', '18', '17');
  foreach ($region_block_settings as $index => $setting) {
    $string = format_string('The setting of count is @setting.', array('@setting' => $setting));
    $elements = $this->xpath('//*[contains(@data-row-id,:id)]//div[contains(@class,:row)]/div[:index]//div[normalize-space(text())=:string]', array(
      ':id' => $data_row_id,
      ':row' => 'l-flexible-row row',
      ':index' => $index + 1,
      ':string' => $string,
    ));
    $this->assertEqual(count($elements), 1, "The sample block was found in the correct region.");
  }

  // Configure the template and move the footer row to the bottom.
  $this->backdropGet($flexible_layout_configure_link);
  $edit = array(
    'row_positions' => "{$layout_region_names[0]},{$layout_region_names[1]},$data_row_id,{$layout_region_names[2]}",
  );
  $this->backdropPost(NULL, $edit, t('Save layout template'));
  $last_row_attr = $this->xpath('//div[contains(@class, :class)]/*[4]/@data-row-id', array(
    ':class' => 'layout-flexible-content',
  ));
  $last_row_attr = (string) $last_row_attr[0][0];
  $this->assertEqual($last_row_attr, $layout_region_names[2], 'The last row is footer.');

  // Go to the block add page and check.
  $this->backdropGet('admin/structure/layouts/manage/' . $layout_name);
  $last_row_attr = $this->xpath('//div[contains(@class, :class)]/*[4]/@data-row-id', array(
    ':class' => 'layout-flexible-content',
  ));
  $last_row_attr = (string) $last_row_attr[0][0];
  $this->assertEqual($last_row_attr, $layout_region_names[2], 'The last row is footer.');

  // Go to the the layout path and check.
  $this->backdropGet($layout_url);
  $last_row_attr = $this->xpath('//div[contains(@class, :class)]/*[4]/@data-row-id', array(
    ':class' => 'layout-flexible-content',
  ));
  $last_row_attr = (string) $last_row_attr[0][0];
  $this->assertEqual($last_row_attr, $layout_region_names[2], 'The last row is footer.');

  // Configure the template and delete the footer row.
  $this->backdropGet($flexible_layout_configure_link);
  $this->clickLink(t('Delete row'), 3);
  $this->backdropPost(NULL, array(), t('Save layout template'));

  // Check for the default three rows.
  $rows = $this->xpath("//*[@id=:id]//*[contains(@id, :row_id)]", array(':id' => 'layout-flexible-content', ':row_id' => 'flexible-row'));
  $this->assertEqual(count($rows), 3, 'Three rows are found in the template');

  $last_row_attr = $this->xpath('//div[contains(@class, :class)]/*[last()]/@data-row-id', array(
    ':class' => 'layout-flexible-content',
  ));
  $last_row_attr = (string) $last_row_attr[0][0];
  $this->assertEqual($last_row_attr, $data_row_id, 'The last row is the new row.');

  // Go to the block add page and check.
  $this->backdropGet('admin/structure/layouts/manage/' . $layout_name);
  $last_row_attr = $this->xpath('//div[contains(@class, :class)]/*[last()]/@data-row-id', array(
    ':class' => 'layout-flexible-content',
  ));
  $last_row_attr = (string) $last_row_attr[0][0];
  $this->assertEqual($last_row_attr, $data_row_id, 'The last row is the new row.');

  // Go to the the layout path and check.
  $this->backdropGet($layout_url);
  $last_row_attr = $this->xpath('//div[contains(@class, :class)]/*[last()]/@data-row-id', array(
    ':class' => 'layout-flexible-content',
  ));
  $last_row_attr = (string) $last_row_attr[0][0];
  $this->assertEqual($last_row_attr, $data_row_id, 'The last row is the new row.');

  // Test that a user without permissions cannot create flexible templates
  // But can still use them.
  $this->no_flex_user = $this->backdropCreateUser(array(
    'access administration pages',
    'administer site configuration',
    'administer layouts',
  ));
  $this->backdropLogin($this->no_flex_user);

  $this->backdropGet('admin/structure/layouts/settings');
  $this->assertNoLink(t('Add flexible layout template'));
  $this->assertNoLink(t('Configure regions'));

  // Attempt to go to the template editor of the flexible template, and
  // confirm no access.
  $flexible_layout_configure_link = 'admin/structure/layouts/settings/flexible-template/' . $template_machine_name1 . '/configure';
  $this->backdropGet($flexible_layout_configure_link);
  $this->assertResponse(403, 'Access not allowed to flexible layout configuration pages without permission.');

  // Go to the layout created with this template and confirm still has access.
  $this->backdropGet('admin/structure/layouts/manage/' . $layout_name);
  $this->backdropPost(NULL, array(), t('Save layout'));
}