*/ class MongoClientTest extends TestCase { /** * @dataProvider provideConnectionUri */ public function testConnectionUri($uri, $expected) { $this->skipTestIf(extension_loaded('mongo')); $this->assertSame($expected, (string) (new \MongoClient($uri, ['connect' => false]))); } public function provideConnectionUri() { yield ['default', sprintf('mongodb://%s:%d', \MongoClient::DEFAULT_HOST, \MongoClient::DEFAULT_PORT)]; yield ['localhost', 'mongodb://localhost']; yield ['mongodb://localhost', 'mongodb://localhost']; } public function testSerialize() { $this->assertIsString(serialize($this->getClient())); } public function testGetDb() { $client = $this->getClient(); $db = $client->selectDB('mongo-php-adapter'); $this->assertInstanceOf('\MongoDB', $db); $this->assertSame('mongo-php-adapter', (string) $db); } public function testSelectDBWithEmptyName() { $this->expectException(\Exception::class); $this->expectExceptionMessage('Database name cannot be empty'); $this->getClient()->selectDB(''); } public function testSelectDBWithInvalidName() { $this->expectException(\Exception::class); $this->expectExceptionMessage('Database name contains invalid characters'); $this->getClient()->selectDB('/'); } public function testGetDbProperty() { $client = $this->getClient(); $db = $client->{'mongo-php-adapter'}; $this->assertInstanceOf('\MongoDB', $db); $this->assertSame('mongo-php-adapter', (string) $db); } public function testGetCollection() { $client = $this->getClient(); $collection = $client->selectCollection('mongo-php-adapter', 'test'); $this->assertInstanceOf('MongoCollection', $collection); $this->assertSame('mongo-php-adapter.test', (string) $collection); } public function testGetHosts() { $client = $this->getClient(); $hosts = $client->getHosts(); $this->assertMatches( [ 'localhost:27017;-;.;' . getmypid() => [ 'host' => 'localhost', 'port' => 27017, 'health' => 1, 'state' => 0, ], ], $hosts ); } public function testGetHostsExceptionHandling() { $this->expectException(\MongoConnectionException::class); $this->expectErrorMessageMatches('/fake_host/'); $client = $this->getClient(null, 'mongodb://fake_host'); $client->getHosts(); } public function testReadPreference() { $client = $this->getClient(); $this->assertSame(['type' => \MongoClient::RP_PRIMARY], $client->getReadPreference()); $this->assertTrue($client->setReadPreference(\MongoClient::RP_SECONDARY, [['a' => 'b']])); $this->assertSame(['type' => \MongoClient::RP_SECONDARY, 'tagsets' => [['a' => 'b']]], $client->getReadPreference()); } public function testWriteConcern() { $client = $this->getClient(); $this->assertTrue($client->setWriteConcern('majority', 100)); $this->assertSame(['w' => 'majority', 'wtimeout' => 100], $client->getWriteConcern()); } public function testListDBs() { $document = ['foo' => 'bar']; $this->getCollection()->insert($document); $databases = $this->getClient()->listDBs(); $this->assertSame(1.0, $databases['ok']); $this->assertArrayHasKey('totalSize', $databases); $this->assertArrayHasKey('databases', $databases); foreach ($databases['databases'] as $database) { $this->assertArrayHasKey('name', $database); $this->assertArrayHasKey('empty', $database); $this->assertArrayHasKey('sizeOnDisk', $database); if ($database['name'] == 'mongo-php-adapter') { $this->assertFalse($database['empty']); return; } } $this->fail('Could not find mongo-php-adapter database in list'); } public function testNoPrefixUri() { $client = $this->getClient(null, 'localhost'); $this->assertNotNull($client); } /** * @dataProvider dataReadPreferenceOptionsAreInherited */ public function testReadPreferenceOptionsAreInherited($options, $uri, $expectedTagsets) { $client = $this->getClient($options, $uri); $collection = $client->selectCollection('test', 'foo'); $this->assertSame( [ 'type' => \MongoClient::RP_SECONDARY_PREFERRED, 'tagsets' => $expectedTagsets ], $collection->getReadPreference() ); } public static function dataReadPreferenceOptionsAreInherited() { $options = [ 'readPreference' => \MongoClient::RP_SECONDARY_PREFERRED, 'readPreferenceTags' => 'a:b', ]; $overriddenOptions = [ 'readPreference' => \MongoClient::RP_NEAREST, 'readPreferenceTags' => 'c:d', ]; $multipleTagsets = [ 'readPreference' => \MongoClient::RP_SECONDARY_PREFERRED, 'readPreferenceTags' => 'a:b,c:d', ]; return [ 'optionsArray' => [ 'options' => $options, 'uri' => 'mongodb://localhost', 'expectedTagsets' => [['a' => 'b']], ], 'queryString' => [ 'options' => [], 'uri' => 'mongodb://localhost/?' . self::makeOptionString($options), 'expectedTagsets' => [['a' => 'b']], ], 'multipleInQueryString' => [ 'options' => [], 'uri' => 'mongodb://localhost/?' . self::makeOptionString($options) . '&readPreferenceTags=c:d', 'expectedTagsets' => [['a' => 'b'], ['c' => 'd']], ], 'overridden' => [ 'options' => $options, 'uri' => 'mongodb://localhost/?' . self::makeOptionString($overriddenOptions), 'expectedTagsets' => [['c' => 'd'], ['a' => 'b']], ], 'multipleTagsetsOptions' => [ 'options' => $multipleTagsets, 'uri' => 'mongodb://localhost', 'expectedTagsets' => [['a' => 'b', 'c' => 'd']], ], 'multipleTagsetsQueryString' => [ 'options' => null, 'uri' => 'mongodb://localhost/?' . self::makeOptionString($multipleTagsets), 'expectedTagsets' => [['a' => 'b', 'c' => 'd']], ], ]; } /** * @dataProvider dataWriteConcernOptionsAreInherited */ public function testWriteConcernOptionsAreInherited($options, $uri) { $client = $this->getClient($options, $uri); $collection = $client->selectCollection('test', 'foo'); $this->assertSame(['w' => 'majority', 'wtimeout' => 666], $collection->getWriteConcern()); } public static function dataWriteConcernOptionsAreInherited() { $options = [ 'w' => 'majority', 'wTimeoutMs' => 666, ]; $overriddenOptions = [ 'w' => '2', 'wTimeoutMs' => 333, ]; return [ 'optionsArray' => [ 'options' => $options, 'uri' => 'mongodb://localhost', ], 'queryString' => [ 'options' => [], 'uri' => 'mongodb://localhost/?' . self::makeOptionString($options), ], 'overridden' => [ 'options' => $options, 'uri' => 'mongodb://localhost/?' . self::makeOptionString($overriddenOptions), ] ]; } public function testConnectWithUsernameAndPassword() { $this->expectException(\MongoConnectionException::class); $this->expectExceptionMessage('Authentication failed'); $client = $this->getClient(['username' => 'alcaeus', 'password' => 'mySuperSecurePassword']); $collection = $client->selectCollection('test', 'foo'); $document = ['foo' => 'bar']; $collection->insert($document); } public function testConnectWithUsernameAndPasswordInConnectionUrl() { $this->expectException(\MongoConnectionException::class); $this->expectExceptionMessage('Authentication failed'); $client = $this->getClient([], 'mongodb://alcaeus:mySuperSecurePassword@localhost'); $collection = $client->selectCollection('test', 'foo'); $document = ['foo' => 'bar']; $collection->insert($document); } public function testConnectionUriOptionIntegerTypeCasting() { $client = new \MongoClient('mongodb://localhost/db?w=0&wtimeout=0', ['connect' => false]); $this->assertSame(['w' => 0, 'wtimeout' => 0], $client->getWriteConcern()); } /** * @param array $options * @return string */ private static function makeOptionString(array $options) { return implode('&', array_map( function ($key, $value) { return $key . '=' . $value; }, array_keys($options), array_values($options) )); } }