Verified Commit 0b2b2c3b authored by Lee Rowlands's avatar Lee Rowlands
Browse files

fix: #3604077 DiscardLayoutChangesForm/RevertOverridesForm::getDescription do...

fix: #3604077 DiscardLayoutChangesForm/RevertOverridesForm::getDescription do not handle NULL context values

By: georg3
By: quietone
By: danielveza
By: smustgrave
(cherry picked from commit a57059c9dcd93db30dcabbf98d8519d6b480c558)
parent 94755bc7
Loading
Loading
Loading
Loading
Loading
+5 −1
Original line number Diff line number Diff line
@@ -83,15 +83,19 @@ public function getQuestion() {
   * {@inheritdoc}
   */
  public function getDescription() {
    $default = $this->t('Any unsaved changes to the layout will be discarded. This action cannot be undone.');
    try {
      $entity = $this->sectionStorage->getContextValue('entity');
      if ($entity === NULL) {
        return $default;
      }
      return $this->t('Any unsaved changes to the layout for %label will be discarded. This action cannot be undone.', [
        '%label' => $entity->label(),
      ]);
    }
    catch (ContextException) {
      // If the entity is not available, just return a generic message.
      return $this->t('Any unsaved changes to the layout will be discarded. This action cannot be undone.');
      return $default;
    }
  }

+6 −2
Original line number Diff line number Diff line
@@ -84,15 +84,19 @@ public function getQuestion() {
   * {@inheritdoc}
   */
  public function getDescription() {
    $default = $this->t('The layout will be reverted to its default state. All layout modifications and inline blocks will be reset.');
    try {
      $entity = $this->sectionStorage->getContextValue('entity');
      return $this->t("The layout for %label will be reverted to its default state. All layout modifications and inline blocks wil be reset.", [
      if ($entity === NULL) {
        return $default;
      }
      return $this->t("The layout for %label will be reverted to its default state. All layout modifications and inline blocks will be reset.", [
        '%label' => $entity->label(),
      ]);
    }
    catch (ContextException) {
      // If the entity is not available, just return a generic message.
      return $this->t('The layout will be reverted to its default state. All layout modifications and inline blocks will be reset.');
      return $default;
    }
  }

+65 −0
Original line number Diff line number Diff line
<?php

declare(strict_types=1);

namespace Drupal\Tests\layout_builder\Unit;

use Drupal\Component\Plugin\Exception\ContextException;
use Drupal\Core\DependencyInjection\ContainerBuilder;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Messenger\MessengerInterface;
use Drupal\layout_builder\Form\DiscardLayoutChangesForm;
use Drupal\layout_builder\LayoutTempstoreRepositoryInterface;
use Drupal\layout_builder\SectionStorageInterface;
use Drupal\Tests\UnitTestCase;
use PHPUnit\Framework\Attributes\CoversClass;
use PHPUnit\Framework\Attributes\Group;

/**
 * Tests the Layout Builder discard layout form.
 */
#[CoversClass(DiscardLayoutChangesForm::class)]
#[Group('layout_builder')]
class DiscardLayoutChangesFormTest extends UnitTestCase {

  /**
   * Tests ::getDescription() with entity, NULL, and ContextException cases.
   */
  public function testGetDescription(): void {
    $container = new ContainerBuilder();
    $container->set('string_translation', $this->getStringTranslationStub());
    \Drupal::setContainer($container);

    $form = new DiscardLayoutChangesForm(
      $this->prophesize(LayoutTempstoreRepositoryInterface::class)->reveal(),
      $this->prophesize(MessengerInterface::class)->reveal(),
    );

    $reflection = new \ReflectionProperty(DiscardLayoutChangesForm::class, 'sectionStorage');
    $default = 'Any unsaved changes to the layout will be discarded. This action cannot be undone.';

    // Test entity label.
    $entity = $this->prophesize(EntityInterface::class);
    $entity->label()->willReturn('My Node');
    $section_storage = $this->prophesize(SectionStorageInterface::class);
    $section_storage->getContextValue('entity')->willReturn($entity->reveal());
    $reflection->setValue($form, $section_storage->reveal());
    $this->assertSame(
      'Any unsaved changes to the layout for <em class="placeholder">My Node</em> will be discarded. This action cannot be undone.',
      (string) $form->getDescription(),
    );

    // Test NULL context.
    $section_storage = $this->prophesize(SectionStorageInterface::class);
    $section_storage->getContextValue('entity')->willReturn(NULL);
    $reflection->setValue($form, $section_storage->reveal());
    $this->assertSame($default, (string) $form->getDescription());

    // Test exception.
    $section_storage = $this->prophesize(SectionStorageInterface::class);
    $section_storage->getContextValue('entity')->willThrow(new ContextException());
    $reflection->setValue($form, $section_storage->reveal());
    $this->assertSame($default, (string) $form->getDescription());
  }

}
+65 −0
Original line number Diff line number Diff line
<?php

declare(strict_types=1);

namespace Drupal\Tests\layout_builder\Unit;

use Drupal\Component\Plugin\Exception\ContextException;
use Drupal\Core\DependencyInjection\ContainerBuilder;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Messenger\MessengerInterface;
use Drupal\layout_builder\Form\RevertOverridesForm;
use Drupal\layout_builder\LayoutTempstoreRepositoryInterface;
use Drupal\layout_builder\OverridesSectionStorageInterface;
use Drupal\Tests\UnitTestCase;
use PHPUnit\Framework\Attributes\CoversClass;
use PHPUnit\Framework\Attributes\Group;

/**
 * Tests the Layout Builder revert overrides form.
 */
#[CoversClass(RevertOverridesForm::class)]
#[Group('layout_builder')]
class RevertOverridesFormTest extends UnitTestCase {

  /**
   * Tests ::getDescription() with entity, NULL, and ContextException cases.
   */
  public function testGetDescription(): void {
    $container = new ContainerBuilder();
    $container->set('string_translation', $this->getStringTranslationStub());
    \Drupal::setContainer($container);

    $form = new RevertOverridesForm(
      $this->prophesize(LayoutTempstoreRepositoryInterface::class)->reveal(),
      $this->prophesize(MessengerInterface::class)->reveal(),
    );

    $reflection = new \ReflectionProperty(RevertOverridesForm::class, 'sectionStorage');
    $default = 'The layout will be reverted to its default state. All layout modifications and inline blocks will be reset.';

    // Test entity label.
    $entity = $this->prophesize(EntityInterface::class);
    $entity->label()->willReturn('My Node');
    $section_storage = $this->prophesize(OverridesSectionStorageInterface::class);
    $section_storage->getContextValue('entity')->willReturn($entity->reveal());
    $reflection->setValue($form, $section_storage->reveal());
    $this->assertSame(
      'The layout for <em class="placeholder">My Node</em> will be reverted to its default state. All layout modifications and inline blocks will be reset.',
      (string) $form->getDescription(),
    );

    // Test NULL context.
    $section_storage = $this->prophesize(OverridesSectionStorageInterface::class);
    $section_storage->getContextValue('entity')->willReturn(NULL);
    $reflection->setValue($form, $section_storage->reveal());
    $this->assertSame($default, (string) $form->getDescription());

    // Test exception.
    $section_storage = $this->prophesize(OverridesSectionStorageInterface::class);
    $section_storage->getContextValue('entity')->willThrow(new ContextException());
    $reflection->setValue($form, $section_storage->reveal());
    $this->assertSame($default, (string) $form->getDescription());
  }

}