14 use PHPUnit\Framework\TestCase;
30 protected function setUp()
34 if (extension_loaded(
'mongodb')) {
35 if (!class_exists(
'MongoDB\Client')) {
36 $this->markTestSkipped(
'The mongodb/mongodb package is required.');
38 } elseif (!extension_loaded(
'mongo')) {
39 $this->markTestSkipped(
'The Mongo or MongoDB extension is required.');
42 if (phpversion(
'mongodb')) {
43 $mongoClass =
'MongoDB\Client';
45 $mongoClass = version_compare(phpversion(
'mongo'),
'1.3.0',
'<') ?
'Mongo' :
'MongoClient';
48 $this->mongo = $this->getMockBuilder($mongoClass)
49 ->disableOriginalConstructor()
52 $this->options = array(
54 'data_field' =>
'data',
55 'time_field' =>
'time',
56 'expiry_field' =>
'expires_at',
57 'database' =>
'sf2-test',
58 'collection' =>
'session-test',
61 $this->storage =
new MongoDbSessionHandler($this->mongo, $this->options);
69 new MongoDbSessionHandler(
new \stdClass(), $this->options);
82 $this->assertTrue($this->storage->open(
'test',
'test'),
'The "open" method should always return true');
87 $this->assertTrue($this->storage->close(),
'The "close" method should always return true');
92 $collection = $this->createMongoCollectionMock();
94 $this->mongo->expects($this->once())
95 ->method(
'selectCollection')
96 ->with($this->options[
'database'], $this->options[
'collection'])
97 ->will($this->returnValue($collection));
101 $testTimeout = time() + 1;
103 $collection->expects($this->once())
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');
109 $this->assertArrayHasKey($this->options[
'expiry_field'], $criteria);
110 $this->assertArrayHasKey(
'$gte', $criteria[$this->options[
'expiry_field']]);
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);
116 $this->assertInstanceOf(
'MongoDate', $criteria[$this->options[
'expiry_field']][
'$gte']);
117 $this->assertGreaterThanOrEqual($criteria[$this->options[
'expiry_field']][
'$gte']->sec, $testTimeout);
121 $this->options[
'id_field'] =>
'foo',
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);
128 $fields[$this->options[
'data_field']] = new \MongoBinData(
'bar', \MongoBinData::BYTE_ARRAY);
129 $fields[$this->options[
'id_field']] = new \MongoDate();
135 $this->assertEquals(
'bar', $this->storage->read(
'foo'));
140 $collection = $this->createMongoCollectionMock();
142 $this->mongo->expects($this->once())
143 ->method(
'selectCollection')
144 ->with($this->options[
'database'], $this->options[
'collection'])
145 ->will($this->returnValue($collection));
149 $methodName = phpversion(
'mongodb') ?
'updateOne' :
'update';
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);
156 if (phpversion(
'mongodb')) {
157 $this->assertEquals(array(
'upsert' =>
true),
$options);
159 $this->assertEquals(array(
'upsert' =>
true,
'multiple' =>
false),
$options);
162 $data = $updateData[
'$set'];
165 $expectedExpiry = time() + (int) ini_get(
'session.gc_maxlifetime');
166 $this->assertTrue($this->storage->write(
'foo',
'bar'));
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));
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);
183 $this->options = array(
185 'data_field' =>
'data',
186 'time_field' =>
'time',
187 'database' =>
'sf2-test',
188 'collection' =>
'session-test',
189 'expiry_field' =>
'expiresAt',
194 $collection = $this->createMongoCollectionMock();
196 $this->mongo->expects($this->once())
197 ->method(
'selectCollection')
198 ->with($this->options[
'database'], $this->options[
'collection'])
199 ->will($this->returnValue($collection));
203 $methodName = phpversion(
'mongodb') ?
'updateOne' :
'update';
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);
210 if (phpversion(
'mongodb')) {
211 $this->assertEquals(array(
'upsert' =>
true),
$options);
213 $this->assertEquals(array(
'upsert' =>
true,
'multiple' =>
false),
$options);
216 $data = $updateData[
'$set'];
219 $this->assertTrue($this->storage->write(
'foo',
'bar'));
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']]);
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']]);
234 $collection = $this->createMongoCollectionMock();
236 $this->mongo->expects($this->once())
237 ->method(
'selectCollection')
238 ->with($this->options[
'database'], $this->options[
'collection'])
239 ->will($this->returnValue($collection));
243 $methodName = phpversion(
'mongodb') ?
'updateOne' :
'update';
245 $collection->expects($this->exactly(2))
246 ->method($methodName)
247 ->will($this->returnCallback(
function ($criteria, $updateData,
$options) use (&$data) {
251 $this->storage->write(
'foo',
'bar');
252 $this->storage->write(
'foo',
'foobar');
254 if (phpversion(
'mongodb')) {
255 $this->assertEquals(
'foobar', $data[
'$set'][$this->options[
'data_field']]->getData());
257 $this->assertEquals(
'foobar', $data[
'$set'][$this->options[
'data_field']]->bin);
263 $collection = $this->createMongoCollectionMock();
265 $this->mongo->expects($this->once())
266 ->method(
'selectCollection')
267 ->with($this->options[
'database'], $this->options[
'collection'])
268 ->will($this->returnValue($collection));
270 $methodName = phpversion(
'mongodb') ?
'deleteOne' :
'remove';
272 $collection->expects($this->once())
273 ->method($methodName)
274 ->with(array($this->options[
'id_field'] =>
'foo'));
276 $this->assertTrue($this->storage->destroy(
'foo'));
281 $collection = $this->createMongoCollectionMock();
283 $this->mongo->expects($this->once())
284 ->method(
'selectCollection')
285 ->with($this->options[
'database'], $this->options[
'collection'])
286 ->will($this->returnValue($collection));
288 $methodName = phpversion(
'mongodb') ?
'deleteOne' :
'remove';
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));
297 $this->assertInstanceOf(
'MongoDate', $criteria[$this->options[
'expiry_field']][
'$lt']);
298 $this->assertGreaterThanOrEqual(time() - 1, $criteria[$this->options[
'expiry_field']][
'$lt']->sec);
302 $this->assertTrue($this->storage->gc(1));
307 $method = new \ReflectionMethod($this->storage,
'getMongo');
308 $method->setAccessible(
true);
310 if (phpversion(
'mongodb')) {
311 $mongoClass =
'MongoDB\Client';
313 $mongoClass = version_compare(phpversion(
'mongo'),
'1.3.0',
'<') ?
'Mongo' :
'MongoClient';
316 $this->assertInstanceOf($mongoClass, $method->invoke($this->storage));
319 private function createMongoCollectionMock()
321 $collectionClass =
'MongoCollection';
322 if (phpversion(
'mongodb')) {
323 $collectionClass =
'MongoDB\Collection';
326 $collection = $this->getMockBuilder($collectionClass)
327 ->disableOriginalConstructor()