CascadingStylesheetsTest.php 6.94 KB
Newer Older
1 2 3 4 5 6 7 8 9
<?php

/**
 * @file
 * Definition of Drupal\system\Tests\Common\CascadingStylesheetsTest.
 */

namespace Drupal\system\Tests\Common;

10
use Drupal\Core\Language\Language;
11
use Drupal\simpletest\DrupalUnitTestBase;
12 13 14 15

/**
 * Tests the Drupal CSS system.
 */
16
class CascadingStylesheetsTest extends DrupalUnitTestBase {
17 18 19 20 21 22

  /**
   * Modules to enable.
   *
   * @var array
   */
23
  public static $modules = array('language', 'system');
24

25 26 27 28 29 30 31 32 33
  public static function getInfo() {
    return array(
      'name' => 'Cascading stylesheets',
      'description' => 'Tests adding various cascading stylesheets to the page.',
      'group' => 'Common',
    );
  }

  function setUp() {
34
    parent::setUp();
35 36
    // Reset _drupal_add_css() before each test.
    drupal_static_reset('_drupal_add_css');
37 38 39
  }

  /**
40
   * Checks that default stylesheets are empty.
41 42
   */
  function testDefault() {
43
    $this->assertEqual(array(), _drupal_add_css(), 'Default CSS is empty.');
44 45 46 47 48 49
  }

  /**
   * Tests adding a file stylesheet.
   */
  function testAddFile() {
50
    $path = drupal_get_path('module', 'simpletest') . '/css/simpletest.module.css';
51
    $css = _drupal_add_css($path);
52
    $this->assertEqual($css['simpletest.module.css']['data'], $path);
53 54 55 56 57 58 59
  }

  /**
   * Tests adding an external stylesheet.
   */
  function testAddExternal() {
    $path = 'http://example.com/style.css';
60
    $css = _drupal_add_css($path, 'external');
61
    $this->assertEqual($css[$path]['type'], 'external', 'Adding an external CSS file caches it properly.');
62 63 64
  }

  /**
65
   * Makes sure that resetting the CSS empties the cache.
66 67
   */
  function testReset() {
68 69
    drupal_static_reset('_drupal_add_css');
    $this->assertEqual(array(), _drupal_add_css(), 'Resetting the CSS empties the cache.');
70 71 72 73 74 75
  }

  /**
   * Tests rendering the stylesheets.
   */
  function testRenderFile() {
76
    $css = drupal_get_path('module', 'simpletest') . '/css/simpletest.module.css';
77
    _drupal_add_css($css);
78
    $styles = drupal_get_css();
79
    $this->assertTrue(strpos($styles, $css) > 0, 'Rendered CSS includes the added stylesheet.');
80
    // Verify that newlines are properly added inside style tags.
81
    $query_string = $this->container->get('state')->get('system.css_js_query_string') ?: '0';
82
    $css_processed = '<link rel="stylesheet" href="' . check_plain(file_create_url($css)) . "?" . $query_string . '" media="all" />';
83
    $this->assertEqual(trim($styles), $css_processed, 'Rendered CSS includes newlines inside style tags for JavaScript use.');
84 85 86 87 88 89 90
  }

  /**
   * Tests rendering an external stylesheet.
   */
  function testRenderExternal() {
    $css = 'http://example.com/style.css';
91
    _drupal_add_css($css, 'external');
92 93 94
    $styles = drupal_get_css();
    // Stylesheet URL may be the href of a LINK tag or in an @import statement
    // of a STYLE tag.
95
    $this->assertTrue(strpos($styles, 'href="' . $css) > 0 || strpos($styles, '@import url("' . $css . '")') > 0, 'Rendering an external CSS file.');
96 97 98 99 100 101
  }

