You are here

class CasUserManagerTest in CAS 8

Same name and namespace in other branches
  1. 2.x tests/src/Unit/Service/CasUserManagerTest.php \Drupal\Tests\cas\Unit\Service\CasUserManagerTest

CasUserManager unit tests.

@group cas

@coversDefaultClass \Drupal\cas\Service\CasUserManager

Hierarchy

Expanded class hierarchy of CasUserManagerTest

File

tests/src/Unit/Service/CasUserManagerTest.php, line 21

Namespace

Drupal\Tests\cas\Unit\Service
View source
class CasUserManagerTest extends UnitTestCase {

  /**
   * The mocked External Auth manager.
   *
   * @var \Drupal\externalauth\ExternalAuthInterface
   */
  protected $externalAuth;

  /**
   * The mocked Authmap.
   *
   * @var \Drupal\externalauth\AuthmapInterface
   */
  protected $authmap;

  /**
   * The mocked Entity Manager.
   *
   * @var \Drupal\Core\Entity\EntityManagerInterface|\PHPUnit_Framework_MockObject_MockObject
   */
  protected $entityManager;

  /**
   * The mocked session manager.
   *
   * @var \Symfony\Component\HttpFoundation\Session\SessionInterface|\PHPUnit_Framework_MockObject_MockObject
   */
  protected $session;

  /**
   * The mocked database connection.
   *
   * @var \Drupal\Core\Database\Connection|\PHPUnit_Framework_MockObject_MockObject
   */
  protected $connection;

  /**
   * The mocked event dispatcher.
   *
   * @var \Symfony\Component\EventDispatcher\EventDispatcherInterface|\PHPUnit_Framework_MockObject_MockObject
   */
  protected $eventDispatcher;

  /**
   * The mocked user manager.
   *
   * @var \Drupal\cas\Service\CasUserManager
   */
  protected $userManager;

  /**
   * The mocked Cas Helper service.
   *
   * @var \Drupal\cas\Service\CasHelper
   */
  protected $casHelper;

  /**
   * The CAS proxy helper.
   *
   * @var \Prophecy\Prophecy\ObjectProphecy
   */
  protected $casProxyHelper;

  /**
   * The mocked user account.
   *
   * @var \Drupal\user\UserInterface
   */
  protected $account;

  /**
   * {@inheritdoc}
   */
  protected function setUp() {
    parent::setUp();
    $this->externalAuth = $this
      ->getMockBuilder('\\Drupal\\externalauth\\ExternalAuth')
      ->disableOriginalConstructor()
      ->getMock();
    $this->authmap = $this
      ->getMockBuilder('\\Drupal\\externalauth\\Authmap')
      ->disableOriginalConstructor()
      ->getMock();
    $storage = $this
      ->getMockBuilder('\\Symfony\\Component\\HttpFoundation\\Session\\Storage\\MockArraySessionStorage')
      ->setMethods(NULL)
      ->getMock();
    $this->session = $this
      ->getMockBuilder('\\Symfony\\Component\\HttpFoundation\\Session\\Session')
      ->setConstructorArgs([
      $storage,
    ])
      ->getMock();
    $this->session
      ->start();
    $this->connection = $this
      ->getMockBuilder('\\Drupal\\Core\\Database\\Connection')
      ->disableOriginalConstructor()
      ->getMock();
    $this->eventDispatcher = $this
      ->getMockBuilder('\\Symfony\\Component\\EventDispatcher\\EventDispatcherInterface')
      ->disableOriginalConstructor()
      ->getMock();
    $this->casHelper = $this
      ->getMockBuilder('\\Drupal\\cas\\Service\\CasHelper')
      ->disableOriginalConstructor()
      ->getMock();
    $this->account = $this
      ->getMockBuilder('Drupal\\user\\UserInterface')
      ->disableOriginalConstructor()
      ->getMock();
    $this->casProxyHelper = $this
      ->prophesize(CasProxyHelper::class);
  }

  /**
   * Basic scenario that user is registered.
   *
   * Create new account for a user.
   *
   * @covers ::register
   */
  public function testUserRegister() {
    $config_factory = $this
      ->getConfigFactoryStub([
      'cas.settings' => [
        'user_accounts.auto_assigned_roles' => [],
      ],
    ]);
    $this->externalAuth
      ->method('register')
      ->willReturn($this->account);
    $cas_user_manager = $this
      ->getMockBuilder('Drupal\\cas\\Service\\CasUserManager')
      ->setMethods([
      'randomPassword',
    ])
      ->setConstructorArgs([
      $this->externalAuth,
      $this->authmap,
      $config_factory,
      $this->session,
      $this->connection,
      $this->eventDispatcher,
      $this->casHelper,
      $this->casProxyHelper
        ->reveal(),
    ])
      ->getMock();
    $this
      ->assertNotEmpty($cas_user_manager
      ->register('test', [], 'test'), 'Successfully registered user.');
  }

