Problem/Motivation

Scenario: Make sure that preview of content show the real preview for the content before saving.

Given that we have a "Drupal 8.4.0" site installed
And we are logged in as the webmaster user number 1
And the config "Error messages to display" value was "All messages, with backtrace information"
When we go to "node/add/page"
And we fill in "Test Basic page" for "Title"
And we fill in the rich text editor field "Body" with "Test Basic page body"
And we press "Preview"
And we save a screenshot for the full page in the browser and take out the toolbar and the preview bar.
Then we should see a clean page, same as the not logged in user.

When we click on "Back to content editing"
And we press "Save"
And we logout
And we go to "/node/1" # the Test Basic page.
And we save a screenshot for the full page in the browser
Then we should see the following image which be the same as the preview image.

Proposed resolution

Preview issues. to prievew without errors. even if the the config "Error messages to display" value was "All messages, with backtrace information"

Or Quick edit should not load when we preview.

Remaining tasks

User interface changes

API changes

Data model changes

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

RajabNatshah created an issue. See original summary.

Rajab Natshah’s picture

Issue summary: View changes
Rajab Natshah’s picture

Issue summary: View changes
Rajab Natshah’s picture

Issue summary: View changes
Rajab Natshah’s picture

Issue summary: View changes
Rajab Natshah’s picture

Issue summary: View changes
Rajab Natshah’s picture

Issue summary: View changes
Rajab Natshah’s picture

Issue summary: View changes
Rajab Natshah’s picture

Issue summary: View changes
timmillwood’s picture

Status: Needs work » Needs review
FileSize
593 bytes
timmillwood’s picture

Priority: Normal » Major

I've been hitting the same issue, we should simply not assume the entity query will return a result. Using reset() will get around this because it doesn't care if the array is empty.

Bumping this to major, was tempted to even make it critical.

TrevorBradley’s picture

Is this issue about the asset library system passing a bad entity to quick-edit, or about quick-edit not being able to handle a bad entity?

They sound like separate issues...

Rajab Natshah’s picture

Status: Needs review » Needs work
Rajab Natshah’s picture

Rajab Natshah’s picture

Status: Needs work » Needs review
timmillwood’s picture

@RajabNatshah - What's the advantage of #14 over #10? #10 is a lot less code and produces the same result.

Take this example:

php > $keys = array_keys([]); var_dump(reset($keys));
php shell code:1:
bool(false)

An empty array returned by the entity query passed into array_keys() then reset() will return FALSE, which is the result we want. We shouldn't need to explicitly return TRUE; or return FALSE;.

Rajab Natshah’s picture

@timmillwood I want to cover most used PHP versions: PHP5.6, PHP7.0, and PHP7.1.
And if we have more than 2000 revision changes, how this will go?!

Still testing.

katannshaw’s picture

@RajabNatshah: I tested out your patch and it worked great. I'm running Drupal 8.4.0, Apache 2.4.17, and PHP 5.5.38 on Acquia Dev Desktop. I hope that it gets committed soon. Thanks.

Kat

timmillwood’s picture

Component: asset library system » quickedit.module
Issue tags: +Workflow Initiative
FileSize
1.76 KB
1.72 KB
2.3 KB

Here's a test for this.

Interdiff from #10 because it's a more simple solution than #14.

Test only patch should fail.

The last submitted patch, 19: 2914938-19-test-only.patch, failed testing. View results

amateescu’s picture

I looked at _quickedit_entity_is_latest_revision() and since that was added we gained the ability to query for the latest revisions with entity queries, so tbh I would rewrite that method like this to make it more clear:

function _quickedit_entity_is_latest_revision(ContentEntityInterface $entity) {
  if (!$entity->getEntityType()->isRevisionable() || $entity->isNew()) {
    return TRUE;
  }

  $latest_revision = \Drupal::entityTypeManager()
    ->getStorage($entity->getEntityTypeId())
    ->getQuery()
    ->latestRevision()
    ->condition($entity->getEntityType()->getKey('id'), $entity->id())
    ->execute();

  return !empty($latest_revision) && $entity->getLoadedRevisionId() == key($latest_revision) ? TRUE : FALSE;
}

Also, I was wondering why the test added in #2903524: Don't add quickedit to displays where entities have a forward revision. does not fail (\Drupal\quickedit\Tests\QuickEditLoadingTest::testWithPendingRevision()). It seems to be doing exactly what's in the new test from #19..

Wim Leers’s picture

so tbh I would rewrite that method like this to make it more clear:

👍

Also, I was wondering why the test added in […] does not fail […]

I think due to the root cause description given by @timmillwood in #11:

I've been hitting the same issue, we should simply not assume the entity query will return a result. Using reset() will get around this because it doesn't care if the array is empty.

The test added there never tests with zero revisions, I think.

timmillwood’s picture

Taking suggestion from #21.
Removing new test from #19.
Testing in existing webtest.

The last submitted patch, 23: interidff-2914938-23.patch, failed testing. View results

amateescu’s picture

+++ b/core/modules/quickedit/src/Tests/QuickEditLoadingTest.php
@@ -330,6 +330,8 @@ public function testUserWithPermission() {
+    $this->drupalPostForm('node/add/article', ['title[0][value]' => 'foo'], t('Preview'));

We don't need to use t() in test code, unless we're actually testing the translation of that string :)

timmillwood’s picture

Fixing usage of t().

amateescu’s picture

Status: Needs review » Reviewed & tested by the community

Ok, this looks great now!

xjm’s picture

Status: Reviewed & tested by the community » Needs review

This looks a lot like the other EFQ that @amateescu patched previously for revisions; I wonder if we should be abstracting it?

Let's add a comment to the test and maybe some more explicit assertions around it? Otherwise the coverage provided by the POST isn't very clear.

Wim Leers’s picture

Hah, so preview allows us to test the case of "no revisions yet"? But there are no assertions. Interesting! Looking forward to seeing #23's test-only patch fail, because I don't yet understand how it will fail :D

The last submitted patch, 23: 2914938-23-test-only.patch, failed testing. View results

timmillwood’s picture

@Wim Leers

It'll fail with:

Exception Notice     quickedit.module   196 _quickedit_entity_is_latest_revisio
    Undefined offset: 0
Exception Notice     quickedit.module   196 _quickedit_entity_is_latest_revisio
    Undefined offset: 0
Exception Notice     quickedit.module   196 _quickedit_entity_is_latest_revisio
    Undefined offset: 0
Exception Notice     quickedit.module   196 _quickedit_entity_is_latest_revisio
    Undefined offset: 0
Wim Leers’s picture

Heh, I guess that works. But apparently @xjm independently raised the same concern. Testing failures through "undefined offset" notices isn't very explicit.

I think we can explicitly test this by repeating the same assertions checking absence? These:

    $this->assertNoRaw('data-quickedit-entity-id="node/' . $this->testNode->id() . '"');
    $this->assertNoRaw('data-quickedit-field-id="node/' . $this->testNode->id() . '/title/' . $this->testNode->language()->getId() . '/full"');
timmillwood’s picture

In #2924724: Add an API to create a new revision correctly handling multilingual pending revisions there is a patch to add a getLatestRevisionId() method which could be used here.

@wimleers - the issue is that when there are no revisions returned by the query it throws a notice, but no real error so the function returns false, which means the quickedit elements are still rendered. So unless warnings and errors are enabled, there's no way to know it failed. One option is to create an unsaved entity object and pass it to the function directly within the webtest.

amateescu’s picture

Status: Needs review » Needs work

This looks a lot like the other EFQ that @amateescu patched previously for revisions; I wonder if we should be abstracting it?

Like @timmillwood mentioned above, #2924724: Add an API to create a new revision correctly handling multilingual pending revisions is the issue which adds a "get latest revision ID" helper to its proper place, the entity storage. However, I think this issue is more advanced in the core review process so it can go in before that, so we need to update the @todo from _quickedit_entity_is_latest_revision to mentioned the issue linked above instead of #2784201: Track the latest_revision and latest_revision_translation_affected ID in the entity data table for revisionable entity types.

As for testing failures through "undefined offset" notices, #33 explains why we can not test this by asserting the return value of that function, so "undefined offset" notices is really the only thing we have to rely on :)

