Update to drupal 8.0.0-rc1. For more information, see https://www.drupal.org/node/2582663

This commit is contained in:
Greg Anderson 2015-10-08 11:40:12 -07:00
parent eb34d130a8
commit f32e58e4b1
8476 changed files with 211648 additions and 170042 deletions

View file

@ -0,0 +1,114 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\HttpFoundation\Tests\Session\Storage\Handler;
use Symfony\Component\HttpFoundation\Session\Storage\Handler\LegacyPdoSessionHandler;
/**
* @group legacy
*/
class LegacyPdoSessionHandlerTest extends \PHPUnit_Framework_TestCase
{
private $pdo;
protected function setUp()
{
if (!class_exists('PDO') || !in_array('sqlite', \PDO::getAvailableDrivers())) {
$this->markTestSkipped('This test requires SQLite support in your environment');
}
$this->pdo = new \PDO('sqlite::memory:');
$this->pdo->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
$sql = 'CREATE TABLE sessions (sess_id VARCHAR(128) PRIMARY KEY, sess_data TEXT, sess_time INTEGER)';
$this->pdo->exec($sql);
}
public function testIncompleteOptions()
{
$this->setExpectedException('InvalidArgumentException');
$storage = new LegacyPdoSessionHandler($this->pdo, array());
}
public function testWrongPdoErrMode()
{
$pdo = new \PDO('sqlite::memory:');
$pdo->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_SILENT);
$pdo->exec('CREATE TABLE sessions (sess_id VARCHAR(128) PRIMARY KEY, sess_data TEXT, sess_time INTEGER)');
$this->setExpectedException('InvalidArgumentException');
$storage = new LegacyPdoSessionHandler($pdo, array('db_table' => 'sessions'));
}
public function testWrongTableOptionsWrite()
{
$storage = new LegacyPdoSessionHandler($this->pdo, array('db_table' => 'bad_name'));
$this->setExpectedException('RuntimeException');
$storage->write('foo', 'bar');
}
public function testWrongTableOptionsRead()
{
$storage = new LegacyPdoSessionHandler($this->pdo, array('db_table' => 'bad_name'));
$this->setExpectedException('RuntimeException');
$storage->read('foo', 'bar');
}
public function testWriteRead()
{
$storage = new LegacyPdoSessionHandler($this->pdo, array('db_table' => 'sessions'));
$storage->write('foo', 'bar');
$this->assertEquals('bar', $storage->read('foo'), 'written value can be read back correctly');
}
public function testMultipleInstances()
{
$storage1 = new LegacyPdoSessionHandler($this->pdo, array('db_table' => 'sessions'));
$storage1->write('foo', 'bar');
$storage2 = new LegacyPdoSessionHandler($this->pdo, array('db_table' => 'sessions'));
$this->assertEquals('bar', $storage2->read('foo'), 'values persist between instances');
}
public function testSessionDestroy()
{
$storage = new LegacyPdoSessionHandler($this->pdo, array('db_table' => 'sessions'));
$storage->write('foo', 'bar');
$this->assertCount(1, $this->pdo->query('SELECT * FROM sessions')->fetchAll());
$storage->destroy('foo');
$this->assertCount(0, $this->pdo->query('SELECT * FROM sessions')->fetchAll());
}
public function testSessionGC()
{
$storage = new LegacyPdoSessionHandler($this->pdo, array('db_table' => 'sessions'));
$storage->write('foo', 'bar');
$storage->write('baz', 'bar');
$this->assertCount(2, $this->pdo->query('SELECT * FROM sessions')->fetchAll());
$storage->gc(-1);
$this->assertCount(0, $this->pdo->query('SELECT * FROM sessions')->fetchAll());
}
public function testGetConnection()
{
$storage = new LegacyPdoSessionHandler($this->pdo, array('db_table' => 'sessions'), array());
$method = new \ReflectionMethod($storage, 'getConnection');
$method->setAccessible(true);
$this->assertInstanceOf('\PDO', $method->invoke($storage));
}
}

View file

