function FrameworkTest::testLazyLoad

Tests that new JavaScript and CSS files are lazy-loaded on an AJAX request.

File

drupal/core/modules/system/lib/Drupal/system/Tests/Ajax/FrameworkTest.php, line 98
Contains \Drupal\system\Tests\Ajax\FrameworkTest.

Class

FrameworkTest
Tests primary Ajax framework functions.

Namespace

Drupal\system\Tests\Ajax

Code

function testLazyLoad() {
  $expected = array(
    'setting_name' => 'ajax_forms_test_lazy_load_form_submit',
    'setting_value' => 'executed',
    'css' => drupal_get_path('module', 'system') . '/css/system.admin.css',
    'js' => drupal_get_path('module', 'system') . '/system.js',
  );

  // CSS files are stored by basename, see drupal_add_css().
  $expected_css_basename = drupal_basename($expected['css']);

  // @todo D8: Add a drupal_css_defaults() helper function.
  $expected_css_html = drupal_get_css(array(
    $expected_css_basename => array(
      'type' => 'file',
      'group' => CSS_AGGREGATE_DEFAULT,
      'weight' => 0,
      'every_page' => FALSE,
      'media' => 'all',
      'preprocess' => TRUE,
      'data' => $expected['css'],
      'browsers' => array(
        'IE' => TRUE,
        '!IE' => TRUE,
      ),
    ),
  ), TRUE);
  $expected_js_html = drupal_get_js('header', array(
    $expected['js'] => drupal_js_defaults($expected['js']),
  ), TRUE);

  // Get the base page.
  $this
    ->drupalGet('ajax_forms_test_lazy_load_form');
  $original_settings = $this
    ->drupalGetSettings();
  $original_css = $original_settings['ajaxPageState']['css'];
  $original_js = $original_settings['ajaxPageState']['js'];

  // Verify that the base page doesn't have the settings and files that are to
  // be lazy loaded as part of the next requests.
  $this
    ->assertTrue(!isset($original_settings[$expected['setting_name']]), format_string('Page originally lacks the %setting, as expected.', array(
    '%setting' => $expected['setting_name'],
  )));
  $this
    ->assertTrue(!isset($original_css[$expected['css']]), format_string('Page originally lacks the %css file, as expected.', array(
    '%css' => $expected['css'],
  )));
  $this
    ->assertTrue(!isset($original_js[$expected['js']]), format_string('Page originally lacks the %js file, as expected.', array(
    '%js' => $expected['js'],
  )));

  // Submit the AJAX request without triggering files getting added.
  $commands = $this
    ->drupalPostAJAX(NULL, array(
    'add_files' => FALSE,
  ), array(
    'op' => t('Submit'),
  ));
  $new_settings = $this
    ->drupalGetSettings();
  $new_css = $new_settings['ajaxPageState']['css'];
  $new_js = $new_settings['ajaxPageState']['js'];

  // Verify the setting was not added when not expected.
  $this
    ->assertTrue(!isset($new_settings[$expected['setting_name']]), format_string('Page still lacks the %setting, as expected.', array(
    '%setting' => $expected['setting_name'],
  )));
  $this
    ->assertTrue(!isset($new_css[$expected['css']]), format_string('Page still lacks the %css file, as expected.', array(
    '%css' => $expected['css'],
  )));
  $this
    ->assertTrue(!isset($new_js[$expected['js']]), format_string('Page still lacks the %js file, as expected.', array(
    '%js' => $expected['js'],
  )));

  // Verify a settings command does not add CSS or scripts to drupalSettings
  // and no command inserts the corresponding tags on the page.
  $found_settings_command = FALSE;
  $found_markup_command = FALSE;
  foreach ($commands as $command) {
    if ($command['command'] == 'settings' && (array_key_exists('css', $command['settings']['ajaxPageState']) || array_key_exists('js', $command['settings']['ajaxPageState']))) {
      $found_settings_command = TRUE;
    }
    if (isset($command['data']) && ($command['data'] == $expected_js_html || $command['data'] == $expected_css_html)) {
      $found_markup_command = TRUE;
    }
  }
  $this
    ->assertFalse($found_settings_command, format_string('Page state still lacks the %css and %js files, as expected.', array(
    '%css' => $expected['css'],
    '%js' => $expected['js'],
  )));
  $this
    ->assertFalse($found_markup_command, format_string('Page still lacks the %css and %js files, as expected.', array(
    '%css' => $expected['css'],
    '%js' => $expected['js'],
  )));

  // Submit the AJAX request and trigger adding files.
  $commands = $this
    ->drupalPostAJAX(NULL, array(
    'add_files' => TRUE,
  ), array(
    'op' => t('Submit'),
  ));
  $new_settings = $this
    ->drupalGetSettings();
  $new_css = $new_settings['ajaxPageState']['css'];
  $new_js = $new_settings['ajaxPageState']['js'];

  // Verify the expected setting was added, both to drupalSettings, and as
  // the first AJAX command.
  $this
    ->assertIdentical($new_settings[$expected['setting_name']], $expected['setting_value'], format_string('Page now has the %setting.', array(
    '%setting' => $expected['setting_name'],
  )));
  $expected_command = new SettingsCommand(array(
    $expected['setting_name'] => $expected['setting_value'],
  ), TRUE);
  $this
    ->assertCommand(array_slice($commands, 0, 1), $expected_command
    ->render(), format_string('The settings command was first.'));

  // Verify the expected CSS file was added, both to drupalSettings, and as
  // the second AJAX command for inclusion into the HTML.
  // @todo Uncomment this assertion after fixing http://drupal.org/node/1941288.

  //$this->assertEqual($new_css, $original_css + array($expected_css_basename => 1), format_string('Page state now has the %css file.', array('%css' => $expected['css'])));
  $this
    ->assertCommand(array_slice($commands, 1, 1), array(
    'data' => $expected_css_html,
  ), format_string('Page now has the %css file.', array(
    '%css' => $expected['css'],
  )));

  // Verify the expected JS file was added, both to drupalSettings, and as
  // the third AJAX command for inclusion into the HTML. By testing for an
  // exact HTML string containing the SCRIPT tag, we also ensure that
  // unexpected JavaScript code, such as a jQuery.extend() that would
  // potentially clobber rather than properly merge settings, didn't
  // accidentally get added.
  // @todo Uncomment this assertion after fixing http://drupal.org/node/1941288.

  //$this->assertEqual($new_js, $original_js + array($expected['js'] => 1), format_string('Page state now has the %js file.', array('%js' => $expected['js'])));
  $this
    ->assertCommand(array_slice($commands, 2, 1), array(
    'data' => $expected_js_html,
  ), format_string('Page now has the %js file.', array(
    '%js' => $expected['js'],
  )));
}