Must verify:

  1. HTML placeholder. (Think status messages, comment form, block, et cetera.)
  2. HTML attribute value placeholder. (Think form action, form token.)
  3. HTML attribute value subset placeholder. (Think CSRF token in URL.)
  4. Custom string to be considered as a placeholder that just happens to not be valid HTML. (This is the crazy edge case. But we want BigPipe to always work reliably.)
  5. … all of the above both in case of the current request having a session and not, and in case of the current request having a BigPipe no-JS cookie or not — in other words, the above must be tested in all four situations
  6. When a session is present (and hence BigPipe can work), BigPipe is always able to deliver all placeholders, regardless what type of placeholder they are (see points 1–4 above).
  7. A HTML placeholder that does not use a #lazy_builder.
Support from Acquia helps fund testing for Drupal Acquia logo

Comments

Wim Leers created an issue. See original summary.

Wim Leers’s picture

Status: Active » Needs review
FileSize
7.11 KB
Wim Leers’s picture

Issue summary: View changes
FileSize
7.26 KB
942 bytes
Wim Leers’s picture

  1. +++ b/tests/src/Unit/Render/Placeholder/BigPipeStrategyTest.php
    @@ -0,0 +1,163 @@
    +      '#markup' => '<div data-big-pipe-selector="callback=Drupal%5CCore%5CRender%5CElement%5CStatusMessages%3A%3ArenderMessages&amp;args[0]&amp;token=a8c34b5e"></div>',
    

    This placeholder makes a ton of sense, and it's legible.

  2. +++ b/tests/src/Unit/Render/Placeholder/BigPipeStrategyTest.php
    @@ -0,0 +1,163 @@
    +      '#markup' => '<div data-big-pipe-selector-nojs="drupal-render-placeholder-callbackdrupalcorerenderelementstatusmessagesrendermessages-arguments0-tokena8c34b5edrupal-render-placeholder"></div>',
    

    This placeholder on the other hand makes little sense, and is not really legible.

    Let's fix that: let's make no-JS BigPipe placeholders also make sense.

Wim Leers’s picture

FileSize
16.88 KB
10.85 KB

#4 let me down a bit of a rabbit hole of inconsistencies.

I refactored the code generating #4.1 into a protected helper method so I can use it also for the no-JS case. No problem.

Then I noticed it was generating a "selector". But it's not really generating a selector, it's generating an identifier. As is evident from the fact that we send these generated selectors to the client side using drupalSettings.bigPipePlaceholders, so that the JS has a whitelist to verify against:

   // Ignore any placeholders that are not in the known placeholder list.
   // This is used to avoid someone trying to XSS the site via the
   // placeholdering mechanism.;
   if (typeof drupalSettings.bigPipePlaceholders[placeholderName] !== 'undefined') {


But note that this JS doesn't call it "selectors" anymore! This is very inconsistent and confusing.

If all this were called "placeholder IDs" instead of "selectors", none of this confusion would arise. So, let's do that renaming first.

Wim Leers’s picture

FileSize
18.37 KB
5.25 KB

And here we go, much saner placeholders + placeholder IDs for BigPipe no-JS placeholders, this addresses #4.2.

Wim Leers’s picture

   * @todo Figure out how to simplify this. Perhaps no new placeholder is in fact necessary?
   * @todo Related, perhaps distinguish between "HTML" and "non-HTML (attr value)" use cases? Because right now, this *breaks* HTML and therefore breaks response filters: this indiscriminately uses a <div> as a placeholder, which is invalid inside a HTML attribute, and thus breaks DOM parsing.
   */
  protected static function createBigPipeNoJsPlaceholder($original_placeholder, array $placeholder_render_array) {

Those two @todos are technically out of scope here.

But…

+++ b/tests/src/Unit/Render/Placeholder/BigPipeStrategyTest.php
@@ -0,0 +1,163 @@
+      '#markup' => '<div data-big-pipe-nojs-placeholder-id="callback=form_builder%3ArenderPlaceholderFormAction&&token=e8cb6dae"></div>',
...
+      '#markup' => '<div data-big-pipe-nojs-placeholder-id="callback=route_processor_csrf%3ArenderPlaceholderCsrfToken&args[0]=admin/config/user-interface/shortcut/manage/default/add-link-inline&token=77d1dce6"></div>',

These three expectations cement the current implementation in the test expectations: they cement the expectation that these placeholders which live in attribute values can in fact be HTML, which breaks response filters as the @todo indicates.

Conclusion: I think it makes sense to fix those todos here, to ensure the test expectations actually make sense.

Wim Leers’s picture

#2674126: BigPipeResponseAttachmentsProcessor test coverage landed in the mean-time, so re-testing #6.

Wim Leers’s picture

FileSize
27.65 KB
3.51 KB

The refactoring I did in #5 resulted in a new helper method (generateBigPipePlaceholderId()), which also made me realize that one test case is still missing: one for a placeholder that does not use #lazy_builder. See #2469431-173: BigPipe for auth users: first send+render the cheap parts of the page, then the expensive parts.

So, first adding test coverage for that.

In doing so, I also noticed that the number of passes did not reflect the number of individual things being tested. So I changed the assertions around a bit: they're now per-placeholder instead of for all placeholders at once. This also greatly simplifies debugging of this test/understanding what exactly is broken.

Wim Leers’s picture

Issue summary: View changes

IS update for #9.

Status: Needs review » Needs work

The last submitted patch, 9: 2674334-9.patch, failed testing.

Wim Leers’s picture

Status: Needs work » Needs review
FileSize
31.36 KB
9.59 KB

And finally, this implements #7.

Status: Needs review » Needs work

The last submitted patch, 12: 2674334-11.patch, failed testing.

Wim Leers’s picture

Status: Needs work » Needs review
FileSize
31.36 KB
858 bytes

I worked on #9 while working on #12, I didn't split them up correctly. Hence the failure in #9.

And in #12, I apparently introduced a typo at the very last minute.

Sorry for the confusion.

Wim Leers’s picture

FileSize
23.61 KB
7.79 KB
--- /dev/null
+++ b/src/Tests/Render/BigPipeResponseAttachmentsProcessorTest.php

Oops, this leftover file snuck in! It's not being run (so it's a "dead test" effectively), but it's making the patch looking much bigger than it is.

Wim Leers’s picture

FileSize
23.72 KB
455 bytes

#2670462: Clean up, document & improve big_pipe.js landed, this needed to be rebased.

After a clean rebase, there was one more small change needed, and only that change is visible in this interdiff.

Wim Leers’s picture

Title: BigPipeStrategy test coverage » BigPipeStrategy test coverage + remaining @todos

Per #7 and since #12, this fixes all remaining @todos in BigPipeStrategy, updating title accordingly.

  • Wim Leers committed 99d272b on 8.x-1.x
    Issue #2674334 by Wim Leers: BigPipeStrategy test coverage + remaining @...
Wim Leers’s picture

Status: Needs review » Fixed

I waited 24 hours to allow for reviews to come in. None happened, that's okay. I don't think there was any controversial change here. Just test coverage, clean-up and renaming.

Fabianx’s picture

RTBC in retrospective

Wim Leers’s picture

Excellent, thanks!

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.