  /**
   * Tests rendering inline stylesheets with preprocessing on.
   */
  function testRenderInlinePreprocess() {
102 103 104 105
    // Turn on CSS aggregation to allow for preprocessing.
    $config = $this->container->get('config.factory')->get('system.performance');
    $config->set('css.preprocess', 1);

106
    $css = 'body { padding: 0px; }';
107
    $css_preprocessed = '<style media="all">' . "\n/* <![CDATA[ */\n" . "body{padding:0px;}\n" . "\n/* ]]> */\n" . '</style>';
108
    _drupal_add_css($css, array('type' => 'inline'));
109
    $styles = drupal_get_css();
110
    $this->assertEqual(trim($styles), $css_preprocessed, 'Rendering preprocessed inline CSS adds it to the page.');
111 112 113 114 115 116 117
  }

  /**
   * Tests rendering inline stylesheets with preprocessing off.
   */
  function testRenderInlineNoPreprocess() {
    $css = 'body { padding: 0px; }';
118
    _drupal_add_css($css, array('type' => 'inline', 'preprocess' => FALSE));
119
    $styles = drupal_get_css();
120
    $this->assertTrue(strpos($styles, $css) > 0, 'Rendering non-preprocessed inline CSS adds it to the page.');
121 122 123
  }

  /**
124
   * Tests CSS ordering.
125 126
   */
  function testRenderOrder() {
127
    // Load a module CSS file.
128
    _drupal_add_css(drupal_get_path('module', 'simpletest') . '/css/simpletest.module.css');
129 130
    // Load a few system CSS files in a custom, early-loading aggregate group.
    $test_aggregate_group = -100;
131
    $system_path = drupal_get_path('module', 'system');
132 133
    _drupal_add_css($system_path . '/css/system.module.css', array('group' => $test_aggregate_group, 'weight' => -10));
    _drupal_add_css($system_path . '/css/system.theme.css', array('group' => $test_aggregate_group));
134 135

    $expected = array(
136 137 138
      $system_path . '/css/system.module.css',
      $system_path . '/css/system.theme.css',
      drupal_get_path('module', 'simpletest') . '/css/simpletest.module.css',
139 140 141 142 143 144 145 146 147 148 149 150
    );

    $styles = drupal_get_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();
    }

151
    $this->assertIdentical($result, $expected, 'The CSS files are in the expected order.');
152 153 154
  }

  /**
155
   * Tests CSS override.
156 157 158 159
   */
  function testRenderOverride() {
    $system = drupal_get_path('module', 'system');

160 161
    _drupal_add_css($system . '/css/system.module.css');
    _drupal_add_css($system . '/tests/css/system.module.css');
162 163 164

    // The dummy stylesheet should be the only one included.
    $styles = drupal_get_css();
165 166
    $this->assert(strpos($styles, $system . '/tests/css/system.module.css') !== FALSE, 'The overriding CSS file is output.');
    $this->assert(strpos($styles, $system . '/css/system.module.css') === FALSE, 'The overridden CSS file is not output.');
167

168 169
    _drupal_add_css($system . '/tests/css/system.module.css');
    _drupal_add_css($system . '/css/system.module.css');
170 171 172

    // The standard stylesheet should be the only one included.
    $styles = drupal_get_css();
173 174
    $this->assert(strpos($styles, $system . '/css/system.module.css') !== FALSE, 'The overriding CSS file is output.');
    $this->assert(strpos($styles, $system . '/tests/css/system.module.css') === FALSE, 'The overridden CSS file is not output.');
175 176 177
  }

  /**
178
   * Tests that CSS query string remains intact when added to file.
179 180
   */
  function testAddCssFileWithQueryString() {
181 182
    $css_without_query_string = drupal_get_path('module', 'node') . '/css/node.admin.css';
    $css_with_query_string = '/' . drupal_get_path('module', 'node') . '/node-fake.css?arg1=value1&arg2=value2';
183 184
    _drupal_add_css($css_without_query_string);
    _drupal_add_css($css_with_query_string);
185 186

    $styles = drupal_get_css();
187
    $query_string = $this->container->get('state')->get('system.css_js_query_string') ?: '0';
188 189
    $this->assertTrue(strpos($styles, $css_without_query_string . '?' . $query_string), 'Query string was appended correctly to css.');
    $this->assertTrue(strpos($styles, str_replace('&', '&amp;', $css_with_query_string)), 'Query string not escaped on a URI.');
190 191
  }
}