From 74f537e89d899831c606b9abe218383a4e71408e Mon Sep 17 00:00:00 2001
From: Nils Adermann <naderman@naderman.de>
Date: Tue, 4 Jan 2011 17:14:36 +0100
Subject: [PATCH 1/3] [task/session-tests] Added tests for the session class.

Two first simple tests to check functionality of session_begin and
session_create.

Added a mock class for the cache as well as a subclass of session
which has its cookie handling function mocked out to avoid header
sending problems.

PHPBB3-9732
---
 tests/bootstrap.php                           |  2 +-
 tests/mock/cache.php                          | 61 ++++++++++++++
 tests/mock/session_testable.php               | 56 +++++++++++++
 tests/session/fixtures/sessions_empty.xml     | 19 +++++
 tests/session/fixtures/sessions_full.xml      | 37 +++++++++
 tests/session/session_continue.php            | 83 +++++++++++++++++++
 tests/session/session_init.php                | 76 +++++++++++++++++
 .../phpbb_database_test_case.php              | 11 +++
 8 files changed, 344 insertions(+), 1 deletion(-)
 create mode 100644 tests/mock/cache.php
 create mode 100644 tests/mock/session_testable.php
 create mode 100644 tests/session/fixtures/sessions_empty.xml
 create mode 100644 tests/session/fixtures/sessions_full.xml
 create mode 100644 tests/session/session_continue.php
 create mode 100644 tests/session/session_init.php

diff --git a/tests/bootstrap.php b/tests/bootstrap.php
index 99f145e427..1fba323277 100644
--- a/tests/bootstrap.php
+++ b/tests/bootstrap.php
@@ -10,7 +10,7 @@
 define('IN_PHPBB', true);
 $phpbb_root_path = 'phpBB/';
 $phpEx = 'php';
-$table_prefix = '';
+$table_prefix = 'phpbb_';
 
 error_reporting(E_ALL & ~E_DEPRECATED);
 