  /**
   * User account doesn't exist but auto registration is disabled.
   *
   * An exception should be thrown and the user should not be logged in.
   *
   * @covers ::login
   */
  public function testUserNotFoundAndAutoRegistrationDisabled() {
    $config_factory = $this
      ->getConfigFactoryStub([
      'cas.settings' => [
        'user_accounts.auto_register' => FALSE,
      ],
    ]);
    $cas_user_manager = $this
      ->getMockBuilder('Drupal\\cas\\Service\\CasUserManager')
      ->setMethods([
      'storeLoginSessionData',
      'register',
    ])
      ->setConstructorArgs([
      $this->externalAuth,
      $this->authmap,
      $config_factory,
      $this->session,
      $this->connection,
      $this->eventDispatcher,
      $this->casHelper,
      $this->casProxyHelper
        ->reveal(),
    ])
      ->getMock();
    $this->externalAuth
      ->method('load')
      ->willReturn(FALSE);
    $cas_user_manager
      ->expects($this
      ->never())
      ->method('register');
    $this->externalAuth
      ->expects($this
      ->never())
      ->method('userLoginFinalize');
    $this
      ->expectException('Drupal\\cas\\Exception\\CasLoginException', 'Cannot login, local Drupal user account does not exist.');
    $cas_user_manager
      ->login(new CasPropertyBag('test'), 'ticket');
  }

  /**
   * User account doesn't exist, auto reg is enabled, but listener denies.
   *
   * @covers ::login
   */
  public function testUserNotFoundAndEventListenerDeniesAutoRegistration() {
    $config_factory = $this
      ->getConfigFactoryStub([
      'cas.settings' => [
        'user_accounts.auto_register' => TRUE,
        'user_accounts.email_assignment_strategy' => CasUserManager::EMAIL_ASSIGNMENT_STANDARD,
        'user_accounts.email_hostname' => 'sample.com',
      ],
    ]);
    $cas_user_manager = $this
      ->getMockBuilder('Drupal\\cas\\Service\\CasUserManager')
      ->setMethods([
      'storeLoginSessionData',
      'register',
    ])
      ->setConstructorArgs([
      $this->externalAuth,
      $this->authmap,
      $config_factory,
      $this->session,
      $this->connection,
      $this->eventDispatcher,
      $this->casHelper,
      $this->casProxyHelper
        ->reveal(),
    ])
      ->getMock();
    $this->externalAuth
      ->method('load')
      ->willReturn(FALSE);
    $this->eventDispatcher
      ->method('dispatch')
      ->willReturnCallback(function ($event_type, $event) {
      if ($event instanceof CasPreRegisterEvent) {
        $event
          ->setAllowAutomaticRegistration(FALSE);
      }
    });
    $cas_user_manager
      ->expects($this
      ->never())
      ->method('register');
    $this->externalAuth
      ->expects($this
      ->never())
      ->method('userLoginFinalize');
    $this
      ->expectException('Drupal\\cas\\Exception\\CasLoginException', 'Cannot register user, an event listener denied access.');
    $cas_user_manager
      ->login(new CasPropertyBag('test'), 'ticket');
  }

