<?php

declare(strict_types=1);

namespace Drupal\Tests\localgov_elections\Functional;

use Drupal\Tests\BrowserTestBase;

/**
 * Test permissions for election module.
 *
 * @group localgov_elections
 */
final class PermissionsTest extends BrowserTestBase {

  /**
   * Test using the Testing profile.
   *
   * @var string
   */
  protected $profile = 'testing';

  /**
   * {@inheritdoc}
   */
  protected $defaultTheme = 'localgov_base';

  /**
   * {@inheritdoc}
   */
  // @codingStandardsIgnoreStart
  protected $strictConfigSchema = FALSE;
  // @codingStandardsIgnoreEnd

  /**
   * {@inheritdoc}
   */
  protected static $modules = [
    'localgov_core',
    'localgov_media',
  ];

  /**
   * Test election node.
   *
   * @var \Drupal\node\NodeInterface
   */
  protected $election;

  /**
   * {@inheritdoc}
   */
  protected function initMink() {
    // Rebuild the router before the first HTTP request to ensure
    // views.view_route_names state is fully populated. localgov_core's
    // install hook enables localgov_page_header_display_extender in
    // views.settings, which can trigger a route rebuild before
    // localgov_election_areas_admin view route is registered, causing
    // ViewsLocalTask::getDerivativeDefinitions() to fail on first request.
    $this->container->get('router.builder')->rebuild();
    return parent::initMink();
  }

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

    // Install localgov_elections here to include optional configuration in D11.
    $this->container->get('module_installer')->install(['localgov_elections']);
    $this->rebuildContainer();
    $this->container->get('router.builder')->rebuild();

    // Create a test election node to replace demo content.
    $this->election = $this->drupalCreateNode([
      'type' => 'localgov_election',
      'title' => 'General Election July 2024',
      'status' => 1,
      'path' => ['alias' => '/election/general-election-july-2024'],
    ]);
  }

  /**
   * Test the visibility of the add area local task.
   */
  public function testAddAreaLocalTaskVisibility(): void {

    $this->drupalPlaceBlock('local_tasks_block', [
      'region' => 'content',
    ]);

    // Anonymous user.
    $this->drupalGet('/election/general-election-july-2024');
    $this->assertSession()->linkNotExists('Add areas');

    // A role who cannot access the button.
    $user = $this->drupalCreateUser();
    $user->addRole('localgov_editor');
    $this->drupalLogin($user);
    $this->drupalGet('/election/general-election-july-2024');
    $this->assertSession()->linkNotExists('Add areas');
    $this->drupalLogout();

    // Election officer.
    $election_officer = $this->drupalCreateUser(['can fetch boundaries']);
    $election_officer->addRole('localgov_elections_officer');
    $this->drupalLogin($election_officer);
    $this->drupalGet('/election/general-election-july-2024');
    $this->assertSession()->linkExists('Add areas');
  }

}
