1: <?php
2:
3: 4: 5: 6: 7: 8: 9: 10:
11:
12: namespace Symfony\Component\HttpFoundation\Tests\Session\Storage\Handler;
13:
14: use Symfony\Component\HttpFoundation\Session\Storage\Handler\MongoDbSessionHandler;
15:
16: 17: 18:
19: class MongoDbSessionHandlerTest extends \PHPUnit_Framework_TestCase
20: {
21: 22: 23:
24: private $mongo;
25: private $storage;
26: public $options;
27:
28: protected function setUp()
29: {
30: if (!extension_loaded('mongo')) {
31: $this->markTestSkipped('MongoDbSessionHandler requires the PHP "mongo" extension.');
32: }
33:
34: $mongoClass = version_compare(phpversion('mongo'), '1.3.0', '<') ? 'Mongo' : 'MongoClient';
35:
36: $this->mongo = $this->getMockBuilder($mongoClass)
37: ->getMock();
38:
39: $this->options = array(
40: 'id_field' => '_id',
41: 'data_field' => 'data',
42: 'time_field' => 'time',
43: 'database' => 'sf2-test',
44: 'collection' => 'session-test',
45: );
46:
47: $this->storage = new MongoDbSessionHandler($this->mongo, $this->options);
48: }
49:
50: 51: 52:
53: public function testConstructorShouldThrowExceptionForInvalidMongo()
54: {
55: new MongoDbSessionHandler(new \stdClass(), $this->options);
56: }
57:
58: 59: 60:
61: public function testConstructorShouldThrowExceptionForMissingOptions()
62: {
63: new MongoDbSessionHandler($this->mongo, array());
64: }
65:
66: public function testOpenMethodAlwaysReturnTrue()
67: {
68: $this->assertTrue($this->storage->open('test', 'test'), 'The "open" method should always return true');
69: }
70:
71: public function testCloseMethodAlwaysReturnTrue()
72: {
73: $this->assertTrue($this->storage->close(), 'The "close" method should always return true');
74: }
75:
76: public function testWrite()
77: {
78: $collection = $this->createMongoCollectionMock();
79:
80: $this->mongo->expects($this->once())
81: ->method('selectCollection')
82: ->with($this->options['database'], $this->options['collection'])
83: ->will($this->returnValue($collection));
84:
85: $that = $this;
86: $data = array();
87:
88: $collection->expects($this->once())
89: ->method('update')
90: ->will($this->returnCallback(function ($criteria, $updateData, $options) use ($that, &$data) {
91: $that->assertEquals(array($that->options['id_field'] => 'foo'), $criteria);
92: $that->assertEquals(array('upsert' => true, 'multiple' => false), $options);
93:
94: $data = $updateData['$set'];
95: }));
96:
97: $this->assertTrue($this->storage->write('foo', 'bar'));
98:
99: $this->assertEquals('bar', $data[$this->options['data_field']]->bin);
100: $that->assertInstanceOf('MongoDate', $data[$this->options['time_field']]);
101: }
102:
103: public function testWriteWhenUsingExpiresField()
104: {
105: $this->options = array(
106: 'id_field' => '_id',
107: 'data_field' => 'data',
108: 'time_field' => 'time',
109: 'database' => 'sf2-test',
110: 'collection' => 'session-test',
111: 'expiry_field' => 'expiresAt',
112: );
113:
114: $this->storage = new MongoDbSessionHandler($this->mongo, $this->options);
115:
116: $collection = $this->createMongoCollectionMock();
117:
118: $this->mongo->expects($this->once())
119: ->method('selectCollection')
120: ->with($this->options['database'], $this->options['collection'])
121: ->will($this->returnValue($collection));
122:
123: $that = $this;
124: $data = array();
125:
126: $collection->expects($this->once())
127: ->method('update')
128: ->will($this->returnCallback(function ($criteria, $updateData, $options) use ($that, &$data) {
129: $that->assertEquals(array($that->options['id_field'] => 'foo'), $criteria);
130: $that->assertEquals(array('upsert' => true, 'multiple' => false), $options);
131:
132: $data = $updateData['$set'];
133: }));
134:
135: $this->assertTrue($this->storage->write('foo', 'bar'));
136:
137: $this->assertEquals('bar', $data[$this->options['data_field']]->bin);
138: $that->assertInstanceOf('MongoDate', $data[$this->options['time_field']]);
139: $that->assertInstanceOf('MongoDate', $data[$this->options['expiry_field']]);
140: }
141:
142: public function testReplaceSessionData()
143: {
144: $collection = $this->createMongoCollectionMock();
145:
146: $this->mongo->expects($this->once())
147: ->method('selectCollection')
148: ->with($this->options['database'], $this->options['collection'])
149: ->will($this->returnValue($collection));
150:
151: $data = array();
152:
153: $collection->expects($this->exactly(2))
154: ->method('update')
155: ->will($this->returnCallback(function ($criteria, $updateData, $options) use (&$data) {
156: $data = $updateData;
157: }));
158:
159: $this->storage->write('foo', 'bar');
160: $this->storage->write('foo', 'foobar');
161:
162: $this->assertEquals('foobar', $data['$set'][$this->options['data_field']]->bin);
163: }
164:
165: public function testDestroy()
166: {
167: $collection = $this->createMongoCollectionMock();
168:
169: $this->mongo->expects($this->once())
170: ->method('selectCollection')
171: ->with($this->options['database'], $this->options['collection'])
172: ->will($this->returnValue($collection));
173:
174: $collection->expects($this->once())
175: ->method('remove')
176: ->with(array($this->options['id_field'] => 'foo'));
177:
178: $this->assertTrue($this->storage->destroy('foo'));
179: }
180:
181: public function testGc()
182: {
183: $collection = $this->createMongoCollectionMock();
184:
185: $this->mongo->expects($this->once())
186: ->method('selectCollection')
187: ->with($this->options['database'], $this->options['collection'])
188: ->will($this->returnValue($collection));
189:
190: $that = $this;
191:
192: $collection->expects($this->once())
193: ->method('remove')
194: ->will($this->returnCallback(function ($criteria) use ($that) {
195: $that->assertInstanceOf('MongoDate', $criteria[$that->options['time_field']]['$lt']);
196: $that->assertGreaterThanOrEqual(time() - 1, $criteria[$that->options['time_field']]['$lt']->sec);
197: }));
198:
199: $this->assertTrue($this->storage->gc(1));
200: }
201:
202: public function testGcWhenUsingExpiresField()
203: {
204: $this->options = array(
205: 'id_field' => '_id',
206: 'data_field' => 'data',
207: 'time_field' => 'time',
208: 'database' => 'sf2-test',
209: 'collection' => 'session-test',
210: 'expiry_field' => 'expiresAt',
211: );
212:
213: $this->storage = new MongoDbSessionHandler($this->mongo, $this->options);
214:
215: $collection = $this->createMongoCollectionMock();
216:
217: $this->mongo->expects($this->never())
218: ->method('selectCollection');
219:
220: $that = $this;
221:
222: $collection->expects($this->never())
223: ->method('remove');
224:
225: $this->assertTrue($this->storage->gc(1));
226: }
227:
228: public function testGetConnection()
229: {
230: $method = new \ReflectionMethod($this->storage, 'getMongo');
231: $method->setAccessible(true);
232:
233: $mongoClass = (version_compare(phpversion('mongo'), '1.3.0', '<')) ? '\Mongo' : '\MongoClient';
234:
235: $this->assertInstanceOf($mongoClass, $method->invoke($this->storage));
236: }
237:
238: private function createMongoCollectionMock()
239: {
240: $mongoClient = $this->getMockBuilder('MongoClient')
241: ->getMock();
242: $mongoDb = $this->getMockBuilder('MongoDB')
243: ->setConstructorArgs(array($mongoClient, 'database-name'))
244: ->getMock();
245: $collection = $this->getMockBuilder('MongoCollection')
246: ->setConstructorArgs(array($mongoDb, 'collection-name'))
247: ->getMock();
248:
249: return $collection;
250: }
251: }
252: