You are here

public function QuickEditLoadingTest::testUserWithPermission in Zircon Profile 8

Same name and namespace in other branches
  1. 8.0 core/modules/quickedit/src/Tests/QuickEditLoadingTest.php \Drupal\quickedit\Tests\QuickEditLoadingTest::testUserWithPermission()

Tests the loading of Quick Edit when a user does have access to it.

Also ensures lazy loading of in-place editors works.

File

core/modules/quickedit/src/Tests/QuickEditLoadingTest.php, line 147
Contains \Drupal\quickedit\Tests\QuickEditLoadingTest.

Class

QuickEditLoadingTest
Tests loading of in-place editing functionality and lazy loading of its in-place editors.

Namespace

Drupal\quickedit\Tests

Code

public function testUserWithPermission() {
  $this
    ->drupalLogin($this->editorUser);
  $this
    ->drupalGet('node/1');

  // Library and in-place editors.
  $settings = $this
    ->getDrupalSettings();
  $libraries = explode(',', $settings['ajaxPageState']['libraries']);
  $this
    ->assertTrue(in_array('quickedit/quickedit', $libraries), 'Quick Edit library loaded.');
  $this
    ->assertFalse(in_array('quickedit/quickedit.inPlaceEditor.form', $libraries), "'form' in-place editor not loaded.");

  // HTML annotation must always exist (to not break the render cache).
  $this
    ->assertRaw('data-quickedit-entity-id="node/1"');
  $this
    ->assertRaw('data-quickedit-field-id="node/1/body/en/full"');

  // There should be only one revision so far.
  $node = Node::load(1);
  $vids = \Drupal::entityManager()
    ->getStorage('node')
    ->revisionIds($node);
  $this
    ->assertIdentical(1, count($vids), 'The node has only one revision.');
  $original_log = $node->revision_log->value;

  // Retrieving the metadata should result in a 200 JSON response.
  $htmlPageDrupalSettings = $this->drupalSettings;
  $post = array(
    'fields[0]' => 'node/1/body/en/full',
  );
  $response = $this
    ->drupalPostWithFormat('quickedit/metadata', 'json', $post);
  $this
    ->assertResponse(200);
  $expected = array(
    'node/1/body/en/full' => array(
      'label' => 'Body',
      'access' => TRUE,
      'editor' => 'form',
    ),
  );
  $this
    ->assertIdentical(Json::decode($response), $expected, 'The metadata HTTP request answers with the correct JSON response.');

  // Restore drupalSettings to build the next requests; simpletest wipes them
  // after a JSON response.
  $this->drupalSettings = $htmlPageDrupalSettings;

  // Retrieving the attachments should result in a 200 response, containing:
  //  1. a settings command with useless metadata: AjaxController is dumb
  //  2. an insert command that loads the required in-place editors
  $post = array(
    'editors[0]' => 'form',
  ) + $this
    ->getAjaxPageStatePostData();
  $response = $this
    ->drupalPost('quickedit/attachments', 'application/vnd.drupal-ajax', $post);
  $ajax_commands = Json::decode($response);
  $this
    ->assertIdentical(2, count($ajax_commands), 'The attachments HTTP request results in two AJAX commands.');

  // First command: settings.
  $this
    ->assertIdentical('settings', $ajax_commands[0]['command'], 'The first AJAX command is a settings command.');

  // Second command: insert libraries into DOM.
  $this
    ->assertIdentical('insert', $ajax_commands[1]['command'], 'The second AJAX command is an append command.');
  $this
    ->assertTrue(in_array('quickedit/quickedit.inPlaceEditor.form', explode(',', $ajax_commands[0]['settings']['ajaxPageState']['libraries'])), 'The quickedit.inPlaceEditor.form library is loaded.');

  // Retrieving the form for this field should result in a 200 response,
  // containing only a quickeditFieldForm command.
  $post = array(
    'nocssjs' => 'true',
    'reset' => 'true',
  ) + $this
    ->getAjaxPageStatePostData();
  $response = $this
    ->drupalPost('quickedit/form/' . 'node/1/body/en/full', 'application/vnd.drupal-ajax', $post);
  $this
    ->assertResponse(200);
  $ajax_commands = Json::decode($response);
  $this
    ->assertIdentical(1, count($ajax_commands), 'The field form HTTP request results in one AJAX command.');
  $this
    ->assertIdentical('quickeditFieldForm', $ajax_commands[0]['command'], 'The first AJAX command is a quickeditFieldForm command.');
  $this
    ->assertIdentical('<form ', Unicode::substr($ajax_commands[0]['data'], 0, 6), 'The quickeditFieldForm command contains a form.');

  // Prepare form values for submission. drupalPostAjaxForm() is not suitable
  // for handling pages with JSON responses, so we need our own solution here.
  $form_tokens_found = preg_match('/\\sname="form_token" value="([^"]+)"/', $ajax_commands[0]['data'], $token_match) && preg_match('/\\sname="form_build_id" value="([^"]+)"/', $ajax_commands[0]['data'], $build_id_match);
  $this
    ->assertTrue($form_tokens_found, 'Form tokens found in output.');
  if ($form_tokens_found) {
    $edit = array(
      'body[0][summary]' => '',
      'body[0][value]' => '<p>Fine thanks.</p>',
      'body[0][format]' => 'filtered_html',
      'op' => t('Save'),
    );
    $post = array(
      'form_id' => 'quickedit_field_form',
      'form_token' => $token_match[1],
      'form_build_id' => $build_id_match[1],
    );
    $post += $edit + $this
      ->getAjaxPageStatePostData();

    // Submit field form and check response. This should store the updated
    // entity in PrivateTempStore on the server.
    $response = $this
      ->drupalPost('quickedit/form/' . 'node/1/body/en/full', 'application/vnd.drupal-ajax', $post);
    $this
      ->assertResponse(200);
    $ajax_commands = Json::decode($response);
    $this
      ->assertIdentical(1, count($ajax_commands), 'The field form HTTP request results in one AJAX command.');
    $this
      ->assertIdentical('quickeditFieldFormSaved', $ajax_commands[0]['command'], 'The first AJAX command is a quickeditFieldFormSaved command.');
    $this
      ->assertTrue(strpos($ajax_commands[0]['data'], 'Fine thanks.'), 'Form value saved and printed back.');
    $this
      ->assertIdentical($ajax_commands[0]['other_view_modes'], array(), 'Field was not rendered in any other view mode.');

    // Ensure the text on the original node did not change yet.
    $this
      ->drupalGet('node/1');
    $this
      ->assertText('How are you?');

    // Save the entity by moving the PrivateTempStore values to entity storage.
    $post = array(
      'nocssjs' => 'true',
    );
    $response = $this
      ->drupalPostWithFormat('quickedit/entity/' . 'node/1', 'json', $post);
    $this
      ->assertResponse(200);
    $ajax_commands = Json::decode($response);
    $this
      ->assertIdentical(1, count($ajax_commands), 'The entity submission HTTP request results in one AJAX command.');
    $this
      ->assertIdentical('quickeditEntitySaved', $ajax_commands[0]['command'], 'The first AJAX command is a quickeditEntitySaved command.');
    $this
      ->assertIdentical($ajax_commands[0]['data']['entity_type'], 'node', 'Saved entity is of type node.');
    $this
      ->assertIdentical($ajax_commands[0]['data']['entity_id'], '1', 'Entity id is 1.');

    // Ensure the text on the original node did change.
    $this
      ->drupalGet('node/1');
    $this
      ->assertText('Fine thanks.');

    // Ensure no new revision was created and the log message is unchanged.
    $node = Node::load(1);
    $vids = \Drupal::entityManager()
      ->getStorage('node')
      ->revisionIds($node);
    $this
      ->assertIdentical(1, count($vids), 'The node has only one revision.');
    $this
      ->assertIdentical($original_log, $node->revision_log->value, 'The revision log message is unchanged.');

    // Now configure this node type to create new revisions automatically,
    // then again retrieve the field form, fill it, submit it (so it ends up
    // in PrivateTempStore) and then save the entity. Now there should be two
    // revisions.
    $node_type = NodeType::load('article');
    $node_type
      ->setNewRevision(TRUE);
    $node_type
      ->save();

    // Retrieve field form.
    $post = array(
      'nocssjs' => 'true',
      'reset' => 'true',
    );
    $response = $this
      ->drupalPost('quickedit/form/' . 'node/1/body/en/full', 'application/vnd.drupal-ajax', $post);
    $this
      ->assertResponse(200);
    $ajax_commands = Json::decode($response);
    $this
      ->assertIdentical(1, count($ajax_commands), 'The field form HTTP request results in one AJAX command.');
    $this
      ->assertIdentical('quickeditFieldForm', $ajax_commands[0]['command'], 'The first AJAX command is a quickeditFieldForm command.');
    $this
      ->assertIdentical('<form ', Unicode::substr($ajax_commands[0]['data'], 0, 6), 'The quickeditFieldForm command contains a form.');

    // Submit field form.
    preg_match('/\\sname="form_token" value="([^"]+)"/', $ajax_commands[0]['data'], $token_match);
    preg_match('/\\sname="form_build_id" value="([^"]+)"/', $ajax_commands[0]['data'], $build_id_match);
    $edit['body[0][value]'] = '<p>kthxbye</p>';
    $post = array(
      'form_id' => 'quickedit_field_form',
      'form_token' => $token_match[1],
      'form_build_id' => $build_id_match[1],
    );
    $post += $edit + $this
      ->getAjaxPageStatePostData();
    $response = $this
      ->drupalPost('quickedit/form/' . 'node/1/body/en/full', 'application/vnd.drupal-ajax', $post);
    $this
      ->assertResponse(200);
    $ajax_commands = Json::decode($response);
    $this
      ->assertIdentical(1, count($ajax_commands), 'The field form HTTP request results in one AJAX command.');
    $this
      ->assertIdentical('quickeditFieldFormSaved', $ajax_commands[0]['command'], 'The first AJAX command is an quickeditFieldFormSaved command.');
    $this
      ->assertTrue(strpos($ajax_commands[0]['data'], 'kthxbye'), 'Form value saved and printed back.');

    // Save the entity.
    $post = array(
      'nocssjs' => 'true',
    );
    $response = $this
      ->drupalPostWithFormat('quickedit/entity/' . 'node/1', 'json', $post);
    $this
      ->assertResponse(200);
    $ajax_commands = Json::decode($response);
    $this
      ->assertIdentical(1, count($ajax_commands));
    $this
      ->assertIdentical('quickeditEntitySaved', $ajax_commands[0]['command'], 'The first AJAX command is an quickeditEntitySaved command.');
    $this
      ->assertEqual($ajax_commands[0]['data'], [
      'entity_type' => 'node',
      'entity_id' => 1,
    ], 'Updated entity type and ID returned');

    // Test that a revision was created with the correct log message.
    $vids = \Drupal::entityManager()
      ->getStorage('node')
      ->revisionIds(Node::load(1));
    $this
      ->assertIdentical(2, count($vids), 'The node has two revisions.');
    $revision = node_revision_load($vids[0]);
    $this
      ->assertIdentical($original_log, $revision->revision_log->value, 'The first revision log message is unchanged.');
    $revision = node_revision_load($vids[1]);
    $this
      ->assertIdentical('Updated the <em class="placeholder">Body</em> field through in-place editing.', $revision->revision_log->value, 'The second revision log message was correctly generated by Quick Edit module.');
  }
}