@ -0,0 +1,132 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\HttpFoundation\Tests\Session\Storage\Handler;
use Symfony\Component\HttpFoundation\Session\Storage\Handler\MemcacheSessionHandler;
class MemcacheSessionHandlerTest extends \PHPUnit_Framework_TestCase
{
const PREFIX = 'prefix_';
const TTL = 1000;
/**
* @var MemcacheSessionHandler
*/
protected $storage;
protected $memcache;
protected function setUp()
{
if (!class_exists('Memcache')) {
$this->markTestSkipped('Skipped tests Memcache class is not present');
}
$this->memcache = $this->getMock('Memcache');
$this->storage = new MemcacheSessionHandler(
$this->memcache,
array('prefix' => self::PREFIX, 'expiretime' => self::TTL)
);
}
protected function tearDown()
{
$this->memcache = null;
$this->storage = null;
}
public function testOpenSession()
{
$this->assertTrue($this->storage->open('', ''));
}
public function testCloseSession()
{
$this->memcache
->expects($this->once())
->method('close')
->will($this->returnValue(true))
;
$this->assertTrue($this->storage->close());
}
public function testReadSession()
{
$this->memcache
->expects($this->once())
->method('get')
->with(self::PREFIX.'id')
;
$this->assertEquals('', $this->storage->read('id'));
}
public function testWriteSession()
{
$this->memcache
->expects($this->once())
->method('set')
->with(self::PREFIX.'id', 'data', 0, $this->equalTo(time() + self::TTL, 2))
->will($this->returnValue(true))
;
$this->assertTrue($this->storage->write('id', 'data'));
}
public function testDestroySession()
{
$this->memcache
->expects($this->once())
->method('delete')
->with(self::PREFIX.'id')
->will($this->returnValue(true))
;
$this->assertTrue($this->storage->destroy('id'));
}
public function testGcSession()
{
$this->assertTrue($this->storage->gc(123));
}
/**
* @dataProvider getOptionFixtures
*/
public function testSupportedOptions($options, $supported)
{
try {
new MemcacheSessionHandler($this->memcache, $options);
$this->assertTrue($supported);
} catch (\InvalidArgumentException $e) {
$this->assertFalse($supported);
}
}
public function getOptionFixtures()
{
return array(
array(array('prefix' => 'session'), true),
array(array('expiretime' => 100), true),
array(array('prefix' => 'session', 'expiretime' => 200), true),
array(array('expiretime' => 100, 'foo' => 'bar'), false),
);
}
public function testGetConnection()
{
$method = new \ReflectionMethod($this->storage, 'getMemcache');
$method->setAccessible(true);
$this->assertInstanceOf('\Memcache', $method->invoke($this->storage));
}
}

View file

@ -0,0 +1,131 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\HttpFoundation\Tests\Session\Storage\Handler;
use Symfony\Component\HttpFoundation\Session\Storage\Handler\MemcachedSessionHandler;
class MemcachedSessionHandlerTest extends \PHPUnit_Framework_TestCase
{
const PREFIX = 'prefix_';
const TTL = 1000;
/**
* @var MemcachedSessionHandler
*/
protected $storage;
protected $memcached;
protected function setUp()
{
if (!class_exists('Memcached')) {
$this->markTestSkipped('Skipped tests Memcached class is not present');
}
if (version_compare(phpversion('memcached'), '2.2.0', '>=')) {
$this->markTestSkipped('Tests can only be run with memcached extension 2.1.0 or lower');
}
$this->memcached = $this->getMock('Memcached');
$this->storage = new MemcachedSessionHandler(
$this->memcached,
array('prefix' => self::PREFIX, 'expiretime' => self::TTL)
);
}
protected function tearDown()
{
$this->memcached = null;
$this->storage = null;
}
public function testOpenSession()
{
$this->assertTrue($this->storage->open('', ''));
}
public function testCloseSession()
{
$this->assertTrue($this->storage->close());
}
public function testReadSession()
{
$this->memcached
->expects($this->once())
->method('get')
->with(self::PREFIX.'id')
;
$this->assertEquals('', $this->storage->read('id'));
}
public function testWriteSession()
{
$this->memcached
->expects($this->once())
->method('set')
->with(self::PREFIX.'id', 'data', $this->equalTo(time() + self::TTL, 2))
->will($this->returnValue(true))
;
$this->assertTrue($this->storage->write('id', 'data'));
}
public function testDestroySession()
{
$this->memcached
->expects($this->once())
->method('delete')
->with(self::PREFIX.'id')
->will($this->returnValue(true))
;
$this->assertTrue($this->storage->destroy('id'));
}
public function testGcSession()
{
$this->assertTrue($this->storage->gc(123));
}
/**
* @dataProvider getOptionFixtures
*/
public function testSupportedOptions($options, $supported)
{
try {
new MemcachedSessionHandler($this->memcached, $options);
$this->assertTrue($supported);
} catch (\InvalidArgumentException $e) {
$this->assertFalse($supported);
}
}
public function getOptionFixtures()
{
return array(
array(array('prefix' => 'session'), true),
array(array('expiretime' => 100), true),
array(array('prefix' => 'session', 'expiretime' => 200), true),
array(array('expiretime' => 100, 'foo' => 'bar'), false),
);
}
public function testGetConnection()
{
$method = new \ReflectionMethod($this->storage, 'getMemcached');
$method->setAccessible(true);
$this->assertInstanceOf('\Memcached', $method->invoke($this->storage));
}
}