diff --git a/tests/mock/cache.php b/tests/mock/cache.php
new file mode 100644
index 0000000000..2ac46f7090
--- /dev/null
+++ b/tests/mock/cache.php
@@ -0,0 +1,61 @@
+<?php
+/**
+*
+* @package testing
+* @copyright (c) 2008 phpBB Group
+* @license http://opensource.org/licenses/gpl-license.php GNU Public License
+*
+*/
+
+class phpbb_mock_cache
+{
+	public function __construct($data = array())
+	{
+		$this->data = $data;
+
+		if (!isset($this->data['_bots']))
+		{
+			$this->data['_bots'] = array();
+		}
+	}
+
+	public function get($var_name)
+	{
+		if (isset($this->data[$var_name]))
+		{
+			return $this->data[$var_name];
+		}
+
+		return false;
+	}
+
+	public function put($var_name, $var, $ttl = 0)
+	{
+		$this->data[$var_name] = $var;
+	}
+
+	/**
+	* Obtain active bots
+	*/
+	public function obtain_bots()
+	{
+		return $this->data['_bots'];
+	}
+
+	public function set_bots($bots)
+	{
+		$this->data['_bots'] = $bots;
+	}
+
+	public function checkVar(PHPUnit_Framework_Assert $test, $var_name, $data)
+	{
+		$test->assertTrue(isset($this->data[$var_name]));
+		$test->assertEquals($data, $this->data[$var_name]);
+	}
+
+	public function check(PHPUnit_Framework_Assert $test, $data)
+	{
+		$test->assertEquals($data, $this->data);
+	}
+}
+
diff --git a/tests/mock/session_testable.php b/tests/mock/session_testable.php
new file mode 100644
index 0000000000..2d7d42f82a
--- /dev/null
+++ b/tests/mock/session_testable.php
@@ -0,0 +1,56 @@
+<?php
+/**
+*
+* @package testing
+* @copyright (c) 2008 phpBB Group
+* @license http://opensource.org/licenses/gpl-license.php GNU Public License
+*
+*/
+
+require_once '../phpBB/includes/functions.php';
+require_once '../phpBB/includes/session.php';
+
+class phpbb_mock_session_testable extends session
+{
+	private $_cookies = array();
+
+	public function set_cookie($name, $data, $time)
+	{
+		$this->_cookies[$name] = array($data, $time);
+	}
+
+	/**
+	* Checks if the cookies were set correctly.
+	*
+	* @param PHPUnit_Framework_Assert test    The test from which this is called
+	* @param array(string => mixed)   cookies The cookie data to check against.
+	*				The keys are cookie names, the values can either be null to
+	*				check only the existance of the cookie, or an array(d, t),
+	*				where d is the cookie data to check, or null to skip the
+	*				check and t is the cookie time to check, or null to skip.
+	*/
+	public function check_cookies(PHPUnit_Framework_Assert $test, $cookies)
+	{
+		$test->assertEquals(array_keys($cookies), array_keys($this->_cookies), 'Incorrect cookies were set');
+
+		foreach ($cookies as $name => $cookie)
+		{
+			if (!is_null($cookie))
+			{
+				$data = $cookie[0];
+				$time = $cookie[1];
+
+				if (!is_null($data))
+				{
+					$test->assertEquals($data, $this->_cookies[$name][0], "Cookie $name contains incorrect data");
+				}
+
+				if (!is_null($time))
+				{
+					$test->assertEquals($time, $this->_cookies[$name][1], "Cookie $name expires at the wrong time");
+				}
+			}
+		}
+	}
+}
+
diff --git a/tests/session/fixtures/sessions_empty.xml b/tests/session/fixtures/sessions_empty.xml
new file mode 100644
index 0000000000..66fa585b18
--- /dev/null
+++ b/tests/session/fixtures/sessions_empty.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<dataset>
+	<table name="phpbb_users">
+		<column>user_id</column>
+		<column>username_clean</column>
+		<row>
+			<value>1</value>
+			<value>anonymous</value>
+		</row>
+		<row>
+			<value>3</value>
+			<value>foo</value>
+		</row>
+		<row>
+			<value>4</value>
+			<value>bar</value>
+		</row>
+	</table>
+</dataset>
diff --git a/tests/session/fixtures/sessions_full.xml b/tests/session/fixtures/sessions_full.xml
new file mode 100644
index 0000000000..4559a08c55
--- /dev/null
+++ b/tests/session/fixtures/sessions_full.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<dataset>
+	<table name="phpbb_users">
+		<column>user_id</column>
+		<column>username_clean</column>
+		<row>
+			<value>1</value>
+			<value>anonymous</value>
+		</row>
+		<row>
+			<value>3</value>
+			<value>foo</value>
+		</row>
+		<row>
+			<value>4</value>
+			<value>bar</value>
+		</row>
+	</table>
+	<table name="phpbb_sessions">
+		<column>session_id</column>
+		<column>session_user_id</column>
+		<column>session_ip</column>
+		<column>session_browser</column>
+		<row>
+			<value>anon_session</value>
+			<value>1</value>
+			<value>127.0.0.1</value>
+			<value>anonymous user agent</value>
+		</row>
+		<row>
+			<value>bar_session</value>
+			<value>4</value>
+			<value>127.0.0.1</value>
+			<value>user agent</value>
+		</row>
+	</table>
+</dataset>
diff --git a/tests/session/session_continue.php b/tests/session/session_continue.php
new file mode 100644
index 0000000000..15be667325
--- /dev/null
+++ b/tests/session/session_continue.php
@@ -0,0 +1,83 @@
+<?php
+/**
+*
+* @package testing
+* @copyright (c) 2008 phpBB Group
+* @license http://opensource.org/licenses/gpl-license.php GNU Public License
+*
+*/
+
+require_once 'test_framework/framework.php';
+require_once 'mock/cache.php';
+require_once 'mock/session_testable.php';
+
+class phpbb_session_continue_test extends phpbb_database_test_case
+{
+	public function getDataSet()
+	{
+		return $this->createXMLDataSet(dirname(__FILE__).'/fixtures/sessions_full.xml');
+	}
+
+	public function test_session_begin_valid_session()
+	{
+		$session = new phpbb_mock_session_testable;
+		$session->page = array('page' => 'page', 'forum' => 0);
+
+		// set up all the global variables used in session_create
+		global $SID, $_SID, $db, $config, $cache;
+
+		$config = $this->get_config();
+		$db = $this->new_dbal();
+		$cache_data = array(
+			'_bots' => array(),
+		);
+		$cache = new phpbb_mock_cache;
+		$SID = $_SID = null;
+
+		$_COOKIE['_sid'] = 'bar_session';
+		$_COOKIE['_u'] = '4';
+		$_SERVER['HTTP_USER_AGENT'] = 'user agent';
+
+		$config['session_length'] = time(); // need to do this to allow sessions started at time 0
+		$session->session_begin();
+
+		$sql = 'SELECT session_id, session_user_id
+			FROM phpbb_sessions';
+
+		$this->assertResultEquals(
+			$sql,
+			array(
+				array('session_id' => 'anon_session', 'session_user_id' => 1),
+				array('session_id' => 'bar_session', 'session_user_id' => 4)
+			),
+			'Check if no new session was created'
+		);
+
+		$cookie_expire = $session->time_now + (($config['max_autologin_time']) ? 86400 * (int) $config['max_autologin_time'] : 31536000);
+
+		$session->check_cookies($this, array());
+
+		$cache->check($this, $cache_data);
+	}
+
+	static public function get_config()
+	{
+		return array(
+			'allow_autologin' => false,
+			'auth_method' => 'db',
+			'forwarded_for_check' => true,
+			'active_sessions' => 0, // disable
+			'rand_seed' => 'foo',
+			'rand_seed_last_update' => 0,
+			'max_autologin_time' => 0,
+			'session_length' => 100,
+			'form_token_lifetime' => 100,
+			'cookie_name' => '',
+			'limit_load' => 0,
+			'limit_search_load' => 0,
+			'ip_check' => 3,
+			'browser_check' => 1,
+		);
+	}
+}
+
diff --git a/tests/session/session_init.php b/tests/session/session_init.php
new file mode 100644
index 0000000000..f6fa564880
--- /dev/null
+++ b/tests/session/session_init.php
@@ -0,0 +1,76 @@
+<?php
+/**
+*
+* @package testing
+* @copyright (c) 2008 phpBB Group
+* @license http://opensource.org/licenses/gpl-license.php GNU Public License
+*
+*/
+
+require_once 'test_framework/framework.php';
+require_once 'mock/cache.php';
+require_once 'mock/session_testable.php';
+
+class phpbb_session_init_test extends phpbb_database_test_case
+{
+	public function getDataSet()
+	{
+		return $this->createXMLDataSet(dirname(__FILE__).'/fixtures/sessions_empty.xml');
+	}
+
+	// also see security/extract_current_page.php
+
+	public function test_login_session_create()
+	{
+		$session = new phpbb_mock_session_testable;
+		$session->page = array('page' => 'page', 'forum' => 0);
+
+		// set up all the global variables used in session_create
+		global $SID, $_SID, $db, $config, $cache;
+
+		$config = $this->get_config();
+		$db = $this->new_dbal();
+		$cache_data = array(
+			'_bots' => array(),
+		);
+		$cache = new phpbb_mock_cache;
+		$SID = $_SID = null;
+
+		$session->session_create(3);
+
+		$sql = 'SELECT session_user_id
+			FROM phpbb_sessions';
+
+		$this->assertResultEquals(
+			$sql,
+			array(array('session_user_id' => 3)),
+			'Check if exacly one session for user id 3 was created'
+		);
+
+		$cookie_expire = $session->time_now + (($config['max_autologin_time']) ? 86400 * (int) $config['max_autologin_time'] : 31536000);
+
+		$session->check_cookies($this, array(
+			'u' => array(null, $cookie_expire),
+			'k' => array(null, $cookie_expire),
+			'sid' => array($_SID, $cookie_expire),
+		));
+
+		$cache->check($this, $cache_data);
+	}
+
+	static public function get_config()
+	{
+		return array(
+			'allow_autologin' => false,
+			'auth_method' => 'db',
+			'forwarded_for_check' => true,
+			'active_sessions' => 0, // disable
+			'rand_seed' => 'foo',
+			'rand_seed_last_update' => 0,
+			'max_autologin_time' => 0,
+			'session_length' => 100,
+			'form_token_lifetime' => 100,
+		);
+	}
+}
+
diff --git a/tests/test_framework/phpbb_database_test_case.php b/tests/test_framework/phpbb_database_test_case.php
index 9752ec2fe6..9f1703b477 100644
--- a/tests/test_framework/phpbb_database_test_case.php
+++ b/tests/test_framework/phpbb_database_test_case.php
@@ -384,6 +384,17 @@ abstract class phpbb_database_test_case extends PHPUnit_Extensions_Database_Test
 		return $db;
 	}
 
