From 6c5130d0c12ed72fa7addca22a6dc0c3b767caca Mon Sep 17 00:00:00 2001
From: Alex Pott <alex.a.pott@googlemail.com>
Date: Mon, 28 Jul 2014 22:49:42 +0100
Subject: [PATCH] Issue #2008566 by kim.pepper, jhedstrom, Berdir: Convert
 PasswordHashingTest unit tests to phpunit.

---
 .../src/Tests/System/PasswordHashingTest.php  |  61 -------
 .../Core/Password/PasswordHashingTest.php     | 156 ++++++++++++++++++
 2 files changed, 156 insertions(+), 61 deletions(-)
 delete mode 100644 core/modules/system/src/Tests/System/PasswordHashingTest.php
 create mode 100644 core/tests/Drupal/Tests/Core/Password/PasswordHashingTest.php

diff --git a/core/modules/system/src/Tests/System/PasswordHashingTest.php b/core/modules/system/src/Tests/System/PasswordHashingTest.php
deleted file mode 100644
index b3c7aad703bc..000000000000
--- a/core/modules/system/src/Tests/System/PasswordHashingTest.php
+++ /dev/null
@@ -1,61 +0,0 @@
-<?php
-
-/**
- * @file
- * Definition of Drupal\system\Tests\System\PasswordHashingTest.
- */
-
-namespace Drupal\system\Tests\System;
-
-use Drupal\simpletest\DrupalUnitTestBase;
-use Drupal\Core\Password\PhpassHashedPassword;
-
-/**
- * Password hashing unit tests.
- *
- * @group system
- */
-class PasswordHashingTest extends DrupalUnitTestBase {
-
-  /**
-   * Modules to enable.
-   *
-   * @var array
-   */
-  public static $modules = array('field', 'user');
-
-  /**
-   * Test password hashing.
-   */
-  function testPasswordHashing() {
-    // Set a log2 iteration count that is deliberately out of bounds to test
-    // that it is corrected to be within bounds.
-    $password_hasher = new PhpassHashedPassword(1);
-    // Set up a fake $account with a password 'baz', hashed with md5.
-    $password = 'baz';
-    $account = entity_create('user', array('name' => 'foo', 'pass' => md5($password)));
-    // The md5 password should be flagged as needing an update.
-    $this->assertTrue($password_hasher->userNeedsNewHash($account), 'User with md5 password needs a new hash.');
-    // Re-hash the password.
-    $old_hash = $account->getPassword();
-    $account->setPassword($password_hasher->hash($password));
-    $this->assertIdentical($password_hasher->getCountLog2($account->getPassword()), $password_hasher::MIN_HASH_COUNT, 'Re-hashed password has the minimum number of log2 iterations.');
-    $this->assertTrue($account->getPassword() != $old_hash, 'Password hash changed.');
-    $this->assertTrue($password_hasher->check($password, $account), 'Password check succeeds.');
-    // Since the log2 setting hasn't changed and the user has a valid password,
-    // $password_hasher->userNeedsNewHash() should return FALSE.
-    $this->assertFalse($password_hasher->userNeedsNewHash($account), 'User does not need a new hash.');
-
-    // Increment the log2 iteration to MIN + 1.
-    $password_hasher = new PhpassHashedPassword($password_hasher::MIN_HASH_COUNT + 1);
-    $this->assertTrue($password_hasher->userNeedsNewHash($account), 'User needs a new hash after incrementing the log2 count.');
-    // Re-hash the password.
-    $old_hash = $account->getPassword();
-    $account->setPassword($password_hasher->hash($password));
-    $this->assertIdentical($password_hasher->getCountLog2($account->getPassword()), $password_hasher::MIN_HASH_COUNT + 1, 'Re-hashed password has the correct number of log2 iterations.');
-    $this->assertTrue($account->getPassword() != $old_hash, 'Password hash changed again.');
-    // Now the hash should be OK.
-    $this->assertFalse($password_hasher->userNeedsNewHash($account), 'Re-hashed password does not need a new hash.');
-    $this->assertTrue($password_hasher->check($password, $account), 'Password check succeeds with re-hashed password.');
-  }
-}
diff --git a/core/tests/Drupal/Tests/Core/Password/PasswordHashingTest.php b/core/tests/Drupal/Tests/Core/Password/PasswordHashingTest.php
new file mode 100644
index 000000000000..bdae80686715
--- /dev/null
+++ b/core/tests/Drupal/Tests/Core/Password/PasswordHashingTest.php
@@ -0,0 +1,156 @@
+<?php
+
+/**
+ * @file
+ * Contains Drupal\system\Tests\System\PasswordHashingTest.
+ */
+
+namespace Drupal\Tests\Core\Password;
+
+use Drupal\Core\Password\PhpassHashedPassword;
+use Drupal\Tests\UnitTestCase;
+
+/**
+ * Unit tests for password hashing API.
+ *
+ * @coversDefaultClass \Drupal\Core\Password\PhpassHashedPassword
+ * @group System
+ */
+class PasswordHashingTest extends UnitTestCase {
+
+  /**
+   * The user for testing.
+   *
+   * @var \PHPUnit_Framework_MockObject_MockObject|\Drupal\user\UserInterface
+   */
+  protected $user;
+
+  /**
+   * The raw password.
+   *
+   * @var string
+   */
+  protected $password;
+
+  /**
+   * The md5 password.
+   *
+   * @var string
+   */
+  protected $md5Password;
+
+  /**
+   * The hashed password.
+   *
+   * @var string
+   */
+  protected $hashedPassword;
+
+  /**
+   * The password hasher under test.
+   *
+   * @var \Drupal\Core\Password\PhpassHashedPassword
+   */
+  protected $passwordHasher;
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp() {
+    parent::setUp();
+    $this->user = $this->getMockBuilder('Drupal\user\Entity\User')
+      ->disableOriginalConstructor()
+      ->getMock();
+    $this->passwordHasher = new PhpassHashedPassword(1);
+  }
+
+  /**
+   * Tests the hash count boundaries are enforced.
+   *
+   * @covers ::enforceLog2Boundaries
+   */
+  public function testWithinBounds() {
+    $hasher = new FakePhpassHashedPassword();
+    $this->assertEquals(PhpassHashedPassword::MIN_HASH_COUNT, $hasher->enforceLog2Boundaries(1), "Min hash count enforced");
+    $this->assertEquals(PhpassHashedPassword::MAX_HASH_COUNT, $hasher->enforceLog2Boundaries(100), "Max hash count enforced");
+  }
+
+
+  /**
+   * Test a password needs update.
+   *
+   * @covers ::userNeedsNewHash
+   */
+  public function testPasswordNeedsUpdate() {
+    $this->user->expects($this->any())
+      ->method('getPassword')
+      ->will($this->returnValue($this->md5Password));
+    // The md5 password should be flagged as needing an update.
+    $this->assertTrue($this->passwordHasher->userNeedsNewHash($this->user), 'User with md5 password needs a new hash.');
+  }
+
+  /**
+   * Test password hashing.
+   *
+   * @covers ::hash
+   * @covers ::getCountLog2
+   * @covers ::check
+   * @covers ::userNeedsNewHash
+   */
+  public function testPasswordHashing() {
+    $this->hashedPassword = $this->passwordHasher->hash($this->password);
+    $this->user->expects($this->any())
+      ->method('getPassword')
+      ->will($this->returnValue($this->hashedPassword));
+    $this->assertSame($this->passwordHasher->getCountLog2($this->hashedPassword), PhpassHashedPassword::MIN_HASH_COUNT, 'Hashed password has the minimum number of log2 iterations.');
+    $this->assertNotEquals($this->hashedPassword, $this->md5Password, 'Password hash changed.');
+    $this->assertTrue($this->passwordHasher->check($this->password, $this->user), 'Password check succeeds.');
+    // Since the log2 setting hasn't changed and the user has a valid password,
+    // userNeedsNewHash() should return FALSE.
+    $this->assertFalse($this->passwordHasher->userNeedsNewHash($this->user), 'User does not need a new hash.');
+  }
+
+  /**
+   * Tests password rehashing.
+   *
+   * @covers ::hash
+   * @covers ::getCountLog2
+   * @covers ::check
+   * @covers ::userNeedsNewHash
+   */
+  public function testPasswordRehashing() {
+
+    // Increment the log2 iteration to MIN + 1.
+    $this->passwordHasher = new PhpassHashedPassword(PhpassHashedPassword::MIN_HASH_COUNT + 1);
+    $this->assertTrue($this->passwordHasher->userNeedsNewHash($this->user), 'User needs a new hash after incrementing the log2 count.');
+    // Re-hash the password.
+    $rehashed_password = $this->passwordHasher->hash($this->password);
+
+    $this->user->expects($this->any())
+      ->method('getPassword')
+      ->will($this->returnValue($rehashed_password));
+    $this->assertSame($this->passwordHasher->getCountLog2($rehashed_password), PhpassHashedPassword::MIN_HASH_COUNT + 1, 'Re-hashed password has the correct number of log2 iterations.');
+    $this->assertNotEquals($rehashed_password, $this->hashedPassword, 'Password hash changed again.');
+
+    // Now the hash should be OK.
+    $this->assertFalse($this->passwordHasher->userNeedsNewHash($this->user), 'Re-hashed password does not need a new hash.');
+    $this->assertTrue($this->passwordHasher->check($this->password, $this->user), 'Password check succeeds with re-hashed password.');
+  }
+
+}
+
+/**
+ * A fake class for tests.
+ */
+class FakePhpassHashedPassword extends PhpassHashedPassword {
+
+  function __construct() {
+    // Noop.
+  }
+
+  // Expose this method as public for tests.
+  public function enforceLog2Boundaries($count_log2) {
+    return parent::enforceLog2Boundaries($count_log2);
+  }
+
+}
-- 
GitLab