  /**
   * User account doesn't exist but is auto-registered and logged in.
   *
   * @dataProvider automaticRegistrationDataProvider
   *
   * @covers ::login
   */
  public function testAutomaticRegistration($email_assignment_strategy) {
    $config_factory = $this
      ->getConfigFactoryStub([
      'cas.settings' => [
        'user_accounts.auto_register' => TRUE,
        'user_accounts.email_assignment_strategy' => $email_assignment_strategy,
        'user_accounts.email_hostname' => 'sample.com',
        'user_accounts.email_attribute' => 'email',
      ],
    ]);
    $cas_user_manager = $this
      ->getMockBuilder('Drupal\\cas\\Service\\CasUserManager')
      ->setMethods([
      'storeLoginSessionData',
      'randomPassword',
    ])
      ->setConstructorArgs([
      $this->externalAuth,
      $this->authmap,
      $config_factory,
      $this->session,
      $this->connection,
      $this->eventDispatcher,
      $this->casHelper,
      $this->casProxyHelper
        ->reveal(),
    ])
      ->getMock();
    $this->externalAuth
      ->method('load')
      ->willReturn(FALSE);
    $this->account
      ->method('isactive')
      ->willReturn(TRUE);

    // The email address assigned to the user differs depending on the settings.
    // If CAS is configured to use "standard" assignment, it should combine the
    // username with the specifed email hostname. If it's configured to use
    // "attribute" assignment, it should use the value of the specified CAS
    // attribute.
    if ($email_assignment_strategy === CasUserManager::EMAIL_ASSIGNMENT_STANDARD) {
      $expected_assigned_email = 'test@sample.com';
    }
    else {
      $expected_assigned_email = 'test_email@foo.com';
    }
    $this->externalAuth
      ->expects($this
      ->once())
      ->method('register')
      ->with('test', 'cas', [
      'name' => 'test',
      'mail' => $expected_assigned_email,
      'pass' => NULL,
    ])
      ->willReturn($this->account);
    $this->externalAuth
      ->expects($this
      ->once())
      ->method('userLoginFinalize')
      ->willReturn($this->account);
    $cas_property_bag = new CasPropertyBag('test');
    $cas_property_bag
      ->setAttributes([
      'email' => 'test_email@foo.com',
    ]);
    $cas_user_manager
      ->login($cas_property_bag, 'ticket');
  }

  /**
   * A data provider for testing automatic user registration.
   *
   * @return array
   *   The two different email assignment strategies.
   */
  public function automaticRegistrationDataProvider() {
    return [
      [
        CasUserManager::EMAIL_ASSIGNMENT_STANDARD,
      ],
      [
        CasUserManager::EMAIL_ASSIGNMENT_ATTRIBUTE,
      ],
    ];
  }

  /**
   * An event listener prevents the user from logging in.
   *
   * @covers ::login
   */
  public function testEventListenerPreventsLogin() {
    $cas_user_manager = $this
      ->getMockBuilder('Drupal\\cas\\Service\\CasUserManager')
      ->setMethods([
      'storeLoginSessionData',
    ])
      ->setConstructorArgs([
      $this->externalAuth,
      $this->authmap,
      $this
        ->getConfigFactoryStub(),
      $this->session,
      $this->connection,
      $this->eventDispatcher,
      $this->casHelper,
      $this->casProxyHelper
        ->reveal(),
    ])
      ->getMock();
    $this->account
      ->method('isactive')
      ->willReturn(TRUE);
    $this->externalAuth
      ->method('load')
      ->willReturn($this->account);
    $this->eventDispatcher
      ->method('dispatch')
      ->willReturnCallback(function ($event_type, $event) {
      if ($event instanceof CasPreLoginEvent) {
        $event
          ->cancelLogin();
      }
    });
    $cas_user_manager
      ->expects($this
      ->never())
      ->method('storeLoginSessionData');
    $this->externalAuth
      ->expects($this
      ->never())
      ->method('userLoginFinalize');
    $this
      ->expectException('Drupal\\cas\\Exception\\CasLoginException', 'Cannot login, an event listener denied access.');
    $cas_user_manager
      ->login(new CasPropertyBag('test'), 'ticket');
  }

  /**
   * A user is able to login when their account exists.
   *
   * @covers ::login
   */
  public function testExistingAccountIsLoggedIn() {
    $cas_user_manager = $this
      ->getMockBuilder('Drupal\\cas\\Service\\CasUserManager')
      ->setMethods([
      'storeLoginSessionData',
    ])
      ->setConstructorArgs([
      $this->externalAuth,
      $this->authmap,
      $this
        ->getConfigFactoryStub(),
      $this->session,
      $this->connection,
      $this->eventDispatcher,
      $this->casHelper,
      $this->casProxyHelper
        ->reveal(),
    ])
      ->getMock();
    $this->account
      ->method('isActive')
      ->willReturn(TRUE);
    $this->externalAuth
      ->method('load')
      ->willReturn($this->account);
    $cas_user_manager
      ->expects($this
      ->once())
      ->method('storeLoginSessionData');
    $this->externalAuth
      ->expects($this
      ->once())
      ->method('userLoginFinalize')
      ->willReturn($this->account);
    $attributes = [
      'attr1' => 'foo',
      'attr2' => 'bar',
    ];
    $this->session
      ->method('set')
      ->withConsecutive([
      'is_cas_user',
      TRUE,
    ], [
      'cas_username',
      'test',
    ]);
    $propertyBag = new CasPropertyBag('test');
    $propertyBag
      ->setAttributes($attributes);
    $cas_user_manager
      ->login($propertyBag, 'ticket');
  }

