Open Monograph Press  3.3.0
MongoDbSessionHandlerTest.php
1 <?php
2 
3 /*
4  * This file is part of the Symfony package.
5  *
6  * (c) Fabien Potencier <fabien@symfony.com>
7  *
8  * For the full copyright and license information, please view the LICENSE
9  * file that was distributed with this source code.
10  */
11 
13 
14 use PHPUnit\Framework\TestCase;
16 
21 class MongoDbSessionHandlerTest extends TestCase
22 {
26  private $mongo;
27  private $storage;
28  public $options;
29 
30  protected function setUp()
31  {
32  parent::setUp();
33 
34  if (extension_loaded('mongodb')) {
35  if (!class_exists('MongoDB\Client')) {
36  $this->markTestSkipped('The mongodb/mongodb package is required.');
37  }
38  } elseif (!extension_loaded('mongo')) {
39  $this->markTestSkipped('The Mongo or MongoDB extension is required.');
40  }
41 
42  if (phpversion('mongodb')) {
43  $mongoClass = 'MongoDB\Client';
44  } else {
45  $mongoClass = version_compare(phpversion('mongo'), '1.3.0', '<') ? 'Mongo' : 'MongoClient';
46  }
47 
48  $this->mongo = $this->getMockBuilder($mongoClass)
49  ->disableOriginalConstructor()
50  ->getMock();
51 
52  $this->options = array(
53  'id_field' => '_id',
54  'data_field' => 'data',
55  'time_field' => 'time',
56  'expiry_field' => 'expires_at',
57  'database' => 'sf2-test',
58  'collection' => 'session-test',
59  );
60 
61  $this->storage = new MongoDbSessionHandler($this->mongo, $this->options);
62  }
63 
68  {
69  new MongoDbSessionHandler(new \stdClass(), $this->options);
70  }
71 
76  {
77  new MongoDbSessionHandler($this->mongo, array());
78  }
79 
80  public function testOpenMethodAlwaysReturnTrue()
81  {
82  $this->assertTrue($this->storage->open('test', 'test'), 'The "open" method should always return true');
83  }
84 
85  public function testCloseMethodAlwaysReturnTrue()
86  {
87  $this->assertTrue($this->storage->close(), 'The "close" method should always return true');
88  }
89 
90  public function testRead()
91  {
92  $collection = $this->createMongoCollectionMock();
93 
94  $this->mongo->expects($this->once())
95  ->method('selectCollection')
96  ->with($this->options['database'], $this->options['collection'])
97  ->will($this->returnValue($collection));
98 
99  // defining the timeout before the actual method call
100  // allows to test for "greater than" values in the $criteria
101  $testTimeout = time() + 1;
102 
103  $collection->expects($this->once())
104  ->method('findOne')
105  ->will($this->returnCallback(function ($criteria) use ($testTimeout) {
106  $this->assertArrayHasKey($this->options['id_field'], $criteria);
107  $this->assertEquals($criteria[$this->options['id_field']], 'foo');
108 
109  $this->assertArrayHasKey($this->options['expiry_field'], $criteria);
110  $this->assertArrayHasKey('$gte', $criteria[$this->options['expiry_field']]);
111 
112  if (phpversion('mongodb')) {
113  $this->assertInstanceOf('MongoDB\BSON\UTCDateTime', $criteria[$this->options['expiry_field']]['$gte']);
114  $this->assertGreaterThanOrEqual(round((string) $criteria[$this->options['expiry_field']]['$gte'] / 1000), $testTimeout);
115  } else {
116  $this->assertInstanceOf('MongoDate', $criteria[$this->options['expiry_field']]['$gte']);
117  $this->assertGreaterThanOrEqual($criteria[$this->options['expiry_field']]['$gte']->sec, $testTimeout);
118  }
119 
120  $fields = array(
121  $this->options['id_field'] => 'foo',
122  );
123 
124  if (phpversion('mongodb')) {
125  $fields[$this->options['data_field']] = new \MongoDB\BSON\Binary('bar', \MongoDB\BSON\Binary::TYPE_OLD_BINARY);
126  $fields[$this->options['id_field']] = new \MongoDB\BSON\UTCDateTime(time() * 1000);
127  } else {
128  $fields[$this->options['data_field']] = new \MongoBinData('bar', \MongoBinData::BYTE_ARRAY);
129  $fields[$this->options['id_field']] = new \MongoDate();
130  }
131 
132  return $fields;
133  }));
134 
135  $this->assertEquals('bar', $this->storage->read('foo'));
136  }
137 
138  public function testWrite()
139  {
140  $collection = $this->createMongoCollectionMock();
141 
142  $this->mongo->expects($this->once())
143  ->method('selectCollection')
144  ->with($this->options['database'], $this->options['collection'])
145  ->will($this->returnValue($collection));
146 
147  $data = array();
148 
149  $methodName = phpversion('mongodb') ? 'updateOne' : 'update';
150 
151  $collection->expects($this->once())
152  ->method($methodName)
153  ->will($this->returnCallback(function ($criteria, $updateData, $options) use (&$data) {
154  $this->assertEquals(array($this->options['id_field'] => 'foo'), $criteria);
155 
156  if (phpversion('mongodb')) {
157  $this->assertEquals(array('upsert' => true), $options);
158  } else {
159  $this->assertEquals(array('upsert' => true, 'multiple' => false), $options);
160  }
161 
162  $data = $updateData['$set'];
163  }));
164 
165  $expectedExpiry = time() + (int) ini_get('session.gc_maxlifetime');
166  $this->assertTrue($this->storage->write('foo', 'bar'));
167 
168  if (phpversion('mongodb')) {
169  $this->assertEquals('bar', $data[$this->options['data_field']]->getData());
170  $this->assertInstanceOf('MongoDB\BSON\UTCDateTime', $data[$this->options['time_field']]);
171  $this->assertInstanceOf('MongoDB\BSON\UTCDateTime', $data[$this->options['expiry_field']]);
172  $this->assertGreaterThanOrEqual($expectedExpiry, round((string) $data[$this->options['expiry_field']] / 1000));
173  } else {
174  $this->assertEquals('bar', $data[$this->options['data_field']]->bin);
175  $this->assertInstanceOf('MongoDate', $data[$this->options['time_field']]);
176  $this->assertInstanceOf('MongoDate', $data[$this->options['expiry_field']]);
177  $this->assertGreaterThanOrEqual($expectedExpiry, $data[$this->options['expiry_field']]->sec);
178  }
179  }
180 
181  public function testWriteWhenUsingExpiresField()
182  {
183  $this->options = array(
184  'id_field' => '_id',
185  'data_field' => 'data',
186  'time_field' => 'time',
187  'database' => 'sf2-test',
188  'collection' => 'session-test',
189  'expiry_field' => 'expiresAt',
190  );
191 
192  $this->storage = new MongoDbSessionHandler($this->mongo, $this->options);
193 
194  $collection = $this->createMongoCollectionMock();
195 
196  $this->mongo->expects($this->once())
197  ->method('selectCollection')
198  ->with($this->options['database'], $this->options['collection'])
199  ->will($this->returnValue($collection));
200 
201  $data = array();
202 
203  $methodName = phpversion('mongodb') ? 'updateOne' : 'update';
204 
205  $collection->expects($this->once())
206  ->method($methodName)
207  ->will($this->returnCallback(function ($criteria, $updateData, $options) use (&$data) {
208  $this->assertEquals(array($this->options['id_field'] => 'foo'), $criteria);
209 
210  if (phpversion('mongodb')) {
211  $this->assertEquals(array('upsert' => true), $options);
212  } else {
213  $this->assertEquals(array('upsert' => true, 'multiple' => false), $options);
214  }
215 
216  $data = $updateData['$set'];
217  }));
218 
219  $this->assertTrue($this->storage->write('foo', 'bar'));
220 
221  if (phpversion('mongodb')) {
222  $this->assertEquals('bar', $data[$this->options['data_field']]->getData());
223  $this->assertInstanceOf('MongoDB\BSON\UTCDateTime', $data[$this->options['time_field']]);
224  $this->assertInstanceOf('MongoDB\BSON\UTCDateTime', $data[$this->options['expiry_field']]);
225  } else {
226  $this->assertEquals('bar', $data[$this->options['data_field']]->bin);
227  $this->assertInstanceOf('MongoDate', $data[$this->options['time_field']]);
228  $this->assertInstanceOf('MongoDate', $data[$this->options['expiry_field']]);
229  }
230  }
231 
232  public function testReplaceSessionData()
233  {
234  $collection = $this->createMongoCollectionMock();
235 
236  $this->mongo->expects($this->once())
237  ->method('selectCollection')
238  ->with($this->options['database'], $this->options['collection'])
239  ->will($this->returnValue($collection));
240 
241  $data = array();
242 
243  $methodName = phpversion('mongodb') ? 'updateOne' : 'update';
244 
245  $collection->expects($this->exactly(2))
246  ->method($methodName)
247  ->will($this->returnCallback(function ($criteria, $updateData, $options) use (&$data) {
248  $data = $updateData;
249  }));
250 
251  $this->storage->write('foo', 'bar');
252  $this->storage->write('foo', 'foobar');
253 
254  if (phpversion('mongodb')) {
255  $this->assertEquals('foobar', $data['$set'][$this->options['data_field']]->getData());
256  } else {
257  $this->assertEquals('foobar', $data['$set'][$this->options['data_field']]->bin);
258  }
259  }
260 
261  public function testDestroy()
262  {
263  $collection = $this->createMongoCollectionMock();
264 
265  $this->mongo->expects($this->once())
266  ->method('selectCollection')
267  ->with($this->options['database'], $this->options['collection'])
268  ->will($this->returnValue($collection));
269 
270  $methodName = phpversion('mongodb') ? 'deleteOne' : 'remove';
271 
272  $collection->expects($this->once())
273  ->method($methodName)
274  ->with(array($this->options['id_field'] => 'foo'));
275 
276  $this->assertTrue($this->storage->destroy('foo'));
277  }
278 
279  public function testGc()
280  {
281  $collection = $this->createMongoCollectionMock();
282 
283  $this->mongo->expects($this->once())
284  ->method('selectCollection')
285  ->with($this->options['database'], $this->options['collection'])
286  ->will($this->returnValue($collection));
287 
288  $methodName = phpversion('mongodb') ? 'deleteOne' : 'remove';
289 
290  $collection->expects($this->once())
291  ->method($methodName)
292  ->will($this->returnCallback(function ($criteria) {
293  if (phpversion('mongodb')) {
294  $this->assertInstanceOf('MongoDB\BSON\UTCDateTime', $criteria[$this->options['expiry_field']]['$lt']);
295  $this->assertGreaterThanOrEqual(time() - 1, round((string) $criteria[$this->options['expiry_field']]['$lt'] / 1000));
296  } else {
297  $this->assertInstanceOf('MongoDate', $criteria[$this->options['expiry_field']]['$lt']);
298  $this->assertGreaterThanOrEqual(time() - 1, $criteria[$this->options['expiry_field']]['$lt']->sec);
299  }
300  }));
301 
302  $this->assertTrue($this->storage->gc(1));
303  }
304 
305  public function testGetConnection()
306  {
307  $method = new \ReflectionMethod($this->storage, 'getMongo');
308  $method->setAccessible(true);
309 
310  if (phpversion('mongodb')) {
311  $mongoClass = 'MongoDB\Client';
312  } else {
313  $mongoClass = version_compare(phpversion('mongo'), '1.3.0', '<') ? 'Mongo' : 'MongoClient';
314  }
315 
316  $this->assertInstanceOf($mongoClass, $method->invoke($this->storage));
317  }
318 
319  private function createMongoCollectionMock()
320  {
321  $collectionClass = 'MongoCollection';
322  if (phpversion('mongodb')) {
323  $collectionClass = 'MongoDB\Collection';
324  }
325 
326  $collection = $this->getMockBuilder($collectionClass)
327  ->disableOriginalConstructor()
328  ->getMock();
329 
330  return $collection;
331  }
332 }
Symfony\Component\HttpFoundation\Tests\Session\Storage\Handler\MongoDbSessionHandlerTest\$options
$options
Definition: MongoDbSessionHandlerTest.php:31
Symfony\Component\HttpFoundation\Tests\Session\Storage\Handler\MongoDbSessionHandlerTest\testOpenMethodAlwaysReturnTrue
testOpenMethodAlwaysReturnTrue()
Definition: MongoDbSessionHandlerTest.php:83
Symfony\Component\HttpFoundation\Tests\Session\Storage\Handler\MongoDbSessionHandlerTest\testConstructorShouldThrowExceptionForMissingOptions
testConstructorShouldThrowExceptionForMissingOptions()
Definition: MongoDbSessionHandlerTest.php:78
Symfony\Component\HttpFoundation\Tests\Session\Storage\Handler\MongoDbSessionHandlerTest\testWrite
testWrite()
Definition: MongoDbSessionHandlerTest.php:141
Symfony\Component\HttpFoundation\Tests\Session\Storage\Handler\MongoDbSessionHandlerTest\testConstructorShouldThrowExceptionForInvalidMongo
testConstructorShouldThrowExceptionForInvalidMongo()
Definition: MongoDbSessionHandlerTest.php:70
Symfony\Component\HttpFoundation\Tests\Session\Storage\Handler\MongoDbSessionHandlerTest
Definition: MongoDbSessionHandlerTest.php:21
Symfony\Component\HttpFoundation\Tests\Session\Storage\Handler\MongoDbSessionHandlerTest\setUp
setUp()
Definition: MongoDbSessionHandlerTest.php:33
Symfony\Component\HttpFoundation\Tests\Session\Storage\Handler\MongoDbSessionHandlerTest\testGetConnection
testGetConnection()
Definition: MongoDbSessionHandlerTest.php:308
Symfony\Component\HttpFoundation\Tests\Session\Storage\Handler\MongoDbSessionHandlerTest\testDestroy
testDestroy()
Definition: MongoDbSessionHandlerTest.php:264
Symfony\Component\HttpFoundation\Tests\Session\Storage\Handler\MongoDbSessionHandlerTest\testGc
testGc()
Definition: MongoDbSessionHandlerTest.php:282
Symfony\Component\HttpFoundation\Session\Storage\Handler\MongoDbSessionHandler
Definition: lib/vendor/symfony/http-foundation/Session/Storage/Handler/MongoDbSessionHandler.php:19
Symfony\Component\HttpFoundation\Tests\Session\Storage\Handler\MongoDbSessionHandlerTest\testCloseMethodAlwaysReturnTrue
testCloseMethodAlwaysReturnTrue()
Definition: MongoDbSessionHandlerTest.php:88
Symfony\Component\HttpFoundation\Tests\Session\Storage\Handler\MongoDbSessionHandlerTest\testWriteWhenUsingExpiresField
testWriteWhenUsingExpiresField()
Definition: MongoDbSessionHandlerTest.php:184
Symfony\Component\HttpFoundation\Tests\Session\Storage\Handler
Definition: MemcachedSessionHandlerTest.php:12
Symfony\Component\HttpFoundation\Tests\Session\Storage\Handler\MongoDbSessionHandlerTest\testRead
testRead()
Definition: MongoDbSessionHandlerTest.php:93
Symfony\Component\HttpFoundation\Tests\Session\Storage\Handler\MongoDbSessionHandlerTest\testReplaceSessionData
testReplaceSessionData()
Definition: MongoDbSessionHandlerTest.php:235