NW for changing the @todo and then it can go back to RTBC in my opinion.

timmillwood’s picture

amateescu’s picture

Status: Needs review » Reviewed & tested by the community

@xjm, I've split the part from #2924724: Add an API to create a new revision correctly handling multilingual pending revisions which will actually allow us to remove this quickedit helper in 8.5.x into #2926483: Add API methods for determining whether an entity object is the latest (translation-affecting) revision

Given the new issue and the comments above, I think the existing patch is fine as a bugfix for 8.4.x.

xjm’s picture

Status: Reviewed & tested by the community » Needs review

Were we going to add that @todo though?

timmillwood’s picture

Status: Needs review » Reviewed & tested by the community

@xjm - there's already a @todo pointing to #2784201: Track the latest_revision and latest_revision_translation_affected ID in the entity data table for revisionable entity types similar to other places where we're getting the latest revision ID.

We could replace with #2924724: Add an API to create a new revision correctly handling multilingual pending revisions or #2926483: Add API methods for determining whether an entity object is the latest (translation-affecting) revision, but all three offer a way to improve or remove this function.

I'd rather have consistency of all places pointing to the same todo.

xjm’s picture

I'm sorry, I keep reading the patch and I don't see it...

xjm’s picture

Oh ah, there's already a @todo on the docblock for the function in HEAD, which doesn't appear in the diff. Sorry, that wasn't clear to me before. :)

timmillwood’s picture

Sorry for the confusion @xjm 😋

xjm’s picture

Status: Reviewed & tested by the community » Needs work
FileSize
2.17 KB
651 bytes

So the thing with the unexplained drupalPostForm() (that has no assertions but yet provides actual coverage) still bothers me; I feel like we should at least assert the expected content on preview.

For now I added a comment (in the attached), but it'd be great if we could assert something so that we're explictly testing a specific code path/bit of functionality. I agree we shouldn't assert the absence of a notice or anything, but we should also have a positive assertion to show that the preview post actually did anything.

Edit: clarity.

timmillwood’s picture

@xjm - here's a new patch which asserts the quick edit items do not appear on the preview page, also in the two cases the quick edit items don't appear I've added an assertion on the status code to make sure the page is actually loading with no "403" or "404" type responses, which would also prevent the quick edit items from appearing.

Status: Reviewed & tested by the community » Needs work

The last submitted patch, 43: 2927248-5.patch, failed testing. View results

timmillwood’s picture

Status: Needs work » Needs review
FileSize
1.31 KB
2.85 KB

Helps if I upload the patch for the correct issue!

🍵

nevergone’s picture

#45 tested and works well!

Manuel Garcia’s picture

#45 looks good to go, just one nitpick about the comment:

+++ b/core/modules/quickedit/src/Tests/QuickEditLoadingTest.php
@@ -330,6 +330,12 @@ public function testUserWithPermission() {
+    // Verify that the preview is loaded correctly.

While the assertions are valid here to prove that quickedit is not showing on preview, we should change the comment on this block to explain that this is what we are proving.

Manuel Garcia’s picture

Status: Needs review » Reviewed & tested by the community
FileSize
821 bytes
2.89 KB

Just went ahead and added the comment that I meant on #47 since Tim is busy with other things, in the hope to keep this moving forward =)

Setting this back to RTBC because I believe that #45 addressed #42, #46 looks to agree, and this is just a small comment clarifying the intention.

timmillwood’s picture

Thanks @Manuel Garcia!
+1 RTBC.

Status: Reviewed & tested by the community » Needs work

The last submitted patch, 48: 2914938-48.patch, failed testing. View results

timmillwood’s picture

Status: Needs work » Reviewed & tested by the community

DrupalCI fail, back to RTBC.

catch’s picture

Status: Reviewed & tested by the community » Fixed

Committed/pushed to 8.5.x and cherry-picked to 8.4.x. Thanks!

  • catch committed 522ed00 on 8.5.x
    Issue #2914938 by timmillwood, RajabNatshah, xjm, Manuel Garcia,...

  • catch committed d661485 on 8.4.x
    Issue #2914938 by timmillwood, RajabNatshah, xjm, Manuel Garcia,...

Status: Fixed » Closed (fixed)

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