Skip to content

Commit 0606fc0

Browse files
authored
Use single connection using DSN for testing (#2462)
* Always use connection string in tests * Document DSN configuration as preferred configuration method * Update wordings * Use matrix config instead of manually specifying builds * Apply StyleCI fixes * Add missing test for code coverage
1 parent 560e05e commit 0606fc0

File tree

9 files changed

+131
-117
lines changed

9 files changed

+131
-117
lines changed

Diff for: .github/workflows/build-ci.yml

+12-12
Original file line numberDiff line numberDiff line change
@@ -30,19 +30,19 @@ jobs:
3030

3131
build:
3232
runs-on: ${{ matrix.os }}
33-
name: PHP v${{ matrix.php }} with Mongo v${{ matrix.mongodb }}
34-
continue-on-error: ${{ matrix.experimental }}
33+
name: PHP v${{ matrix.php }} with MongoDB ${{ matrix.mongodb }}
3534
strategy:
3635
matrix:
37-
include:
38-
- { os: ubuntu-latest, php: 8.0, mongodb: '4.0', experimental: false }
39-
- { os: ubuntu-latest, php: 8.0, mongodb: 4.2, experimental: false }
40-
- { os: ubuntu-latest, php: 8.0, mongodb: 4.4, experimental: false }
41-
- { os: ubuntu-latest, php: 8.0, mongodb: '5.0', experimental: false }
42-
- { os: ubuntu-latest, php: 8.1, mongodb: '4.0', experimental: false }
43-
- { os: ubuntu-latest, php: 8.1, mongodb: 4.2, experimental: false }
44-
- { os: ubuntu-latest, php: 8.1, mongodb: 4.4, experimental: false }
45-
- { os: ubuntu-latest, php: 8.1, mongodb: '5.0', experimental: false }
36+
os:
37+
- ubuntu-latest
38+
mongodb:
39+
- '4.0'
40+
- '4.2'
41+
- '4.4'
42+
- '5.0'
43+
php:
44+
- '8.0'
45+
- '8.1'
4646
services:
4747
mongo:
4848
image: mongo:${{ matrix.mongodb }}
@@ -88,7 +88,7 @@ jobs:
8888
run: |
8989
./vendor/bin/phpunit --coverage-clover coverage.xml
9090
env:
91-
MONGO_HOST: 0.0.0.0
91+
MONGODB_URI: 'mongodb://127.0.0.1/'
9292
MYSQL_HOST: 0.0.0.0
9393
MYSQL_PORT: 3307
9494
- uses: codecov/codecov-action@v1

Diff for: README.md

+15-26
Original file line numberDiff line numberDiff line change
@@ -143,47 +143,36 @@ Keep in mind that these traits are not yet supported:
143143

144144
Configuration
145145
-------------
146-
You can use MongoDB either as the main database, either as a side database. To do so, add a new `mongodb` connection to `config/database.php`:
146+
147+
To configure a new MongoDB connection, add a new connection entry to `config/database.php`:
147148

148149
```php
149150
'mongodb' => [
150151
'driver' => 'mongodb',
151-
'host' => env('DB_HOST', '127.0.0.1'),
152-
'port' => env('DB_PORT', 27017),
152+
'dsn' => env('DB_DSN'),
153153
'database' => env('DB_DATABASE', 'homestead'),
154-
'username' => env('DB_USERNAME', 'homestead'),
155-
'password' => env('DB_PASSWORD', 'secret'),
156-
'options' => [
157-
// here you can pass more settings to the Mongo Driver Manager
158-
// see https://www.php.net/manual/en/mongodb-driver-manager.construct.php under "Uri Options" for a list of complete parameters that you can use
159-
160-
'database' => env('DB_AUTHENTICATION_DATABASE', 'admin'), // required with Mongo 3+
161-
],
162154
],
163155
```
164156

165-
For multiple servers or replica set configurations, set the host to an array and specify each server host:
157+
The `dsn` key contains the connection string used to connect to your MongoDB deployment. The format and available options are documented in the [MongoDB documentation](https://docs.mongodb.com/manual/reference/connection-string/).
158+
159+
Instead of using a connection string, you can also use the `host` and `port` configuration options to have the connection string created for you.
166160

167161
```php
168162
'mongodb' => [
169163
'driver' => 'mongodb',
170-
'host' => ['server1', 'server2', ...],
171-
...
164+
'host' => env('DB_HOST', '127.0.0.1'),
165+
'port' => env('DB_PORT', 27017),
166+
'database' => env('DB_DATABASE', 'homestead'),
167+
'username' => env('DB_USERNAME', 'homestead'),
168+
'password' => env('DB_PASSWORD', 'secret'),
172169
'options' => [
173-
'replicaSet' => 'rs0',
170+
'appname' => 'homestead',
174171
],
175172
],
176173
```
177174

178-
If you wish to use a connection string instead of full key-value params, you can set it so. Check the documentation on MongoDB's URI format: https://docs.mongodb.com/manual/reference/connection-string/
179-
180-
```php
181-
'mongodb' => [
182-
'driver' => 'mongodb',
183-
'dsn' => env('DB_DSN'),
184-
'database' => env('DB_DATABASE', 'homestead'),
185-
],
186-
```
175+
The `options` key in the connection configuration corresponds to the [`uriOptions` parameter](https://www.php.net/manual/en/mongodb-driver-manager.construct.php#mongodb-driver-manager.construct-urioptions).
187176

188177
Eloquent
189178
--------
@@ -223,7 +212,7 @@ class Book extends Model
223212
protected $primaryKey = 'id';
224213
}
225214

226-
// Mongo will also create _id, but the 'id' property will be used for primary key actions like find().
215+
// MongoDB will also create _id, but the 'id' property will be used for primary key actions like find().
227216
Book::create(['id' => 1, 'title' => 'The Fault in Our Stars']);
228217
```
229218

@@ -238,7 +227,7 @@ class Book extends Model
238227
}
239228
```
240229

241-
### Extending the Authenticable base model
230+
### Extending the Authenticatable base model
242231
This package includes a MongoDB Authenticatable Eloquent class `Jenssegers\Mongodb\Auth\User` that you can use to replace the default Authenticatable class `Illuminate\Foundation\Auth\User` for your `User` model.
243232

244233
```php

Diff for: phpunit.xml.dist

+1-2
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,8 @@
3535
</testsuite>
3636
</testsuites>
3737
<php>
38-
<env name="MONGO_HOST" value="mongodb"/>
38+
<env name="MONGODB_URI" value="mongodb://127.0.0.1/" />
3939
<env name="MONGO_DATABASE" value="unittest"/>
40-
<env name="MONGO_PORT" value="27017"/>
4140
<env name="MYSQL_HOST" value="mysql"/>
4241
<env name="MYSQL_PORT" value="3306"/>
4342
<env name="MYSQL_DATABASE" value="unittest"/>

Diff for: src/Eloquent/Builder.php

+3-2
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,7 @@ public function raw($expression = null)
174174
$results = iterator_to_array($results, false);
175175

176176
return $this->model->hydrate($results);
177-
} // Convert Mongo BSONDocument to a single object.
177+
} // Convert MongoDB BSONDocument to a single object.
178178
elseif ($results instanceof BSONDocument) {
179179
$results = $results->getArrayCopy();
180180

@@ -192,7 +192,8 @@ public function raw($expression = null)
192192
* TODO Remove if https://github.com/laravel/framework/commit/6484744326531829341e1ff886cc9b628b20d73e
193193
* wiil be reverted
194194
* Issue in laravel frawework https://github.com/laravel/framework/issues/27791.
195-
* @param array $values
195+
*
196+
* @param array $values
196197
* @return array
197198
*/
198199
protected function addUpdatedAtColumn(array $values)

Diff for: src/Eloquent/Model.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ abstract class Model extends BaseModel
5555
*/
5656
public function getIdAttribute($value = null)
5757
{
58-
// If we don't have a value for 'id', we will use the Mongo '_id' value.
58+
// If we don't have a value for 'id', we will use the MongoDB '_id' value.
5959
// This allows us to work with models in a more sql-like way.
6060
if (! $value && array_key_exists('_id', $this->attributes)) {
6161
$value = $this->attributes['_id'];

Diff for: tests/ConnectionTest.php

+94-33
Original file line numberDiff line numberDiff line change
@@ -37,11 +37,101 @@ public function testDb()
3737
$this->assertInstanceOf(Client::class, $connection->getMongoClient());
3838
}
3939

40-
public function testDsnDb()
40+
public function dataConnectionConfig(): Generator
4141
{
42-
$connection = DB::connection('dsn_mongodb_db');
43-
$this->assertInstanceOf(Database::class, $connection->getMongoDB());
44-
$this->assertInstanceOf(Client::class, $connection->getMongoClient());
42+
yield 'Single host' => [
43+
'expectedUri' => 'mongodb://some-host',
44+
'expectedDatabaseName' => 'tests',
45+
'config' => [
46+
'host' => 'some-host',
47+
'database' => 'tests',
48+
],
49+
];
50+
51+
yield 'Host and port' => [
52+
'expectedUri' => 'mongodb://some-host:12345',
53+
'expectedDatabaseName' => 'tests',
54+
'config' => [
55+
'host' => 'some-host',
56+
'port' => 12345,
57+
'database' => 'tests',
58+
],
59+
];
60+
61+
yield 'Port in host name takes precedence' => [
62+
'expectedUri' => 'mongodb://some-host:12345',
63+
'expectedDatabaseName' => 'tests',
64+
'config' => [
65+
'host' => 'some-host:12345',
66+
'port' => 54321,
67+
'database' => 'tests',
68+
],
69+
];
70+
71+
yield 'Multiple hosts' => [
72+
'expectedUri' => 'mongodb://host-1,host-2',
73+
'expectedDatabaseName' => 'tests',
74+
'config' => [
75+
'host' => ['host-1', 'host-2'],
76+
'database' => 'tests',
77+
],
78+
];
79+
80+
yield 'Multiple hosts with same port' => [
81+
'expectedUri' => 'mongodb://host-1:12345,host-2:12345',
82+
'expectedDatabaseName' => 'tests',
83+
'config' => [
84+
'host' => ['host-1', 'host-2'],
85+
'port' => 12345,
86+
'database' => 'tests',
87+
],
88+
];
89+
90+
yield 'Multiple hosts with port' => [
91+
'expectedUri' => 'mongodb://host-1:12345,host-2:54321',
92+
'expectedDatabaseName' => 'tests',
93+
'config' => [
94+
'host' => ['host-1:12345', 'host-2:54321'],
95+
'database' => 'tests',
96+
],
97+
];
98+
99+
yield 'DSN takes precedence over host/port config' => [
100+
'expectedUri' => 'mongodb://some-host:12345/auth-database',
101+
'expectedDatabaseName' => 'tests',
102+
'config' => [
103+
'dsn' => 'mongodb://some-host:12345/auth-database',
104+
'host' => 'wrong-host',
105+
'port' => 54321,
106+
'database' => 'tests',
107+
],
108+
];
109+
110+
yield 'Database is extracted from DSN if not specified' => [
111+
'expectedUri' => 'mongodb://some-host:12345/tests',
112+
'expectedDatabaseName' => 'tests',
113+
'config' => [
114+
'dsn' => 'mongodb://some-host:12345/tests',
115+
],
116+
];
117+
}
118+
119+
/** @dataProvider dataConnectionConfig */
120+
public function testConnectionConfig(string $expectedUri, string $expectedDatabaseName, array $config): void
121+
{
122+
$connection = new Connection($config);
123+
$client = $connection->getMongoClient();
124+
125+
$this->assertSame($expectedUri, (string) $client);
126+
$this->assertSame($expectedDatabaseName, $connection->getMongoDB()->getDatabaseName());
127+
}
128+
129+
public function testConnectionWithoutConfiguredDatabase(): void
130+
{
131+
$this->expectException(InvalidArgumentException::class);
132+
$this->expectExceptionMessage('Database is not properly configured.');
133+
134+
new Connection(['dsn' => 'mongodb://some-host']);
45135
}
46136

47137
public function testCollection()
@@ -89,33 +179,4 @@ public function testDriverName()
89179
$driver = DB::connection('mongodb')->getDriverName();
90180
$this->assertEquals('mongodb', $driver);
91181
}
92-
93-
public function testAuth()
94-
{
95-
$host = Config::get('database.connections.mongodb.host');
96-
Config::set('database.connections.mongodb.username', 'foo');
97-
Config::set('database.connections.mongodb.password', 'bar');
98-
Config::set('database.connections.mongodb.options.database', 'custom');
99-
100-
$connection = DB::connection('mongodb');
101-
$this->assertEquals('mongodb://'.$host.'/custom', (string) $connection->getMongoClient());
102-
}
103-
104-
public function testCustomHostAndPort()
105-
{
106-
Config::set('database.connections.mongodb.host', 'db1');
107-
Config::set('database.connections.mongodb.port', 27000);
108-
109-
$connection = DB::connection('mongodb');
110-
$this->assertEquals('mongodb://db1:27000', (string) $connection->getMongoClient());
111-
}
112-
113-
public function testHostWithPorts()
114-
{
115-
Config::set('database.connections.mongodb.port', 27000);
116-
Config::set('database.connections.mongodb.host', ['db1:27001', 'db2:27002', 'db3:27000']);
117-
118-
$connection = DB::connection('mongodb');
119-
$this->assertEquals('mongodb://db1:27001,db2:27002,db3:27000', (string) $connection->getMongoClient());
120-
}
121182
}

Diff for: tests/DsnTest.php

-16
This file was deleted.

Diff for: tests/TestCase.php

+3-5
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ class TestCase extends Orchestra\Testbench\TestCase
99
/**
1010
* Get application providers.
1111
*
12-
* @param \Illuminate\Foundation\Application $app
12+
* @param \Illuminate\Foundation\Application $app
1313
* @return array
1414
*/
1515
protected function getApplicationProviders($app)
@@ -24,7 +24,7 @@ protected function getApplicationProviders($app)
2424
/**
2525
* Get package providers.
2626
*
27-
* @param \Illuminate\Foundation\Application $app
27+
* @param \Illuminate\Foundation\Application $app
2828
* @return array
2929
*/
3030
protected function getPackageProviders($app)
@@ -40,7 +40,7 @@ protected function getPackageProviders($app)
4040
/**
4141
* Define environment setup.
4242
*
43-
* @param Illuminate\Foundation\Application $app
43+
* @param Illuminate\Foundation\Application $app
4444
* @return void
4545
*/
4646
protected function getEnvironmentSetUp($app)
@@ -56,8 +56,6 @@ protected function getEnvironmentSetUp($app)
5656
$app['config']->set('database.connections.mysql', $config['connections']['mysql']);
5757
$app['config']->set('database.connections.mongodb', $config['connections']['mongodb']);
5858
$app['config']->set('database.connections.mongodb2', $config['connections']['mongodb']);
59-
$app['config']->set('database.connections.dsn_mongodb', $config['connections']['dsn_mongodb']);
60-
$app['config']->set('database.connections.dsn_mongodb_db', $config['connections']['dsn_mongodb_db']);
6159

6260
$app['config']->set('auth.model', 'User');
6361
$app['config']->set('auth.providers.users.model', 'User');

Diff for: tests/config/database.php

+2-20
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,18 @@
11
<?php
22

3-
$mongoHost = env('MONGO_HOST', 'mongodb');
4-
$mongoPort = env('MONGO_PORT') ? (int) env('MONGO_PORT') : 27017;
5-
$mysqlPort = env('MYSQL_PORT') ? (int) env('MYSQL_PORT') : 3306;
6-
73
return [
8-
94
'connections' => [
10-
115
'mongodb' => [
126
'name' => 'mongodb',
137
'driver' => 'mongodb',
14-
'host' => $mongoHost,
8+
'dsn' => env('MONGODB_URI', 'mongodb://127.0.0.1/'),
159
'database' => env('MONGO_DATABASE', 'unittest'),
1610
],
1711

18-
'dsn_mongodb' => [
19-
'driver' => 'mongodb',
20-
'dsn' => "mongodb://$mongoHost:$mongoPort",
21-
'database' => env('MONGO_DATABASE', 'unittest'),
22-
],
23-
24-
'dsn_mongodb_db' => [
25-
'driver' => 'mongodb',
26-
'dsn' => "mongodb://$mongoHost:$mongoPort/".env('MONGO_DATABASE', 'unittest'),
27-
],
28-
2912
'mysql' => [
3013
'driver' => 'mysql',
3114
'host' => env('MYSQL_HOST', 'mysql'),
32-
'port' => $mysqlPort,
15+
'port' => env('MYSQL_PORT') ? (int) env('MYSQL_PORT') : 3306,
3316
'database' => env('MYSQL_DATABASE', 'unittest'),
3417
'username' => env('MYSQL_USERNAME', 'root'),
3518
'password' => env('MYSQL_PASSWORD', ''),
@@ -38,5 +21,4 @@
3821
'prefix' => '',
3922
],
4023
],
41-
4224
];

0 commit comments

Comments
 (0)