09ab6430c0
Commits -------5ae76f1
[HttpFoundation] Update documentation.910b5c7
[HttpFoudation] CS, more tests and some optimization.b0466e8
[HttpFoundation] Refactored BC Session class methods.84c2e3c
[HttpFoundation] Allow flash messages to have multiple messages per type. Discussion ---------- [2.1][HttpFoundation] Multiple session flash messages Bug fix: no Feature addition: yes Backwards compatibility break: yes, but this already happened in #2583. BC `Session` methods remain unbroken. Symfony2 tests pass: yes Fixes the following tickets: #1863 References the following tickets: #2714, #2753, #2510, #2543, #2853 Todo: - This PR alters flash messages so that it is possible to store more than one message per flash type using the `add()` method or by passing an array of messages to `set()`. __NOTES ABOUT BC__ This PR maintains BC behaviour with the `Session` class in that the old Symfony 2.0 methods will continue to work as before. --------------------------------------------------------------------------- by drak at 2012-02-13T06:28:33Z I think this is ready for review @fabpot @lsmith77 --------------------------------------------------------------------------- by lsmith77 at 2012-02-14T19:30:39Z the FlashBag vs. AutoExpireFlashBag behavior and setup difference should probably also be explained in the upgrading log --------------------------------------------------------------------------- by drak at 2012-02-15T04:43:14Z @lsmith77 Those differences are explained already in the changelog * Added `FlashBag`. Flashes expire when retrieved by `get()` or `all()`. This makes the implementation ESI compatible. * Added `AutoExpireFlashBag` (default) to replicate Symfony 2.0.x auto expire behaviour of messages auto expiring after one page page load. Messages must be retrived by `get()` or `all()`. --------------------------------------------------------------------------- by Crell at 2012-02-19T17:35:34Z Drak asked me to weigh in here with use cases. Drupal currently has a similar session-stored-messaging system in place that I'd like to be able to replace with Flash messages. We frequently have multiple messages within a single request, however, so this change is critical to our being able to do so. For instance, when saving an article in Drupal there is, by default, a "yay, you saved an article!" type message that gets displayed. If you also have the site configured to send email when a post is updated, you may see a "email notifications sent" message (depending on your access level). If you have a Solr server setup for search, and you're in debug mode, there will also be a "record ID X added to Solr, it should update in 2 minutes" message. And if there's a bug somewhere, you'll also get, as an error message rather than notice message, a "Oops, E_NOTICE on line 54" message. Form validation is another case. If you have multiple errors in a single form, we prefer to list all of them. So if you screw up 4 times on a form, you may get 4 different error messages showing what you screwed up so you can fix it in one go instead of several. Now sure, one could emulate that by building a multi-message layer on top of single-layer messages, but, really, why? "One is a special case of many", and there are many many cases where you'll want to post multiple messages. Like, most of Drupal. :-) --------------------------------------------------------------------------- by lsmith77 at 2012-03-06T20:55:51Z @fabpot is there any information you still need before merging this? do you want more discussion in which case you might want to take this to the mailing list .. --------------------------------------------------------------------------- by drak at 2012-03-08T18:54:13Z Another plus for this PR is that it requires no extra lines of code in templates etc to display the flashes, see https://github.com/symfony/symfony/pull/3267/files#diff-1 --------------------------------------------------------------------------- by drak at 2012-03-15T06:38:21Z Rebased against current `master`, should be mergeable again.. --------------------------------------------------------------------------- by evillemez at 2012-03-17T03:08:41Z +1 to this, I have an extended version of HttpFoundation just for this... would love to get rid of it.
257 lines
7.8 KiB
PHP
257 lines
7.8 KiB
PHP
<?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\Tests\Component\HttpFoundation\Session;
|
|
|
|
use Symfony\Component\HttpFoundation\Session\Session;
|
|
use Symfony\Component\HttpFoundation\Session\Flash\FlashBag;
|
|
use Symfony\Component\HttpFoundation\Session\Attribute\AttributeBag;
|
|
use Symfony\Component\HttpFoundation\Session\Storage\MockArraySessionStorage;
|
|
|
|
/**
|
|
* SessionTest
|
|
*
|
|
* @author Fabien Potencier <fabien@symfony.com>
|
|
* @author Robert Schönthal <seroscho@googlemail.com>
|
|
* @author Drak <drak@zikula.org>
|
|
*/
|
|
class SessionTest extends \PHPUnit_Framework_TestCase
|
|
{
|
|
/**
|
|
* @var \Symfony\Component\HttpFoundation\Session\Storage\SessionStorageInterface
|
|
*/
|
|
protected $storage;
|
|
|
|
/**
|
|
* @var \Symfony\Component\HttpFoundation\Session\SessionInterface
|
|
*/
|
|
protected $session;
|
|
|
|
public function setUp()
|
|
{
|
|
$this->storage = new MockArraySessionStorage();
|
|
$this->session = new Session($this->storage, new AttributeBag(), new FlashBag());
|
|
}
|
|
|
|
protected function tearDown()
|
|
{
|
|
$this->storage = null;
|
|
$this->session = null;
|
|
}
|
|
|
|
public function testStart()
|
|
{
|
|
$this->assertEquals('', $this->session->getId());
|
|
$this->assertTrue($this->session->start());
|
|
$this->assertNotEquals('', $this->session->getId());
|
|
}
|
|
|
|
public function testGet()
|
|
{
|
|
// tests defaults
|
|
$this->assertNull($this->session->get('foo'));
|
|
$this->assertEquals(1, $this->session->get('foo', 1));
|
|
}
|
|
|
|
/**
|
|
* @dataProvider setProvider
|
|
*/
|
|
public function testSet($key, $value)
|
|
{
|
|
$this->session->set($key, $value);
|
|
$this->assertEquals($value, $this->session->get($key));
|
|
}
|
|
|
|
/**
|
|
* @dataProvider setProvider
|
|
*/
|
|
public function testHas($key, $value)
|
|
{
|
|
$this->session->set($key, $value);
|
|
$this->assertTrue($this->session->has($key));
|
|
$this->assertFalse($this->session->has($key.'non_value'));
|
|
}
|
|
|
|
public function testReplace()
|
|
{
|
|
$this->session->replace(array('happiness' => 'be good', 'symfony' => 'awesome'));
|
|
$this->assertEquals(array('happiness' => 'be good', 'symfony' => 'awesome'), $this->session->all());
|
|
$this->session->replace(array());
|
|
$this->assertEquals(array(), $this->session->all());
|
|
}
|
|
|
|
/**
|
|
* @dataProvider setProvider
|
|
*/
|
|
public function testAll($key, $value, $result)
|
|
{
|
|
$this->session->set($key, $value);
|
|
$this->assertEquals($result, $this->session->all());
|
|
}
|
|
|
|
/**
|
|
* @dataProvider setProvider
|
|
*/
|
|
public function testClear($key, $value)
|
|
{
|
|
$this->session->set('hi', 'fabien');
|
|
$this->session->set($key, $value);
|
|
$this->session->clear();
|
|
$this->assertEquals(array(), $this->session->all());
|
|
}
|
|
|
|
public function setProvider()
|
|
{
|
|
return array(
|
|
array('foo', 'bar', array('foo' => 'bar')),
|
|
array('foo.bar', 'too much beer', array('foo.bar' => 'too much beer')),
|
|
array('great', 'symfony2 is great', array('great' => 'symfony2 is great')),
|
|
);
|
|
}
|
|
|
|
/**
|
|
* @dataProvider setProvider
|
|
*/
|
|
public function testRemove($key, $value)
|
|
{
|
|
$this->session->set('hi.world', 'have a nice day');
|
|
$this->session->set($key, $value);
|
|
$this->session->remove($key);
|
|
$this->assertEquals(array('hi.world' => 'have a nice day'), $this->session->all());
|
|
}
|
|
|
|
public function testInvalidate()
|
|
{
|
|
$this->session->set('invalidate', 123);
|
|
$this->session->invalidate();
|
|
$this->assertEquals(array(), $this->session->all());
|
|
}
|
|
|
|
public function testMigrate()
|
|
{
|
|
$this->session->set('migrate', 321);
|
|
$this->session->migrate();
|
|
$this->assertEquals(321, $this->session->get('migrate'));
|
|
}
|
|
|
|
public function testMigrateDestroy()
|
|
{
|
|
$this->session->set('migrate', 333);
|
|
$this->session->migrate(true);
|
|
$this->assertEquals(333, $this->session->get('migrate'));
|
|
}
|
|
|
|
public function testSave()
|
|
{
|
|
$this->session->save();
|
|
}
|
|
|
|
public function testGetId()
|
|
{
|
|
$this->assertEquals('', $this->session->getId());
|
|
$this->session->start();
|
|
$this->assertNotEquals('', $this->session->getId());
|
|
}
|
|
|
|
public function testGetFlashBag()
|
|
{
|
|
$this->assertInstanceOf('Symfony\\Component\\HttpFoundation\\Session\\Flash\\FlashBagInterface', $this->session->getFlashBag());
|
|
}
|
|
|
|
// deprecated since 2.1, will be removed from 2.3
|
|
|
|
public function testGetSetFlashes()
|
|
{
|
|
$array = array('notice' => 'hello', 'error' => 'none');
|
|
$this->assertEquals(array(), $this->session->getFlashes());
|
|
$this->session->setFlashes($array);
|
|
$this->assertEquals($array, $this->session->getFlashes());
|
|
$this->assertEquals(array(), $this->session->getFlashes());
|
|
$this->session->getFlashBag()->add('notice', 'foo');
|
|
|
|
// test that BC works by only retrieving the first added.
|
|
$this->session->getFlashBag()->add('notice', 'foo2');
|
|
$this->assertEquals(array('notice' => 'foo'), $this->session->getFlashes());
|
|
}
|
|
|
|
public function testGetSetFlash()
|
|
{
|
|
$this->assertNull($this->session->getFlash('notice'));
|
|
$this->assertEquals('default', $this->session->getFlash('notice', 'default'));
|
|
$this->session->getFlashBag()->add('notice', 'foo');
|
|
$this->session->getFlashBag()->add('notice', 'foo2');
|
|
|
|
// test that BC works by only retrieving the first added.
|
|
$this->assertEquals('foo', $this->session->getFlash('notice'));
|
|
$this->assertNull($this->session->getFlash('notice'));
|
|
}
|
|
|
|
public function testHasFlash()
|
|
{
|
|
$this->assertFalse($this->session->hasFlash('notice'));
|
|
$this->session->setFlash('notice', 'foo');
|
|
$this->assertTrue($this->session->hasFlash('notice'));
|
|
}
|
|
|
|
public function testRemoveFlash()
|
|
{
|
|
$this->session->setFlash('notice', 'foo');
|
|
$this->session->setFlash('error', 'bar');
|
|
$this->assertTrue($this->session->hasFlash('notice'));
|
|
$this->session->removeFlash('error');
|
|
$this->assertTrue($this->session->hasFlash('notice'));
|
|
$this->assertFalse($this->session->hasFlash('error'));
|
|
}
|
|
|
|
public function testClearFlashes()
|
|
{
|
|
$this->assertFalse($this->session->hasFlash('notice'));
|
|
$this->assertFalse($this->session->hasFlash('error'));
|
|
$this->session->setFlash('notice', 'foo');
|
|
$this->session->setFlash('error', 'bar');
|
|
$this->assertTrue($this->session->hasFlash('notice'));
|
|
$this->assertTrue($this->session->hasFlash('error'));
|
|
$this->session->clearFlashes();
|
|
$this->assertFalse($this->session->hasFlash('notice'));
|
|
$this->assertFalse($this->session->hasFlash('error'));
|
|
}
|
|
|
|
/**
|
|
* @covers Symfony\Component\HttpFoundation\Session\Session::getIterator
|
|
*/
|
|
public function testGetIterator()
|
|
{
|
|
$attributes = array('hello' => 'world', 'symfony2' => 'rocks');
|
|
foreach ($attributes as $key => $val) {
|
|
$this->session->set($key, $val);
|
|
}
|
|
|
|
$i = 0;
|
|
foreach ($this->session as $key => $val) {
|
|
$this->assertEquals($attributes[$key], $val);
|
|
$i++;
|
|
}
|
|
|
|
$this->assertEquals(count($attributes), $i);
|
|
}
|
|
|
|
/**
|
|
* @covers Symfony\Component\HttpFoundation\Session\Session::count
|
|
*/
|
|
public function testGetCount()
|
|
{
|
|
$this->session->set('hello', 'world');
|
|
$this->session->set('symfony2', 'rocks');
|
|
|
|
$this->assertEquals(2, count($this->session));
|
|
}
|
|
}
|