46377800bca88851ac54b59d11ba395f501b98fd
[yaffs-website] / web / core / modules / big_pipe / src / Tests / BigPipePlaceholderTestCases.php
1 <?php
2
3 /**
4  * @file
5  * Contains \Drupal\Tests\big_pipe\Unit\Render\Placeholder\BigPipePlaceholderTestCases.
6  */
7
8 namespace Drupal\big_pipe\Tests;
9
10 use Drupal\big_pipe\Render\BigPipeMarkup;
11 use Drupal\Core\Session\AccountInterface;
12 use Drupal\Core\StringTranslation\PluralTranslatableMarkup;
13 use Drupal\Core\Url;
14 use Symfony\Component\DependencyInjection\ContainerInterface;
15
16 /**
17  * BigPipe placeholder test cases for use in both unit and integration tests.
18  *
19  * - Unit test:
20  *   \Drupal\Tests\big_pipe\Unit\Render\Placeholder\BigPipeStrategyTest
21  * - Integration test for BigPipe with JS on:
22  *   \Drupal\big_pipe\Tests\BigPipeTest::testBigPipe()
23  * - Integration test for BigPipe with JS off:
24  *   \Drupal\big_pipe\Tests\BigPipeTest::testBigPipeNoJs()
25  */
26 class BigPipePlaceholderTestCases {
27
28   /**
29    * Gets all BigPipe placeholder test cases.
30    *
31    * @param \Symfony\Component\DependencyInjection\ContainerInterface|null $container
32    *   Optional. Necessary to get the embedded AJAX/HTML responses.
33    * @param \Drupal\Core\Session\AccountInterface|null $user
34    *   Optional. Necessary to get the embedded AJAX/HTML responses.
35    *
36    * @return \Drupal\big_pipe\Tests\BigPipePlaceholderTestCase[]
37    */
38   public static function cases(ContainerInterface $container = NULL, AccountInterface $user = NULL) {
39     // Define the two types of cacheability that we expect to see. These will be
40     // used in the expectations.
41     $cacheability_depends_on_session_only = [
42       'max-age' => 0,
43       'contexts' => ['session.exists'],
44     ];
45     $cacheability_depends_on_session_and_nojs_cookie = [
46       'max-age' => 0,
47       'contexts' => ['session.exists', 'cookies:big_pipe_nojs'],
48     ];
49
50
51     // 1. Real-world example of HTML placeholder.
52     $status_messages = new BigPipePlaceholderTestCase(
53       ['#type' => 'status_messages'],
54       '<drupal-render-placeholder callback="Drupal\Core\Render\Element\StatusMessages::renderMessages" arguments="0" token="_HAdUpwWmet0TOTe2PSiJuMntExoshbm1kh2wQzzzAA"></drupal-render-placeholder>',
55       [
56         '#lazy_builder' => [
57           'Drupal\Core\Render\Element\StatusMessages::renderMessages',
58           [NULL]
59         ],
60       ]
61     );
62     $status_messages->bigPipePlaceholderId = 'callback=Drupal%5CCore%5CRender%5CElement%5CStatusMessages%3A%3ArenderMessages&amp;args%5B0%5D&amp;token=_HAdUpwWmet0TOTe2PSiJuMntExoshbm1kh2wQzzzAA';
63     $status_messages->bigPipePlaceholderRenderArray = [
64       '#markup' => '<span data-big-pipe-placeholder-id="callback=Drupal%5CCore%5CRender%5CElement%5CStatusMessages%3A%3ArenderMessages&amp;args%5B0%5D&amp;token=_HAdUpwWmet0TOTe2PSiJuMntExoshbm1kh2wQzzzAA"></span>',
65       '#cache' => $cacheability_depends_on_session_and_nojs_cookie,
66       '#attached' => [
67         'library' => ['big_pipe/big_pipe'],
68         'drupalSettings' => [
69           'bigPipePlaceholderIds' => [
70             'callback=Drupal%5CCore%5CRender%5CElement%5CStatusMessages%3A%3ArenderMessages&args%5B0%5D&token=_HAdUpwWmet0TOTe2PSiJuMntExoshbm1kh2wQzzzAA' => TRUE,
71           ],
72         ],
73         'big_pipe_placeholders' => [
74           'callback=Drupal%5CCore%5CRender%5CElement%5CStatusMessages%3A%3ArenderMessages&amp;args%5B0%5D&amp;token=_HAdUpwWmet0TOTe2PSiJuMntExoshbm1kh2wQzzzAA' => $status_messages->placeholderRenderArray,
75         ],
76       ],
77     ];
78     $status_messages->bigPipeNoJsPlaceholder = '<span data-big-pipe-nojs-placeholder-id="callback=Drupal%5CCore%5CRender%5CElement%5CStatusMessages%3A%3ArenderMessages&amp;args%5B0%5D&amp;token=_HAdUpwWmet0TOTe2PSiJuMntExoshbm1kh2wQzzzAA"></span>';
79     $status_messages->bigPipeNoJsPlaceholderRenderArray = [
80       '#markup' => '<span data-big-pipe-nojs-placeholder-id="callback=Drupal%5CCore%5CRender%5CElement%5CStatusMessages%3A%3ArenderMessages&amp;args%5B0%5D&amp;token=_HAdUpwWmet0TOTe2PSiJuMntExoshbm1kh2wQzzzAA"></span>',
81       '#cache' => $cacheability_depends_on_session_and_nojs_cookie,
82       '#attached' => [
83         'big_pipe_nojs_placeholders' => [
84           '<span data-big-pipe-nojs-placeholder-id="callback=Drupal%5CCore%5CRender%5CElement%5CStatusMessages%3A%3ArenderMessages&amp;args%5B0%5D&amp;token=_HAdUpwWmet0TOTe2PSiJuMntExoshbm1kh2wQzzzAA"></span>' => $status_messages->placeholderRenderArray,
85         ],
86       ],
87     ];
88     if ($container && $user) {
89       $status_messages->embeddedAjaxResponseCommands = [
90         [
91           'command' => 'settings',
92           'settings' => [
93             'ajaxPageState' => [
94               'theme' => 'classy',
95               'libraries' => 'big_pipe/big_pipe,classy/base,classy/messages,core/drupal.active-link,core/html5shiv,core/normalize,system/base',
96             ],
97             'pluralDelimiter' => PluralTranslatableMarkup::DELIMITER,
98             'user' => [
99               'uid' => '1',
100               'permissionsHash' => $container->get('user_permissions_hash_generator')->generate($user),
101             ],
102           ],
103           'merge' => TRUE,
104         ],
105         [
106           'command' => 'add_css',
107           'data' => '<link rel="stylesheet" href="' . base_path() . 'core/themes/classy/css/components/messages.css?' . $container->get('state')->get('system.css_js_query_string') . '" media="all" />' . "\n"
108         ],
109         [
110           'command' => 'insert',
111           'method' => 'replaceWith',
112           'selector' => '[data-big-pipe-placeholder-id="callback=Drupal%5CCore%5CRender%5CElement%5CStatusMessages%3A%3ArenderMessages&args%5B0%5D&token=_HAdUpwWmet0TOTe2PSiJuMntExoshbm1kh2wQzzzAA"]',
113           'data' => "\n" . '    <div role="contentinfo" aria-label="Status message" class="messages messages--status">' . "\n" . '                  <h2 class="visually-hidden">Status message</h2>' . "\n" . '                    Hello from BigPipe!' . "\n" . '            </div>' . "\n    ",
114           'settings' => NULL,
115         ],
116       ];
117       $status_messages->embeddedHtmlResponse = '<link rel="stylesheet" href="' . base_path() . 'core/themes/classy/css/components/messages.css?' . $container->get('state')->get('system.css_js_query_string') . '" media="all" />' . "\n" . "\n" . '    <div role="contentinfo" aria-label="Status message" class="messages messages--status">' . "\n" . '                  <h2 class="visually-hidden">Status message</h2>' . "\n" . '                    Hello from BigPipe!' . "\n" . '            </div>' . "\n    \n";
118     }
119
120
121     // 2. Real-world example of HTML attribute value placeholder: form action.
122     $form_action = new BigPipePlaceholderTestCase(
123       $container ? $container->get('form_builder')->getForm('Drupal\big_pipe_test\Form\BigPipeTestForm') : [],
124       'form_action_cc611e1d',
125       [
126         '#lazy_builder' => ['form_builder:renderPlaceholderFormAction', []],
127       ]
128     );
129     $form_action->bigPipeNoJsPlaceholder = 'big_pipe_nojs_placeholder_attribute_safe:form_action_cc611e1d';
130     $form_action->bigPipeNoJsPlaceholderRenderArray = [
131       '#markup' => 'big_pipe_nojs_placeholder_attribute_safe:form_action_cc611e1d',
132       '#cache' => $cacheability_depends_on_session_only,
133       '#attached' => [
134         'big_pipe_nojs_placeholders' => [
135           'big_pipe_nojs_placeholder_attribute_safe:form_action_cc611e1d' => $form_action->placeholderRenderArray,
136         ],
137       ],
138     ];
139     if ($container) {
140       $form_action->embeddedHtmlResponse = '<form class="big-pipe-test-form" data-drupal-selector="big-pipe-test-form" action="' . base_path() . 'big_pipe_test"';
141     }
142
143
144     // 3. Real-world example of HTML attribute value subset placeholder: CSRF
145     // token in link.
146     $csrf_token = new BigPipePlaceholderTestCase(
147       [
148         '#title' => 'Link with CSRF token',
149         '#type' => 'link',
150         '#url' => Url::fromRoute('system.theme_set_default'),
151       ],
152       'e88b559cce72c80b687d56b0e2a3a5ae4b66bc0e',
153       [
154         '#lazy_builder' => [
155           'route_processor_csrf:renderPlaceholderCsrfToken',
156           ['admin/config/user-interface/shortcut/manage/default/add-link-inline']
157         ],
158       ]
159     );
160     $csrf_token->bigPipeNoJsPlaceholder = 'big_pipe_nojs_placeholder_attribute_safe:e88b559cce72c80b687d56b0e2a3a5ae4b66bc0e';
161     $csrf_token->bigPipeNoJsPlaceholderRenderArray = [
162       '#markup' => 'big_pipe_nojs_placeholder_attribute_safe:e88b559cce72c80b687d56b0e2a3a5ae4b66bc0e',
163       '#cache' => $cacheability_depends_on_session_only,
164       '#attached' => [
165         'big_pipe_nojs_placeholders' => [
166           'big_pipe_nojs_placeholder_attribute_safe:e88b559cce72c80b687d56b0e2a3a5ae4b66bc0e' => $csrf_token->placeholderRenderArray,
167         ],
168       ],
169     ];
170     if ($container) {
171       $csrf_token->embeddedHtmlResponse = $container->get('csrf_token')->get('admin/appearance/default');
172     }
173
174
175     // 4. Edge case: custom string to be considered as a placeholder that
176     // happens to not be valid HTML.
177     $hello = new BigPipePlaceholderTestCase(
178       [
179         '#markup' => BigPipeMarkup::create('<hello'),
180         '#attached' => [
181           'placeholders' => [
182             '<hello' => ['#lazy_builder' => ['\Drupal\big_pipe_test\BigPipeTestController::helloOrYarhar', []]],
183           ]
184         ],
185       ],
186       '<hello',
187       [
188         '#lazy_builder' => [
189           'hello_or_yarhar',
190           []
191         ],
192       ]
193     );
194     $hello->bigPipeNoJsPlaceholder = 'big_pipe_nojs_placeholder_attribute_safe:&lt;hello';
195     $hello->bigPipeNoJsPlaceholderRenderArray = [
196       '#markup' => 'big_pipe_nojs_placeholder_attribute_safe:&lt;hello',
197       '#cache' => $cacheability_depends_on_session_only,
198       '#attached' => [
199         'big_pipe_nojs_placeholders' => [
200           'big_pipe_nojs_placeholder_attribute_safe:&lt;hello' => $hello->placeholderRenderArray,
201         ],
202       ],
203     ];
204     $hello->embeddedHtmlResponse = '<marquee>Yarhar llamas forever!</marquee>';
205
206
207     // 5. Edge case: non-#lazy_builder placeholder.
208     $current_time = new BigPipePlaceholderTestCase(
209       [
210         '#markup' => BigPipeMarkup::create('<time>CURRENT TIME</time>'),
211         '#attached' => [
212           'placeholders' => [
213             '<time>CURRENT TIME</time>' => [
214               '#pre_render' => [
215                 '\Drupal\big_pipe_test\BigPipeTestController::currentTime',
216               ],
217             ]
218           ]
219         ]
220       ],
221       '<time>CURRENT TIME</time>',
222       [
223         '#pre_render' => ['current_time'],
224       ]
225     );
226     $current_time->bigPipePlaceholderId = 'timecurrent-timetime';
227     $current_time->bigPipePlaceholderRenderArray = [
228       '#markup' => '<span data-big-pipe-placeholder-id="timecurrent-timetime"></span>',
229       '#cache' => $cacheability_depends_on_session_and_nojs_cookie,
230       '#attached' => [
231         'library' => ['big_pipe/big_pipe'],
232         'drupalSettings' => [
233           'bigPipePlaceholderIds' => [
234             'timecurrent-timetime' => TRUE,
235           ],
236         ],
237         'big_pipe_placeholders' => [
238           'timecurrent-timetime' => $current_time->placeholderRenderArray,
239         ],
240       ],
241     ];
242     $current_time->embeddedAjaxResponseCommands = [
243       [
244         'command' => 'insert',
245         'method' => 'replaceWith',
246         'selector' => '[data-big-pipe-placeholder-id="timecurrent-timetime"]',
247         'data' => '<time datetime="1991-03-14"></time>',
248         'settings' => NULL,
249       ],
250     ];
251     $current_time->bigPipeNoJsPlaceholder = '<span data-big-pipe-nojs-placeholder-id="timecurrent-timetime"></span>';
252     $current_time->bigPipeNoJsPlaceholderRenderArray = [
253       '#markup' => '<span data-big-pipe-nojs-placeholder-id="timecurrent-timetime"></span>',
254       '#cache' => $cacheability_depends_on_session_and_nojs_cookie,
255       '#attached' => [
256         'big_pipe_nojs_placeholders' => [
257           '<span data-big-pipe-nojs-placeholder-id="timecurrent-timetime"></span>' => $current_time->placeholderRenderArray,
258         ],
259       ],
260     ];
261     $current_time->embeddedHtmlResponse = '<time datetime="1991-03-14"></time>';
262
263
264     // 6. Edge case: #lazy_builder that throws an exception.
265     $exception = new BigPipePlaceholderTestCase(
266       [
267         '#lazy_builder' => ['\Drupal\big_pipe_test\BigPipeTestController::exception', ['llamas', 'suck']],
268         '#create_placeholder' => TRUE,
269       ],
270       '<drupal-render-placeholder callback="\Drupal\big_pipe_test\BigPipeTestController::exception" arguments="0=llamas&amp;1=suck" token="uhKFNfT4eF449_W-kDQX8E5z4yHyt0-nSHUlwaGAQeU"></drupal-render-placeholder>',
271       [
272         '#lazy_builder' => ['\Drupal\big_pipe_test\BigPipeTestController::exception', ['llamas', 'suck']],
273       ]
274     );
275     $exception->bigPipePlaceholderId = 'callback=%5CDrupal%5Cbig_pipe_test%5CBigPipeTestController%3A%3Aexception&amp;args%5B0%5D=llamas&amp;args%5B1%5D=suck&amp;token=uhKFNfT4eF449_W-kDQX8E5z4yHyt0-nSHUlwaGAQeU';
276     $exception->bigPipePlaceholderRenderArray = [
277       '#markup' => '<span data-big-pipe-placeholder-id="callback=%5CDrupal%5Cbig_pipe_test%5CBigPipeTestController%3A%3Aexception&amp;args%5B0%5D=llamas&amp;args%5B1%5D=suck&amp;token=uhKFNfT4eF449_W-kDQX8E5z4yHyt0-nSHUlwaGAQeU"></span>',
278       '#cache' => $cacheability_depends_on_session_and_nojs_cookie,
279       '#attached' => [
280         'library' => ['big_pipe/big_pipe'],
281         'drupalSettings' => [
282           'bigPipePlaceholderIds' => [
283             'callback=%5CDrupal%5Cbig_pipe_test%5CBigPipeTestController%3A%3Aexception&args%5B0%5D=llamas&args%5B1%5D=suck&token=uhKFNfT4eF449_W-kDQX8E5z4yHyt0-nSHUlwaGAQeU' => TRUE,
284           ],
285         ],
286         'big_pipe_placeholders' => [
287           'callback=%5CDrupal%5Cbig_pipe_test%5CBigPipeTestController%3A%3Aexception&amp;args%5B0%5D=llamas&amp;args%5B1%5D=suck&amp;token=uhKFNfT4eF449_W-kDQX8E5z4yHyt0-nSHUlwaGAQeU' => $exception->placeholderRenderArray,
288         ],
289       ],
290     ];
291     $exception->embeddedAjaxResponseCommands = NULL;
292     $exception->bigPipeNoJsPlaceholder = '<span data-big-pipe-nojs-placeholder-id="callback=%5CDrupal%5Cbig_pipe_test%5CBigPipeTestController%3A%3Aexception&amp;args%5B0%5D=llamas&amp;args%5B1%5D=suck&amp;token=uhKFNfT4eF449_W-kDQX8E5z4yHyt0-nSHUlwaGAQeU"></span>';
293     $exception->bigPipeNoJsPlaceholderRenderArray = [
294       '#markup' => $exception->bigPipeNoJsPlaceholder,
295       '#cache' => $cacheability_depends_on_session_and_nojs_cookie,
296       '#attached' => [
297         'big_pipe_nojs_placeholders' => [
298           $exception->bigPipeNoJsPlaceholder => $exception->placeholderRenderArray,
299         ],
300       ],
301     ];
302     $exception->embeddedHtmlResponse = NULL;
303
304     // 7. Edge case: response filter throwing an exception for this placeholder.
305     $embedded_response_exception = new BigPipePlaceholderTestCase(
306       [
307         '#lazy_builder' => ['\Drupal\big_pipe_test\BigPipeTestController::responseException', []],
308         '#create_placeholder' => TRUE,
309       ],
310       '<drupal-render-placeholder callback="\Drupal\big_pipe_test\BigPipeTestController::responseException" arguments="" token="PxOHfS_QL-T01NjBgu7Z7I04tIwMp6La5vM-mVxezbU"></drupal-render-placeholder>',
311       [
312         '#lazy_builder' => ['\Drupal\big_pipe_test\BigPipeTestController::responseException', []],
313       ]
314     );
315     $embedded_response_exception->bigPipePlaceholderId = 'callback=%5CDrupal%5Cbig_pipe_test%5CBigPipeTestController%3A%3AresponseException&amp;&amp;token=PxOHfS_QL-T01NjBgu7Z7I04tIwMp6La5vM-mVxezbU';
316     $embedded_response_exception->bigPipePlaceholderRenderArray = [
317       '#markup' => '<span data-big-pipe-placeholder-id="callback=%5CDrupal%5Cbig_pipe_test%5CBigPipeTestController%3A%3AresponseException&amp;&amp;token=PxOHfS_QL-T01NjBgu7Z7I04tIwMp6La5vM-mVxezbU"></span>',
318       '#cache' => $cacheability_depends_on_session_and_nojs_cookie,
319       '#attached' => [
320         'library' => ['big_pipe/big_pipe'],
321         'drupalSettings' => [
322           'bigPipePlaceholderIds' => [
323             'callback=%5CDrupal%5Cbig_pipe_test%5CBigPipeTestController%3A%3AresponseException&&token=PxOHfS_QL-T01NjBgu7Z7I04tIwMp6La5vM-mVxezbU' => TRUE,
324           ],
325         ],
326         'big_pipe_placeholders' => [
327           'callback=%5CDrupal%5Cbig_pipe_test%5CBigPipeTestController%3A%3AresponseException&amp;&amp;token=PxOHfS_QL-T01NjBgu7Z7I04tIwMp6La5vM-mVxezbU' => $embedded_response_exception->placeholderRenderArray,
328         ],
329       ],
330     ];
331     $embedded_response_exception->embeddedAjaxResponseCommands = NULL;
332     $embedded_response_exception->bigPipeNoJsPlaceholder = '<span data-big-pipe-nojs-placeholder-id="callback=%5CDrupal%5Cbig_pipe_test%5CBigPipeTestController%3A%3AresponseException&amp;&amp;token=PxOHfS_QL-T01NjBgu7Z7I04tIwMp6La5vM-mVxezbU"></span>';
333     $embedded_response_exception->bigPipeNoJsPlaceholderRenderArray = [
334       '#markup' => $embedded_response_exception->bigPipeNoJsPlaceholder,
335       '#cache' => $cacheability_depends_on_session_and_nojs_cookie,
336       '#attached' => [
337         'big_pipe_nojs_placeholders' => [
338           $embedded_response_exception->bigPipeNoJsPlaceholder => $embedded_response_exception->placeholderRenderArray,
339         ],
340       ],
341     ];
342     $exception->embeddedHtmlResponse = NULL;
343
344     return [
345       'html' => $status_messages,
346       'html_attribute_value' => $form_action,
347       'html_attribute_value_subset' => $csrf_token,
348       'edge_case__invalid_html' => $hello,
349       'edge_case__html_non_lazy_builder' => $current_time,
350       'exception__lazy_builder' => $exception,
351       'exception__embedded_response' => $embedded_response_exception,
352     ];
353   }
354
355 }
356
357 class BigPipePlaceholderTestCase {
358
359   /**
360    * The original render array.
361    *
362    * @var array
363    */
364   public $renderArray;
365
366   /**
367    * The expected corresponding placeholder string.
368    *
369    * @var string
370    */
371   public $placeholder;
372
373   /**
374    * The expected corresponding placeholder render array.
375    *
376    * @var array
377    */
378   public $placeholderRenderArray;
379
380   /**
381    * The expected BigPipe placeholder ID.
382    *
383    * (Only possible for HTML placeholders.)
384    *
385    * @var null|string
386    */
387   public $bigPipePlaceholderId = NULL;
388
389   /**
390    * The corresponding expected BigPipe placeholder render array.
391    *
392    * @var null|array
393    */
394   public $bigPipePlaceholderRenderArray = NULL;
395
396   /**
397    * The corresponding expected embedded AJAX response.
398    *
399    * @var null|array
400    */
401   public $embeddedAjaxResponseCommands = NULL;
402
403
404   /**
405    * The expected BigPipe no-JS placeholder.
406    *
407    * (Possible for all placeholders, HTML or non-HTML.)
408    *
409    * @var string
410    */
411   public $bigPipeNoJsPlaceholder;
412
413   /**
414    * The corresponding expected BigPipe no-JS placeholder render array.
415    *
416    * @var array
417    */
418   public $bigPipeNoJsPlaceholderRenderArray;
419
420   /**
421    * The corresponding expected embedded HTML response.
422    *
423    * @var string
424    */
425   public $embeddedHtmlResponse;
426
427   public function __construct(array $render_array, $placeholder, array $placeholder_render_array) {
428     $this->renderArray = $render_array;
429     $this->placeholder = $placeholder;
430     $this->placeholderRenderArray = $placeholder_render_array;
431   }
432
433 }