1722 lines
84 KiB
Plaintext

<?php
/**
* @file
* Tests for advagg.module.
*/
/**
* @defgroup advagg_tests Advanced Aggregates Tests
*
* @{
* Advanced Aggregates testing functionality.
*/
// Include all files in the project for simple sanity checking.
$files = file_scan_directory(drupal_get_path('module', 'advagg'), "/.*\.(inc|module|install|php)$/", array(
'nomask' => '/(\\.\\.?|CVS|tpl\.php)$/',
));
foreach ($files as $file) {
include_once DRUPAL_ROOT . '/' . $file->uri;
}
/**
* Resets static variables related to adding CSS or JS to a page.
*/
function advagg_test_reset_statics() {
drupal_static_reset('drupal_add_css');
drupal_static_reset('drupal_add_library');
drupal_static_reset('drupal_get_library');
drupal_static_reset('drupal_add_js');
drupal_static_reset('drupal_add_js:jquery_added');
drupal_static_reset('advagg_get_js');
}
/**
* Generates a large CSS string.
*
* @param int $selector_count
* The number of selectors to generate.
* @param int $denominator
* The max string length of the selector names.
*
* @return string
* Generated CSS string.
*/
function advagg_test_generate_selector_css($selector_count, $denominator = 5) {
static $count = 0;
$pool = array_merge(range('a', 'z'), range('A', 'Z'));
$selector_count = 10000;
$css = '';
while ($selector_count > 0) {
$rand_string = advagg_test_randon_string(($selector_count % $denominator) + 3, $pool);
$css .= ".{$rand_string}, ";
--$selector_count;
}
$css .= "#last$count {z-index: 2; margin-left: -1px; content: \" \"; display: table;}";
++$count;
return $css;
}
/**
* Generates random string.
*
* @param int $length
* How many characters will this string contain.
* @param array $pool
* Array of characters to use.
*
* @return string
* Random string.
*/
function advagg_test_randon_string($length, array $pool) {
$string = '';
$count = count($pool);
for ($i = 0; $i < $length; $i++) {
$string .= $pool[mt_rand(0, $count - 1)];
}
return $string;
}
/**
* Strip the codingStandardsIgnoreFile string from the input.
*
* @param string $input
* The input string.
*
* @return string
* The input string with codingStandardsIgnoreFile removed from it.
*/
function advagg_test_remove_sniffer_comments($input) {
$string = "/* @codingStandardsIgnoreFile */\n";
return str_replace($string, '', $input);
}
/**
* Test the Drupal CSS system.
*/
class AdvAggCascadingStylesheetsTestCase extends DrupalWebTestCase {
/**
* Store configured value for CSS preprocessing.
*
* @var bool
*/
protected $preprocessCss = NULL;
/**
* Create user.
*
* @var object
*/
protected $bigUser;
/**
* Theme settings.
*
* @var array
*/
protected $themes;
/**
* Provide information to the UI for this test.
*/
public static function getInfo() {
return array(
'name' => 'CSS',
'description' => 'Tests adding various cascading stylesheets to the page.',
'group' => 'AdvAgg',
);
}
/**
* Install the advagg module and include needed files.
*/
public function setUp() {
// Enable any modules required for the test. This should be an array of
// module names.
parent::setUp(array(
'advagg',
'php',
'locale',
'common_test',
'menu_test',
'color',
));
// Include the advagg.module file.
drupal_load('module', 'advagg');
module_load_include('inc', 'advagg', 'advagg');
// Set settings for testing.
$GLOBALS['conf']['advagg_convert_absolute_to_relative_path'] = FALSE;
$GLOBALS['conf']['advagg_convert_absolute_to_protocol_relative_path'] = FALSE;
$GLOBALS['conf']['advagg_force_https_path'] = FALSE;
$GLOBALS['conf']['advagg_skip_file_create_url_inside_css'] = FALSE;
// Disable CSS preprocessing.
$this->preprocessCss = variable_get('preprocess_css', 0);
variable_set('preprocess_css', 0);
// Create users.
$this->bigUser = $this->drupalCreateUser(array('administer themes'));
// This tests the color module in both Bartik and Garland.
$this->themes = array(
'bartik' => array(
'palette_input' => 'palette[bg]',
'scheme' => 'slate',
'scheme_color' => '#3b3b3b',
),
);
theme_enable(array_keys($this->themes));
// Reset drupal_add_css() before each test.
advagg_test_reset_statics();
}
/**
* Restore any variables we set.
*/
public function tearDown() {
// Restore configured value for CSS preprocessing.
variable_set('preprocess_css', $this->preprocessCss);
parent::tearDown();
}
/**
* Tests rendering the stylesheets.
*/
public function testRenderFile() {
foreach ($this->themes as $theme => $test_values) {
variable_set('theme_default', $theme);
$settings_path = 'admin/appearance/settings/' . $theme;
$this->drupalLogin($this->bigUser);
$this->drupalGet($settings_path);
$this->assertResponse(200);
$edit['scheme'] = '';
$edit[$test_values['palette_input']] = '#123456';
$this->drupalPost($settings_path, $edit, t('Save configuration'));
// Reset drupal_add_css() before each test.
$GLOBALS['conf']['advagg_convert_absolute_to_relative_path'] = FALSE;
$GLOBALS['conf']['advagg_convert_absolute_to_protocol_relative_path'] = FALSE;
advagg_test_reset_statics();
// Add the css file.
$stylesheets = variable_get('color_' . $theme . '_stylesheets', array());
drupal_add_css($stylesheets[0]);
$css = file_create_url($stylesheets[0]);
// Get the render array.
$full_css = advagg_get_css();
$styles = drupal_render($full_css);
$this->assertTrue(strpos($styles, $css) !== FALSE, "Rendered CSS includes the added stylesheet ($css).");
}
// Reset drupal_add_css() before each test.
advagg_test_reset_statics();
// Add the css file.
$css = drupal_get_path('module', 'simpletest') . '/simpletest.css';
drupal_add_css($css);
// Get the render array.
$full_css = advagg_get_css();
// Render the CSS.
$styles = drupal_render($full_css);
$this->assertTrue(strpos($styles, $css) > 0, "Rendered CSS includes the added stylesheet ($css).");
// Verify that newlines are properly added inside style tags.
$query_string = variable_get('css_js_query_string', '0');
$css_processed = "<style type=\"text/css\" media=\"all\">\n@import url(\"" . check_plain(file_create_url($css)) . "?" . $query_string . "\");\n</style>";
$this->assertEqual(trim($styles), $css_processed, 'Rendered CSS includes newlines inside style tags for JavaScript use.');
//
// Tests rendering an external stylesheet.
advagg_test_reset_statics();
// Add the css file.
$css = 'http://example.com/style.css';
drupal_add_css($css, 'external');
// Get the render array.
$full_css = advagg_get_css();
// Render the CSS.
$styles = drupal_render($full_css);
// Stylesheet URL may be the href of a LINK tag or in an @import statement
// of a STYLE tag.
$this->assertTrue(strpos($styles, 'href="' . $css) > 0 || strpos($styles, '@import url("' . $css . '")') > 0, 'Rendering an external CSS file.');
//
// Tests rendering inline stylesheets with preprocessing on.
advagg_test_reset_statics();
// Add the inline css.
$css = 'body { padding: 0px; }';
list($embed_prefix, $embed_suffix) = advagg_get_css_prefix_suffix();
$css_preprocessed = '<style type="text/css" media="all">' . $embed_prefix . advagg_load_stylesheet_content($css, TRUE) . $embed_suffix . '</style>';
drupal_add_css($css, array('type' => 'inline'));
// Get the render array.
$full_css = advagg_get_css();
// Render the CSS.
$styles = drupal_render($full_css);
$this->assertEqual(trim($styles), $css_preprocessed, 'Rendering preprocessed inline CSS adds it to the page.');
//
// Tests removing charset when rendering stylesheets with preprocessing on.
advagg_test_reset_statics();
$cases = array(
array(
'asset' => '@charset "UTF-8";html{font-family:"sans-serif";}',
'expected' => 'html{font-family:"sans-serif";}',
),
// This asset contains extra \n character.
array(
'asset' => "@charset 'UTF-8';\nhtml{font-family:'sans-serif';}",
'expected' => "\nhtml{font-family:'sans-serif';}",
),
);
foreach ($cases as $case) {
$this->assertEqual(
$case['expected'],
advagg_load_stylesheet_content($case['asset']),
'CSS optimizing correctly removes the charset declaration.'
);
}
//
// Tests rendering inline stylesheets with preprocessing off.
advagg_test_reset_statics();
// Add the inline css.
$css = 'body { padding: 0px; }';
drupal_add_css($css, array('type' => 'inline', 'preprocess' => FALSE));
// Get the render array.
$full_css = advagg_get_css();
// Render the CSS.
$styles = drupal_render($full_css);
$this->assertTrue(strpos($styles, $css) > 0, 'Rendering non-preprocessed inline CSS adds it to the page.');
//
// Test CSS ordering.
advagg_test_reset_statics();
// A module CSS file.
drupal_add_css(drupal_get_path('module', 'simpletest') . '/simpletest.css');
// A few system CSS files, ordered in a strange way.
$system_path = drupal_get_path('module', 'system');
drupal_add_css($system_path . '/system.menus.css', array('group' => CSS_SYSTEM));
drupal_add_css($system_path . '/system.base.css', array('group' => CSS_SYSTEM, 'weight' => -10));
drupal_add_css($system_path . '/system.theme.css', array('group' => CSS_SYSTEM));
$expected = array(
$system_path . '/system.base.css',
$system_path . '/system.menus.css',
$system_path . '/system.theme.css',
drupal_get_path('module', 'simpletest') . '/simpletest.css',
);
// Get the render array.
$full_css = advagg_get_css();
// Render the CSS.
$styles = drupal_render($full_css);
// Stylesheet URL may be the href of a LINK tag or in an @import statement
// of a STYLE tag.
if (preg_match_all('/(href="|url\(")' . preg_quote($GLOBALS['base_url'] . '/', '/') . '([^?]+)\?/', $styles, $matches)) {
$result = $matches[2];
}
else {
$result = array();
}
$this->assertIdentical($result, $expected, 'The CSS files are in the expected order.');
//
// Test CSS override.
advagg_test_reset_statics();
$system = drupal_get_path('module', 'system');
$simpletest = drupal_get_path('module', 'simpletest');
drupal_add_css($system . '/system.base.css');
drupal_add_css($simpletest . '/tests/system.base.css');
// The dummy stylesheet should be the only one included.
// Get the render array.
$full_css = advagg_get_css();
// Render the CSS.
$styles = drupal_render($full_css);
$this->assert(strpos($styles, $simpletest . '/tests/system.base.css') !== FALSE, 'The overriding CSS file is output.');
$this->assert(strpos($styles, $system . '/system.base.css') === FALSE, 'The overridden CSS file is not output.');
// The reset is needed here until this is fixed
// https://www.drupal.org/node/1388546
advagg_test_reset_statics();
drupal_add_css($simpletest . '/tests/system.base.css');
drupal_add_css($system . '/system.base.css');
// Get the render array.
$full_css = advagg_get_css();
// Render the CSS.
$styles = drupal_render($full_css);
// The standard stylesheet should be the only one included.
$this->assert(strpos($styles, $system . '/system.base.css') !== FALSE, 'The overriding CSS file is output.');
$this->assert(strpos($styles, $simpletest . '/tests/system.base.css') === FALSE, 'The overridden CSS file is not output.');
//
// Tests Locale module's CSS Alter to include RTL overrides.
advagg_test_reset_statics();
// Switch the language to a right to left language and add system.base.css.
global $language;
$language->direction = LANGUAGE_RTL;
$path = drupal_get_path('module', 'system');
drupal_add_css($path . '/system.base.css', array('group' => CSS_SYSTEM));
drupal_add_css($path . '/system.menus.css', array('group' => CSS_SYSTEM));
drupal_add_css($path . '/system.theme.css', array('group' => CSS_SYSTEM));
// Get the render array.
$full_css = advagg_get_css();
// Render the CSS.
$styles = drupal_render($full_css);
// Check to see if system.base-rtl.css was also added.
$base_pos = strpos($styles, $path . '/system.base.css');
$base_rtl_pos = strpos($styles, $path . '/system.base-rtl.css');
$this->assert($base_rtl_pos !== FALSE, 'CSS is alterable as right to left overrides are added.');
$this->assert($base_pos < $base_rtl_pos, 'system.base-rtl.css is added after system.base.css.');
// Check to see if system.menus-rtl.css was also added.
$menus_pos = strpos($styles, $path . '/system.menus.css');
$menus_rtl_pos = strpos($styles, $path . '/system.menus-rtl.css');
$this->assert($menus_rtl_pos !== FALSE, 'CSS is alterable as right to left overrides are added.');
$this->assert($menus_pos < $menus_rtl_pos, 'system.menus-rtl.css is added after system.menus.css.');
// Check to see if system.theme-rtl.css was also added.
$theme_pos = strpos($styles, $path . '/system.theme.css');
$theme_rtl_pos = strpos($styles, $path . '/system.theme-rtl.css');
$this->assert($theme_rtl_pos !== FALSE, 'CSS is alterable as right to left overrides are added.');
$this->assert($theme_pos < $theme_rtl_pos, 'system.theme-rtl.css is added after system.theme.css.');
// Change the language back to left to right.
$language->direction = LANGUAGE_LTR;
//
// Tests rendering inline stylesheets through a full page request.
advagg_test_reset_statics();
$css = 'body { font-size: 254px; }';
// Inline CSS is minified unless 'preprocess' => FALSE is passed as a
// drupal_add_css() option.
$expected = 'body{font-size:254px;}';
// Create a node, using the PHP filter that tests drupal_add_css().
$php_format_id = 'php_code';
$settings = array(
'type' => 'page',
'body' => array(
LANGUAGE_NONE => array(
array(
'value' => t('This tests the inline CSS!') . "<?php drupal_add_css('$css', 'inline'); ?>",
'format' => $php_format_id,
),
),
),
'promote' => 1,
);
$node = $this->drupalCreateNode($settings);
// Fetch the page.
$this->drupalGet('node/' . $node->nid);
$this->assertRaw($expected, 'Inline stylesheets appear in the full page rendering.');
//
// Tests that the query string remains intact when adding CSS files that
// have query string parameters.
advagg_test_reset_statics();
$this->drupalGet('common-test/query-string');
$query_string = variable_get('css_js_query_string', '0');
$this->assertRaw(drupal_get_path('module', 'node') . '/node.css?' . $query_string, 'Query string was appended correctly to css.');
$this->assertRaw(drupal_get_path('module', 'node') . '/node-fake.css?arg1=value1&amp;arg2=value2', 'Query string not escaped on a URI.');
//
// Make the tests below more robust by explicitly setting the default theme
// and administrative theme that they expect.
theme_enable(array('bartik'));
variable_set('theme_default', 'bartik');
variable_set('admin_theme', 'seven');
// Test the theme callback when it is set to use an administrative theme.
advagg_test_reset_statics();
$this->drupalGet('menu-test/theme-callback/use-admin-theme');
$this->assertText('Custom theme: seven. Actual theme: seven.', 'The administrative theme can be correctly set in a theme callback.');
$this->assertRaw('seven/style.css', "The administrative theme's CSS appears on the page.");
//
// Test that the theme callback is properly inherited.
advagg_test_reset_statics();
$this->drupalGet('menu-test/theme-callback/use-admin-theme/inheritance');
$this->assertText('Custom theme: seven. Actual theme: seven. Theme callback inheritance is being tested.', 'Theme callback inheritance correctly uses the administrative theme.');
$this->assertRaw('seven/style.css', "The administrative theme's CSS appears on the page.");
//
// Test the theme callback when the site is in maintenance mode.
advagg_test_reset_statics();
variable_set('maintenance_mode', TRUE);
// For a regular user, the fact that the site is in maintenance mode means
// we expect the theme callback system to be bypassed entirely.
$this->drupalGet('menu-test/theme-callback/use-admin-theme');
$this->assertRaw('bartik/css/style.css', "The maintenance theme's CSS appears on the page.");
// An administrator, however, should continue to see the requested theme.
$admin_user = $this->drupalCreateUser(array('access site in maintenance mode'));
$this->drupalLogin($admin_user);
$this->drupalGet('menu-test/theme-callback/use-admin-theme');
$this->assertText('Custom theme: seven. Actual theme: seven.', 'The theme callback system is correctly triggered for an administrator when the site is in maintenance mode.');
$this->assertRaw('seven/style.css', "The administrative theme's CSS appears on the page.");
variable_set('maintenance_mode', FALSE);
//
// Test the theme callback when it is set to use an optional theme.
advagg_test_reset_statics();
// Request a theme that is not enabled.
$this->drupalGet('menu-test/theme-callback/use-stark-theme');
$this->assertText('Custom theme: NONE. Actual theme: bartik.', 'The theme callback system falls back on the default theme when a theme that is not enabled is requested.');
$this->assertRaw('bartik/css/style.css', "The default theme's CSS appears on the page.");
// Now enable the theme and request it again.
theme_enable(array('stark'));
$this->drupalGet('menu-test/theme-callback/use-stark-theme');
$this->assertText('Custom theme: stark. Actual theme: stark.', 'The theme callback system uses an optional theme once it has been enabled.');
$this->assertRaw('stark/layout.css', "The optional theme's CSS appears on the page.");
// Test the theme callback when it is set to use a theme that does not
// exist.
$this->drupalGet('menu-test/theme-callback/use-fake-theme');
$this->assertText('Custom theme: NONE. Actual theme: bartik.', 'The theme callback system falls back on the default theme when a theme that does not exist is requested.');
$this->assertRaw('bartik/css/style.css', "The default theme's CSS appears on the page.");
//
// Test the theme callback when no theme is requested.
advagg_test_reset_statics();
$this->drupalGet('menu-test/theme-callback/no-theme-requested');
$this->assertText('Custom theme: NONE. Actual theme: bartik.', 'The theme callback system falls back on the default theme when no theme is requested.');
$this->assertRaw('bartik/css/style.css', "The default theme's CSS appears on the page.");
//
// Test that hook_custom_theme() can control the theme of a page.
advagg_test_reset_statics();
// Trigger hook_custom_theme() to dynamically request the Stark theme for
// the requested page.
variable_set('menu_test_hook_custom_theme_name', 'stark');
theme_enable(array('stark'));
// Visit a page that does not implement a theme callback. The above request
// should be honored.
$this->drupalGet('menu-test/no-theme-callback');
$this->assertText('Custom theme: stark. Actual theme: stark.', 'The result of hook_custom_theme() is used as the theme for the current page.');
$this->assertRaw('stark/layout.css', "The Stark theme's CSS appears on the page.");
//
// Test that the theme callback wins out over hook_custom_theme().
advagg_test_reset_statics();
// Trigger hook_custom_theme() to dynamically request the Stark theme for
// the requested page.
variable_set('menu_test_hook_custom_theme_name', 'stark');
theme_enable(array('stark'));
// The menu "theme callback" should take precedence over a value set in
// hook_custom_theme().
$this->drupalGet('menu-test/theme-callback/use-admin-theme');
$this->assertText('Custom theme: seven. Actual theme: seven.', 'The result of hook_custom_theme() does not override what was set in a theme callback.');
$this->assertRaw('seven/style.css', "The Seven theme's CSS appears on the page.");
//
// Test css split file processing.
// Generate a massive css file.
$css_string = advagg_test_generate_selector_css(1000);
$css_string .= '@media print {' . advagg_test_generate_selector_css(1000) . '}';
$css_string .= advagg_test_generate_selector_css(1000);
$css_string .= '@media screen {' . advagg_test_generate_selector_css(1000) . '}';
$css_string .= advagg_test_generate_selector_css(1000);
$css_string .= '@media print {' . advagg_test_generate_selector_css(1000) . '}';
$css_string .= advagg_test_generate_selector_css(9000);
$css_string .= '@media print {' . advagg_test_generate_selector_css(9000) . '}';
$css_string .= advagg_test_generate_selector_css(9000);
$css_string .= '@media screen {' . advagg_test_generate_selector_css(9000) . '}';
$css_string .= '@media print {' . advagg_test_generate_selector_css(50) . '}';
$css_string .= '@media screen {' . advagg_test_generate_selector_css(50) . '}';
$css_string .= advagg_test_generate_selector_css(10);
$css_string .= '@media print {' . advagg_test_generate_selector_css(50) . '}';
$css_string .= '@media screen {' . advagg_test_generate_selector_css(50) . '}';
$css_string .= '@media print {' . advagg_test_generate_selector_css(50) . '}';
$css_string .= '@media screen {' . advagg_test_generate_selector_css(50) . '}';
$css_string .= advagg_test_generate_selector_css(10);
$css_string .= advagg_test_generate_selector_css(10);
$css_string .= advagg_test_generate_selector_css(10);
$css_string .= advagg_test_generate_selector_css(10);
$css_string .= advagg_test_generate_selector_css(15000);
$css_string .= '@media print {' . advagg_test_generate_selector_css(15000) . '}';
$css_string .= advagg_test_generate_selector_css(10);
$css_string .= advagg_test_generate_selector_css(10);
$css_string .= advagg_test_generate_selector_css(10);
$css_string .= advagg_test_generate_selector_css(10);
$css_string .= advagg_test_generate_selector_css(10);
$file_info = array(
// Use a file that exists but isn't actually being used here.
'data' => drupal_get_path('module', 'advagg') . '/tests/css_test_files/advagg.css',
);
$before_selector_count = advagg_count_css_selectors($css_string);
// Split the huge css file.
$parts = advagg_split_css_file($file_info, $css_string);
$after = '';
foreach ($parts as $part) {
// Get written file.
$after .= "\n" . (string) @advagg_file_get_contents($part['data']);
// Cleanup.
unlink($part['data']);
}
// Note that a diff of the text can not be used for this test. Counting
// selectors is close enough for now.
$after_selector_count = advagg_count_css_selectors($after);
$this->assertEqual($before_selector_count, $after_selector_count, t('Expected %before selectors, got %after.', array('%before' => $before_selector_count, '%after' => $after_selector_count)));
//
// Test css file processing.
advagg_test_reset_statics();
// Array of files to test living in 'advagg/tests/css_test_files/'.
// - Original: name.css
// - Unoptimized expected content: name.css.unoptimized.css
// - Optimized expected content: name.css.optimized.css
//
// File. Tests: css_input_without_import.css.
// - Stripped comments and white-space.
// - Retain white-space in selectors. (http://drupal.org/node/472820)
// - Retain pseudo-selectors. (http://drupal.org/node/460448)
//
// File. Tests: css_input_with_import.css.
// - Proper URLs in imported files. (http://drupal.org/node/265719)
// - A background image with relative paths, which must be rewritten.
// - The rewritten background image path must also be passed through
// file_create_url(). (https://drupal.org/node/1961340)
// - Imported files that are external (protocol-relative URL or not)
// should not be expanded. (https://drupal.org/node/2014851)
//
// File in sub-folder. Tests: css_subfolder/css_input_with_import.css.
// - CSS import path interpreted. (https://drupal.org/node/1198904)
// - Don't adjust data URIs (https://drupal.org/node/2142441)
//
// File. Tests: comment_hacks.css.
// - Retain comment hacks.
$testfiles = array(
'css_input_without_import.css',
'css_input_with_import.css',
'css_subfolder/css_input_with_import.css',
'comment_hacks.css',
);
$path = drupal_get_path('module', 'advagg') . '/tests/css_test_files';
foreach ($testfiles as $file) {
$file_path = $path . '/' . $file;
$file_url = $GLOBALS['base_url'] . '/' . $file_path;
$expected = advagg_file_get_contents($file_path . '.unoptimized.css');
$unoptimized_output = advagg_load_stylesheet($file_path, FALSE);
$this->assertEqual($unoptimized_output, $expected, format_string('Unoptimized CSS file has expected contents (@file)', array('@file' => $file)));
$expected = advagg_file_get_contents($file_path . '.optimized.css');
$expected = advagg_test_remove_sniffer_comments($expected);
$optimized_output = advagg_load_stylesheet($file_path, TRUE);
$this->assertEqual($optimized_output, $expected, format_string('Optimized CSS file has expected contents (@file)', array('@file' => $file)));
// Repeat the tests by accessing the stylesheets by URL.
$expected = advagg_file_get_contents($file_path . '.unoptimized.css');
$unoptimized_output_url = advagg_load_stylesheet($file_url, FALSE);
$this->assertEqual($unoptimized_output_url, $expected, format_string('Unoptimized CSS file (loaded from an URL) has expected contents (@file)', array('@file' => $file)));
$expected = advagg_file_get_contents($file_path . '.optimized.css');
$expected = advagg_test_remove_sniffer_comments($expected);
$optimized_output_url = advagg_load_stylesheet($file_url, TRUE);
$this->assertEqual($optimized_output_url, $expected, format_string('Optimized CSS file (loaded from an URL) has expected contents (@file)', array('@file' => $file)));
}
// File. Tests: charset*.css
// - Any @charaset declaration at the beginning of a file should be
// removed without breaking subsequent CSS.
$testfiles = array(
'charset.css',
'charset_newline.css',
'charset_sameline.css',
);
$path = drupal_get_path('module', 'advagg') . '/tests/css_test_files';
foreach ($testfiles as $file) {
$file_path = $path . '/' . $file;
$file_url = $GLOBALS['base_url'] . '/' . $file_path;
$expected = advagg_file_get_contents($file_path . '.optimized.css');
$expected = advagg_test_remove_sniffer_comments($expected);
$optimized_output = advagg_load_stylesheet($file_path, TRUE);
$this->assertEqual($optimized_output, $expected, format_string('Optimized CSS file has expected contents (@file)', array('@file' => $file)));
$expected = advagg_file_get_contents($file_path . '.optimized.css');
$expected = advagg_test_remove_sniffer_comments($expected);
$optimized_output_url = advagg_load_stylesheet($file_url, TRUE);
$this->assertEqual($optimized_output_url, $expected, format_string('Optimized CSS file (loaded from an URL) has expected contents (@file)', array('@file' => $file)));
}
// Set all to FALSE.
$GLOBALS['conf']['advagg_convert_absolute_to_relative_path'] = FALSE;
$GLOBALS['conf']['advagg_convert_absolute_to_protocol_relative_path'] = FALSE;
$GLOBALS['conf']['advagg_force_https_path'] = FALSE;
$GLOBALS['conf']['advagg_skip_file_create_url_inside_css'] = FALSE;
$settings_to_change = array(
'' => '',
'advagg_skip_file_create_url_inside_css' => TRUE,
'advagg_convert_absolute_to_relative_path' => TRUE,
'advagg_convert_absolute_to_protocol_relative_path' => TRUE,
'advagg_force_https_path' => TRUE,
);
$advagg_path = drupal_get_path('module', 'advagg');
$path = $advagg_path . '/tests/css_test_files';
foreach ($settings_to_change as $name => $value) {
$before = '';
if (!empty($name)) {
$before = variable_get($name, defined(strtoupper($name)) ? constant(strtoupper($name)) : NULL);
$GLOBALS['conf'][$name] = $value;
}
// File. Tests: advagg.css
// - Various url() tests.
// https://www.drupal.org/node/1514182
// https://www.drupal.org/node/1961340
// https://www.drupal.org/node/2362643
// https://www.drupal.org/node/2112067
$testfiles = array(
'advagg.css',
);
foreach ($testfiles as $testfile) {
$base_url_before = $GLOBALS['base_url'];
$GLOBALS['base_url'] = advagg_force_http_path($GLOBALS['base_url']);
$aggregate_settings = array(
'variables' => array(
'is_https' => FALSE,
'base_path' => ($GLOBALS['base_path'] === '/checkout/') ? $GLOBALS['base_path'] : $GLOBALS['base_path'] . 'advagg_base_path_test/',
'advagg_convert_absolute_to_relative_path' => $GLOBALS['conf']['advagg_convert_absolute_to_relative_path'],
'advagg_convert_absolute_to_protocol_relative_path' => $GLOBALS['conf']['advagg_convert_absolute_to_protocol_relative_path'],
'advagg_force_https_path' => $GLOBALS['conf']['advagg_force_https_path'],
'advagg_skip_file_create_url_inside_css' => $GLOBALS['conf']['advagg_skip_file_create_url_inside_css'],
),
);
if (module_exists('cdn')) {
$aggregate_settings['variables'][CDN_MODE_VARIABLE] = CDN_DISABLED;
$aggregate_settings['variables'][CDN_STATUS_VARIABLE] = CDN_DISABLED;
}
$file_path = $path . '/' . $testfile;
$files = array(
'file' => $file_path,
'external' => $GLOBALS['base_url'] . '/' . $file_path,
);
$expected = advagg_test_remove_sniffer_comments(advagg_file_get_contents($file_path . '.optimized.css'));
foreach ($files as $type => $file) {
$optimized_output = advagg_load_css_stylesheet($file, TRUE, $aggregate_settings);
$mode = 0;
if ($aggregate_settings['variables']['advagg_skip_file_create_url_inside_css'] && $type !== 'external') {
$mode = "01";
$optimized_output = str_replace($aggregate_settings['variables']['base_path'] . $advagg_path . '/', '', $optimized_output);
}
elseif (!$aggregate_settings['variables']['advagg_convert_absolute_to_relative_path']
&& !$aggregate_settings['variables']['advagg_convert_absolute_to_protocol_relative_path']
&& !$aggregate_settings['variables']['advagg_force_https_path']
) {
$mode = 4;
$optimized_output = str_replace('http://' . $_SERVER['HTTP_HOST'] . $aggregate_settings['variables']['base_path'] . $advagg_path . '/', '', $optimized_output);
}
elseif ($aggregate_settings['variables']['advagg_convert_absolute_to_protocol_relative_path']) {
$mode = 2;
$optimized_output = str_replace('//' . $_SERVER['HTTP_HOST'] . $aggregate_settings['variables']['base_path'] . $advagg_path . '/', '', $optimized_output);
}
elseif ($aggregate_settings['variables']['advagg_force_https_path']) {
$mode = 3;
$optimized_output = str_replace('https://' . $_SERVER['HTTP_HOST'] . $aggregate_settings['variables']['base_path'] . $advagg_path . '/', '', $optimized_output);
}
else {
$mode = 1;
$optimized_output = str_replace($aggregate_settings['variables']['base_path'] . $advagg_path . '/', '', $optimized_output);
}
$this->assertEqual($optimized_output, $expected, format_string("Optimized CSS file has expected contents (@file). Setting tested: @name; value before: @before, value after: @after.<br>mode: @mode. <p>!replacements</p> <p><code>!debug</code></p>", array(
'@file' => $file,
'@name' => $name,
'@before' => (is_bool($before) || strlen((string) $before) == 0) ? strtoupper(var_export($before, TRUE)) : $before,
'@after' => (is_bool($value) || strlen((string) $value) == 0) ? strtoupper(var_export($value, TRUE)) : $value,
'@mode' => $mode,
'!replacements' => "1: {$aggregate_settings['variables']['base_path']}{$advagg_path}/ <br> 2: //{$_SERVER['HTTP_HOST']}{$aggregate_settings['variables']['base_path']}{$advagg_path}/ <br> 3: https://{$_SERVER['HTTP_HOST']}{$aggregate_settings['variables']['base_path']}{$advagg_path}/ <br> 4: http://{$_SERVER['HTTP_HOST']}{$aggregate_settings['variables']['base_path']}{$advagg_path}/",
'!debug' => nl2br(str_replace(' ', '&nbsp;', $optimized_output)),
)));
$GLOBALS['base_url'] = $base_url_before;
}
}
if (!empty($name)) {
$GLOBALS['conf'][$name] = $before;
}
}
}
}
/**
* Tests for the JavaScript system.
*/
class AdvAggJavaScriptTestCase extends DrupalWebTestCase {
/**
* Store configured value for JavaScript preprocessing.
*
* @var bool
*/
protected $preprocessJs = NULL;
/**
* Provide information to the UI for this test.
*/
public static function getInfo() {
return array(
'name' => 'JavaScript',
'description' => 'Tests the JavaScript system.',
'group' => 'AdvAgg',
);
}
/**
* Install the advagg module and include needed files.
*/
public function setUp() {
// Enable Locale and SimpleTest in the test environment.
parent::setUp(array(
'locale',
'locale_test',
'simpletest',
'common_test',
'form_test',
'advagg',
'color',
));
// Include the advagg.module file.
drupal_load('module', 'advagg');
module_load_include('inc', 'advagg', 'advagg');
// Disable preprocessing.
$this->preprocessJs = variable_get('preprocess_js', 0);
variable_set('preprocess_js', 0);
// Reset before each test.
advagg_test_reset_statics();
// Set settings for testing.
$GLOBALS['conf']['advagg_convert_absolute_to_relative_path'] = FALSE;
$GLOBALS['conf']['advagg_convert_absolute_to_protocol_relative_path'] = FALSE;
$GLOBALS['conf']['advagg_force_https_path'] = FALSE;
$GLOBALS['conf']['advagg_mod_js_footer'] = 0;
}
/**
* Restore any variables we set.
*/
public function tearDown() {
// Restore configured value for JavaScript preprocessing.
variable_set('preprocess_js', $this->preprocessJs);
parent::tearDown();
}
/**
* Test the 'javascript_always_use_jquery' variable.
*/
public function testJavaScriptAlwaysUsejQuery() {
// The default front page of the site should use jQuery and other standard
// scripts and settings.
advagg_test_reset_statics();
$GLOBALS['conf']['advagg_convert_absolute_to_relative_path'] = FALSE;
$GLOBALS['conf']['advagg_convert_absolute_to_protocol_relative_path'] = FALSE;
$GLOBALS['conf']['advagg_force_https_path'] = FALSE;
$GLOBALS['conf']['advagg_mod_js_footer'] = 0;
$this->drupalGet('');
$this->assertRaw('misc/jquery.js', 'Default behavior: The front page of the site includes jquery.js.');
$this->assertRaw('misc/drupal.js', 'Default behavior: The front page of the site includes drupal.js.');
$this->assertRaw('Drupal.settings', 'Default behavior: The front page of the site includes Drupal settings.');
$this->assertRaw('basePath', 'Default behavior: The front page of the site includes the basePath Drupal setting.');
//
// The default front page should not use jQuery and other standard scripts
// and settings when the 'javascript_always_use_jquery' variable is set to
// FALSE.
advagg_test_reset_statics();
variable_set('javascript_always_use_jquery', FALSE);
$render_array = advagg_get_js();
$javascript = drupal_render($render_array);
$this->drupalGet('');
$this->assertNoRaw('misc/jquery.js', 'When "javascript_always_use_jquery" is FALSE: The front page of the site does not include jquery.js.');
$this->assertNoRaw('misc/drupal.js', 'When "javascript_always_use_jquery" is FALSE: The front page of the site does not include drupal.js.');
$this->assertNoRaw('Drupal.settings', 'When "javascript_always_use_jquery" is FALSE: The front page of the site does not include Drupal settings.');
$this->assertNoRaw('basePath', 'When "javascript_always_use_jquery" is FALSE: The front page of the site does not include the basePath Drupal setting.');
variable_del('javascript_always_use_jquery');
//
// When only settings have been added via drupal_add_js(), drupal_get_js()
// should still return jQuery and other standard scripts and settings.
advagg_test_reset_statics();
drupal_add_js(array('testJavaScriptSetting' => 'test'), 'setting');
$render_array = advagg_get_js();
$javascript = drupal_render($render_array);
$this->assertTrue(strpos($javascript, 'misc/jquery.js') !== FALSE, 'Default behavior: The JavaScript returned by drupal_get_js() when only settings have been added includes jquery.js.');
$this->assertTrue(strpos($javascript, 'misc/drupal.js') !== FALSE, 'Default behavior: The JavaScript returned by drupal_get_js() when only settings have been added includes drupal.js.');
$this->assertTrue(strpos($javascript, 'Drupal.settings') !== FALSE, 'Default behavior: The JavaScript returned by drupal_get_js() when only settings have been added includes Drupal.settings.');
$this->assertTrue(strpos($javascript, 'basePath') !== FALSE, 'Default behavior: The JavaScript returned by drupal_get_js() when only settings have been added includes the basePath Drupal setting.');
$this->assertTrue(strpos($javascript, 'testJavaScriptSetting') !== FALSE, 'Default behavior: The JavaScript returned by drupal_get_js() when only settings have been added includes the added Drupal settings.');
//
// When only settings have been added via drupal_add_js() and the
// 'javascript_always_use_jquery' variable is set to FALSE, drupal_get_js()
// should not return jQuery and other standard scripts and settings, nor
// should it return the requested settings (since they cannot actually be
// added to the page without jQuery).
advagg_test_reset_statics();
variable_set('javascript_always_use_jquery', FALSE);
drupal_add_js(array('testJavaScriptSetting' => 'test'), 'setting');
$render_array = advagg_get_js();
$javascript = drupal_render($render_array);
$this->assertTrue(strpos($javascript, 'misc/jquery.js') === FALSE, 'When "javascript_always_use_jquery" is FALSE: The JavaScript returned by drupal_get_js() when only settings have been added does not include jquery.js.');
$this->assertTrue(strpos($javascript, 'misc/drupal.js') === FALSE, 'When "javascript_always_use_jquery" is FALSE: The JavaScript returned by drupal_get_js() when only settings have been added does not include drupal.js.');
$this->assertTrue(strpos($javascript, 'Drupal.settings') === FALSE, 'When "javascript_always_use_jquery" is FALSE: The JavaScript returned by drupal_get_js() when only settings have been added does not include Drupal.settings.');
$this->assertTrue(strpos($javascript, 'basePath') === FALSE, 'When "javascript_always_use_jquery" is FALSE: The JavaScript returned by drupal_get_js() when only settings have been added does not include the basePath Drupal setting.');
$this->assertTrue(strpos($javascript, 'testJavaScriptSetting') === FALSE, 'When "javascript_always_use_jquery" is FALSE: The JavaScript returned by drupal_get_js() when only settings have been added does not include the added Drupal settings.');
variable_del('javascript_always_use_jquery');
//
// When a regular file has been added via drupal_add_js(), drupal_get_js()
// should return jQuery and other standard scripts and settings.
advagg_test_reset_statics();
drupal_add_js('misc/collapse.js');
$render_array = advagg_get_js();
$javascript = drupal_render($render_array);
$this->assertTrue(strpos($javascript, 'misc/jquery.js') !== FALSE, 'Default behavior: The JavaScript returned by drupal_get_js() when a custom JavaScript file has been added includes jquery.js.');
$this->assertTrue(strpos($javascript, 'misc/drupal.js') !== FALSE, 'Default behavior: The JavaScript returned by drupal_get_js() when a custom JavaScript file has been added includes drupal.js.');
$this->assertTrue(strpos($javascript, 'Drupal.settings') !== FALSE, 'Default behavior: The JavaScript returned by drupal_get_js() when a custom JavaScript file has been added includes Drupal.settings.');
$this->assertTrue(strpos($javascript, 'basePath') !== FALSE, 'Default behavior: The JavaScript returned by drupal_get_js() when a custom JavaScript file has been added includes the basePath Drupal setting.');
$this->assertTrue(strpos($javascript, 'misc/collapse.js') !== FALSE, 'Default behavior: The JavaScript returned by drupal_get_js() when a custom JavaScript file has been added includes the custom file.');
//
// When a regular file has been added via drupal_add_js() and the
// 'javascript_always_use_jquery' variable is set to FALSE, drupal_get_js()
// should still return jQuery and other standard scripts and settings
// (since the file is assumed to require jQuery by default).
advagg_test_reset_statics();
variable_set('javascript_always_use_jquery', FALSE);
drupal_add_js('misc/collapse.js');
$render_array = advagg_get_js();
$javascript = drupal_render($render_array);
$this->assertTrue(strpos($javascript, 'misc/jquery.js') !== FALSE, 'When "javascript_always_use_jquery" is FALSE: The JavaScript returned by drupal_get_js() when a custom JavaScript file has been added includes jquery.js.');
$this->assertTrue(strpos($javascript, 'misc/drupal.js') !== FALSE, 'When "javascript_always_use_jquery" is FALSE: The JavaScript returned by drupal_get_js() when a custom JavaScript file has been added includes drupal.js.');
$this->assertTrue(strpos($javascript, 'Drupal.settings') !== FALSE, 'When "javascript_always_use_jquery" is FALSE: The JavaScript returned by drupal_get_js() when a custom JavaScript file has been added includes Drupal.settings.');
$this->assertTrue(strpos($javascript, 'basePath') !== FALSE, 'When "javascript_always_use_jquery" is FALSE: The JavaScript returned by drupal_get_js() when a custom JavaScript file has been added includes the basePath Drupal setting.');
$this->assertTrue(strpos($javascript, 'misc/collapse.js') !== FALSE, 'When "javascript_always_use_jquery" is FALSE: The JavaScript returned by drupal_get_js() when a custom JavaScript file has been added includes the custom file.');
variable_del('javascript_always_use_jquery');
//
// When a file that does not require jQuery has been added via
// drupal_add_js(), drupal_get_js() should still return jQuery and other
// standard scripts and settings by default.
advagg_test_reset_statics();
drupal_add_js('misc/collapse.js', array('requires_jquery' => FALSE));
$render_array = advagg_get_js();
$javascript = drupal_render($render_array);
$this->assertTrue(strpos($javascript, 'misc/jquery.js') !== FALSE, 'Default behavior: The JavaScript returned by drupal_get_js() when a custom JavaScript file that does not require jQuery has been added includes jquery.js.');
$this->assertTrue(strpos($javascript, 'misc/drupal.js') !== FALSE, 'Default behavior: The JavaScript returned by drupal_get_js() when a custom JavaScript file that does not require jQuery has been added includes drupal.js.');
$this->assertTrue(strpos($javascript, 'Drupal.settings') !== FALSE, 'Default behavior: The JavaScript returned by drupal_get_js() when a custom JavaScript file that does not require jQuery has been added includes Drupal.settings.');
$this->assertTrue(strpos($javascript, 'basePath') !== FALSE, 'Default behavior: The JavaScript returned by drupal_get_js() when a custom JavaScript file that does not require jQuery has been added includes the basePath Drupal setting.');
$this->assertTrue(strpos($javascript, 'misc/collapse.js') !== FALSE, 'Default behavior: The JavaScript returned by drupal_get_js() when a custom JavaScript file that does not require jQuery has been added includes the custom file.');
//
// When a file that does not require jQuery has been added via
// drupal_add_js() and the 'javascript_always_use_jquery' variable is set
// to FALSE, drupal_get_js() should not return jQuery and other standard
// scripts and setting, but it should still return the requested file.
advagg_test_reset_statics();
variable_set('javascript_always_use_jquery', FALSE);
drupal_add_js('misc/collapse.js', array('requires_jquery' => FALSE));
$render_array = advagg_get_js();
$javascript = drupal_render($render_array);
$this->assertTrue(strpos($javascript, 'misc/jquery.js') === FALSE, 'When "javascript_always_use_jquery" is FALSE: The JavaScript returned by drupal_get_js() when a custom JavaScript file that does not require jQuery has been added does not include jquery.js.');
$this->assertTrue(strpos($javascript, 'misc/drupal.js') === FALSE, 'When "javascript_always_use_jquery" is FALSE: The JavaScript returned by drupal_get_js() when a custom JavaScript file that does not require jQuery has been added does not include drupal.js.');
$this->assertTrue(strpos($javascript, 'Drupal.settings') === FALSE, 'When "javascript_always_use_jquery" is FALSE: The JavaScript returned by drupal_get_js() when a custom JavaScript file that does not require jQuery has been added does not include Drupal.settings.');
$this->assertTrue(strpos($javascript, 'basePath') === FALSE, 'When "javascript_always_use_jquery" is FALSE: The JavaScript returned by drupal_get_js() when a custom JavaScript file that does not require jQuery has been added does not include the basePath Drupal setting.');
$this->assertTrue(strpos($javascript, 'misc/collapse.js') !== FALSE, 'When "javascript_always_use_jquery" is FALSE: The JavaScript returned by drupal_get_js() when a custom JavaScript file that does not require jQuery has been added includes the custom file.');
variable_del('javascript_always_use_jquery');
//
// When 'javascript_always_use_jquery' is set to FALSE and a file that does
// not require jQuery is added, followed by one that does, drupal_get_js()
// should return jQuery and other standard scripts and settings, in
// addition to both of the requested files.
advagg_test_reset_statics();
variable_set('javascript_always_use_jquery', FALSE);
drupal_add_js('misc/collapse.js', array('requires_jquery' => FALSE));
drupal_add_js('misc/ajax.js');
$render_array = advagg_get_js();
$javascript = drupal_render($render_array);
$this->assertTrue(strpos($javascript, 'misc/jquery.js') !== FALSE, 'When "javascript_always_use_jquery" is FALSE: The JavaScript returned by drupal_get_js() when at least one custom JavaScript file that requires jQuery has been added includes jquery.js.');
$this->assertTrue(strpos($javascript, 'misc/drupal.js') !== FALSE, 'When "javascript_always_use_jquery" is FALSE: The JavaScript returned by drupal_get_js() when at least one custom JavaScript file that requires jQuery has been added includes drupal.js.');
$this->assertTrue(strpos($javascript, 'Drupal.settings') !== FALSE, 'When "javascript_always_use_jquery" is FALSE: The JavaScript returned by drupal_get_js() when at least one custom JavaScript file that requires jQuery has been added includes Drupal.settings.');
$this->assertTrue(strpos($javascript, 'basePath') !== FALSE, 'When "javascript_always_use_jquery" is FALSE: The JavaScript returned by drupal_get_js() when at least one custom JavaScript file that requires jQuery has been added includes the basePath Drupal setting.');
$this->assertTrue(strpos($javascript, 'misc/collapse.js') !== FALSE, 'When "javascript_always_use_jquery" is FALSE: The JavaScript returned by drupal_get_js() when at least one custom JavaScript file that requires jQuery has been added includes the first custom file.');
$this->assertTrue(strpos($javascript, 'misc/ajax.js') !== FALSE, 'When "javascript_always_use_jquery" is FALSE: The JavaScript returned by drupal_get_js() when at least one custom JavaScript file that requires jQuery has been added includes the second custom file.');
variable_del('javascript_always_use_jquery');
//
// Tests JavaScript aggregation when files are added to a different scope.
advagg_test_reset_statics();
// Enable JavaScript aggregation.
variable_set('preprocess_js', 1);
// Add two JavaScript files to the current request and build the cache.
drupal_add_js('misc/ajax.js');
drupal_add_js('misc/autocomplete.js');
$js_items = drupal_add_js();
drupal_build_js_cache(array(
'misc/ajax.js' => $js_items['misc/ajax.js'],
'misc/autocomplete.js' => $js_items['misc/autocomplete.js'],
));
// Store the expected key for the first item in the cache.
$cache = array_keys(variable_get('drupal_js_cache_files', array()));
$expected_key = $cache[0];
// Reset variables and add a file in a different scope first.
variable_del('drupal_js_cache_files');
advagg_test_reset_statics();
drupal_add_js('some/custom/javascript_file.js', array('scope' => 'footer'));
drupal_add_js('misc/ajax.js');
drupal_add_js('misc/autocomplete.js');
// Rebuild the cache.
$js_items = drupal_add_js();
drupal_build_js_cache(array(
'misc/ajax.js' => $js_items['misc/ajax.js'],
'misc/autocomplete.js' => $js_items['misc/autocomplete.js'],
));
// Compare the expected key for the first file to the current one.
$cache = array_keys(variable_get('drupal_js_cache_files', array()));
$key = $cache[0];
$this->assertEqual($key, $expected_key, 'JavaScript aggregation is not affected by ordering in different scopes.');
variable_set('preprocess_js', 0);
//
// Test JavaScript ordering.
advagg_test_reset_statics();
// Add a bunch of JavaScript in strange ordering.
drupal_add_js('(function($){alert("Weight 5 #1");})(jQuery);', array(
'type' => 'inline',
'scope' => 'footer',
'weight' => 5,
));
drupal_add_js('(function($){alert("Weight 0 #1");})(jQuery);', array(
'type' => 'inline',
'scope' => 'footer',
));
drupal_add_js('(function($){alert("Weight 0 #2");})(jQuery);', array(
'type' => 'inline',
'scope' => 'footer',
));
drupal_add_js('(function($){alert("Weight -8 #1");})(jQuery);', array(
'type' => 'inline',
'scope' => 'footer',
'weight' => -8,
));
drupal_add_js('(function($){alert("Weight -8 #2");})(jQuery);', array(
'type' => 'inline',
'scope' => 'footer',
'weight' => -8,
));
drupal_add_js('(function($){alert("Weight -8 #3");})(jQuery);', array(
'type' => 'inline',
'scope' => 'footer',
'weight' => -8,
));
drupal_add_js('http://example.com/example.js?Weight -5 #1', array(
'type' => 'external',
'scope' => 'footer',
'weight' => -5,
));
drupal_add_js('(function($){alert("Weight -8 #4");})(jQuery);', array(
'type' => 'inline',
'scope' => 'footer',
'weight' => -8,
));
drupal_add_js('(function($){alert("Weight 5 #2");})(jQuery);', array(
'type' => 'inline',
'scope' => 'footer',
'weight' => 5,
));
drupal_add_js('(function($){alert("Weight 0 #3");})(jQuery);', array(
'type' => 'inline',
'scope' => 'footer',
));
// Construct the expected result from the regex.
$expected = array(
"-8 #1",
"-8 #2",
"-8 #3",
"-8 #4",
// -5 #1: The external script.
"-5 #1",
"0 #1",
"0 #2",
"0 #3",
"5 #1",
"5 #2",
);
// Retrieve the rendered JavaScript and test against the regex.
$render_array = advagg_get_js('footer');
$js = drupal_render($render_array);
$matches = array();
if (preg_match_all('/Weight\s([-0-9]+\s[#0-9]+)/', $js, $matches)) {
$result = $matches[1];
}
else {
$result = array();
}
$this->assertIdentical($result, $expected, 'JavaScript is added in the expected weight order.');
//
// Test default JavaScript is empty.
advagg_test_reset_statics();
$this->assertEqual(array(), drupal_add_js(), 'Default JavaScript is empty.');
//
// Test drupal_get_js() for JavaScript settings.
advagg_test_reset_statics();
// Only the second of these two entries should appear in Drupal.settings.
drupal_add_js(array('commonTest' => 'commonTestShouldNotAppear'), 'setting');
drupal_add_js(array('commonTest' => 'commonTestShouldAppear'), 'setting');
// All three of these entries should appear in Drupal.settings.
drupal_add_js(array('commonTestArray' => array('commonTestValue0')), 'setting');
drupal_add_js(array('commonTestArray' => array('commonTestValue1')), 'setting');
drupal_add_js(array('commonTestArray' => array('commonTestValue2')), 'setting');
// Only the second of these two entries should appear in Drupal.settings.
drupal_add_js(array('commonTestArray' => array('key' => 'commonTestOldValue')), 'setting');
drupal_add_js(array('commonTestArray' => array('key' => 'commonTestNewValue')), 'setting');
$render_array = advagg_get_js('header');
$javascript = drupal_render($render_array);
$this->assertTrue(strpos($javascript, 'basePath') > 0, 'Rendered JavaScript header returns basePath setting.');
$this->assertTrue(strpos($javascript, 'misc/jquery.js') > 0, 'Rendered JavaScript header includes jQuery.');
$this->assertTrue(strpos($javascript, 'pathPrefix') > 0, 'Rendered JavaScript header returns pathPrefix setting.');
// Test whether drupal_add_js can be used to override a previous setting.
$this->assertTrue(strpos($javascript, 'commonTestShouldAppear') > 0, 'Rendered JavaScript header returns custom setting.');
$this->assertTrue(strpos($javascript, 'commonTestShouldNotAppear') === FALSE, 'drupal_add_js() correctly overrides a custom setting.');
// Test whether drupal_add_js can be used to add numerically indexed values
// to an array.
$array_values_appear = strpos($javascript, 'commonTestValue0') > 0 && strpos($javascript, 'commonTestValue1') > 0 && strpos($javascript, 'commonTestValue2') > 0;
$this->assertTrue($array_values_appear, 'drupal_add_js() correctly adds settings to the end of an indexed array.');
// Test whether drupal_add_js can be used to override the entry for an
// existing key in an associative array.
$associative_array_override = strpos($javascript, 'commonTestNewValue') > 0 && strpos($javascript, 'commonTestOldValue') === FALSE;
$this->assertTrue($associative_array_override, 'drupal_add_js() correctly overrides settings within an associative array.');
//
// Test rendering an external JavaScript file.
advagg_test_reset_statics();
$GLOBALS['conf']['advagg_convert_absolute_to_relative_path'] = FALSE;
$GLOBALS['conf']['advagg_convert_absolute_to_protocol_relative_path'] = FALSE;
$GLOBALS['conf']['advagg_force_https_path'] = FALSE;
$external = 'http://example.com/example.js';
drupal_add_js($external, 'external');
$render_array = advagg_get_js();
$javascript = drupal_render($render_array);
// Local files have a base_path() prefix, external files should not.
$this->assertTrue(strpos($javascript, 'src="' . $external) > 0, 'Rendering an external JavaScript file.');
//
// Test drupal_get_js() with a footer scope.
advagg_test_reset_statics();
$inline = 'jQuery(function () { });';
drupal_add_js($inline, array('type' => 'inline', 'scope' => 'footer'));
$render_array = advagg_get_js('footer');
$javascript = drupal_render($render_array);
$this->assertTrue(strpos($javascript, $inline) > 0, 'Rendered JavaScript footer returns the inline code.');
//
// Ensures that vertical-tabs.js is included before collapse.js.
advagg_test_reset_statics();
$this->drupalGet('form_test/vertical-tabs');
$position1 = strpos($this->content, 'misc/vertical-tabs.js');
$position2 = strpos($this->content, 'misc/collapse.js');
$this->assertTrue($position1 !== FALSE && $position2 !== FALSE && $position1 < $position2, 'vertical-tabs.js is included before collapse.js');
//
// Test rendering the JavaScript with a file's weight above jQuery's.
advagg_test_reset_statics();
// JavaScript files are sorted first by group, then by the 'every_page'
// flag, then by weight (see drupal_sort_css_js()), so to test the effect of
// weight, we need the other two options to be the same.
drupal_add_js('misc/collapse.js', array(
'group' => JS_LIBRARY,
'every_page' => TRUE,
'weight' => -21,
));
$render_array = advagg_get_js();
$javascript = drupal_render($render_array);
$this->assertTrue(strpos($javascript, 'misc/collapse.js') < strpos($javascript, 'misc/jquery.js'), 'Rendering a JavaScript file above jQuery.');
//
// Test altering a JavaScript's weight via hook_js_alter().
advagg_test_reset_statics();
// Add both tableselect.js and simpletest.js, with a larger weight on
// SimpleTest.
drupal_add_js('misc/tableselect.js');
drupal_add_js(drupal_get_path('module', 'simpletest') . '/simpletest.js', array('weight' => 9999));
// Render the JavaScript, testing if simpletest.js was altered to be before
// tableselect.js. See simpletest_js_alter() to see where this alteration
// takes place.
$render_array = advagg_get_js();
$javascript = drupal_render($render_array);
$this->assertTrue(strpos($javascript, 'simpletest.js') < strpos($javascript, 'misc/tableselect.js'), 'Altering JavaScript weight through the alter hook.');
//
// Adds a library to the page and tests for both its JavaScript and its CSS.
advagg_test_reset_statics();
$result = drupal_add_library('system', 'farbtastic');
$this->assertTrue($result !== FALSE, 'Library was added without errors.');
$render_array = advagg_get_js();
$scripts = drupal_render($render_array);
$render_array = advagg_get_css();
$styles = drupal_render($render_array);
$this->assertTrue(strpos($scripts, 'misc/farbtastic/farbtastic.js'), 'JavaScript of library was added to the page.');
$this->assertTrue(strpos($styles, 'misc/farbtastic/farbtastic.css'), 'Stylesheet of library was added to the page.');
//
// Adds a JavaScript library to the page and alters it.
advagg_test_reset_statics();
// Verify that common_test altered the title of Farbtastic.
$library = drupal_get_library('system', 'farbtastic');
$this->assertEqual($library['title'], 'Farbtastic: Altered Library', 'Registered libraries were altered.');
// common_test_library_alter() also added a dependency on jQuery Form.
drupal_add_library('system', 'farbtastic');
$render_array = advagg_get_js();
$scripts = drupal_render($render_array);
$this->assertTrue(strpos($scripts, 'misc/jquery.form.js'), 'Altered library dependencies are added to the page.');
//
// Tests non-existing libraries.
advagg_test_reset_statics();
$result = drupal_get_library('unknown', 'unknown');
$this->assertFalse($result, 'Unknown library returned FALSE.');
advagg_test_reset_statics();
$result = drupal_add_library('unknown', 'unknown');
$this->assertFalse($result, 'Unknown library returned FALSE.');
$render_array = advagg_get_js();
$scripts = drupal_render($render_array);
$this->assertTrue(strpos($scripts, 'unknown') === FALSE, 'Unknown library was not added to the page.');
//
// Tests the addition of libraries through the #attached['library']
// property.
advagg_test_reset_statics();
$element['#attached']['library'][] = array('system', 'farbtastic');
drupal_render($element);
$render_array = advagg_get_js();
$scripts = drupal_render($render_array);
$this->assertTrue(strpos($scripts, 'misc/farbtastic/farbtastic.js'), 'The attached_library property adds the additional libraries.');
//
// Test #attached functionality in children elements.
advagg_test_reset_statics();
// The cache system is turned off for POST requests.
$request_method = $_SERVER['REQUEST_METHOD'];
$_SERVER['REQUEST_METHOD'] = 'GET';
// Create an element with a child and subchild. Each element loads a
// different JavaScript file using #attached.
$parent_js = drupal_get_path('module', 'user') . '/user.js';
$child_js = drupal_get_path('module', 'color') . '/color.js';
$subchild_js = drupal_get_path('module', 'book') . '/book.js';
$element = array(
'#type' => 'fieldset',
'#cache' => array(
'keys' => array('simpletest', 'drupal_render', 'children_attached'),
),
'#attached' => array('js' => array($parent_js)),
'#title' => 'Parent',
);
$element['child'] = array(
'#type' => 'fieldset',
'#attached' => array('js' => array($child_js)),
'#title' => 'Child',
);
$element['child']['subchild'] = array(
'#attached' => array('js' => array($subchild_js)),
'#markup' => 'Subchild',
);
// Render the element and verify the presence of #attached JavaScript.
drupal_render($element);
$render_array = advagg_get_js();
$scripts = drupal_render($render_array);
$this->assertTrue(strpos($scripts, $parent_js), 'The element #attached JavaScript was included.');
$this->assertTrue(strpos($scripts, $child_js), 'The child #attached JavaScript was included.');
$this->assertTrue(strpos($scripts, $subchild_js), 'The subchild #attached JavaScript was included.');
// Load the element from cache and verify the presence of the #attached
// JavaScript.
advagg_test_reset_statics();
$this->assertTrue(drupal_render_cache_get($element), 'The element was retrieved from cache.');
$render_array = advagg_get_js();
$scripts = drupal_render($render_array);
$this->assertTrue(strpos($scripts, $parent_js), 'The element #attached JavaScript was included when loading from cache.');
$this->assertTrue(strpos($scripts, $child_js), 'The child #attached JavaScript was included when loading from cache.');
$this->assertTrue(strpos($scripts, $subchild_js), 'The subchild #attached JavaScript was included when loading from cache.');
$_SERVER['REQUEST_METHOD'] = $request_method;
//
// Tests the localisation of JavaScript libraries. Verifies that the
// datepicker can be localized.
advagg_test_reset_statics();
drupal_add_library('system', 'ui.datepicker');
$GLOBALS['conf']['advagg_mod_js_footer'] = 0;
$render_array = advagg_get_js();
$javascript = drupal_render($render_array);
$this->assertTrue(strpos($javascript, 'locale.datepicker.js'), 'locale.datepicker.js added to scripts.');
//
// Functional tests for JavaScript parsing for translatable strings.
// Tests parsing js files for translatable strings.
advagg_test_reset_statics();
$filename = drupal_get_path('module', 'locale_test') . '/locale_test.js';
// Parse the file to look for source strings.
_locale_parse_js_file($filename);
// Get all of the source strings that were found.
$source_strings = db_select('locales_source', 's')
->fields('s', array('source', 'context'))
->condition('s.location', $filename)
->execute()
->fetchAllKeyed();
// List of all strings that should be in the file.
$test_strings = array(
"Standard Call t" => '',
"Whitespace Call t" => '',
"Single Quote t" => '',
"Single Quote \\'Escaped\\' t" => '',
"Single Quote Concat strings t" => '',
"Double Quote t" => '',
"Double Quote \\\"Escaped\\\" t" => '',
"Double Quote Concat strings t" => '',
"Context !key Args t" => "Context string",
"Context Unquoted t" => "Context string unquoted",
"Context Single Quoted t" => "Context string single quoted",
"Context Double Quoted t" => "Context string double quoted",
"Standard Call plural" => '',
"Standard Call @count plural" => '',
"Whitespace Call plural" => '',
"Whitespace Call @count plural" => '',
"Single Quote plural" => '',
"Single Quote @count plural" => '',
"Single Quote \\'Escaped\\' plural" => '',
"Single Quote \\'Escaped\\' @count plural" => '',
"Double Quote plural" => '',
"Double Quote @count plural" => '',
"Double Quote \\\"Escaped\\\" plural" => '',
"Double Quote \\\"Escaped\\\" @count plural" => '',
"Context !key Args plural" => "Context string",
"Context !key Args @count plural" => "Context string",
"Context Unquoted plural" => "Context string unquoted",
"Context Unquoted @count plural" => "Context string unquoted",
"Context Single Quoted plural" => "Context string single quoted",
"Context Single Quoted @count plural" => "Context string single quoted",
"Context Double Quoted plural" => "Context string double quoted",
"Context Double Quoted @count plural" => "Context string double quoted",
);
// Assert that all strings were found properly.
foreach ($test_strings as $str => $context) {
$args = array('%source' => $str, '%context' => $context);
// Make sure that the string was found in the file.
$this->assertTrue(isset($source_strings[$str]), format_string('Found source string: %source', $args));
// Make sure that the proper context was matched.
$this->assertTrue(isset($source_strings[$str]) && $source_strings[$str] === $context, strlen($context) > 0 ? format_string('Context for %source is %context', $args) : format_string('Context for %source is blank', $args));
}
$this->assertEqual(count($source_strings), count($test_strings), 'Found correct number of source strings.');
//
// Adds a language and checks that the JavaScript translation files are
// properly created and rebuilt on deletion.
$user = $this->drupalCreateUser(array(
'translate interface',
'administer languages',
'access administration pages',
));
$this->drupalLogin($user);
$langcode = 'xx';
// The English name for the language. This will be translated.
$name = $this->randomName(16);
// The native name for the language.
$native = $this->randomName(16);
// The domain prefix.
$prefix = $langcode;
// Add custom language.
$edit = array(
'langcode' => $langcode,
'name' => $name,
'native' => $native,
'prefix' => $prefix,
'direction' => '0',
);
$this->drupalPost('admin/config/regional/language/add', $edit, t('Add custom language'));
drupal_static_reset('language_list');
// Build the JavaScript translation file.
$this->drupalGet('admin/config/regional/translate/translate');
// Retrieve the id of the first string available in the {locales_source}
// table and translate it.
$query = db_select('locales_source', 'l');
$query->addExpression('min(l.lid)', 'lid');
$result = $query->condition('l.location', '%.js%', 'LIKE')
->condition('l.textgroup', 'default')
->execute();
$url = 'admin/config/regional/translate/edit/' . $result->fetchObject()->lid;
$edit = array('translations[' . $langcode . ']' => $this->randomName());
$this->drupalPost($url, $edit, t('Save translations'));
// Trigger JavaScript translation parsing and building.
require_once DRUPAL_ROOT . '/includes/locale.inc';
_locale_rebuild_js($langcode);
// Retrieve the JavaScript translation hash code for the custom language to
// check that the translation file has been properly built.
$file = db_select('languages', 'l')
->fields('l', array('javascript'))
->condition('language', $langcode)
->execute()
->fetchObject();
$js_file = 'public://' . variable_get('locale_js_directory', 'languages') . '/' . $langcode . '_' . $file->javascript . '.js';
$this->assertTrue($result = file_exists($js_file), format_string('JavaScript file created: %file', array('%file' => $result ? $js_file : 'not found')));
// Test JavaScript translation rebuilding.
file_unmanaged_delete($js_file);
$this->assertTrue($result = !file_exists($js_file), format_string('JavaScript file deleted: %file', array('%file' => $result ? $js_file : 'found')));
cache_clear_all();
_locale_rebuild_js($langcode);
$this->assertTrue($result = file_exists($js_file), format_string('JavaScript file rebuilt: %file', array('%file' => $result ? $js_file : 'not found')));
}
}
/**
* Unit tests for the Theme API.
*/
class AdvAggThemeTestCase extends AJAXTestCase {
/**
* Provide information to the UI for this test.
*/
public static function getInfo() {
return array(
'name' => 'Theme API and AJAX',
'description' => 'Test low-level theme functions and AJAX framework functions and commands.',
'group' => 'AdvAgg',
);
}
/**
* Install the advagg module and include needed files.
*/
public function setUp() {
parent::setUp(array('advagg'));
// Include the advagg.module file.
drupal_load('module', 'advagg');
module_load_include('inc', 'advagg', 'advagg');
module_enable(array('theme_test'));
theme_enable(array('test_theme'));
// Reset before each test.
advagg_test_reset_statics();
// Set settings for testing.
$GLOBALS['conf']['advagg_convert_absolute_to_relative_path'] = FALSE;
$GLOBALS['conf']['advagg_convert_absolute_to_protocol_relative_path'] = FALSE;
$GLOBALS['conf']['advagg_force_https_path'] = FALSE;
}
/**
* Check theme and ajax functions and commands.
*/
public function testCssOverride() {
// Ensures a theme's .info file is able to override a module CSS file from
// being added to the page.
advagg_test_reset_statics();
// Reuse the same page as in testPreprocessForSuggestions(). We're testing
// what is output to the HTML HEAD based on what is in a theme's .info file,
// so it doesn't matter what page we get, as long as it is themed with the
// test theme. First we test with CSS aggregation disabled.
$GLOBALS['conf']['preprocess_css'] = 0;
variable_set('preprocess_css', 0);
$this->drupalGet('theme-test/suggestion');
$this->assertNoText('system.base.css', 'The theme\'s .info file is able to override a module CSS file from being added to the page.');
// Also test with aggregation enabled, simply ensuring no PHP errors are
// triggered during drupal_build_css_cache() when a source file doesn't
// exist. Then allow remaining tests to continue with aggregation disabled
// by default.
variable_set('preprocess_css', 1);
$this->drupalGet('theme-test/suggestion');
variable_set('preprocess_css', 0);
//
// Test ajax and js settings.
advagg_test_reset_statics();
$commands = $this->drupalGetAJAX('ajax-test/render');
// Verify that there is a command to load settings added with
// drupal_add_js().
$expected = array(
'command' => 'settings',
'settings' => array('basePath' => base_path(), 'ajax' => 'test'),
);
$this->assertCommand($commands, $expected, t('ajax_render() loads settings added with drupal_add_js().'));
// Verify that Ajax settings are loaded for #type 'link'.
$this->drupalGet('ajax-test/link');
$settings = $this->drupalGetSettings();
$this->assertEqual($settings['ajax']['ajax-link']['url'], url('filter/tips'));
$this->assertEqual($settings['ajax']['ajax-link']['wrapper'], 'block-system-main');
//
// Test behavior of ajax_render_error().
// Reset before each test.
advagg_test_reset_statics();
// Verify default error message.
$commands = $this->drupalGetAJAX('ajax-test/render-error');
$expected = array(
'command' => 'alert',
'text' => t('An error occurred while handling the request: The server received invalid input.'),
);
$this->assertCommand($commands, $expected, t('ajax_render_error() invokes alert command.'));
// Verify custom error message.
$edit = array(
'message' => 'Custom error message.',
);
$commands = $this->drupalGetAJAX('ajax-test/render-error', array('query' => $edit));
$expected = array(
'command' => 'alert',
'text' => $edit['message'],
);
$this->assertCommand($commands, $expected, t('Custom error message is output.'));
//
// Test that new JavaScript and CSS files added during an AJAX request are
// returned.
// Reset before each test.
advagg_test_reset_statics();
$expected = array(
'setting_name' => 'ajax_forms_test_lazy_load_form_submit',
'setting_value' => 'executed',
'css' => drupal_get_path('module', 'system') . '/system.admin.css',
'js' => drupal_get_path('module', 'system') . '/system.js',
);
// @todo D8: Add a drupal_css_defaults() helper function.
$expected_css_render_array = advagg_get_css(array(
$expected['css'] => array(
'type' => 'file',
'group' => CSS_DEFAULT,
'weight' => 0,
'every_page' => FALSE,
'media' => 'all',
'preprocess' => TRUE,
'data' => $expected['css'],
'browsers' => array('IE' => TRUE, '!IE' => TRUE),
),
), TRUE);
$expected_css_html = drupal_render($expected_css_render_array);
$expected_js_render_array = advagg_get_js('header', array($expected['js'] => drupal_js_defaults($expected['js'])), TRUE);
$expected_js_html = drupal_render($expected_js_render_array);
// 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']]), t('Page originally lacks the %setting, as expected.', array('%setting' => $expected['setting_name'])));
$this->assertTrue(!isset($original_settings[$expected['css']]), t('Page originally lacks the %css file, as expected.', array('%css' => $expected['css'])));
$this->assertTrue(!isset($original_settings[$expected['js']]), t('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();
// Verify the setting was not added when not expected.
$this->assertTrue(!isset($new_settings['setting_name']), t('Page still lacks the %setting, as expected.', array('%setting' => $expected['setting_name'])));
// Verify a settings command does not add CSS or scripts to Drupal.settings
// 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, t('Page state still lacks the %css and %js files, as expected.', array('%css' => $expected['css'], '%js' => $expected['js'])));
$this->assertFalse($found_markup_command, t('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.
$this->assertIdentical($new_settings[$expected['setting_name']], $expected['setting_value'], t('Page now has the %setting.', array('%setting' => $expected['setting_name'])));
// Verify the expected CSS file was added, both to Drupal.settings, and as
// an AJAX command for inclusion into the HTML.
$this->assertEqual($new_css, $original_css + array($expected['css'] => 1), t('Page state now has the %css file.', array('%css' => $expected['css'])));
$this->assertCommand($commands, array('data' => $expected_css_html), t('Page now has the %css file.', array('%css' => $expected['css'])));
// Verify the expected JS file was added, both to Drupal.settings, and as
// an 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.
$this->assertEqual($new_js, $original_js + array($expected['js'] => 1), t('Page state now has the %js file.', array('%js' => $expected['js'])));
$this->assertCommand($commands, array('data' => $expected_js_html), t('Page now has the %js file.', array('%js' => $expected['js'])));
//
// Tests that overridden CSS files are not added during lazy load.
// Reset before each test.
advagg_test_reset_statics();
// The test theme overrides system.base.css without an implementation,
// thereby removing it.
theme_enable(array('test_theme'));
variable_set('theme_default', 'test_theme');
// This gets the form, and emulates an Ajax submission on it, including
// adding markup to the HEAD and BODY for any lazy loaded JS/CSS files.
$this->drupalPostAJAX('ajax_forms_test_lazy_load_form', array('add_files' => TRUE), array('op' => t('Submit')));
// Verify that the resulting HTML does not load the overridden CSS file.
// We add a "?" to the assertion, because Drupal.settings may include
// information about the file; we only really care about whether it appears
// in a LINK or STYLE tag, for which Drupal always adds a query string for
// cache control.
$this->assertNoText('system.base.css?', 'Ajax lazy loading does not add overridden CSS files.');
//
// Test the various Ajax Commands.
// Reset before each test.
advagg_test_reset_statics();
$form_path = 'ajax_forms_test_ajax_commands_form';
$web_user = $this->drupalCreateUser(array('access content'));
$this->drupalLogin($web_user);
$edit = array();
// Tests the 'after' command.
$commands = $this->drupalPostAJAX($form_path, $edit, array('op' => t("AJAX 'After': Click to put something after the div")));
$expected = array(
'command' => 'insert',
'method' => 'after',
'data' => 'This will be placed after',
);
$this->assertCommand($commands, $expected, "'after' AJAX command issued with correct data");
// Tests the 'alert' command.
$commands = $this->drupalPostAJAX($form_path, $edit, array('op' => t("AJAX 'Alert': Click to alert")));
$expected = array(
'command' => 'alert',
'text' => 'Alert',
);
$this->assertCommand($commands, $expected, "'alert' AJAX Command issued with correct text");
// Tests the 'append' command.
$commands = $this->drupalPostAJAX($form_path, $edit, array('op' => t("AJAX 'Append': Click to append something")));
$expected = array(
'command' => 'insert',
'method' => 'append',
'data' => 'Appended text',
);
$this->assertCommand($commands, $expected, "'append' AJAX command issued with correct data");
// Tests the 'before' command.
$commands = $this->drupalPostAJAX($form_path, $edit, array('op' => t("AJAX 'before': Click to put something before the div")));
$expected = array(
'command' => 'insert',
'method' => 'before',
'data' => 'Before text',
);
$this->assertCommand($commands, $expected, "'before' AJAX command issued with correct data");
// Tests the 'changed' command.
$commands = $this->drupalPostAJAX($form_path, $edit, array('op' => t("AJAX changed: Click to mark div changed.")));
$expected = array(
'command' => 'changed',
'selector' => '#changed_div',
);
$this->assertCommand($commands, $expected, "'changed' AJAX command issued with correct selector");
// Tests the 'changed' command using the second argument.
$commands = $this->drupalPostAJAX($form_path, $edit, array('op' => t("AJAX changed: Click to mark div changed with asterisk.")));
$expected = array(
'command' => 'changed',
'selector' => '#changed_div',
'asterisk' => '#changed_div_mark_this',
);
$this->assertCommand($commands, $expected, "'changed' AJAX command (with asterisk) issued with correct selector");
// Tests the 'css' command.
$commands = $this->drupalPostAJAX($form_path, $edit, array('op' => t("Set the '#box' div to be blue.")));
$expected = array(
'command' => 'css',
'selector' => '#css_div',
'argument' => array('background-color' => 'blue'),
);
$this->assertCommand($commands, $expected, "'css' AJAX command issued with correct selector");
// Tests the 'data' command.
$commands = $this->drupalPostAJAX($form_path, $edit, array('op' => t("AJAX data command: Issue command.")));
$expected = array(
'command' => 'data',
'name' => 'testkey',
'value' => 'testvalue',
);
$this->assertCommand($commands, $expected, "'data' AJAX command issued with correct key and value");
// Tests the 'invoke' command.
$commands = $this->drupalPostAJAX($form_path, $edit, array('op' => t("AJAX invoke command: Invoke addClass() method.")));
$expected = array(
'command' => 'invoke',
'method' => 'addClass',
'arguments' => array('error'),
);
$this->assertCommand($commands, $expected, "'invoke' AJAX command issued with correct method and argument");
// Tests the 'html' command.
$commands = $this->drupalPostAJAX($form_path, $edit, array('op' => t("AJAX html: Replace the HTML in a selector.")));
$expected = array(
'command' => 'insert',
'method' => 'html',
'data' => 'replacement text',
);
$this->assertCommand($commands, $expected, "'html' AJAX command issued with correct data");
// Tests the 'insert' command.
$commands = $this->drupalPostAJAX($form_path, $edit, array('op' => t("AJAX insert: Let client insert based on #ajax['method'].")));
$expected = array(
'command' => 'insert',
'data' => 'insert replacement text',
);
$this->assertCommand($commands, $expected, "'insert' AJAX command issued with correct data");
// Tests the 'prepend' command.
$commands = $this->drupalPostAJAX($form_path, $edit, array('op' => t("AJAX 'prepend': Click to prepend something")));
$expected = array(
'command' => 'insert',
'method' => 'prepend',
'data' => 'prepended text',
);
$this->assertCommand($commands, $expected, "'prepend' AJAX command issued with correct data");
// Tests the 'remove' command.
$commands = $this->drupalPostAJAX($form_path, $edit, array('op' => t("AJAX 'remove': Click to remove text")));
$expected = array(
'command' => 'remove',
'selector' => '#remove_text',
);
$this->assertCommand($commands, $expected, "'remove' AJAX command issued with correct command and selector");
// Tests the 'restripe' command.
$commands = $this->drupalPostAJAX($form_path, $edit, array('op' => t("AJAX 'restripe' command")));
$expected = array(
'command' => 'restripe',
'selector' => '#restripe_table',
);
$this->assertCommand($commands, $expected, "'restripe' AJAX command issued with correct selector");
// Tests the 'settings' command.
$commands = $this->drupalPostAJAX($form_path, $edit, array('op' => t("AJAX 'settings' command")));
$expected = array(
'command' => 'settings',
'settings' => array('ajax_forms_test' => array('foo' => 42)),
);
$this->assertCommand($commands, $expected, "'settings' AJAX command issued with correct data");
// Tests the 'add_css' command.
$commands = $this->drupalPostAJAX($form_path, $edit, array('op' => t("AJAX 'add_css' command")));
$expected = array(
'command' => 'add_css',
'data' => 'my/file.css',
);
$this->assertCommand($commands, $expected, "'add_css' AJAX command issued with correct data");
}
}
/**
* @} End of "defgroup advagg_tests".
*/