View file

@ -0,0 +1,255 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\HttpFoundation\Tests\Session\Storage\Handler;
use Symfony\Component\HttpFoundation\Session\Storage\Handler\MongoDbSessionHandler;
/**
* @author Markus Bachmann <markus.bachmann@bachi.biz>
*/
class MongoDbSessionHandlerTest extends \PHPUnit_Framework_TestCase
{
/**
* @var \PHPUnit_Framework_MockObject_MockObject
*/
private $mongo;
private $storage;
public $options;
protected function setUp()
{
if (!extension_loaded('mongo')) {
$this->markTestSkipped('MongoDbSessionHandler requires the PHP "mongo" extension.');
}
$mongoClass = version_compare(phpversion('mongo'), '1.3.0', '<') ? 'Mongo' : 'MongoClient';
$this->mongo = $this->getMockBuilder($mongoClass)
->getMock();
$this->options = array(
'id_field' => '_id',
'data_field' => 'data',
'time_field' => 'time',
'expiry_field' => 'expires_at',
'database' => 'sf2-test',
'collection' => 'session-test',
);
$this->storage = new MongoDbSessionHandler($this->mongo, $this->options);
}
/**
* @expectedException \InvalidArgumentException
*/
public function testConstructorShouldThrowExceptionForInvalidMongo()
{
new MongoDbSessionHandler(new \stdClass(), $this->options);
}
/**
* @expectedException \InvalidArgumentException
*/
public function testConstructorShouldThrowExceptionForMissingOptions()
{
new MongoDbSessionHandler($this->mongo, array());
}
public function testOpenMethodAlwaysReturnTrue()
{
$this->assertTrue($this->storage->open('test', 'test'), 'The "open" method should always return true');
}
public function testCloseMethodAlwaysReturnTrue()
{
$this->assertTrue($this->storage->close(), 'The "close" method should always return true');
}
public function testRead()
{
$collection = $this->createMongoCollectionMock();
$this->mongo->expects($this->once())
->method('selectCollection')
->with($this->options['database'], $this->options['collection'])
->will($this->returnValue($collection));
$that = $this;
// defining the timeout before the actual method call
// allows to test for "greater than" values in the $criteria
$testTimeout = time() + 1;
$collection->expects($this->once())
->method('findOne')
->will($this->returnCallback(function ($criteria) use ($that, $testTimeout) {
$that->assertArrayHasKey($that->options['id_field'], $criteria);
$that->assertEquals($criteria[$that->options['id_field']], 'foo');
$that->assertArrayHasKey($that->options['expiry_field'], $criteria);
$that->assertArrayHasKey('$gte', $criteria[$that->options['expiry_field']]);
$that->assertInstanceOf('MongoDate', $criteria[$that->options['expiry_field']]['$gte']);
$that->assertGreaterThanOrEqual($criteria[$that->options['expiry_field']]['$gte']->sec, $testTimeout);
return array(
$that->options['id_field'] => 'foo',
$that->options['data_field'] => new \MongoBinData('bar', \MongoBinData::BYTE_ARRAY),
$that->options['id_field'] => new \MongoDate(),
);
}));
$this->assertEquals('bar', $this->storage->read('foo'));
}
public function testWrite()
{
$collection = $this->createMongoCollectionMock();
$this->mongo->expects($this->once())
->method('selectCollection')
->with($this->options['database'], $this->options['collection'])
->will($this->returnValue($collection));
$that = $this;
$data = array();
$collection->expects($this->once())
->method('update')
->will($this->returnCallback(function ($criteria, $updateData, $options) use ($that, &$data) {
$that->assertEquals(array($that->options['id_field'] => 'foo'), $criteria);
$that->assertEquals(array('upsert' => true, 'multiple' => false), $options);
$data = $updateData['$set'];
}));
$expectedExpiry = time() + (int) ini_get('session.gc_maxlifetime');
$this->assertTrue($this->storage->write('foo', 'bar'));
$this->assertEquals('bar', $data[$this->options['data_field']]->bin);
$that->assertInstanceOf('MongoDate', $data[$this->options['time_field']]);
$this->assertInstanceOf('MongoDate', $data[$this->options['expiry_field']]);
$this->assertGreaterThanOrEqual($expectedExpiry, $data[$this->options['expiry_field']]->sec);
}
public function testWriteWhenUsingExpiresField()
{
$this->options = array(
'id_field' => '_id',
'data_field' => 'data',
'time_field' => 'time',
'database' => 'sf2-test',
'collection' => 'session-test',
'expiry_field' => 'expiresAt',
);
$this->storage = new MongoDbSessionHandler($this->mongo, $this->options);
$collection = $this->createMongoCollectionMock();
$this->mongo->expects($this->once())
->method('selectCollection')
->with($this->options['database'], $this->options['collection'])
->will($this->returnValue($collection));
$that = $this;
$data = array();
$collection->expects($this->once())
->method('update')
->will($this->returnCallback(function ($criteria, $updateData, $options) use ($that, &$data) {
$that->assertEquals(array($that->options['id_field'] => 'foo'), $criteria);
$that->assertEquals(array('upsert' => true, 'multiple' => false), $options);
$data = $updateData['$set'];
}));
$this->assertTrue($this->storage->write('foo', 'bar'));
$this->assertEquals('bar', $data[$this->options['data_field']]->bin);
$that->assertInstanceOf('MongoDate', $data[$this->options['time_field']]);
$that->assertInstanceOf('MongoDate', $data[$this->options['expiry_field']]);
}
public function testReplaceSessionData()
{
$collection = $this->createMongoCollectionMock();
$this->mongo->expects($this->once())
->method('selectCollection')
->with($this->options['database'], $this->options['collection'])
->will($this->returnValue($collection));
$data = array();
$collection->expects($this->exactly(2))
->method('update')
->will($this->returnCallback(function ($criteria, $updateData, $options) use (&$data) {
$data = $updateData;
}));
$this->storage->write('foo', 'bar');
$this->storage->write('foo', 'foobar');
$this->assertEquals('foobar', $data['$set'][$this->options['data_field']]->bin);
}
public function testDestroy()
{
$collection = $this->createMongoCollectionMock();
$this->mongo->expects($this->once())
->method('selectCollection')
->with($this->options['database'], $this->options['collection'])
->will($this->returnValue($collection));
$collection->expects($this->once())
->method('remove')
->with(array($this->options['id_field'] => 'foo'));
$this->assertTrue($this->storage->destroy('foo'));
}
public function testGc()
{
$collection = $this->createMongoCollectionMock();
$this->mongo->expects($this->once())
->method('selectCollection')
->with($this->options['database'], $this->options['collection'])
->will($this->returnValue($collection));
$that = $this;
$collection->expects($this->once())
->method('remove')
->will($this->returnCallback(function ($criteria) use ($that) {
$that->assertInstanceOf('MongoDate', $criteria[$that->options['expiry_field']]['$lt']);
$that->assertGreaterThanOrEqual(time() - 1, $criteria[$that->options['expiry_field']]['$lt']->sec);
}));
$this->assertTrue($this->storage->gc(1));
}
private function createMongoCollectionMock()
{
$mongoClient = $this->getMockBuilder('MongoClient')
->getMock();
$mongoDb = $this->getMockBuilder('MongoDB')
->setConstructorArgs(array($mongoClient, 'database-name'))
->getMock();
$collection = $this->getMockBuilder('MongoCollection')
->setConstructorArgs(array($mongoDb, 'collection-name'))
->getMock();
return $collection;
}
}

