You are here

public function AdvancedPluginSelectorBaseTest::testValidateSelectorForm in Plugin 8.2

@covers ::validateSelectorForm

File

tests/src/Unit/Plugin/Plugin/PluginSelector/AdvancedPluginSelectorBaseTest.php, line 328

Class

AdvancedPluginSelectorBaseTest
@coversDefaultClass \Drupal\plugin\Plugin\Plugin\PluginSelector\AdvancedPluginSelectorBase

Namespace

Drupal\Tests\plugin\Unit\Plugin\Plugin\PluginSelector

Code

public function testValidateSelectorForm() {
  $plugin_id_a = $this
    ->randomMachineName();
  $plugin_id_b = $this
    ->randomMachineName();
  $form = [
    'container' => [
      '#parents' => [
        'foo',
        'bar',
        'container',
      ],
      'plugin_form' => [
        $this
          ->randomMachineName() => [],
      ],
    ],
  ];
  $plugin_a = $this
    ->getMockForAbstractClass(AdvancedPluginSelectorBaseUnitTestPluginFormPluginInterface::class);
  $plugin_a
    ->expects($this
    ->any())
    ->method('getPluginId')
    ->willReturn($plugin_id_a);
  $plugin_b = $this
    ->getMockForAbstractClass(AdvancedPluginSelectorBaseUnitTestPluginFormPluginInterface::class);
  $plugin_b
    ->expects($this
    ->never())
    ->method('validateConfigurationForm');
  $plugin_b
    ->expects($this
    ->any())
    ->method('getPluginId')
    ->willReturn($plugin_id_b);
  $map = [
    [
      $plugin_id_a,
      [],
      $plugin_a,
    ],
    [
      $plugin_id_b,
      [],
      $plugin_b,
    ],
  ];
  $this->selectablePluginManager
    ->expects($this
    ->exactly(2))
    ->method('createInstance')
    ->willReturnMap($map);

  // The plugin is set for the first time. The plugin form must not be
  // validated, as there is no input for it yet.
  $form_state = $this
    ->createMock(FormStateInterface::class);
  $form_state
    ->expects($this
    ->atLeastOnce())
    ->method('getValues')
    ->willReturn([
    'foo' => [
      'bar' => [
        'container' => [
          'select' => [
            'container' => [
              'plugin_id' => $plugin_id_a,
            ],
          ],
        ],
      ],
    ],
  ]);
  $form_state
    ->expects($this
    ->once())
    ->method('setRebuild');
  $this->sut
    ->validateSelectorForm($form, $form_state);
  $this
    ->assertSame($plugin_a, $this->sut
    ->getSelectedPlugin());

  // The form is validated, but the plugin remains unchanged, and as such
  // should validate its own form as well.
  $form_state = $this
    ->createMock(FormStateInterface::class);
  $form_state
    ->expects($this
    ->atLeastOnce())
    ->method('getValues')
    ->willReturn([
    'foo' => [
      'bar' => [
        'container' => [
          'select' => [
            'container' => [
              'plugin_id' => $plugin_id_a,
            ],
          ],
        ],
      ],
    ],
  ]);
  $form_state
    ->expects($this
    ->never())
    ->method('setRebuild');
  $plugin_a
    ->expects($this
    ->once())
    ->method('validateConfigurationForm')
    ->with($form['container']['plugin_form'], $form_state);
  $this->sut
    ->validateSelectorForm($form, $form_state);
  $this
    ->assertSame($plugin_a, $this->sut
    ->getSelectedPlugin());

  // The plugin has changed. The plugin form must not be validated, as there
  // is no input for it yet.
  $form_state = $this
    ->createMock(FormStateInterface::class);
  $form_state
    ->expects($this
    ->atLeastOnce())
    ->method('getValues')
    ->willReturn([
    'foo' => [
      'bar' => [
        'container' => [
          'select' => [
            'container' => [
              'plugin_id' => $plugin_id_b,
            ],
          ],
        ],
      ],
    ],
  ]);
  $form_state
    ->expects($this
    ->once())
    ->method('setRebuild');
  $this->sut
    ->validateSelectorForm($form, $form_state);
  $this
    ->assertSame($plugin_b, $this->sut
    ->getSelectedPlugin());

  // Change the plugin ID back to the original. No new plugin may be
  // instantiated, nor must the plugin form be validated.
  $form_state = $this
    ->createMock(FormStateInterface::class);
  $form_state
    ->expects($this
    ->atLeastOnce())
    ->method('getValues')
    ->willReturn([
    'foo' => [
      'bar' => [
        'container' => [
          'select' => [
            'container' => [
              'plugin_id' => $plugin_id_a,
            ],
          ],
        ],
      ],
    ],
  ]);
  $form_state
    ->expects($this
    ->once())
    ->method('setRebuild');
  $this->sut
    ->validateSelectorForm($form, $form_state);
  $this
    ->assertSame($plugin_a, $this->sut
    ->getSelectedPlugin());
}