-
Notifications
You must be signed in to change notification settings - Fork 4.3k
/
class-wp-style-engine-css-declarations-test.php
275 lines (248 loc) · 9.84 KB
/
class-wp-style-engine-css-declarations-test.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
<?php
/**
* Tests the Style Engine CSS declarations class.
*
* @package Gutenberg
* @subpackage style-engine
*/
/**
* Tests registering, storing and generating CSS declarations.
*
* @coversDefaultClass WP_Style_Engine_CSS_Declarations_Gutenberg
*/
class WP_Style_Engine_CSS_Declarations_Test extends WP_UnitTestCase {
/**
* Tests setting declarations on instantiation.
*
* @covers ::__construct
*/
public function test_should_instantiate_with_declarations() {
$input_declarations = array(
'margin-top' => '10px',
'font-size' => '2rem',
);
$css_declarations = new WP_Style_Engine_CSS_Declarations_Gutenberg( $input_declarations );
$this->assertSame( $input_declarations, $css_declarations->get_declarations() );
}
/**
* Tests that declarations are added.
*
* @covers ::add_declarations
* @covers ::add_declaration
*/
public function test_should_add_declarations() {
$input_declarations = array(
'padding' => '20px',
'color' => 'var(--wp--preset--elbow-patches)',
);
$css_declarations = new WP_Style_Engine_CSS_Declarations_Gutenberg();
$css_declarations->add_declarations( $input_declarations );
$this->assertSame( $input_declarations, $css_declarations->get_declarations() );
}
/**
* Tests that new declarations are added to existing declarations.
*
* @covers ::add_declarations
* @covers ::add_declaration
*/
public function test_should_add_new_declarations_to_existing() {
$input_declarations = array(
'border-width' => '1%',
'background-color' => 'var(--wp--preset--english-mustard)',
);
$css_declarations = new WP_Style_Engine_CSS_Declarations_Gutenberg( $input_declarations );
$extra_declaration = array(
'letter-spacing' => '1.5px',
);
$css_declarations->add_declarations( $extra_declaration );
$this->assertSame( array_merge( $input_declarations, $extra_declaration ), $css_declarations->get_declarations() );
}
/**
* Tests that properties are sanitized before storing.
*
* @covers ::filter_declaration
* @covers ::sanitize_property
*/
public function test_should_sanitize_properties() {
$input_declarations = array(
'^--wp--style--sleepy-potato$' => '40px',
'<background-//color>' => 'var(--wp--preset--english-mustard)',
);
$css_declarations = new WP_Style_Engine_CSS_Declarations_Gutenberg( $input_declarations );
$this->assertSame(
array(
'--wp--style--sleepy-potato' => '40px',
'background-color' => 'var(--wp--preset--english-mustard)',
),
$css_declarations->get_declarations()
);
}
/**
* Tests that values with HTML tags are escaped, and CSS properties are run through safecss_filter_attr().
*
* @covers ::get_declarations_string
* @covers ::filter_declaration
*/
public function test_should_strip_html_tags_and_remove_unsafe_css_properties() {
$input_declarations = array(
'font-size' => '<red/>',
'padding' => '</style>',
'potato' => 'uppercase',
'cheese' => '10px',
'margin-right' => '10em',
);
$css_declarations = new WP_Style_Engine_CSS_Declarations_Gutenberg( $input_declarations );
$safe_style_css_mock_action = new MockAction();
// filter_declaration() is called in get_declarations_string().
add_filter( 'safe_style_css', array( $safe_style_css_mock_action, 'filter' ) );
$css_declarations_string = $css_declarations->get_declarations_string();
$this->assertSame(
3, // Values with HTML tags are removed first by wp_strip_all_tags().
$safe_style_css_mock_action->get_call_count(),
'"safe_style_css" filters were not applied to CSS declaration properties.'
);
$this->assertSame(
'margin-right:10em;',
$css_declarations_string,
'Unallowed CSS properties or values with HTML tags were not removed.'
);
}
/**
* Tests that calc, clamp, min, max, minmax CSS functions and CSS custom properties are allowed.
*
* @covers ::get_declarations_string
* @covers ::filter_declaration
*/
public function test_should_allow_css_functions_and_custom_properties_and_strip_unsafe_css_values() {
$input_declarations = array(
'background' => 'var(--wp--preset--color--primary, 10px)', // Simple var().
'font-size' => 'clamp(36.00rem, calc(32.00rem + 10.00vw), 40.00rem)', // Nested clamp().
'width' => 'min(150vw, 100px)',
'min-width' => 'max(150vw, 100px)',
'max-width' => 'minmax(400px, 50%)',
'padding' => 'calc(80px * -1)',
'background-image' => 'url("https://wordpress.org")',
'line-height' => 'url("https://wordpress.org")',
'margin' => 'illegalfunction(30px)',
'--wp--style--unstable-gallery-gap' => '12em',
'/::border-[<width>]' => '2000.75em',
);
$css_declarations = new WP_Style_Engine_CSS_Declarations_Gutenberg( $input_declarations );
$safecss_filter_attr_allow_css_mock_action = new MockAction();
// filter_declaration() is called in get_declarations_string().
add_filter( 'safecss_filter_attr_allow_css', array( $safecss_filter_attr_allow_css_mock_action, 'filter' ) );
$css_declarations_string = $css_declarations->get_declarations_string();
$this->assertSame(
11,
$safecss_filter_attr_allow_css_mock_action->get_call_count(),
'"safecss_filter_attr_allow_css" filters were not applied to CSS declaration values.'
);
$this->assertSame(
'background:var(--wp--preset--color--primary, 10px);font-size:clamp(36.00rem, calc(32.00rem + 10.00vw), 40.00rem);width:min(150vw, 100px);min-width:max(150vw, 100px);max-width:minmax(400px, 50%);padding:calc(80px * -1);background-image:url("https://wordpress.org");--wp--style--unstable-gallery-gap:12em;border-width:2000.75em;',
$css_declarations_string,
'Unsafe values were not removed'
);
}
/**
* Tests that CSS declarations are compiled into a CSS declarations block string.
*
* @covers ::get_declarations_string
*
* @dataProvider data_should_compile_css_declarations_to_css_declarations_string
*
* @param string $expected The expected declarations block string.
* @param bool $should_prettify Optional. Whether to pretty the string. Default false.
* @param int $indent_count Optional. The number of tab indents. Default false.
*/
public function test_should_compile_css_declarations_to_css_declarations_string( $expected, $should_prettify = false, $indent_count = 0 ) {
$input_declarations = array(
'color' => 'red',
'border-top-left-radius' => '99px',
'text-decoration' => 'underline',
);
$css_declarations = new WP_Style_Engine_CSS_Declarations_Gutenberg( $input_declarations );
$this->assertSame(
$expected,
$css_declarations->get_declarations_string( $should_prettify, $indent_count )
);
}
/**
* Data provider for test_should_compile_css_declarations_to_css_declarations_string().
*
* @return array
*/
public function data_should_compile_css_declarations_to_css_declarations_string() {
return array(
'unprettified, no indent' => array(
'expected' => 'color:red;border-top-left-radius:99px;text-decoration:underline;',
),
'unprettified, one indent' => array(
'expected' => 'color:red;border-top-left-radius:99px;text-decoration:underline;',
'should_prettify' => false,
'indent_count' => 1,
),
'prettified, no indent' => array(
'expected' => 'color: red; border-top-left-radius: 99px; text-decoration: underline;',
'should_prettify' => true,
),
'prettified, one indent' => array(
'expected' => "\tcolor: red;\n\tborder-top-left-radius: 99px;\n\ttext-decoration: underline;",
'should_prettify' => true,
'indent_count' => 1,
),
'prettified, two indents' => array(
'expected' => "\t\tcolor: red;\n\t\tborder-top-left-radius: 99px;\n\t\ttext-decoration: underline;",
'should_prettify' => true,
'indent_count' => 2,
),
);
}
/**
* Tests removing a single declaration.
*
* @covers ::remove_declaration
*/
public function test_should_remove_single_declaration() {
$input_declarations = array(
'color' => 'tomato',
'margin' => '10em 10em 20em 1px',
'font-family' => 'Happy Font serif',
);
$css_declarations = new WP_Style_Engine_CSS_Declarations_Gutenberg( $input_declarations );
$this->assertSame(
'color:tomato;margin:10em 10em 20em 1px;font-family:Happy Font serif;',
$css_declarations->get_declarations_string(),
'CSS declarations string does not match the values of `$declarations` passed to the constructor.'
);
$css_declarations->remove_declaration( 'color' );
$this->assertSame(
'margin:10em 10em 20em 1px;font-family:Happy Font serif;',
$css_declarations->get_declarations_string(),
'Output after removing "color" declaration via `remove_declaration()` does not match expectations'
);
}
/**
* Tests that multiple declarations are removed.
*
* @covers ::remove_declarations
*/
public function test_should_remove_multiple_declarations() {
$input_declarations = array(
'color' => 'cucumber',
'margin' => '10em 10em 20em 1px',
'font-family' => 'Happy Font serif',
);
$css_declarations = new WP_Style_Engine_CSS_Declarations_Gutenberg( $input_declarations );
$this->assertSame(
'color:cucumber;margin:10em 10em 20em 1px;font-family:Happy Font serif;',
$css_declarations->get_declarations_string(),
'CSS declarations string does not match the values of `$declarations` passed to the constructor.'
);
$css_declarations->remove_declarations( array( 'color', 'margin' ) );
$this->assertSame(
'font-family:Happy Font serif;',
$css_declarations->get_declarations_string(),
'Output after removing "color" and "margin" declarations via `remove_declarations()` does not match expectations'
);
}
}