View file

@ -0,0 +1,81 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\HttpFoundation\Tests\Session\Storage\Handler;
use Symfony\Component\HttpFoundation\Session\Storage\Handler\NativeFileSessionHandler;
use Symfony\Component\HttpFoundation\Session\Storage\NativeSessionStorage;
/**
* Test class for NativeFileSessionHandler.
*
* @author Drak <drak@zikula.org>
*
* @runTestsInSeparateProcesses
* @preserveGlobalState disabled
*/
class NativeFileSessionHandlerTest extends \PHPUnit_Framework_TestCase
{
public function testConstruct()
{
$storage = new NativeSessionStorage(array('name' => 'TESTING'), new NativeFileSessionHandler(sys_get_temp_dir()));
if (PHP_VERSION_ID < 50400) {
$this->assertEquals('files', $storage->getSaveHandler()->getSaveHandlerName());
$this->assertEquals('files', ini_get('session.save_handler'));
} else {
$this->assertEquals('files', $storage->getSaveHandler()->getSaveHandlerName());
$this->assertEquals('user', ini_get('session.save_handler'));
}
$this->assertEquals(sys_get_temp_dir(), ini_get('session.save_path'));
$this->assertEquals('TESTING', ini_get('session.name'));
}
/**
* @dataProvider savePathDataProvider
*/
public function testConstructSavePath($savePath, $expectedSavePath, $path)
{
$handler = new NativeFileSessionHandler($savePath);
$this->assertEquals($expectedSavePath, ini_get('session.save_path'));
$this->assertTrue(is_dir(realpath($path)));
rmdir($path);
}
public function savePathDataProvider()
{
$base = sys_get_temp_dir();
return array(
array("$base/foo", "$base/foo", "$base/foo"),
array("5;$base/foo", "5;$base/foo", "$base/foo"),
array("5;0600;$base/foo", "5;0600;$base/foo", "$base/foo"),
);
}
/**
* @expectedException \InvalidArgumentException
*/
public function testConstructException()
{
$handler = new NativeFileSessionHandler('something;invalid;with;too-many-args');
}
public function testConstructDefault()
{
$path = ini_get('session.save_path');
$storage = new NativeSessionStorage(array('name' => 'TESTING'), new NativeFileSessionHandler());
$this->assertEquals($path, ini_get('session.save_path'));
}
}

