From a524b090c309519c7be271bae8e96812c24f8e8a Mon Sep 17 00:00:00 2001
From: Erick Hitter <git-contrib@ethitter.com>
Date: Sat, 9 Jul 2022 14:19:09 -0700
Subject: [PATCH] Test coverage

---
 inc/class-plugin.php            |  34 +------
 phpunit.xml                     |   2 +-
 tests/inc/class-test-plugin.php | 172 ++++++++++++++++++++++++++++++--
 3 files changed, 168 insertions(+), 40 deletions(-)

diff --git a/inc/class-plugin.php b/inc/class-plugin.php
index e6b2e07..942b9c3 100644
--- a/inc/class-plugin.php
+++ b/inc/class-plugin.php
@@ -104,9 +104,6 @@ class Plugin extends WP_Session_Tokens {
 	/**
 	 * Get all sessions of a user.
 	 *
-	 * @since 0.1
-	 * @access protected
-	 *
 	 * @return array Sessions of a user.
 	 */
 	protected function get_sessions() {
@@ -146,9 +143,6 @@ class Plugin extends WP_Session_Tokens {
 	/**
 	 * Retrieve a session by its verifier (token hash).
 	 *
-	 * @since 0.1
-	 * @access protected
-	 *
 	 * @param string $verifier Verifier of the session to retrieve.
 	 * @return array|null The session, or null if it does not exist
 	 */
@@ -165,9 +159,6 @@ class Plugin extends WP_Session_Tokens {
 	/**
 	 * Update a session by its verifier.
 	 *
-	 * @since 0.1
-	 * @access protected
-	 *
 	 * @param string $verifier Verifier of the session to update.
 	 * @param array  $session  Optional. Session. Omitting this argument destroys the session.
 	 */
@@ -186,9 +177,6 @@ class Plugin extends WP_Session_Tokens {
 	/**
 	 * Update a user's sessions in Redis.
 	 *
-	 * @since 0.1
-	 * @access protected
-	 *
 	 * @param array $sessions Sessions.
 	 */
 	protected function update_sessions( $sessions ) {
@@ -196,10 +184,6 @@ class Plugin extends WP_Session_Tokens {
 			return;
 		}
 
-		if ( ! has_filter( 'attach_session_information' ) ) {
-			$sessions = wp_list_pluck( $sessions, 'expiration' );
-		}
-
 		$key = $this->get_key();
 
 		if ( $sessions ) {
@@ -212,9 +196,6 @@ class Plugin extends WP_Session_Tokens {
 	/**
 	 * Destroy all session tokens for a user, except a single session passed.
 	 *
-	 * @since 0.1
-	 * @access protected
-	 *
 	 * @param string $verifier Verifier of the session to keep.
 	 */
 	protected function destroy_other_sessions( $verifier ) {
@@ -224,9 +205,6 @@ class Plugin extends WP_Session_Tokens {
 
 	/**
 	 * Destroy all session tokens for a user.
-	 *
-	 * @since 0.1
-	 * @access protected
 	 */
 	protected function destroy_all_sessions() {
 		$this->update_sessions( array() );
@@ -235,10 +213,6 @@ class Plugin extends WP_Session_Tokens {
 	/**
 	 * Destroy all session tokens for all users.
 	 *
-	 * @since 0.1
-	 * @access public
-	 * @static
-	 *
 	 * @return bool
 	 */
 	public static function drop_sessions() {
@@ -248,9 +222,6 @@ class Plugin extends WP_Session_Tokens {
 	/**
 	 * Empty database, clearing all tokens.
 	 *
-	 * @since 0.2
-	 * @access protected
-	 *
 	 * @return bool
 	 */
 	protected function flush_redis_db() {
@@ -258,10 +229,7 @@ class Plugin extends WP_Session_Tokens {
 	}
 
 	/**
-	 * Build key for current user
-	 *
-	 * @since 0.1
-	 * @access protected
+	 * Build key for current user.
 	 *
 	 * @return string
 	 */
diff --git a/phpunit.xml b/phpunit.xml
index 53d42fe..a76c2f2 100644
--- a/phpunit.xml
+++ b/phpunit.xml
@@ -8,7 +8,7 @@
 	convertWarningsToExceptions="true"
 	>
 	<testsuites>
-		<testsuite>
+		<testsuite name="wpruss">
 			<directory suffix=".php">./tests/</directory>
 			<exclude>./tests/bootstrap.php</exclude>
 		</testsuite>
diff --git a/tests/inc/class-test-plugin.php b/tests/inc/class-test-plugin.php
index fb3de76..28c9604 100755
--- a/tests/inc/class-test-plugin.php
+++ b/tests/inc/class-test-plugin.php
@@ -9,6 +9,7 @@ namespace Redis_User_Session_Storage\Tests\Inc;
 
 use Redis;
 use Redis_User_Session_Storage\Plugin;
+use ReflectionClass;
 use WP_Session_Tokens;
 use WP_UnitTestCase;
 
@@ -18,6 +19,16 @@ use WP_UnitTestCase;
  * @coversDefaultClass \Redis_User_Session_Storage\Plugin
  */
 class Test_Plugin extends WP_UnitTestCase {
+	/**
+	 * Clear stored sessions after each test, as factory can create user with
+	 * same ID as previous test.
+	 */
+	public function tear_down() {
+		parent::tear_down();
+
+		$this->_invoke_method( 0, 'flush_redis_db' );
+	}
+
 	/**
 	 * Test construction.
 	 *
@@ -25,14 +36,163 @@ class Test_Plugin extends WP_UnitTestCase {
 	 * @return void
 	 */
 	public function test__construct() {
-		$user_id      = $this->factory->user->create();
-		$this->plugin = new Plugin( $user_id );
+		$user_id = $this->factory->user->create();
+		$object  = new Plugin( $user_id );
+
+		$this->assertInstanceOf(
+			WP_Session_Tokens::class,
+			$object,
+			'Failed to assert that plugin class is an instance of `WP_Session_Tokens`.'
+		);
+
+		$this->assertEquals( 'wpruss', $object->prefix );
+
+		$this->assertTrue(
+			$this->_get_property( $user_id, 'redis_connected' ),
+			'Failed to assert that Redis is connected.'
+		);
+
+		$this->assertInstanceOf(
+			Redis::class,
+			$this->_get_property( $user_id, 'redis' ),
+			'Failed to assert that Redis client is an instance of `Redis`.'
+		);
+	}
+
+	/**
+	 * Test `get_sessions()` method.
+	 *
+	 * @covers ::get_sessions()
+	 * @return void
+	 */
+	public function test_get_sessions() {
+		$user_id = $this->factory->user->create();
+		$plugin  = new Plugin( $user_id );
+
+		$this->assertEmpty(
+			$this->_invoke_method( $user_id, 'get_sessions' ),
+			'Failed to assert that no sessions are returned before user logs in.'
+		);
+
+		$plugin->create( time() + 60 );
+
+		$this->assertNotEmpty(
+			$this->_invoke_method( $user_id, 'get_sessions' ),
+			'Failed to assert that session token is stored in Redis.'
+		);
+	}
+
+	/**
+	 * Test `get_session()` method.
+	 *
+	 * @covers ::get_session()
+	 * @return void
+	 */
+	public function test_get_session() {
+		$user_id = $this->factory->user->create();
+		$plugin  = new Plugin( $user_id );
+
+		$this->assertEmpty(
+			$this->_invoke_method(
+				$user_id,
+				'get_session',
+				array(
+					'abcdef0123456789',
+				)
+			),
+			'Failed to assert that arbitrary verifier does not return a session.'
+		);
+
+		$expiration = time() + 60;
+
+		$plugin->create( $expiration );
+		$tokens   = $this->_invoke_method( $user_id, 'get_sessions' );
+		$verifier = array_keys( $tokens )[0];
+
+		$session_data = $this->_invoke_method(
+			$user_id,
+			'get_session',
+			array(
+				$verifier,
+			)
+		);
+
+		$this->assertEquals(
+			$session_data['expiration'],
+			$expiration,
+			'Failed to assert that session expiration is stored in Redis.'
+		);
+	}
+
+	/**
+	 * Test `prepare_session()` method.
+	 *
+	 * @covers ::prepare_session()
+	 * @return void
+	 */
+	public function test_prepare_session() {
+		$this->assertEquals(
+			array(
+				'expiration' => 1,
+			),
+			$this->_invoke_method(
+				0,
+'prepare_session',
+				array(
+					1,
+				)
+			),
+			'Failed to assert that session data is transformed as expected.'
+		);
 
-		$this->assertTrue( class_exists( Redis::class, false ) );
+		$test_data = array(
+			'expiration' => 2,
+			'foo'        => 'bar',
+		);
 
-		$this->assertInstanceOf( Plugin::class, $this->plugin );
-		$this->assertInstanceOf( WP_Session_Tokens::class, $this->plugin );
+		$this->assertEquals(
+			$test_data,
+			$this->_invoke_method(
+				0,
+				'prepare_session',
+				array(
+					$test_data,
+				)
+			),
+			'Failed to assert that session data is not transformed if it is already prepared.'
+		);
+	}
+
+	/**
+	 * Invoke a non-public class method.
+	 *
+	 * @param int    $user_id     WP User ID.
+	 * @param string $method_name Method name.
+	 * @param array  $args        Method arguments.
+	 * @return mixed
+	 */
+	protected function _invoke_method( $user_id, $method_name, $args = [] ) {
+		$object     = new Plugin( $user_id );
+		$reflection = new ReflectionClass( $object );
+		$method     = $reflection->getMethod( $method_name );
+		$method->setAccessible( true );
+
+		return $method->invokeArgs( $object, $args );
+	}
+
+	/**
+	 * Get value of non-public property.
+	 *
+	 * @param int    $user_id       WP User ID.
+	 * @param string $property_name Property name.
+	 * @return mixed
+	 */
+	protected function _get_property( $user_id, $property_name ) {
+		$object     = new Plugin( $user_id );
+		$reflection = new ReflectionClass( $object );
+		$property   = $reflection->getProperty( $property_name );
+		$property->setAccessible( true );
 
-		$this->assertEquals( 'wpruss', $this->plugin->prefix );
+		return $property->getValue( $object );
 	}
 }
-- 
GitLab