<?php

declare(strict_types=1);

namespace Drupal\Tests\simple_interactive_maps\Kernel;

use Drupal\Core\Cache\CacheableMetadata;
use Drupal\KernelTests\KernelTestBase;
use Drupal\simple_interactive_maps\Entity\InteractiveMap;
use Drupal\simple_interactive_maps\InteractiveMapListBuilder;
use Drupal\Tests\user\Traits\UserCreationTrait;
use PHPUnit\Framework\Attributes\CoversClass;
use PHPUnit\Framework\Attributes\Group;
use PHPUnit\Framework\Attributes\RunTestsInSeparateProcesses;

/**
 * Regression guard for InteractiveMapListBuilder::getDefaultOperations().
 *
 * Needed a ?CacheableMetadata $cacheability = NULL parameter added to match
 * the signature Drupal 11.3 added to the parent class.
 */
#[Group('simple_interactive_maps')]
#[CoversClass(InteractiveMapListBuilder::class)]
#[RunTestsInSeparateProcesses]
final class InteractiveMapListBuilderTest extends KernelTestBase {

  use UserCreationTrait;

  /**
   * {@inheritdoc}
   */
  protected static $modules = [
    'system',
    'user',
    'field_group',
    'simple_interactive_maps',
  ];

  /**
   * {@inheritdoc}
   */
  protected function setUp(): void {
    parent::setUp();
    $this->installEntitySchema('user');
    $this->setUpCurrentUser([], ['administer interactive_map']);
  }

  /**
   * Gets the interactive_map entity type's list builder.
   */
  private function createListBuilder(): InteractiveMapListBuilder {
    $entityTypeManager = $this->container->get('entity_type.manager');
    /** @var \Drupal\simple_interactive_maps\InteractiveMapListBuilder $listBuilder */
    $listBuilder = $entityTypeManager->getListBuilder('interactive_map');
    return $listBuilder;
  }

  /**
   * Tests getDefaultOperations() when no cacheability object is supplied.
   */
  public function testDefaultOperationsWithoutCacheability(): void {
    $map = InteractiveMap::create([
      'id' => 'test_map',
      'label' => 'Test Map',
      'base_map' => 'us_states_territories',
    ]);
    $map->save();

    $operations = $this->createListBuilder()->getDefaultOperations($map);

    $this->assertArrayHasKey('edit', $operations);
    $this->assertArrayHasKey('details', $operations);
    $this->assertArrayHasKey('groups', $operations);
    $this->assertArrayHasKey('preview', $operations);
    $this->assertArrayHasKey('tools', $operations);
    $this->assertSame(10, $operations['details']['weight']);
    $this->assertSame(40, $operations['tools']['weight']);
  }

  /**
   * Tests getDefaultOperations() when a cacheability object is supplied.
   */
  public function testDefaultOperationsWithExplicitCacheability(): void {
    $map = InteractiveMap::create([
      'id' => 'test_map',
      'label' => 'Test Map',
      'base_map' => 'us_states_territories',
    ]);
    $map->save();

    $cacheability = new CacheableMetadata();
    $operations = $this->createListBuilder()->getDefaultOperations($map, $cacheability);

    $this->assertArrayHasKey('details', $operations);
    // The parent class's update-access check adds the "user.permissions"
    // cache context when a cacheability object is supplied.
    $this->assertContains('user.permissions', $cacheability->getCacheContexts());
  }

  /**
   * Tests that buildRow() includes the thumbnail and label.
   */
  public function testBuildRowIncludesThumbnailAndLabel(): void {
    $map = InteractiveMap::create([
      'id' => 'test_map',
      'label' => 'Test Map',
      'base_map' => 'us_states_territories',
    ]);
    $map->save();

    $row = $this->createListBuilder()->buildRow($map);

    $this->assertSame('Test Map', $row['label']);
    $this->assertSame('html_tag', $row['thumb']['data']['#type']);
    $this->assertSame('img', $row['thumb']['data']['#tag']);
  }

}