View file

@ -0,0 +1,40 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\HttpFoundation\Tests\Session\Storage\Handler;
use Symfony\Component\HttpFoundation\Session\Storage\Handler\NativeSessionHandler;
/**
* Test class for NativeSessionHandler.
*
* @author Drak <drak@zikula.org>
*
* @runTestsInSeparateProcesses
* @preserveGlobalState disabled
*/
class NativeSessionHandlerTest extends \PHPUnit_Framework_TestCase
{
public function testConstruct()
{
$handler = new NativeSessionHandler();
// note for PHPUnit optimisers - the use of assertTrue/False
// here is deliberate since the tests do not require the classes to exist - drak
if (PHP_VERSION_ID < 50400) {
$this->assertFalse($handler instanceof \SessionHandler);
$this->assertTrue($handler instanceof NativeSessionHandler);
} else {
$this->assertTrue($handler instanceof \SessionHandler);
$this->assertTrue($handler instanceof NativeSessionHandler);
}
}
}

View file

@ -0,0 +1,58 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\HttpFoundation\Tests\Session\Storage\Handler;
use Symfony\Component\HttpFoundation\Session\Storage\Handler\NullSessionHandler;
use Symfony\Component\HttpFoundation\Session\Storage\NativeSessionStorage;
use Symfony\Component\HttpFoundation\Session\Session;
/**
* Test class for NullSessionHandler.
*
* @author Drak <drak@zikula.org>
*
* @runTestsInSeparateProcesses
* @preserveGlobalState disabled
*/
class NullSessionHandlerTest extends \PHPUnit_Framework_TestCase
{
public function testSaveHandlers()
{
$storage = $this->getStorage();
$this->assertEquals('user', ini_get('session.save_handler'));
}
public function testSession()
{
session_id('nullsessionstorage');
$storage = $this->getStorage();
$session = new Session($storage);
$this->assertNull($session->get('something'));
$session->set('something', 'unique');
$this->assertEquals('unique', $session->get('something'));
}
public function testNothingIsPersisted()
{
session_id('nullsessionstorage');
$storage = $this->getStorage();
$session = new Session($storage);
$session->start();
$this->assertEquals('nullsessionstorage', $session->getId());
$this->assertNull($session->get('something'));
}
public function getStorage()
{
return new NativeSessionStorage(array(), new NullSessionHandler());
}
}

