feedback-3.x-dev/tests/src/Functional/CreateReadUpdateDeleteMessageTest.php

tests/src/Functional/CreateReadUpdateDeleteMessageTest.php
<?php

namespace Drupal\Tests\feedback\Functional;

use Drupal\Core\Entity\EntityStorageInterface;
use Drupal\Core\Url;
use Drupal\Tests\BrowserTestBase;
use Drupal\feedback\Entity\FeedbackMessage;
use Drupal\user\UserInterface;

/**
 * Test that feedback messages can be added, viewed, changed, and deleted.
 *
 * @group feedback
 */
class CreateReadUpdateDeleteMessageTest extends BrowserTestBase {

  /**
   * {@inheritdoc}
   */
  protected static $modules = ['feedback', 'block'];

  /**
   * {@inheritdoc}
   */
  protected $defaultTheme = 'stark';

  /**
   * A published feedback message we will use during the tests.
   *
   * @var \Drupal\feedback\Entity\FeedbackMessage
   */
  protected FeedbackMessage $publishedMessage;

  /**
   * The body of the published feedback message we will use during the tests.
   *
   * @var string
   */
  protected string $publishedMessageBody;

  /**
   * An unpublished feedback message we will use during the tests.
   *
   * @var \Drupal\feedback\Entity\FeedbackMessage
   */
  protected FeedbackMessage $unpublishedMessage;

  /**
   * The body of the unpublished feedback message we will use during the tests.
   *
   * @var string
   */
  protected string $unpublishedMessageBody;

  /**
   * The ID of the user who submitted the feedback message we are testing with.
   *
   * @var \Drupal\user\UserInterface
   */
  protected UserInterface $unpublishedMessageSender;

  /**
   * {@inheritdoc}
   */
  protected function setUp(): void {
    parent::setUp();

    // Setup: Create a user account that we can say sent a message. Note since
    // we are creating the messages programmatically, the permissions don't
    // really matter.
    $this->unpublishedMessageSender = $this->createUser(['add feedback message entities']);

    // Setup: Programmatically create two messages.
    $common = [
      'type' => 'default_feedback',
      'link' => 'internal:/node',
      'langcode' => 'en',
      'created' => time(),
      'changed' => time(),
    ];
    $this->publishedMessageBody = \trim($this->getRandomGenerator()->paragraphs(1));
    $this->publishedMessage = FeedbackMessage::create([
      'status' => 1,
      'body' => $this->publishedMessageBody,
      'user_id' => 0,
    ] + $common);
    $this->publishedMessage->save();
    $this->unpublishedMessageBody = \trim($this->getRandomGenerator()->paragraphs(1));
    $this->unpublishedMessage = FeedbackMessage::create([
      'status' => 0,
      'body' => $this->unpublishedMessageBody,
      'user_id' => $this->unpublishedMessageSender->id(),
    ] + $common);
    $this->unpublishedMessage->save();
  }

  /**
   * Test that a user with correct permissions can create a feedback message.
   */
  public function testCreateMessage(): void {
    // Setup: Place the feedback block.
    $this->placeBlock('feedback_block', [
      'id' => 'test_feedback_block',
      'feedback_type' => 'default_feedback',
      'feedback_help' => 'Help text',
      'feedback_submit' => 'Submit feedback',
    ]);

    // Setup: Log in as a user with permission to create a feedback message.
    $this->drupalLogin($this->createUser(['add feedback message entities']));

    // Setup: Navigate to a page with a feedback message form.
    $this->drupalGet('<front>');
    $feedbackMessage = \trim($this->getRandomGenerator()->paragraphs(1));
    $this->submitForm([
      'body[0][value]' => $feedbackMessage,
    ], 'Submit');

    // Assertions: Check that we got the status message we expected.
    $this->assertSession()->statusMessageContains('Thank you for your feedback.');

    // Assertions: Check that we can load the feedback message that was just
    // submitted.
    $messages = $this->getMessageStorage()->loadByProperties([
      'body' => $feedbackMessage,
    ]);
    $this->assertIsArray($messages);
    $this->assertCount(1, $messages);
    $submittedMessage = reset($messages);
    $this->assertInstanceOf(FeedbackMessage::class, $submittedMessage);
    $this->assertEquals($feedbackMessage, $submittedMessage->get('body')->first()->getValue()['value']);
  }

