From e0bce73c2961afbdbd865678aa4be5b1c5486131 Mon Sep 17 00:00:00 2001
From: Demian Katz <demian.katz@villanova.edu>
Date: Fri, 24 Aug 2012 10:35:26 -0400
Subject: [PATCH] Added unit test for ILS authentication; made ILS
 authentication module more testable (with optional dependency injection) and
 less error-prone (isset checks to avoid notices).

---
 module/VuFind/src/VuFind/Auth/ILS.php |  46 +++++--
 module/VuFind/tests/Auth/ILSTest.php  | 176 ++++++++++++++++++++++++++
 2 files changed, 213 insertions(+), 9 deletions(-)
 create mode 100644 module/VuFind/tests/Auth/ILSTest.php

diff --git a/module/VuFind/src/VuFind/Auth/ILS.php b/module/VuFind/src/VuFind/Auth/ILS.php
index f3d8f92bc37..6982defb664 100644
--- a/module/VuFind/src/VuFind/Auth/ILS.php
+++ b/module/VuFind/src/VuFind/Auth/ILS.php
@@ -42,6 +42,34 @@ use VuFind\Connection\Manager as ConnectionManager,
  */
 class ILS extends AbstractBase
 {
+    protected $catalog = null;
+
+    /**
+     * Get the ILS driver associated with this object (or load the default from
+     * the connection manager.
+     *
+     * @return \VuFind\ILS\Driver\DriverInterface
+     */
+    public function getCatalog()
+    {
+        if (null === $this->catalog) {
+            $this->catalog = ConnectionManager::connectToCatalog();
+        }
+        return $this->catalog;
+    }
+
+    /**
+     * Set the ILS driver associated with this object.
+     *
+     * @param \VuFind\ILS\Driver\DriverInterface $driver Driver to set
+     *
+     * @return void
+     */
+    public function setCatalog(\VuFind\ILS\Driver\DriverInterface $driver)
+    {
+        $this->catalog = $driver;
+    }
+
     /**
      * Attempt to authenticate the current user.  Throws exception if login fails.
      *
@@ -58,10 +86,10 @@ class ILS extends AbstractBase
         if ($username == '' || $password == '') {
             throw new AuthException('authentication_error_blank');
         }
+
         // Connect to catalog:
         try {
-            $catalog = ConnectionManager::connectToCatalog();
-            $patron = $catalog->patronLogin($username, $password);
+            $patron = $this->getCatalog()->patronLogin($username, $password);
         } catch (\Exception $e) {
             throw new AuthException('authentication_error_technical');
         }
@@ -101,15 +129,15 @@ class ILS extends AbstractBase
         $user->password = "";
 
         // Update user information based on ILS data:
-        $user->firstname = $info['firstname'] == null ? " " : $info['firstname'];
-        $user->lastname = $info['lastname'] == null ? " " : $info['lastname'];
-        $user->cat_username = $info['cat_username'] == null
+        $user->firstname = !isset($info['firstname']) ? " " : $info['firstname'];
+        $user->lastname = !isset($info['lastname']) ? " " : $info['lastname'];
+        $user->cat_username = !isset($info['cat_username'])
             ? " " : $info['cat_username'];
-        $user->cat_password = $info['cat_password'] == null
+        $user->cat_password = !isset($info['cat_password'])
             ? " " : $info['cat_password'];
-        $user->email = $info['email'] == null ? " " : $info['email'];
-        $user->major = $info['major'] == null ? " " : $info['major'];
-        $user->college = $info['college'] == null ? " " : $info['college'];
+        $user->email = !isset($info['email']) ? " " : $info['email'];
+        $user->major = !isset($info['major']) ? " " : $info['major'];
+        $user->college = !isset($info['college']) ? " " : $info['college'];
 
         // Update the user in the database, then return it to the caller:
         $user->save();
diff --git a/module/VuFind/tests/Auth/ILSTest.php b/module/VuFind/tests/Auth/ILSTest.php
new file mode 100644
index 00000000000..3e066cf601d
--- /dev/null
+++ b/module/VuFind/tests/Auth/ILSTest.php
@@ -0,0 +1,176 @@
+<?php
+/**
+ * ILS authentication test class.
+ *
+ * PHP version 5
+ *
+ * Copyright (C) Villanova University 2011.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * @category VuFind2
+ * @package  Tests
+ * @author   Demian Katz <demian.katz@villanova.edu>
+ * @license  http://opensource.org/licenses/gpl-2.0.php GNU General Public License
+ * @link     http://www.vufind.org  Main Page
+ */
+namespace VuFind\Tests\Auth;
+use VuFind\Auth\ILS, VuFind\Db\Table\User;
+
+/**
+ * ILS authentication test class.
+ *
+ * @category VuFind2
+ * @package  Tests
+ * @author   Demian Katz <demian.katz@villanova.edu>
+ * @license  http://opensource.org/licenses/gpl-2.0.php GNU General Public License
+ * @link     http://www.vufind.org  Main Page
+ */
+class ILSTest extends \VuFind\Tests\DbTestCase
+{
+    protected $auth;
+    protected $driver;
+
+    /**
+     * Constructor
+     */
+    public function __construct()
+    {
+        $this->driver = $this->getMock('VuFind\ILS\Driver\Demo');
+        $this->auth = new ILS();
+        $this->auth->setCatalog($this->driver);
+    }
+
+    /**
+     * Standard setup method.
+     *
+     * @return void
+     */
+    public static function setUpBeforeClass()
+    {
+        // Set up database adapter:
+        static::prepareAdapter();
+
+        // Fail if there are already users in the database (we don't want to run this
+        // on a real system -- it's only meant for the continuous integration server)
+        $userTable = new User();
+        if (count($userTable->select()) > 0) {
+            throw new \Exception('Test cannot run with pre-existing user data!');
+        }
+    }
+
+    /**
+     * Test account creation is disallowed.
+     *
+     * @return void
+     */
+    public function testCreateIsDisallowed()
+    {
+        $this->assertFalse($this->auth->supportsCreation());
+    }
+
+    /**
+     * Support method -- get parameters to log into an account (but allow override of
+     * individual parameters so we can test different scenarios).
+     *
+     * @param array $overrides Associative array of parameters to override.
+     *
+     * @return \Zend\Http\Request
+     */
+    protected function getLoginRequest($overrides = array())
+    {
+        $post = $overrides + array(
+            'username' => 'testuser', 'password' => 'testpass'
+        );
+        $request = new \Zend\Http\Request();
+        $request->setPost(new \Zend\Stdlib\Parameters($post));
+        return $request;
+    }
+
+    /**
+     * Test login with blank username.
+     *
+     * @return void
+     */
+    public function testLoginWithBlankUsername()
+    {
+        $this->setExpectedException('VuFind\Exception\Auth');
+        $request = $this->getLoginRequest(array('username' => ''));
+        $this->auth->authenticate($request);
+    }
+
+    /**
+     * Test login with blank password.
+     *
+     * @return void
+     */
+    public function testLoginWithBlankPassword()
+    {
+        $this->setExpectedException('VuFind\Exception\Auth');
+        $request = $this->getLoginRequest(array('password' => ''));
+        $this->auth->authenticate($request);
+    }
+
+    /**
+     * Test login with technical error.
+     *
+     * @return void
+     */
+    public function testBadLoginResponse()
+    {
+        // VuFind requires the ILS driver to return a value in cat_username
+        // by default -- if that is missing, we should fail.
+        $response = array();
+        $this->driver->expects($this->once())->method('patronLogin')
+            ->with($this->equalTo('testuser'), $this->equalTo('testpass'))
+            ->will($this->returnValue($response));
+        $this->setExpectedException('VuFind\Exception\Auth');
+        $this->auth->authenticate($this->getLoginRequest());
+    }
+
+    /**
+     * Test successful login.
+     *
+     * @return void
+     */
+    public function testLogin()
+    {
+        $response = array(
+            'cat_username' => 'testuser', 'cat_password' => 'testpass',
+            'email' => 'user@test.com'
+        );
+        $this->driver->expects($this->once())->method('patronLogin')
+            ->with($this->equalTo('testuser'), $this->equalTo('testpass'))
+            ->will($this->returnValue($response));
+        $user = $this->auth->authenticate($this->getLoginRequest());
+        $this->assertEquals('testuser', $user->username);
+        $this->assertEquals('user@test.com', $user->email);
+    }
+
+    /**
+     * Standard teardown method.
+     *
+     * @return void
+     */
+    public static function tearDownAfterClass()
+    {
+        // Delete test user
+        $userTable = new User();
+        $user = $userTable->getByUsername('testuser', false);
+        if (empty($user)) {
+            throw new \Exception('Problem deleting expected user.');
+        }
+        $user->delete();
+    }
+}
\ No newline at end of file
-- 
GitLab