+	public function assertResultEquals($sql, $expected, $message = '')
+	{
+		$db = $this->new_dbal();
+
+		$result = $db->sql_query($sql);
+		$rows = $db->sql_fetchrowset($result);
+		$db->sql_freeresult($result);
+
+		$this->assertEquals($expected, $rows, $message);
+	}
+
 	public function setExpectedTriggerError($errno, $message = '')
 	{
 		$this->get_test_case_helpers()->setExpectedTriggerError($errno, $message);

From 8538561b31d4d7cc995d6948062b496f260ae05a Mon Sep 17 00:00:00 2001
From: Nils Adermann <naderman@naderman.de>
Date: Thu, 6 Jan 2011 23:06:59 +0100
Subject: [PATCH 2/3] [task/session-tests] Test additional combinations of
 session_begin.

PHPBB3-9732
---
 tests/session/session_continue.php | 58 +++++++++++++++++++++++-------
 1 file changed, 46 insertions(+), 12 deletions(-)

diff --git a/tests/session/session_continue.php b/tests/session/session_continue.php
index 15be667325..58956c18a9 100644
--- a/tests/session/session_continue.php
+++ b/tests/session/session_continue.php
@@ -18,7 +18,38 @@ class phpbb_session_continue_test extends phpbb_database_test_case
 		return $this->createXMLDataSet(dirname(__FILE__).'/fixtures/sessions_full.xml');
 	}
 