View file

@ -0,0 +1,359 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\HttpFoundation\Tests\Session\Storage\Handler;
use Symfony\Component\HttpFoundation\Session\Storage\Handler\PdoSessionHandler;
class PdoSessionHandlerTest extends \PHPUnit_Framework_TestCase
{
private $dbFile;
protected function setUp()
{
if (!class_exists('PDO') || !in_array('sqlite', \PDO::getAvailableDrivers())) {
$this->markTestSkipped('This test requires SQLite support in your environment');
}
}
protected function tearDown()
{
// make sure the temporary database file is deleted when it has been created (even when a test fails)
if ($this->dbFile) {
@unlink($this->dbFile);
}
}
protected function getPersistentSqliteDsn()
{
$this->dbFile = tempnam(sys_get_temp_dir(), 'sf2_sqlite_sessions');
return 'sqlite:'.$this->dbFile;
}
protected function getMemorySqlitePdo()
{
$pdo = new \PDO('sqlite::memory:');
$pdo->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
$storage = new PdoSessionHandler($pdo);
$storage->createTable();
return $pdo;
}
/**
* @expectedException \InvalidArgumentException
*/
public function testWrongPdoErrMode()
{
$pdo = $this->getMemorySqlitePdo();
$pdo->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_SILENT);
$storage = new PdoSessionHandler($pdo);
}
/**
* @expectedException \RuntimeException
*/
public function testInexistentTable()
{
$storage = new PdoSessionHandler($this->getMemorySqlitePdo(), array('db_table' => 'inexistent_table'));
$storage->open('', 'sid');
$storage->read('id');
$storage->write('id', 'data');
$storage->close();
}
/**
* @expectedException \RuntimeException
*/
public function testCreateTableTwice()
{
$storage = new PdoSessionHandler($this->getMemorySqlitePdo());
$storage->createTable();
}
public function testWithLazyDsnConnection()
{
$dsn = $this->getPersistentSqliteDsn();
$storage = new PdoSessionHandler($dsn);
$storage->createTable();
$storage->open('', 'sid');
$data = $storage->read('id');
$storage->write('id', 'data');
$storage->close();
$this->assertSame('', $data, 'New session returns empty string data');
$storage->open('', 'sid');
$data = $storage->read('id');
$storage->close();
$this->assertSame('data', $data, 'Written value can be read back correctly');
}
public function testWithLazySavePathConnection()
{
$dsn = $this->getPersistentSqliteDsn();
// Open is called with what ini_set('session.save_path', $dsn) would mean
$storage = new PdoSessionHandler(null);
$storage->open($dsn, 'sid');
$storage->createTable();
$data = $storage->read('id');
$storage->write('id', 'data');
$storage->close();
$this->assertSame('', $data, 'New session returns empty string data');
$storage->open($dsn, 'sid');
$data = $storage->read('id');
$storage->close();
$this->assertSame('data', $data, 'Written value can be read back correctly');
}
public function testReadWriteReadWithNullByte()
{
$sessionData = 'da'."\0".'ta';
$storage = new PdoSessionHandler($this->getMemorySqlitePdo());
$storage->open('', 'sid');
$readData = $storage->read('id');
$storage->write('id', $sessionData);
$storage->close();
$this->assertSame('', $readData, 'New session returns empty string data');
$storage->open('', 'sid');
$readData = $storage->read('id');
$storage->close();
$this->assertSame($sessionData, $readData, 'Written value can be read back correctly');
}
public function testReadConvertsStreamToString()
{
$pdo = new MockPdo('pgsql');
$pdo->prepareResult = $this->getMock('PDOStatement');
$content = 'foobar';
$stream = $this->createStream($content);
$pdo->prepareResult->expects($this->once())->method('fetchAll')
->will($this->returnValue(array(array($stream, 42, time()))));
$storage = new PdoSessionHandler($pdo);
$result = $storage->read('foo');
$this->assertSame($content, $result);
}
public function testReadLockedConvertsStreamToString()
{
$pdo = new MockPdo('pgsql');
$selectStmt = $this->getMock('PDOStatement');
$insertStmt = $this->getMock('PDOStatement');
$pdo->prepareResult = function ($statement) use ($selectStmt, $insertStmt) {
return 0 === strpos($statement, 'INSERT') ? $insertStmt : $selectStmt;
};
$content = 'foobar';
$stream = $this->createStream($content);
$exception = null;
$selectStmt->expects($this->atLeast(2))->method('fetchAll')
->will($this->returnCallback(function () use (&$exception, $stream) {
return $exception ? array(array($stream, 42, time())) : array();
}));
$insertStmt->expects($this->once())->method('execute')
->will($this->returnCallback(function () use (&$exception) {
throw $exception = new \PDOException('', '23');
}));
$storage = new PdoSessionHandler($pdo);
$result = $storage->read('foo');
$this->assertSame($content, $result);
}
public function testReadingRequiresExactlySameId()
{
$storage = new PdoSessionHandler($this->getMemorySqlitePdo());
$storage->open('', 'sid');
$storage->write('id', 'data');
$storage->write('test', 'data');
$storage->write('space ', 'data');
$storage->close();
$storage->open('', 'sid');
$readDataCaseSensitive = $storage->read('ID');
$readDataNoCharFolding = $storage->read('tést');
$readDataKeepSpace = $storage->read('space ');
$readDataExtraSpace = $storage->read('space ');
$storage->close();
$this->assertSame('', $readDataCaseSensitive, 'Retrieval by ID should be case-sensitive (collation setting)');
$this->assertSame('', $readDataNoCharFolding, 'Retrieval by ID should not do character folding (collation setting)');
$this->assertSame('data', $readDataKeepSpace, 'Retrieval by ID requires spaces as-is');
$this->assertSame('', $readDataExtraSpace, 'Retrieval by ID requires spaces as-is');
}
/**
* Simulates session_regenerate_id(true) which will require an INSERT or UPDATE (replace).
*/
public function testWriteDifferentSessionIdThanRead()
{
$storage = new PdoSessionHandler($this->getMemorySqlitePdo());
$storage->open('', 'sid');
$storage->read('id');
$storage->destroy('id');
$storage->write('new_id', 'data_of_new_session_id');
$storage->close();
$storage->open('', 'sid');
$data = $storage->read('new_id');
$storage->close();
$this->assertSame('data_of_new_session_id', $data, 'Data of regenerated session id is available');
}
public function testWrongUsageStillWorks()
{
// wrong method sequence that should no happen, but still works
$storage = new PdoSessionHandler($this->getMemorySqlitePdo());
$storage->write('id', 'data');
$storage->write('other_id', 'other_data');
$storage->destroy('inexistent');
$storage->open('', 'sid');
$data = $storage->read('id');
$otherData = $storage->read('other_id');
$storage->close();
$this->assertSame('data', $data);
$this->assertSame('other_data', $otherData);
}
public function testSessionDestroy()
{
$pdo = $this->getMemorySqlitePdo();
$storage = new PdoSessionHandler($pdo);
$storage->open('', 'sid');
$storage->read('id');
$storage->write('id', 'data');
$storage->close();
$this->assertEquals(1, $pdo->query('SELECT COUNT(*) FROM sessions')->fetchColumn());
$storage->open('', 'sid');
$storage->read('id');
$storage->destroy('id');
$storage->close();
$this->assertEquals(0, $pdo->query('SELECT COUNT(*) FROM sessions')->fetchColumn());
$storage->open('', 'sid');
$data = $storage->read('id');
$storage->close();
$this->assertSame('', $data, 'Destroyed session returns empty string');
}
public function testSessionGC()
{
$previousLifeTime = ini_set('session.gc_maxlifetime', 1000);
$pdo = $this->getMemorySqlitePdo();
$storage = new PdoSessionHandler($pdo);
$storage->open('', 'sid');
$storage->read('id');
$storage->write('id', 'data');
$storage->close();
$storage->open('', 'sid');
$storage->read('gc_id');
ini_set('session.gc_maxlifetime', -1); // test that you can set lifetime of a session after it has been read
$storage->write('gc_id', 'data');
$storage->close();
$this->assertEquals(2, $pdo->query('SELECT COUNT(*) FROM sessions')->fetchColumn(), 'No session pruned because gc not called');
$storage->open('', 'sid');
$data = $storage->read('gc_id');
$storage->gc(-1);
$storage->close();
ini_set('session.gc_maxlifetime', $previousLifeTime);
$this->assertSame('', $data, 'Session already considered garbage, so not returning data even if it is not pruned yet');
$this->assertEquals(1, $pdo->query('SELECT COUNT(*) FROM sessions')->fetchColumn(), 'Expired session is pruned');
}
public function testGetConnection()
{
$storage = new PdoSessionHandler($this->getMemorySqlitePdo());
$method = new \ReflectionMethod($storage, 'getConnection');
$method->setAccessible(true);
$this->assertInstanceOf('\PDO', $method->invoke($storage));
}
public function testGetConnectionConnectsIfNeeded()
{
$storage = new PdoSessionHandler('sqlite::memory:');
$method = new \ReflectionMethod($storage, 'getConnection');
$method->setAccessible(true);
$this->assertInstanceOf('\PDO', $method->invoke($storage));
}
private function createStream($content)
{
$stream = tmpfile();
fwrite($stream, $content);
fseek($stream, 0);
return $stream;
}
}
class MockPdo extends \PDO
{
public $prepareResult;
private $driverName;
private $errorMode;
public function __construct($driverName = null, $errorMode = null)
{
$this->driverName = $driverName;
$this->errorMode = null !== $errorMode ?: \PDO::ERRMODE_EXCEPTION;
}
public function getAttribute($attribute)
{
if (\PDO::ATTR_ERRMODE === $attribute) {
return $this->errorMode;
}
if (\PDO::ATTR_DRIVER_NAME === $attribute) {
return $this->driverName;
}
return parent::getAttribute($attribute);
}
public function prepare($statement, $driverOptions = array())
{
return is_callable($this->prepareResult)
? call_user_func($this->prepareResult, $statement, $driverOptions)
: $this->prepareResult;
}
public function beginTransaction()
{
}
}

