<?php

namespace Drupal\Tests\acquia_contenthub_publisher\Unit\EventSubscriber\ReplaceEntityIdWithUuid;

use Drupal\acquia_contenthub_publisher\Event\ViewFilterPluginReplaceEntityIdWithUuidEvent;
use Drupal\acquia_contenthub_publisher\EventSubscriber\ReplaceEntityIdWithUuid\NumericViewFilterPlugin;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Entity\EntityStorageInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Logger\RfcLogLevel;
use Drupal\field\FieldStorageConfigInterface;
use Drupal\Tests\acquia_contenthub\Unit\Helpers\LoggerMock;
use Drupal\Tests\UnitTestCase;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
 * Tests replacing entity id with uuid for NumericViewFilterPlugin.
 *
 * @group acquia_contenthub_publisher
 *
 * @package Drupal\Tests\acquia_contenthub_publisher\Unit\EventSubscriber\ReplaceEntityIdWithUuid
 *
 * @coversDefaultClass \Drupal\acquia_contenthub_publisher\EventSubscriber\ReplaceEntityIdWithUuid\NumericViewFilterPlugin
 */
class NumericViewFilterPluginTest extends UnitTestCase {

  /**
   * Test replacing entity id with uuid for NumericViewFilterPlugin.
   *
   * Field type: entity_reference.
   *
   * @covers ::replaceEntityIdWithUuidForViewFilterPlugin
   */
  public function testNumericViewFilterPluginEntityReferenceFieldType() {
    $field_definition = $this->prophesize(FieldStorageConfigInterface::class);
    $field_definition->getType()->willReturn('entity_reference');
    $field_definition->getSettings()->willReturn([
      'target_type' => 'node',
    ]);
    $entity = $this->prophesize(EntityInterface::class);
    $entity->uuid()->willReturn('random-uuid');
    $entity_storage = $this->prophesize(EntityStorageInterface::class);
    $entity_storage->load('node.field_basic_content_type')->willReturn($field_definition->reveal());
    $entity_storage->load(20)->willReturn($entity->reveal());
    $entity_storage->load(1)->willReturn(NULL);
    $entity_storage->load('')->willReturn(NULL);
    $entity_type_manager = $this->prophesize(EntityTypeManagerInterface::class);
    $entity_type_manager->getStorage('field_storage_config')->willReturn($entity_storage);
    $entity_type_manager->getStorage('node')->willReturn($entity_storage);

    $container = $this->prophesize(ContainerInterface::class);
    $container
      ->get('entity_type.manager')
      ->willReturn($entity_type_manager->reveal());
    \Drupal::setContainer($container->reveal());

    $filter_data = [
      'table' => 'node__field_basic_content_type',
      'plugin_id' => 'numeric',
      'value' => [
        'min' => '',
        'max' => '1',
        'value' => 20,
      ],
    ];
    $plugin_id = 'numeric';

    $event = new ViewFilterPluginReplaceEntityIdWithUuidEvent($filter_data, $plugin_id);
    $logger = new LoggerMock();
    $event_subscriber = new NumericViewFilterPlugin($entity_type_manager->reveal(), $logger);
    $event_subscriber->onReplaceEntityIdWithUuid($event);

    $expected_filter_data = [
      'table' => 'node__field_basic_content_type',
      'plugin_id' => 'numeric',
      'value' => [
        'min' => '',
        'max' => '1',
        'value' => 'random-uuid',
      ],
    ];
    $this->assertSame($expected_filter_data, $event->getFilterData());
    $log_messages = $logger->getLogMessages();
    $this->assertNotEmpty($log_messages);
    $this->assertEquals(
      'Entity of type: node and id: 1 not found while serialization of numeric view filter plugin.',
      $log_messages[RfcLogLevel::WARNING][0]
    );
  }

  /**
   * Test replacing entity id with uuid for NumericViewFilterPlugin.
   *
   * Field type: integer.
   *
   * @covers ::replaceEntityIdWithUuidForViewFilterPlugin
   */
  public function testNumericViewFilterPluginIntegerFieldType() {
    $field_definition = $this->prophesize(FieldStorageConfigInterface::class);
    $field_definition->getType()->willReturn('integer');
    $entity_storage = $this->prophesize(EntityStorageInterface::class);
    $entity_storage->load('node.field_age')->willReturn($field_definition->reveal());
    $entity_type_manager = $this->prophesize(EntityTypeManagerInterface::class);
    $entity_type_manager->getStorage('field_storage_config')->willReturn($entity_storage);
    $container = $this->prophesize(ContainerInterface::class);
    $container
      ->get('entity_type.manager')
      ->willReturn($entity_type_manager->reveal());
    \Drupal::setContainer($container->reveal());

    $filter_data = [
      'table' => 'node__field_age',
      'plugin_id' => 'numeric',
      'value' => [
        'min' => '',
        'max' => '',
        'value' => 20,
      ],
    ];
    $plugin_id = 'numeric';

    $event = new ViewFilterPluginReplaceEntityIdWithUuidEvent($filter_data, $plugin_id);
    $event_subscriber = new NumericViewFilterPlugin($entity_type_manager->reveal(), new LoggerMock());
    $event_subscriber->onReplaceEntityIdWithUuid($event);
    $this->assertSame($filter_data, $event->getFilterData());
  }

}