-	public function test_session_begin_valid_session()
+	static public function session_begin_attempts()
+	{
+		return array(
+			array(
+				'bar_session', '4', 'user agent',
+				array(
+					array('session_id' => 'anon_session', 'session_user_id' => 1),
+					array('session_id' => 'bar_session', 'session_user_id' => 4)
+				),
+				array(),
+				'Check if no new session was created',
+			),
+			array(
+				'anon_session', '4', 'user agent',
+				array(
+					array('session_id' => 'bar_session', 'session_user_id' => 4),
+					array('session_id' => null, 'session_user_id' => 1) // use generated SID
+				),
+				array(
+					'u' => array('1', null),
+					'k' => array(null, null),
+					'sid' => array($_SID, null),
+				),
+				'Check if an anonymous new session was created',
+			),
+		);
+	}
+
+	/**
+	* @dataProvider session_begin_attempts
+	*/
+	public function test_session_begin_valid_session($session_id, $user_id, $user_agent, $expected_sessions, $expected_cookies, $message)
 	{
 		$session = new phpbb_mock_session_testable;
 		$session->page = array('page' => 'page', 'forum' => 0);
@@ -34,9 +65,9 @@ class phpbb_session_continue_test extends phpbb_database_test_case
 		$cache = new phpbb_mock_cache;
 		$SID = $_SID = null;
 
-		$_COOKIE['_sid'] = 'bar_session';
-		$_COOKIE['_u'] = '4';
-		$_SERVER['HTTP_USER_AGENT'] = 'user agent';
+		$_COOKIE['_sid'] = $session_id;
+		$_COOKIE['_u'] = $user_id;
+		$_SERVER['HTTP_USER_AGENT'] = $user_agent;
 
 		$config['session_length'] = time(); // need to do this to allow sessions started at time 0
 		$session->session_begin();
@@ -44,22 +75,25 @@ class phpbb_session_continue_test extends phpbb_database_test_case
 		$sql = 'SELECT session_id, session_user_id
 			FROM phpbb_sessions';
 
+		// little tickery to allow using a dataProvider with dynamic expected result
+		foreach ($expected_sessions as $i => $s)
+		{
+			if (is_null($s['session_id']))
+			{
+				$expected_sessions[$i]['session_id'] = $session->session_id;
+			}
+		}
+
 		$this->assertResultEquals(
 			$sql,
-			array(
-				array('session_id' => 'anon_session', 'session_user_id' => 1),
-				array('session_id' => 'bar_session', 'session_user_id' => 4)
-			),
+			$expected_sessions,
 			'Check if no new session was created'
 		);
 
-		$cookie_expire = $session->time_now + (($config['max_autologin_time']) ? 86400 * (int) $config['max_autologin_time'] : 31536000);
-
-		$session->check_cookies($this, array());
+		$session->check_cookies($this, $expected_cookies);
 
 		$cache->check($this, $cache_data);
 	}
-
 	static public function get_config()
 	{
 		return array(

From cd694e9b9dfd59c8be00a52b30db8e6c280b97a9 Mon Sep 17 00:00:00 2001
From: Nils Adermann <naderman@naderman.de>
Date: Fri, 21 Jan 2011 21:31:41 +0100
Subject: [PATCH 3/3] [task/session-tests] Renamed assertSqlResultEquals and
 fixed its param order

PHPBB3-9732
---
 tests/test_framework/phpbb_database_test_case.php | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tests/test_framework/phpbb_database_test_case.php b/tests/test_framework/phpbb_database_test_case.php
index 9f1703b477..a325855da4 100644
--- a/tests/test_framework/phpbb_database_test_case.php
+++ b/tests/test_framework/phpbb_database_test_case.php
@@ -384,7 +384,7 @@ abstract class phpbb_database_test_case extends PHPUnit_Extensions_Database_Test
 		return $db;
 	}
 
-	public function assertResultEquals($sql, $expected, $message = '')
+	public function assertSqlResultEquals($expected, $sql, $message = '')
 	{
 		$db = $this->new_dbal();