  /**
   * Test that a user with correct permissions can delete a feedback message.
   */
  public function testDeleteMessage(): void {
    // Setup: Log in as a user with permission to delete a feedback message.
    $this->drupalLogin($this->createUser(['delete feedback message entities']));

    // Setup: Store the message ID so we can try to load it after deleting.
    $publishedMessageId = $this->publishedMessage->id();

    // Setup: Navigate to the delete form for a published message.
    $this->drupalGet($this->publishedMessage->toUrl('delete-form'));

    // System under test: Submit the form.
    $this->submitForm([], 'Delete');

    // Assertions: Check that the message was deleted.
    $this->assertNull($this->getMessageStorage()->load($publishedMessageId));

    // Setup: Store the message ID so we can try to load it after deleting.
    $unpublishedMessageId = $this->unpublishedMessage->id();

    // Setup: Navigate to the delete form for an unpublished message.
    $this->drupalGet($this->unpublishedMessage->toUrl('delete-form'));

    // System under test: Submit the form.
    $this->submitForm([], 'Delete');

    // Assertions: Check that the message was deleted.
    $this->assertNull($this->getMessageStorage()->load($unpublishedMessageId));
  }

  /**
   * Test that the Feedback Message list works as-intended.
   */
  public function testListMessages(): void {
    // Setup: Log in as a user with permission to see the feedback message list.
    $this->drupalLogin($this->createUser([
      'access feedback message list',
    ]));

    // System under test: Load the Feedback Message List page.
    $this->drupalGet(Url::fromRoute('entity.feedback_message.collection'));

    // Assertions: Check that the feedback message list appears.
    $this->assertSession()->elementExists('xpath', $this->assertSession()->buildXPathQuery('//table//th[1][text()="Feedback message ID"]'));
    $this->assertSession()->elementExists('xpath', $this->assertSession()->buildXPathQuery('//table//th[2][text()="Name"]'));
    $this->assertSession()->elementExists('xpath', $this->assertSession()->buildXPathQuery('//table//th[3][text()="Path"]'));
    $this->assertSession()->elementExists('xpath', $this->assertSession()->buildXPathQuery('//table//th[4][text()="User"]'));
    $this->assertSession()->elementExists('xpath', $this->assertSession()->buildXPathQuery('//table//th[5][text()="Operations"]'));

    // Assertions: Check there is a row for the published message we created in
    // the setUp.
    $this->assertSession()->elementExists('xpath', $this->assertSession()->buildXPathQuery('//table//tr/td[1][.=:message_id]', [
      ':message_id' => $this->publishedMessage->id(),
    ]));
    $this->assertSession()->elementExists('xpath', $this->assertSession()->buildXPathQuery('//table//tr/td[2]//a[@href=:message_url][.=:message_label]', [
      ':message_url' => $this->publishedMessage->toUrl('canonical')->toString(),
      ':message_label' => 'Feedback message ' . $this->publishedMessage->id(),
    ]));
    // It is unclear how to get the URL in the same format as what's displayed
    // in the table (e.g.: 'internal:/user/2?check_logged_in=1') in the setUp()
    // function before we submit the form. Creating a Url::fromRoute('<front>'),
    // storing it, visiting it, and parsing it here returns 'route:<front>', '',
    // or '/' (depending on the function called), which isn't helpful. Asking
    // the driver for the current URL gives us 'http://web/user/2' or '/user/2',
    // but not the HTTP GET query string at the end. So the best we can do here
    // is check that the text starts with the substring 'internal:'.
    $this->assertSession()->elementExists('xpath', $this->assertSession()->buildXPathQuery('//table//tr/td[3][starts-with(text(),"internal:/")]'));
    $this->assertSession()->elementExists('xpath', $this->assertSession()->buildXPathQuery('//table//tr/td[4][.="Anonymous"]'));
    $this->assertSession()->elementExists('xpath', $this->assertSession()->buildXPathQuery('//table//tr/td[5][.=""]'));

    // Assertions: Check there is a row for the unpublished message we created
    // in the setUp.
    $this->assertSession()->elementExists('xpath', $this->assertSession()->buildXPathQuery('//table//tr/td[1][.=:message_id]', [
      ':message_id' => $this->unpublishedMessage->id(),
    ]));
    $this->assertSession()->elementExists('xpath', $this->assertSession()->buildXPathQuery("//table//tr/td[2]//a[@href=:message_url][.=:message_label]", [
      ':message_url' => $this->unpublishedMessage->toUrl('canonical')->toString(),
      ':message_label' => 'Feedback message ' . $this->unpublishedMessage->id(),
    ]));
    // It is unclear how to get the URL in the same format as what's displayed
    // in the table (e.g.: 'internal:/user/2?check_logged_in=1') in the setUp()
    // function before we submit the form. Creating a Url::fromRoute('<front>'),
    // storing it, visiting it, and parsing it here returns 'route:<front>', '',
    // or '/' (depending on the function called), which isn't helpful. Asking
    // the driver for the current URL gives us 'http://web/user/2' or '/user/2',
    // but not the HTTP GET query string at the end. So the best we can do here
    // is check that the text starts with the substring 'internal:'.
    $this->assertSession()->elementExists('xpath', $this->assertSession()->buildXPathQuery('//table//tr/td[3][starts-with(text(),"internal:/")]'));
    $this->assertSession()->elementExists('xpath', $this->assertSession()->buildXPathQuery("//table//tr/td[4]//a[@href=:message_sender_url]", [
      ':message_sender_url' => $this->unpublishedMessageSender->toUrl('canonical')->toString(),
    ]));
    $this->assertSession()->elementExists('xpath', $this->assertSession()->buildXPathQuery('//table//tr/td[5][.=""]'));
  }

