cas-8.x-1.x-dev/tests/src/Unit/Service/CasRedirectorTest.php

tests/src/Unit/Service/CasRedirectorTest.php
<?php

declare(strict_types=1);

namespace Drupal\Tests\cas\Unit\Service;

use Drupal\Component\Utility\UrlHelper;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Routing\TrustedRedirectResponse;
use Drupal\Core\Routing\UrlGeneratorInterface;
use Drupal\Tests\UnitTestCase;
use Drupal\cas\CasRedirectData;
use Drupal\cas\Event\CasPreRedirectEvent;
use Drupal\cas\Model\SslCertificateVerification;
use Drupal\cas\Service\CasHelper;
use Drupal\cas\Service\CasRedirector;
use PHPUnit\Framework\MockObject\MockBuilder;
use PHPUnit\Framework\MockObject\MockObject;
use Symfony\Component\DependencyInjection\Container;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;

/**
 * Cas Redirector Unit Tests.
 *
 * @group cas
 *
 * @ingroup cas
 *
 * @coversDefaultClass \Drupal\cas\Service\CasRedirector
 */
class CasRedirectorTest extends UnitTestCase {

  /**
   * Mock Cas Helper.
   */
  protected CasHelper|MockObject $casHelper;

  /**
   * Mock URL Generator.
   */
  protected UrlGeneratorInterface|MockObject $urlGenerator;

  /**
   * The mocked event dispatcher.
   */
  protected EventDispatcherInterface|MockBuilder $eventDispatcher;

  /**
   * The mocked config factory service.
   */
  protected ConfigFactoryInterface|MockBuilder $configFactory;

  /**
   * Storage for events during tests.
   */
  protected array $events;

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

    $this->configFactory = $this->getConfigFactoryStub([
      'cas.settings' => [
        'server.hostname' => 'example-server.com',
        'server.protocol' => 'https',
        'server.port' => 443,
        'server.path' => '/cas',
        'server.version' => '2.0',
        'server.verify' => SslCertificateVerification::Default->value,
        'server.cert' => 'foo',
        'advanced.connection_timeout' => 30,
      ],
    ]);

    $this->casHelper = $this->createMock('\Drupal\cas\Service\CasHelper');
    $this->casHelper->method('getCasSettings')->willReturn($this->configFactory->get('cas.settings'));

    $this->urlGenerator = $this->createMock('\Drupal\Core\Routing\UrlGeneratorInterface');
    $this->urlGenerator->method('generate')
      ->willReturnCallback([$this, 'getServiceUrl']);

    // Mock event dispatcher to dispatch events.
    $this->eventDispatcher = $this->createMock(EventDispatcherInterface::class);

    // We have to mock the cache context manager which is called when we
    // add cache contexts to a cacheable metadata.
    $cache_contexts_manager = $this->createMock('Drupal\Core\Cache\Context\CacheContextsManager');
    $cache_contexts_manager->method('assertValidTokens')->willReturn(TRUE);

