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