<?php

declare(strict_types=1);

namespace Drupal\Tests\Core\Config;

use Drupal\Core\Config\Config;
use Drupal\Core\Config\ConfigFactory;
use Drupal\Tests\UnitTestCase;
use PHPUnit\Framework\Attributes\CoversClass;
use PHPUnit\Framework\Attributes\Group;
use Symfony\Component\DependencyInjection\ContainerBuilder;

/**
 * Tests Drupal\Core\Config\ConfigFactory.
 */
#[CoversClass(ConfigFactory::class)]
#[Group('Config')]
class ConfigFactoryTest extends UnitTestCase {

  /**
   * Config factory under test.
   *
   * @var \Drupal\Core\Config\ConfigFactory
   */
  protected $configFactory;

  /**
   * Storage.
   *
   * @var \Drupal\Core\Config\StorageInterface|\PHPUnit\Framework\MockObject\MockObject
   */
  protected $storage;

  /**
   * Event Dispatcher.
   *
   * @var \Symfony\Contracts\EventDispatcher\EventDispatcherInterface|\PHPUnit\Framework\MockObject\MockObject
   */
  protected $eventDispatcher;

  /**
   * Typed Config.
   *
   * @var \Drupal\Core\Config\TypedConfigManagerInterface|\PHPUnit\Framework\MockObject\MockObject
   */
  protected $typedConfig;

  /**
   * The mocked cache tags invalidator.
   *
   * @var \Drupal\Core\Cache\CacheTagsInvalidatorInterface|\PHPUnit\Framework\MockObject\MockObject
   */
  protected $cacheTagsInvalidator;

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

    $this->storage = $this->createMock('Drupal\Core\Config\StorageInterface');
    $this->eventDispatcher = $this->createMock('Symfony\Contracts\EventDispatcher\EventDispatcherInterface');
    $this->typedConfig = $this->createMock('\Drupal\Core\Config\TypedConfigManagerInterface');
    $this->configFactory = new ConfigFactory($this->storage, $this->eventDispatcher, $this->typedConfig);

    $this->cacheTagsInvalidator = $this->createMock('Drupal\Core\Cache\CacheTagsInvalidatorInterface');

    $container = new ContainerBuilder();
    $container->set('cache_tags.invalidator', $this->cacheTagsInvalidator);
    \Drupal::setContainer($container);
  }

  /**
   * Tests rename.
   */
  public function testRename(): void {
    $old = new Config($this->randomMachineName(), $this->storage, $this->eventDispatcher, $this->typedConfig);
    $new = new Config($this->randomMachineName(), $this->storage, $this->eventDispatcher, $this->typedConfig);

    $this->storage->expects($this->exactly(2))
      ->method('readMultiple')
      ->willReturnMap([
        [[$old->getName()], $old->getRawData()],
        [[$new->getName()], $new->getRawData()],
      ]);

    $this->cacheTagsInvalidator->expects($this->once())
      ->method('invalidateTags')
      ->with($old->getCacheTags());

    $this->storage->expects($this->once())
      ->method('rename')
      ->with($old->getName(), $new->getName());

    $this->configFactory->rename($old->getName(), $new->getName());
  }

}
