Commit 49c9094f authored by Taylor Otwell's avatar Taylor Otwell

refactored session and added unit tests for manager and driver.

parent 5196d015
......@@ -9,7 +9,7 @@ class APC extends Driver {
*
* @var Proxy
*/
private $apc;
private $proxy;
/**
* The cache key from the cache configuration file.
......@@ -25,7 +25,7 @@ class APC extends Driver {
* @param string $key
* @return void
*/
public function __construct(Proxy $apc, $key)
public function __construct(Proxy $proxy, $key)
{
$this->key = $key;
$this->proxy = $proxy;
......
......@@ -74,11 +74,15 @@ else
$response->content = $response->render();
// --------------------------------------------------------------
// Close the session.
// Close the session and write the session cookie.
// --------------------------------------------------------------
if ($config->get('session.driver') !== '')
{
$container->resolve('laravel.session')->close($container->resolve('laravel.input'));
$session = $container->resolve('laravel.session');
$session->close($container->resolve('laravel.input'), time());
$session->cookie($container->resolve('laravel.cookie'));
}
// --------------------------------------------------------------
......
......@@ -5,6 +5,10 @@ class APC extends Driver {
/**
* The APC cache driver instance.
*
* This session driver relies on the APC cache driver to provide an interface for
* working with an APC equipped server. The cache driver will provide all of the
* functionality for retrieving and storing items in APC.
*
* @var Cache\Drivers\APC
*/
protected $apc;
......@@ -23,6 +27,10 @@ class APC extends Driver {
/**
* Load a session by ID.
*
* This method is responsible for retrieving the session from persistant storage. If the
* session does not exist in storage, nothing should be returned from the method, in which
* case a new session will be created by the base driver.
*
* @param string $id
* @return array
*/
......@@ -34,21 +42,23 @@ class APC extends Driver {
/**
* Save the session to persistant storage.
*
* @param array $session
* @return void
*/
protected function save()
protected function save($session)
{
$this->apc->put($this->session['id'], $this->session, $this->config->get('session.lifetime'));
$this->apc->put($session['id'], $session, $this->config->get('session.lifetime'));
}
/**
* Delete the session from persistant storage.
*
* @param string $id
* @return void
*/
protected function delete()
protected function delete($id)
{
$this->apc->forget($this->session['id']);
$this->apc->forget($id);
}
}
\ No newline at end of file
......@@ -14,6 +14,10 @@ class Cookie extends Driver {
/**
* The crypter instance.
*
* All session cookies have an encrypted payload. Since the session contains sensitive
* data that cannot be compromised, it is important that the payload be encrypted using
* the strong encryption provided by the Crypter class.
*
* @var Crypter
*/
private $crypter;
......@@ -34,6 +38,10 @@ class Cookie extends Driver {
/**
* Load a session by ID.
*
* This method is responsible for retrieving the session from persistant storage. If the
* session does not exist in storage, nothing should be returned from the method, in which
* case a new session will be created by the base driver.
*
* @param string $id
* @return array
*/
......@@ -48,9 +56,10 @@ class Cookie extends Driver {
/**
* Save the session to persistant storage.
*
* @param array $session
* @return void
*/
protected function save()
protected function save($session)
{
if ( ! headers_sent())
{
......@@ -58,7 +67,7 @@ class Cookie extends Driver {
extract($config);
$payload = $this->crypter->encrypt(serialize($this->session));
$payload = $this->crypter->encrypt(serialize($session));
$this->cookie->put('session_payload', $payload, $lifetime, $path, $domain);
}
......@@ -67,9 +76,10 @@ class Cookie extends Driver {
/**
* Delete the session from persistant storage.
*
* @param string $id
* @return void
*/
protected function delete()
protected function delete($id)
{
$this->cookie->forget('session_payload');
}
......
......@@ -25,6 +25,10 @@ class Database extends Driver implements Sweeper {
/**
* Load a session by ID.
*
* This method is responsible for retrieving the session from persistant storage. If the
* session does not exist in storage, nothing should be returned from the method, in which
* case a new session will be created by the base driver.
*
* @param string $id
* @return array
*/
......@@ -45,27 +49,29 @@ class Database extends Driver implements Sweeper {
/**
* Save the session to persistant storage.
*
* @param array $session
* @return void
*/
protected function save()
protected function save($session)
{
$this->delete($this->session['id']);
$this->delete($session['id']);
$this->table()->insert(array(
'id' => $this->session['id'],
'last_activity' => $this->session['last_activity'],
'data' => serialize($this->session['data'])
'id' => $session['id'],
'last_activity' => $session['last_activity'],
'data' => serialize($session['data'])
));
}
/**
* Delete the session from persistant storage.
*
* @param string $id
* @return void
*/
protected function delete()
protected function delete($id)
{
$this->table()->delete($this->session['id']);
$this->table()->delete($id);
}
/**
......
......@@ -42,7 +42,7 @@ abstract class Driver {
// string ID to uniquely identify it among the application's current users.
if (is_null($this->session) or $this->expired())
{
$this->session = array('id' => Str::random(40), 'data' => array());
$this->session = array('id' => Str::random(40), 'last_activity' => time(), 'data' => array());
}
// If a CSRF token is not present in the session, we will generate one. These tokens
......@@ -69,6 +69,10 @@ abstract class Driver {
/**
* Load a session by ID.
*
* This method is responsible for retrieving the session from persistant storage. If the
* session does not exist in storage, nothing should be returned from the method, in which
* case a new session will be created by the base driver.
*
* @param string $id
* @return array
*/
......@@ -77,16 +81,18 @@ abstract class Driver {
/**
* Delete the session from persistant storage.
*
* @param string $id
* @return void
*/
abstract protected function delete();
abstract protected function delete($id);
/**
* Save the session to persistant storage.
*
* @param array $session
* @return void
*/
abstract protected function save();
abstract protected function save($session);
/**
* Determine if the session or flash data contains an item.
......@@ -205,7 +211,7 @@ abstract class Driver {
*/
public final function regenerate()
{
$this->delete();
$this->delete($this->session['id']);
$this->session['id'] = Str::random(40);
}
......@@ -227,20 +233,19 @@ abstract class Driver {
* Close the session and store the session payload in persistant storage.
*
* @param Laravel\Input $input
* @param int $time
* @return void
*/
public function close(Input $input)
public final function close(Input $input, $time)
{
// The input for the current request will be flashed to the session for
// convenient access through the "old" method of the input class. This
// allows the easy repopulation of forms.
$this->flash('laravel_old_input', $input->get())->age();
$this->session['last_activity'] = time();
$this->save();
$this->session['last_activity'] = $time;
$this->cookie($input->cookies);
$this->save($this->session);
// Some session drivers implement the "Sweeper" interface, which specifies
// that the driver needs to manually clean up its expired sessions. If the
......@@ -248,27 +253,10 @@ abstract class Driver {
// sweep method on the driver.
if ($this instanceof Sweeper and mt_rand(1, 100) <= 2)
{
$this->sweep(time() - ($this->config['lifetime'] * 60));
$this->sweep($time - ($this->config->get('session.lifetime') * 60));
}
}
/**
* Age the session flash data.
*
* @return void
*/
private function age()
{
// To age the data, we will forget all of the old keys and then rewrite the newly
// flashed items to have old keys, which will be available for the next request.
foreach ($this->session['data'] as $key => $value)
{
if (strpos($key, ':old:') === 0) $this->forget($key);
}
$this->readdress(':new:', ':old:', array_keys($this->session['data']));
}
/**
* Write the session cookie.
*
......@@ -276,7 +264,7 @@ abstract class Driver {
* @param array $config
* @return void
*/
private function cookie(Cookie $cookies)
public final function cookie(Cookie $cookies)
{
if ( ! headers_sent())
{
......@@ -290,6 +278,23 @@ abstract class Driver {
}
}
/**
* Age the session flash data.
*
* @return void
*/
private function age()
{
// To age the data, we will forget all of the old keys and then rewrite the newly
// flashed items to have old keys, which will be available for the next request.
foreach ($this->session['data'] as $key => $value)
{
if (strpos($key, ':old:') === 0) $this->forget($key);
}
$this->readdress(':new:', ':old:', array_keys($this->session['data']));
}
/**
* Magic Method for retrieving items from the session.
*/
......
......@@ -32,6 +32,10 @@ class File extends Driver implements Sweeper {
/**
* Load a session by ID.
*
* This method is responsible for retrieving the session from persistant storage. If the
* session does not exist in storage, nothing should be returned from the method, in which
* case a new session will be created by the base driver.
*
* @param string $id
* @return array
*/
......@@ -43,21 +47,23 @@ class File extends Driver implements Sweeper {
/**
* Save the session to persistant storage.
*
* @param array $session
* @return void
*/
protected function save()
protected function save($session)
{
$this->file->put($this->path.$this->session['id'], serialize($this->session), LOCK_EX);
$this->file->put($this->path.$session['id'], serialize($session), LOCK_EX);
}
/**
* Delete the session from persistant storage.
*
* @param string $id
* @return void
*/
protected function delete()
protected function delete($id)
{
$this->file->delete($this->path.$this->session['id']);
$this->file->delete($this->path.$id);
}
/**
......
......@@ -23,6 +23,10 @@ class Memcached extends Driver {
/**
* Load a session by ID.
*
* This method is responsible for retrieving the session from persistant storage. If the
* session does not exist in storage, nothing should be returned from the method, in which
* case a new session will be created by the base driver.
*
* @param string $id
* @return array
*/
......@@ -34,21 +38,23 @@ class Memcached extends Driver {
/**
* Save the session to persistant storage.
*
* @param array $session
* @return void
*/
protected function save()
protected function save($session)
{
$this->memcached->put($this->session['id'], $this->session, $this->config->get('session.lifetime'));
$this->memcached->put($session['id'], $session, $this->config->get('session.lifetime'));
}
/**
* Delete the session from persistant storage.
*
* @param string $id
* @return void
*/
protected function delete()
protected function delete($id)
{
$this->memcached->forget($this->session['id']);
$this->memcached->forget($id);
}
}
\ No newline at end of file
......@@ -96,7 +96,7 @@ class Str {
$pool = ($type == 'alpha_num') ? '0123456789'.$alpha : $alpha;
return implode('', array_map(function() use ($pool) { return $pool[mt_rand(0, strlen($pool) - 1)]; }, range(0, $length)));
return implode('', array_map(function() use ($pool) { return $pool[mt_rand(0, strlen($pool) - 1)]; }, range(0, $length - 1)));
}
/**
......
<?php
class AssetTest extends PHPUnit_Framework_TestCase {
public function testContainerMethodReturnsContainer()
{
$asset = Laravel\IoC::resolve('laravel.asset');
$this->assertInstanceOf('Laravel\\Asset_Container', $asset->container());
$this->assertInstanceOf('Laravel\\Asset_Container', $asset->container('footer'));
$this->assertEquals($asset->container()->name, 'default');
$this->assertEquals($asset->container('footer')->name, 'footer');
}
public function testAssetManagerMagicallyCallsDefaultContainer()
{
$asset = Laravel\IoC::resolve('laravel.asset');
$mock = $this->getMockBuilder('Laravel\\Asset_Container')->disableOriginalConstructor()->getMock();
$mock->expects($this->any())->method('styles')->will($this->returnValue('styles'));
$asset->containers['default'] = $mock;
$this->assertEquals($asset->styles(), 'styles');
}
public function testAddMethodAddsAssetBasedOnExtension()
{
$container = $this->getContainer();
$container->add('jquery', 'js/jquery.js');
$container->add('jquery-css', 'css/jquery.css');
$this->assertEquals($container->assets['script']['jquery']['source'], 'js/jquery.js');
$this->assertEquals($container->assets['style']['jquery-css']['source'], 'css/jquery.css');
}
/**
* @dataProvider assetProvider
*/
public function testStyleMethodRegistersStylesheetAsset($type, $source, $attributes, $testAttributes)
{
$container = $this->getContainer();
$dependencies = array('jquery');
$container->$type('reset', $source, $dependencies, $attributes);
$this->assertEquals($container->assets[$type]['reset']['source'], $source);
$this->assertEquals($container->assets[$type]['reset']['dependencies'], $dependencies);
$this->assertEquals($container->assets[$type]['reset']['attributes'], $testAttributes);
}
public function assetProvider()
{
$attributes = array('test' => 'test');
return array(
array('style', 'css/reset.css', $attributes, array_merge($attributes, array('media' => 'all'))),
array('script', 'js/jquery.js', $attributes, $attributes),
);
}
public function testAllStylesCanBeRetrievedViaStylesMethod()
{
$container = new Laravel\Asset_Container('default', new HTMLAssetStub);
$container->style('reset', 'css/reset.css');
$container->style('jquery', 'css/jquery.css');
$this->assertEquals($container->styles(), 'css/reset.css media:allcss/jquery.css media:all');
}
public function testAllScriptsCanBeRetrievedViaScriptsMethod()
{
$container = new Laravel\Asset_Container('default', new HTMLAssetStub);
$container->script('jquery-ui', 'js/jquery-ui.js');
$container->script('jquery', 'js/jquery.js', array(), array('test' => 'value'));
$this->assertEquals($container->scripts(), 'js/jquery-ui.js js/jquery.js test:value');
}
public function testAssetsAreSortedBasedOnDependencies()
{
$container = $this->getContainer();
$container->script('jquery', 'js/jquery.js', array('jquery-ui'));
$container->script('jquery-ui', 'js/jquery-ui.js');
$scripts = $container->scripts();
$this->assertTrue(strpos($scripts, 'js/jquery-ui.js') < strpos($scripts, 'js/jquery.js'));
}
/**
* @expectedException Exception
*/
public function testAssetsCannotBeDependentOnSelf()
{
$container = $this->getContainer();
$container->script('jquery', 'js/jquery.js', array('jquery'));
$container->scripts();
}
/**
* @expectedException Exception
*/
public function testAssetDependenciesCannotBeCircular()
{
$container = $this->getContainer();
$container->script('jquery', 'js/jquery.js', array('jquery-ui'));
$container->script('jquery-ui', 'js/jquery-ui.js', array('jquery'));
$container->scripts();
}
private function getContainer()
{
return new Laravel\Asset_Container('default', Laravel\IoC::resolve('laravel.html'));
}
}
class HTMLAssetStub extends Laravel\HTML {
public function __construct() {}
public function style($source, $attributes)
{
return $source.' '.$this->getAttributes($attributes);
}
public function script($source, $attributes)
{
return $source.' '.$this->getAttributes($attributes);
}
private function getAttributes($attributes)
{
$html = '';
foreach ($attributes as $key => $value)
{
$html .= $key.':'.$value;
}
return $html;
}
}
\ No newline at end of file
......@@ -41,7 +41,7 @@ class ConfigTest extends PHPUnit_Framework_TestCase {
public function testConfigClassCanRetrieveItems()
{
$config = IoC::container()->config;
$config = IoC::container()->resolve('laravel.config');
$this->assertTrue(is_array($config->get('application')));
$this->assertEquals($config->get('application.url'), 'http://localhost');
......@@ -49,7 +49,7 @@ class ConfigTest extends PHPUnit_Framework_TestCase {
public function testGetMethodReturnsDefaultWhenItemDoesntExist()
{
$config = IoC::container()->config;
$config = IoC::container()->resolve('laravel.config');
$this->assertNull($config->get('config.item'));
$this->assertEquals($config->get('config.item', 'test'), 'test');
......@@ -58,7 +58,7 @@ class ConfigTest extends PHPUnit_Framework_TestCase {
public function testConfigClassCanSetItems()
{
$config = IoC::container()->config;
$config = IoC::container()->resolve('laravel.config');
$config->set('application.names.test', 'test');
$config->set('application.url', 'test');
......
<?php
use Laravel\IoC;
class SessionDriverTest extends PHPUnit_Framework_TestCase {
public function testStartMethodStartsNewSessionWhenNullIDGiven()
{
$driver = IoC::resolve('laravel.session.file');
$driver->start(IoC::resolve('laravel.config'), null);
$this->assertTrue(is_string($driver->session['id']));
$this->assertEquals(strlen($driver->session['id']), 40);
$this->assertTrue(is_array($driver->session['data']));
$this->assertEquals(strlen($driver->session['data']['csrf_token']), 16);
}
public function testStartMethodCallsLoadWhenIDIsGiven()
{
$mock = $this->getFileDriverMock();
$mock->expects($this->once())
->method('load')
->with($this->equalTo('something'));
$mock->start(IoC::resolve('laravel.config'), 'something');
}
public function testSessionIsLoadedWhenIDIsValid()
{
$mock = $this->getFileDriverMock();
$time = time();
$session = array('id' => 'something', 'last_activity' => $time, 'data' => array('name' => 'Taylor', 'csrf_token' => 'token'));
$this->setMockLoadExpectations($mock, $session);
$mock->start(IoC::resolve('laravel.config'), 'something');
$this->assertEquals($mock->session['id'], 'something');
$this->assertEquals($mock->session['last_activity'], $time);
$this->assertEquals($mock->session['data'], array('name' => 'Taylor', 'csrf_token' => 'token'));
}
public function testSessionIsRestartedWhenLoadedSessionIsExpired()
{
$mock = $this->getFileDriverMock();
$time = new DateTime('2009-01-01');
$time = $time->getTimestamp();
$session = array('id' => 'something', 'last_activity' => $time, 'data' => array('name' => 'Taylor'));
$this->setMockLoadExpectations($mock, $session);
$mock->start(IoC::resolve('laravel.config'), 'something');
$this->assertEquals(strlen($mock->session['id']), 40);
$this->assertFalse(isset($mock->session['data']['name']));
$this->assertTrue(isset($mock->session['data']['csrf_token']));
}
public function testHasMethodIndicatesIfItemExistsInSession()
{
$mock = $this->getSessionDriverWithData();
$this->assertTrue($mock->has('name'));
$this->assertFalse($mock->has('test'));
}
public function testGetMethodGetsItemsFromTheSession()
{
$mock = $this->getSessionDriverWithData();
$this->assertNull($mock->get('test'));
$this->assertEquals($mock->get('name'), 'Taylor');
$this->assertEquals($mock->name, 'Taylor');
$this->assertEquals($mock->get('test', 'Taylor'), 'Taylor');
$this->assertEquals($mock->get('test', function() {return 'Taylor';}), 'Taylor');
$mock->session['data'][':old:test1'] = 'test1';
$mock->session['data'][':new:test2'] = 'test2';
$this->assertEquals($mock->get('test1'), 'test1');
$this->assertEquals($mock->get('test2'), 'test2');
}
public function testPutMethodPutsItemsInTheSession()
{
$mock = $this->getSessionDriverWithData();
$mock->put('name', 'Tony');
$mock->age = 30;
$this->assertEquals($mock->session['data']['name'], 'Tony');
$this->assertEquals($mock->session['data']['age'], 30);
}
public function testFlashMethodPutsItemsInFlashData()
{
$mock = $this->getSessionDriverWithData();
$mock->flash('name', 'James');
$this->assertEquals($mock->session['data'][':new:name'], 'James');
}
public function testKeepMethodRejuvenatesFlashData()
{
$mock = $this->getSessionDriverWithData();
$mock->session['data'][':old:test'] = 'test';
$mock->keep('test');
$this->assertFalse(isset($mock->session['data'][':old:test']));
$this->assertEquals($mock->session['data'][':new:test'], 'test');
}
public function testKeepMethodRejuvenatesAllFlashDataInArray()
{
$mock = $this->getSessionDriverWithData();
$mock->session['data'][':old:test1'] = 'test1';
$mock->session['data'][':old:test2'] = 'test2';
$mock->keep(array('test1', 'test2'));
$this->assertFalse(isset($mock->session['data'][':old:test1']));
$this->assertFalse(isset($mock->session['data'][':old:test2']));
$this->assertEquals($mock->session['data'][':new:test1'], 'test1');
$this->assertEquals($mock->session['data'][':new:test2'], 'test2');
}
public function testReflashMethodRejuvenatesAllFlashData()
{
$mock = $this->getSessionDriverWithData();
$mock->session['data'][':old:test1'] = 'test1';
$mock->session['data'][':old:test2'] = 'test2';
$mock->reflash();
$this->assertFalse(isset($mock->session['data'][':old:test1']));
$this->assertFalse(isset($mock->session['data'][':old:test2']));
$this->assertEquals($mock->session['data'][':new:test1'], 'test1');
$this->assertEquals($mock->session['data'][':new:test2'], 'test2');
}
public function testForgetMethodRemovesDataFromSession()
{
$mock = $this->getSessionDriverWithData();
$mock->forget('name');
$this->assertFalse(isset($mock->session['data']['name']));
}
public function testFlushMethodsClearsEntireSessionData()
{
$mock = $this->getSessionDriverWithData();
$mock->flush();
$this->assertEquals(count($mock->session['data']), 0);
}
public function testRegenerateMethodDeletesSessionAndResetsID()
{
$mock = $this->getMock('Laravel\\Session\\Drivers\\File', array('load', 'delete'), $this->getFileDriverConstructor());
$this->setMockLoadExpectations($mock, $this->getDummySession());
$mock->expects($this->once())
->method('delete')
->with($this->equalTo('something'));
$mock->start(IoC::resolve('laravel.config'), 'something');
$mock->regenerate();
$this->assertEquals(strlen($mock->session['id']), 40);
}
public function testCloseMethodFlashesOldInputData()
{
$mock = $this->getMock('Laravel\\Session\\Drivers\\File', array('save'), $this->getFileDriverConstructor());
$this->setMockLoadExpectations($mock, $this->getDummySession());
$mock->start(IoC::resolve('laravel.config'), 'something');
$mock->close(new InputStub, time());
$this->assertEquals($mock->session['data'][':old:laravel_old_input'], array('name' => 'Taylor'));
}
public function testCloseMethodAgesFlashData()
{
$mock = $this->getSessionDriverWithData();
$mock->session['data'][':old:old'] = 'old';
$mock->flash('flash', 'flash');
$mock->close(new InputStub, time());
$this->assertFalse(isset($mock->session['data'][':old:old']));
$this->assertFalse(isset($mock->session['data'][':new:flash']));
$this->assertEquals($mock->session['data'][':old:flash'], 'flash');
}
public function testCloseMethodSavesSession()
{
$mock = $this->getMock('Laravel\\Session\\Drivers\\File', array('load', 'save', 'sweep'), $this->getFileDriverConstructor());
$session = $this->getDummySession();
$session['data']['csrf_token'] = 'token';
$this->setMockLoadExpectations($mock, $session);
$expect = $session;
Laravel\Arr::set($expect, 'data.:old:laravel_old_input', array('name' => 'Taylor'));
$mock->expects($this->once())
->method('save')
->with($this->equalTo($expect));
$mock->start(IoC::resolve('laravel.config'), 'something');
$mock->close(new InputStub, $mock->session['last_activity']);
}
/**
* @dataProvider cookieMethodProvider
*/
public function testCookieMethodWritesCookie($expire_on_close, $minutes)
{
$mock = $this->getSessionDriverWithData();
$config = IoC::resolve('laravel.config');
$config->set('session.expire_on_close', $expire_on_close);
$mock->start($config, 'something');
$cookieMock = $this->getMock('Laravel\\Cookie', array('put'), array(array()));
$cookieMock->expects($this->once())
->method('put')
->with('laravel_session', 'something', $minutes, $config->get('session.path'), $config->get('session.domain'));
$mock->cookie($cookieMock);
}
// -----------------------------------------------------------------------------------
// Utility Methods & Providers
// -----------------------------------------------------------------------------------
public function getSessionDriverWithData()
{
$mock = $this->getFileDriverMock();
$this->setMockLoadExpectations($mock, $this->getDummySession());
$mock->start(IoC::resolve('laravel.config'), 'something');
return $mock;
}
private function getFileDriverMock()
{
return $this->getMock('Laravel\\Session\\Drivers\\File', array('load', 'save'), $this->getFileDriverConstructor());
}
private function getFileDriverConstructor()
{
return array(IoC::resolve('laravel.file'), null);
}
private function setMockLoadExpectations($mock, $session)
{
$mock->expects($this->any())
->method('load')
->will($this->returnValue($session));
}
private function getDummySession()
{
return array('id' => 'something', 'last_activity' => time(), 'data' => array('name' => 'Taylor'));
}
public function cookieMethodProvider()
{
return array(
array(false, 60),
array(true, 0),
);
}
}
// -----------------------------------------------------------------------------------
// Stub Classes
// -----------------------------------------------------------------------------------
class InputStub extends Laravel\Input {
public function __construct() {}
public function get($key = null, $default = null)
{
return array('name' => 'Taylor');
}
}
class CookieStub extends Laravel\Cookie {
public function put() {}
}
\ No newline at end of file
<?php
class SessionManagerTest extends PHPUnit_Framework_TestCase {
public function testDriverMethodReturnsDriverWhenOneIsRegistered()
{
$dependencies = array(
'laravel.session.test' => array('resolver' => function($container)
{
return new stdClass;
})
);
$manager = new Laravel\Session\Manager(new Laravel\Container($dependencies));
$this->assertInstanceOf('stdClass', $manager->driver('test'));
}
/**
* @expectedException Exception
*/
public function testDriverMethodThrowsExceptionForUndefinedDriver()
{
$manager = new Laravel\Session\Manager(new Laravel\Container(array()));
$manager->driver('test');
}
}
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment