@@ -30,12 +30,74 @@ public function set_up() {
3030 'description ' => 'Recursive pattern. ' ,
3131 )
3232 );
33+ register_block_pattern (
34+ 'core/single-root ' ,
35+ array (
36+ 'title ' => 'Single Root Pattern ' ,
37+ 'content ' => '<!-- wp:paragraph -->Single root content<!-- /wp:paragraph --> ' ,
38+ 'description ' => 'A single root pattern. ' ,
39+ 'categories ' => array ( 'text ' ),
40+ )
41+ );
42+ register_block_pattern (
43+ 'core/single-root-with-forbidden-chars-in-attrs ' ,
44+ array (
45+ 'title ' => 'Single Root Pattern<script>alert("XSS")</script> ' ,
46+ 'content ' => '<!-- wp:paragraph -->Single root content<!-- /wp:paragraph --> ' ,
47+ 'description ' => 'A single root pattern.<script>alert("XSS")</script><img src=x onerror=alert(1)> ' ,
48+ 'categories ' => array (
49+ 'text<script>alert("XSS")</script> ' ,
50+ 'bad \'); DROP TABLE wp_posts;-- ' ,
51+ '<img src=x onerror=alert(1)> ' ,
52+ "evil \x00null \nbyte " ,
53+ 'category with <strong>html</strong> tags ' ,
54+ ),
55+ )
56+ );
57+ register_block_pattern (
58+ 'core/with-attrs ' ,
59+ array (
60+ 'title ' => 'Pattern With Attrs ' ,
61+ 'content ' => '<!-- wp:paragraph {"className":"custom-class"} -->Content<!-- /wp:paragraph --> ' ,
62+ 'description ' => 'A pattern with existing attributes. ' ,
63+ )
64+ );
65+ register_block_pattern (
66+ 'core/nested-single ' ,
67+ array (
68+ 'title ' => 'Nested Pattern ' ,
69+ 'content ' => '<!-- wp:group --><!-- wp:paragraph -->Nested content<!-- /wp:paragraph --><!-- wp:pattern {"slug":"core/single-root"} /--><!-- /wp:group --> ' ,
70+ 'description ' => 'A nested single root pattern. ' ,
71+ 'categories ' => array ( 'featured ' ),
72+ )
73+ );
74+ register_block_pattern (
75+ 'core/existing-metadata ' ,
76+ array (
77+ 'title ' => 'Existing Metadata Pattern ' ,
78+ 'content ' => '<!-- wp:paragraph {"metadata":{"patternName":"core/existing-metadata-should-not-overwrite","description":"A existing metadata pattern.","categories":["cake"]}} -->Existing metadata content<!-- /wp:paragraph --> ' ,
79+ )
80+ );
81+ register_block_pattern (
82+ 'core/with-custom-metadata ' ,
83+ array (
84+ 'title ' => 'Pattern With Custom Metadata ' ,
85+ 'content ' => '<!-- wp:paragraph {"metadata":{"customKey":"customValue","anotherKey":123,"booleanKey":true}} -->Content with custom metadata<!-- /wp:paragraph --> ' ,
86+ 'description ' => 'A pattern with custom metadata keys. ' ,
87+ 'categories ' => array ( 'test ' ),
88+ )
89+ );
3390 }
3491
3592 public function tear_down () {
3693 unregister_block_pattern ( 'core/test ' );
3794 unregister_block_pattern ( 'core/recursive ' );
38-
95+ unregister_block_pattern ( 'core/single-root ' );
96+ unregister_block_pattern ( 'core/single-root-with-forbidden-chars-in-attrs ' );
97+ unregister_block_pattern ( 'core/with-attrs ' );
98+ unregister_block_pattern ( 'core/nested-single ' );
99+ unregister_block_pattern ( 'core/existing-metadata ' );
100+ unregister_block_pattern ( 'core/with-custom-metadata ' );
39101 parent ::tear_down ();
40102 }
41103
@@ -60,13 +122,55 @@ public function test_should_resolve_pattern_blocks_as_expected( $blocks, $expect
60122 public function data_should_resolve_pattern_blocks_as_expected () {
61123 return array (
62124 // Works without attributes, leaves the block as is.
63- 'pattern with no slug attribute ' => array ( '<!-- wp:pattern /--> ' , '<!-- wp:pattern /--> ' ),
125+ 'pattern with no slug attribute ' => array (
126+ '<!-- wp:pattern /--> ' ,
127+ '<!-- wp:pattern /--> ' ,
128+ ),
64129 // Resolves the pattern.
65- 'test pattern ' => array ( '<!-- wp:pattern {"slug":"core/test"} /--> ' , '<!-- wp:paragraph -->Hello<!-- /wp:paragraph --><!-- wp:paragraph -->World<!-- /wp:paragraph --> ' ),
130+ 'test pattern ' => array (
131+ '<!-- wp:pattern {"slug":"core/test"} /--> ' ,
132+ '<!-- wp:paragraph -->Hello<!-- /wp:paragraph --><!-- wp:paragraph -->World<!-- /wp:paragraph --> ' ,
133+ ),
66134 // Skips recursive patterns.
67- 'recursive pattern ' => array ( '<!-- wp:pattern {"slug":"core/recursive"} /--> ' , '<!-- wp:paragraph -->Recursive<!-- /wp:paragraph --> ' ),
135+ 'recursive pattern ' => array (
136+ '<!-- wp:pattern {"slug":"core/recursive"} /--> ' ,
137+ '<!-- wp:paragraph -->Recursive<!-- /wp:paragraph --> ' ,
138+ ),
68139 // Resolves the pattern within a block.
69- 'pattern within a block ' => array ( '<!-- wp:group --><!-- wp:paragraph -->Before<!-- /wp:paragraph --><!-- wp:pattern {"slug":"core/test"} /--><!-- wp:paragraph -->After<!-- /wp:paragraph --><!-- /wp:group --> ' , '<!-- wp:group --><!-- wp:paragraph -->Before<!-- /wp:paragraph --><!-- wp:paragraph -->Hello<!-- /wp:paragraph --><!-- wp:paragraph -->World<!-- /wp:paragraph --><!-- wp:paragraph -->After<!-- /wp:paragraph --><!-- /wp:group --> ' ),
140+ 'pattern within a block ' => array (
141+ '<!-- wp:group --><!-- wp:paragraph -->Before<!-- /wp:paragraph --><!-- wp:pattern {"slug":"core/test"} /--><!-- wp:paragraph -->After<!-- /wp:paragraph --><!-- /wp:group --> ' ,
142+ '<!-- wp:group --><!-- wp:paragraph -->Before<!-- /wp:paragraph --><!-- wp:paragraph -->Hello<!-- /wp:paragraph --><!-- wp:paragraph -->World<!-- /wp:paragraph --><!-- wp:paragraph -->After<!-- /wp:paragraph --><!-- /wp:group --> ' ,
143+ ),
144+ // Resolves the single-root pattern and adds metadata.
145+ 'single-root pattern ' => array (
146+ '<!-- wp:pattern {"slug":"core/single-root"} /--> ' ,
147+ '<!-- wp:paragraph {"metadata":{"patternName":"core/single-root","name":"Single Root Pattern","description":"A single root pattern.","categories":["text"]}} -->Single root content<!-- /wp:paragraph --> ' ,
148+ ),
149+ // Existing attributes are preserved when adding metadata.
150+ 'existing attributes preserved ' => array (
151+ '<!-- wp:pattern {"slug":"core/with-attrs"} /--> ' ,
152+ '<!-- wp:paragraph {"className":"custom-class","metadata":{"patternName":"core/with-attrs","name":"Pattern With Attrs","description":"A pattern with existing attributes."}} -->Content<!-- /wp:paragraph --> ' ,
153+ ),
154+ // Resolves the nested single-root pattern and adds metadata.
155+ 'nested single-root pattern ' => array (
156+ '<!-- wp:pattern {"slug":"core/nested-single"} /--> ' ,
157+ '<!-- wp:group {"metadata":{"patternName":"core/nested-single","name":"Nested Pattern","description":"A nested single root pattern.","categories":["featured"]}} --><!-- wp:paragraph -->Nested content<!-- /wp:paragraph --><!-- wp:paragraph {"metadata":{"patternName":"core/single-root","name":"Single Root Pattern","description":"A single root pattern.","categories":["text"]}} -->Single root content<!-- /wp:paragraph --><!-- /wp:group --> ' ,
158+ ),
159+ // Sanitizes fields.
160+ 'sanitized pattern attrs ' => array (
161+ '<!-- wp:pattern {"slug":"core/single-root-with-forbidden-chars-in-attrs"} /--> ' ,
162+ '<!-- wp:paragraph {"metadata":{"patternName":"core/single-root-with-forbidden-chars-in-attrs","name":"Single Root Pattern","description":"A single root pattern.","categories":["text","bad \'); DROP TABLE wp_posts;\u002d\u002d","","evil\u0000null byte","category with html tags"]}} -->Single root content<!-- /wp:paragraph --> ' ,
163+ ),
164+ // Metadata is merged with existing metadata and existing metadata is preserved.
165+ 'existing metadata preserved ' => array (
166+ '<!-- wp:pattern {"slug":"core/existing-metadata"} /--> ' ,
167+ '<!-- wp:paragraph {"metadata":{"patternName":"core/existing-metadata","description":"A existing metadata pattern.","categories":["cake"],"name":"Existing Metadata Pattern"}} -->Existing metadata content<!-- /wp:paragraph --> ' ,
168+ ),
169+ // Custom metadata keys are preserved when resolving patterns.
170+ 'custom metadata preserved ' => array (
171+ '<!-- wp:pattern {"slug":"core/with-custom-metadata"} /--> ' ,
172+ '<!-- wp:paragraph {"metadata":{"customKey":"customValue","anotherKey":123,"booleanKey":true,"patternName":"core/with-custom-metadata","name":"Pattern With Custom Metadata","description":"A pattern with custom metadata keys.","categories":["test"]}} -->Content with custom metadata<!-- /wp:paragraph --> ' ,
173+ ),
70174 );
71175 }
72176}
0 commit comments