  /**
   * Test that a user with correct permissions can edit a feedback message.
   */
  public function testUpdateMessage(): void {
    // Setup: Log in as a user with permission to update a feedback message.
    $this->drupalLogin($this->createUser(['edit feedback message entities']));

    // System under test: Navigate to the edit form for a published message.
    $this->drupalGet($this->publishedMessage->toUrl('edit-form'));

    // Assertions: Check that we can see the fields we expect.
    $this->assertSession()->fieldExists('body[0][value]');
    $this->assertSession()->fieldValueEquals('body[0][value]', $this->publishedMessageBody);
    $this->assertSession()->buttonExists('Save');

    // System under test: Edit some fields and submit the form.
    $newPublishedMessageBody = \trim($this->getRandomGenerator()->paragraphs(1));
    $this->submitForm([
      'body[0][value]' => $newPublishedMessageBody,
    ], 'Save');

    // Assertions: Check that the message was changed.
    $this->assertSession()->statusMessageContains("Saved the Feedback message {$this->publishedMessage->id()} Feedback message.");
    $this->assertSession()->fieldValueNotEquals('body[0][value]', $this->publishedMessageBody);
    $this->assertSession()->fieldValueEquals('body[0][value]', $newPublishedMessageBody);

    // System under test: Navigate to the edit form for an unpublished message.
    $this->drupalGet($this->unpublishedMessage->toUrl('edit-form'));

    // Assertions: Check that we can see the fields we expect.
    $this->assertSession()->fieldExists('body[0][value]');
    $this->assertSession()->fieldValueEquals('body[0][value]', $this->unpublishedMessageBody);
    $this->assertSession()->buttonExists('Save');

    // System under test: Edit some fields and submit the form.
    $newUnpublishedMessageBody = \trim($this->getRandomGenerator()->paragraphs(1));
    $this->submitForm([
      'body[0][value]' => $newUnpublishedMessageBody,
    ], 'Save');

    // Assertions: Check that the message was changed.
    $this->assertSession()->statusMessageContains("Saved the Feedback message {$this->unpublishedMessage->id()} Feedback message.");
    $this->assertSession()->fieldValueNotEquals('body[0][value]', $this->unpublishedMessageBody);
    $this->assertSession()->fieldValueEquals('body[0][value]', $newUnpublishedMessageBody);
  }

  /**
   * Test that a user with correct permissions can view a message.
   */
  public function testViewMessage(): void {
    // Setup: Log in as a user with permission to view a published message.
    $this->drupalLogin($this->createUser(['view published feedback message entities']));

    // System under test: Try to view a published message.
    $this->drupalGet($this->publishedMessage->toUrl('canonical'));

    // Assertions: Check we can see the message and URL it was submitted from.
    $this->assertSession()->pageTextContains($this->publishedMessageBody);
    $this->assertSession()->pageTextContains('internal:/node');

    // System under test: Try to view an unpublished message.
    $this->drupalGet($this->unpublishedMessage->toUrl('canonical'));

    // Assertions: Check that we cannot see the message.
    $this->assertSession()->pageTextContains('You are not authorized to access this page.');
    $this->assertSession()->pageTextNotContains($this->unpublishedMessageBody);

    // Setup: Log in as a user with permission to view an unpublished message.
    $this->drupalLogin($this->createUser(['view unpublished feedback message entities']));

    // System under test: Try to view a published message.
    $this->drupalGet($this->publishedMessage->toUrl('canonical'));

    // Assertions: Check that we cannot see the message.
    $this->assertSession()->pageTextContains('You are not authorized to access this page.');
    $this->assertSession()->pageTextNotContains($this->publishedMessageBody);

    // System under test: Try to view an unpublished message.
    $this->drupalGet($this->unpublishedMessage->toUrl('canonical'));

    // Assertions: Check we can see the message and URL it was submitted from.
    $this->assertSession()->pageTextContains($this->unpublishedMessageBody);
    $this->assertSession()->pageTextContains('internal:/node');
  }

  /**
   * Get an entity storage interface for feedback messages.
   *
   * @return \Drupal\Core\Entity\EntityStorageInterface
   *   An entity storage interface for feedback messages.
   */
  protected function getMessageStorage(): EntityStorageInterface {
    return $this->container->get('entity_type.manager')
      ->getStorage('feedback_message');
  }

}

Главная | Обратная связь

drupal hosting | друпал хостинг | it patrol .inc