  /**
   * Blockers users cannot log in.
   *
   * @covers ::login
   */
  public function testBlockedAccountIsNotLoggedIn() {
    $cas_user_manager = $this
      ->getMockBuilder('Drupal\\cas\\Service\\CasUserManager')
      ->setMethods([
      'storeLoginSessionData',
    ])
      ->setConstructorArgs([
      $this->externalAuth,
      $this->authmap,
      $this
        ->getConfigFactoryStub(),
      $this->session,
      $this->connection,
      $this->eventDispatcher,
      $this->casHelper,
      $this->casProxyHelper
        ->reveal(),
    ])
      ->getMock();
    $this->account
      ->method('isactive')
      ->willReturn(FALSE);
    $this->account
      ->method('getaccountname')
      ->willReturn('user');
    $this->externalAuth
      ->method('load')
      ->willReturn($this->account);
    $this->externalAuth
      ->expects($this
      ->never())
      ->method('userLoginFinalize');
    $this
      ->expectException('Drupal\\cas\\Exception\\CasLoginException', 'The username user has not been activated or is blocked.');
    $this->session
      ->method('set')
      ->withConsecutive([
      'is_cas_user',
      TRUE,
    ], [
      'cas_username',
      'test',
    ]);
    $propertyBag = new CasPropertyBag('test');
    $cas_user_manager
      ->login($propertyBag, 'ticket');
  }

}

Members

Namesort descending Modifiers Type Description Overrides
CasUserManagerTest::$account protected property The mocked user account.
CasUserManagerTest::$authmap protected property The mocked Authmap.
CasUserManagerTest::$casHelper protected property The mocked Cas Helper service.
CasUserManagerTest::$casProxyHelper protected property The CAS proxy helper.
CasUserManagerTest::$connection protected property The mocked database connection.
CasUserManagerTest::$entityManager protected property The mocked Entity Manager.
CasUserManagerTest::$eventDispatcher protected property The mocked event dispatcher.
CasUserManagerTest::$externalAuth protected property The mocked External Auth manager.
CasUserManagerTest::$session protected property The mocked session manager.
CasUserManagerTest::$userManager protected property The mocked user manager.
CasUserManagerTest::automaticRegistrationDataProvider public function A data provider for testing automatic user registration.
CasUserManagerTest::setUp protected function Overrides UnitTestCase::setUp
CasUserManagerTest::testAutomaticRegistration public function User account doesn't exist but is auto-registered and logged in.
CasUserManagerTest::testBlockedAccountIsNotLoggedIn public function Blockers users cannot log in.
CasUserManagerTest::testEventListenerPreventsLogin public function An event listener prevents the user from logging in.
CasUserManagerTest::testExistingAccountIsLoggedIn public function A user is able to login when their account exists.
CasUserManagerTest::testUserNotFoundAndAutoRegistrationDisabled public function User account doesn't exist but auto registration is disabled.
CasUserManagerTest::testUserNotFoundAndEventListenerDeniesAutoRegistration public function User account doesn't exist, auto reg is enabled, but listener denies.
CasUserManagerTest::testUserRegister public function Basic scenario that user is registered.
PhpunitCompatibilityTrait::getMock Deprecated public function Returns a mock object for the specified class using the available method.
PhpunitCompatibilityTrait::setExpectedException Deprecated public function Compatibility layer for PHPUnit 6 to support PHPUnit 4 code.
UnitTestCase::$randomGenerator protected property The random generator.
UnitTestCase::$root protected property The app root. 1
UnitTestCase::assertArrayEquals protected function Asserts if two arrays are equal by sorting them first.
UnitTestCase::getBlockMockWithMachineName Deprecated protected function Mocks a block with a block plugin. 1
UnitTestCase::getClassResolverStub protected function Returns a stub class resolver.
UnitTestCase::getConfigFactoryStub public function Returns a stub config factory that behaves according to the passed array.
UnitTestCase::getConfigStorageStub public function Returns a stub config storage that returns the supplied configuration.
UnitTestCase::getContainerWithCacheTagsInvalidator protected function Sets up a container with a cache tags invalidator.
UnitTestCase::getRandomGenerator protected function Gets the random generator for the utility methods.
UnitTestCase::getStringTranslationStub public function Returns a stub translation manager that just returns the passed string.
UnitTestCase::randomMachineName public function Generates a unique random string containing letters and numbers.