    $container = new Container();
    $container->set('cache_contexts_manager', $cache_contexts_manager);
    \Drupal::setContainer($container);
  }

  /**
   * Get a service URL.
   *
   * @param string $route
   *   The route name.
   * @param array|null $parameters
   *   The service URL parameters.
   *
   * @return string
   *   The constructed service URL.
   */
  public function getServiceUrl(string $route, ?array $parameters = NULL): string {
    if ($parameters) {
      return 'http://example.com/casservice?' . UrlHelper::buildQuery($parameters);
    }
    else {
      return 'http://example.com/casservice';
    }
  }

  /**
   * Dispatch an event.
   *
   * @param \Drupal\cas\Event\CasPreRedirectEvent $event
   *   Event fired.
   *
   * @return \Drupal\cas\Event\CasPreRedirectEvent
   *   The event instance.
   */
  public function dispatchEvent(CasPreRedirectEvent $event): CasPreRedirectEvent {
    $this->events[$event::class] = $event;
    $data = $event->getCasRedirectData();
    $data->setParameter('strong_auth', 'true');
    $data->forceRedirection();
    return $event;
  }

  /**
   * Test buildRedirectResponse.
   */
  public function testBuildRedirectResponse(): void {
    $cas_redirector = new CasRedirector($this->casHelper, $this->eventDispatcher, $this->urlGenerator);
    $cas_data = new CasRedirectData();
    $cas_data->forceRedirection();

    $response = $cas_redirector->buildRedirectResponse($cas_data, TRUE);
    // Make sure that are url begins with the login redirection.
    $this->assertEquals('https://example-server.com/cas/login?service=http%3A//example.com/casservice', $response->getTargetUrl());
    $this->assertInstanceOf('\Drupal\core\Routing\TrustedRedirectResponse', $response);

    // Validate redirection control.
    $cas_data->preventRedirection();
    $response = $cas_redirector->buildRedirectResponse($cas_data);
    $this->assertNull($response, 'Return null for no response');

    $cas_data->forceRedirection();
    $response = $cas_redirector->buildRedirectResponse($cas_data);
    $this->assertNotNull($response, 'Found response for redirect data');

    // Make sure setting of normal parameters works.
    $cas_data->setParameter('strong_auth', 'true');
    $response = $cas_redirector->buildRedirectResponse($cas_data);
    $this->assertEquals('https://example-server.com/cas/login?strong_auth=true&service=http%3A//example.com/casservice', $response->getTargetUrl(), 'Target URL with parameters');
    $cas_data->setParameter('strong_auth', NULL);

    // Verify setting of gateway parameters.
    $cas_data->setServiceParameter('destination', 'node/1');
    $response = $cas_redirector->buildRedirectResponse($cas_data);
    $this->assertEquals('https://example-server.com/cas/login?service=http%3A//example.com/casservice%3Fdestination%3Dnode/1', $response->getTargetUrl(), 'Service parameters present');

    // Verify proper redirector type.
    $cas_data->setIsCacheable(TRUE);
    /** @var \Drupal\Core\Routing\TrustedRedirectResponse $response */
    $response = $cas_redirector->buildRedirectResponse($cas_data);
    $this->assertInstanceOf('\Drupal\core\Routing\TrustedRedirectResponse', $response);
    $data = $response->getCacheableMetadata();
    $tags = $data->getCacheTags();
    $this->assertSame(['config:cas.settings'], $tags);

    // Simulate a config override that adds an additional cache tag.
    // This happens in e.g. cas_mock_server.
    $config = $this->casHelper->getCasSettings();
    assert($config instanceof MockObject);
    $config->method('getCacheTags')
      ->willReturn(['config:cas.settings', 'custom_cache_tag']);

    $response = $cas_redirector->buildRedirectResponse($cas_data);
    $this->assertInstanceOf(TrustedRedirectResponse::class, $response);
    $tags = $response->getCacheableMetadata()->getCacheTags();
    // In Drupal < 11.1, array keys for merged tags are not normalized.
    /* @see \Drupal\Core\Cache\Cache::mergeTags() */
    $tags = array_values($tags);
    $this->assertSame(['config:cas.settings', 'custom_cache_tag'], $tags);

    // Verify proper redirector type.
    $cas_data->setIsCacheable(FALSE);
    $response = $cas_redirector->buildRedirectResponse($cas_data);
    $this->assertInstanceOf('\Drupal\cas\CasRedirectResponse', $response, 'Non-cacheable response');
  }

  /**
   * Tests the events dispatched by the listener.
   *
   * @covers ::buildRedirectResponse
   */
  public function testEventsDispatched(): void {
    // Mock up listener on dispatched event.
    $this->eventDispatcher
      ->method('dispatch')
      ->willReturnCallback([$this, 'dispatchEvent']);
    $this->events = [];

    // Fire the redirection event.
    $cas_redirector = new CasRedirector($this->casHelper, $this->eventDispatcher, $this->urlGenerator);
    $cas_data = new CasRedirectData();
    $response = $cas_redirector->buildRedirectResponse($cas_data);

    // Verify that the event fired and the redirector was appropriately altered.
    $this->assertEquals(1, count($this->events), 'One Event was fired');
    $this->assertEquals('https://example-server.com/cas/login?strong_auth=true&service=http%3A//example.com/casservice', $response->getTargetUrl(), 'Altered parameters');
  }

}

Главная | Обратная связь

drupal hosting | друпал хостинг | it patrol .inc