View file

@ -0,0 +1,94 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\HttpFoundation\Tests\Session\Storage\Handler;
use Symfony\Component\HttpFoundation\Session\Storage\Handler\WriteCheckSessionHandler;
/**
* @author Adrien Brault <adrien.brault@gmail.com>
*/
class WriteCheckSessionHandlerTest extends \PHPUnit_Framework_TestCase
{
public function test()
{
$wrappedSessionHandlerMock = $this->getMock('SessionHandlerInterface');
$writeCheckSessionHandler = new WriteCheckSessionHandler($wrappedSessionHandlerMock);
$wrappedSessionHandlerMock
->expects($this->once())
->method('close')
->with()
->will($this->returnValue(true))
;
$this->assertTrue($writeCheckSessionHandler->close());
}
public function testWrite()
{
$wrappedSessionHandlerMock = $this->getMock('SessionHandlerInterface');
$writeCheckSessionHandler = new WriteCheckSessionHandler($wrappedSessionHandlerMock);
$wrappedSessionHandlerMock
->expects($this->once())
->method('write')
->with('foo', 'bar')
->will($this->returnValue(true))
;
$this->assertTrue($writeCheckSessionHandler->write('foo', 'bar'));
}
public function testSkippedWrite()
{
$wrappedSessionHandlerMock = $this->getMock('SessionHandlerInterface');
$writeCheckSessionHandler = new WriteCheckSessionHandler($wrappedSessionHandlerMock);
$wrappedSessionHandlerMock
->expects($this->once())
->method('read')
->with('foo')
->will($this->returnValue('bar'))
;
$wrappedSessionHandlerMock
->expects($this->never())
->method('write')
;
$this->assertEquals('bar', $writeCheckSessionHandler->read('foo'));
$this->assertTrue($writeCheckSessionHandler->write('foo', 'bar'));
}
public function testNonSkippedWrite()
{
$wrappedSessionHandlerMock = $this->getMock('SessionHandlerInterface');
$writeCheckSessionHandler = new WriteCheckSessionHandler($wrappedSessionHandlerMock);
$wrappedSessionHandlerMock
->expects($this->once())
->method('read')
->with('foo')
->will($this->returnValue('bar'))
;
$wrappedSessionHandlerMock
->expects($this->once())
->method('write')
->with('foo', 'baZZZ')
->will($this->returnValue(true))
;
$this->assertEquals('bar', $writeCheckSessionHandler->read('foo'));
$this->assertTrue($writeCheckSessionHandler->write('foo', 'baZZZ'));
}
}