Skip to content

Commit 32a0d08

Browse files
committed
Merge branch 'master' into 6.9
2 parents d1dea8f + 59e5338 commit 32a0d08

13 files changed

+224
-168
lines changed

docs/validation.md

+7-7
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,8 @@ Before we get into the specifics of validation syntax, please keep the following
3434
Mongoose has several built-in validators.
3535

3636
- All [SchemaTypes](schematypes.html) have the built-in [required](api/schematype.html#schematype_SchemaType-required) validator. The required validator uses the [SchemaType's `checkRequired()` function](api/schematype.html#schematype_SchemaType-checkRequired) to determine if the value satisfies the required validator.
37-
- [Numbers](api/schema-number-js.html#schema-number-js) have [`min` and `max`](schematypes.html#number-validators) validators.
38-
- [Strings](api/schema-string-js.html#schema-string-js) have [`enum`, `match`, `minLength`, and `maxLength`](schematypes.html#string-validators) validators.
37+
- [Numbers](schematypes.html#numbers) have [`min` and `max`](schematypes.html#number-validators) validators.
38+
- [Strings](schematypes.html#strings) have [`enum`, `match`, `minLength`, and `maxLength`](schematypes.html#string-validators) validators.
3939

4040
Each of the validator links above provide more information about how to enable them and customize their error messages.
4141

@@ -96,7 +96,7 @@ the value `false`, Mongoose will consider that a validation error.
9696

9797
Errors returned after failed validation contain an `errors` object
9898
whose values are `ValidatorError` objects. Each
99-
[ValidatorError](api/error-validation-js.html#error-validation-js) has `kind`, `path`,
99+
[ValidatorError](api/error.html#error_Error-ValidatorError) has `kind`, `path`,
100100
`value`, and `message` properties.
101101
A ValidatorError also may have a `reason` property. If an error was
102102
thrown in the validator, this property will contain the error that was
@@ -142,10 +142,10 @@ nested objects are not fully fledged paths.
142142
### Update Validators
143143

144144
In the above examples, you learned about document validation. Mongoose also
145-
supports validation for [`update()`](query.html#query_Query-update),
146-
[`updateOne()`](query.html#query_Query-updateOne),
147-
[`updateMany()`](query.html#query_Query-updateMany),
148-
and [`findOneAndUpdate()`](query.html#query_Query-findOneAndUpdate) operations.
145+
supports validation for [`update()`](api/query.html#query_Query-update),
146+
[`updateOne()`](api/query.html#query_Query-updateOne),
147+
[`updateMany()`](api/query.html#query_Query-updateMany),
148+
and [`findOneAndUpdate()`](api/query.html#query_Query-findOneAndUpdate) operations.
149149
Update validators are off by default - you need to specify
150150
the `runValidators` option.
151151

lib/cast.js

+2-1
Original file line numberDiff line numberDiff line change
@@ -394,7 +394,8 @@ function getStrictQuery(queryOptions, schemaUserProvidedOptions, schemaOptions,
394394
if ('strict' in schemaUserProvidedOptions) {
395395
return schemaUserProvidedOptions.strict;
396396
}
397-
const mongooseOptions = context.mongooseCollection &&
397+
const mongooseOptions = context &&
398+
context.mongooseCollection &&
398399
context.mongooseCollection.conn &&
399400
context.mongooseCollection.conn.base &&
400401
context.mongooseCollection.conn.base.options;

lib/cursor/ChangeStream.js

+12
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,12 @@ class ChangeStream extends EventEmitter {
5454

5555
['close', 'change', 'end', 'error'].forEach(ev => {
5656
this.driverChangeStream.on(ev, data => {
57+
// Sometimes Node driver still polls after close, so
58+
// avoid any uncaught exceptions due to closed change streams
59+
// See tests for gh-7022
60+
if (ev === 'error' && this.closed) {
61+
return;
62+
}
5763
if (data != null && data.fullDocument != null && this.options && this.options.hydrate) {
5864
data.fullDocument = this.options.model.hydrate(data.fullDocument);
5965
}
@@ -71,6 +77,12 @@ class ChangeStream extends EventEmitter {
7177

7278
['close', 'change', 'end', 'error'].forEach(ev => {
7379
this.driverChangeStream.on(ev, data => {
80+
// Sometimes Node driver still polls after close, so
81+
// avoid any uncaught exceptions due to closed change streams
82+
// See tests for gh-7022
83+
if (ev === 'error' && this.closed) {
84+
return;
85+
}
7486
this.emit(ev, data);
7587
});
7688
});

lib/schema/array.js

+6-6
Original file line numberDiff line numberDiff line change
@@ -557,17 +557,17 @@ function cast$all(val) {
557557
val = [val];
558558
}
559559

560-
val = val.map(function(v) {
560+
val = val.map((v) => {
561561
if (!utils.isObject(v)) {
562562
return v;
563563
}
564564
if (v.$elemMatch != null) {
565-
return { $elemMatch: cast(this.casterConstructor.schema, v.$elemMatch) };
565+
return { $elemMatch: cast(this.casterConstructor.schema, v.$elemMatch, null, this && this.$$context) };
566566
}
567567

568568
const o = {};
569569
o[this.path] = v;
570-
return cast(this.casterConstructor.schema, o)[this.path];
570+
return cast(this.casterConstructor.schema, o, null, this && this.$$context)[this.path];
571571
}, this);
572572

573573
return this.castForQuery(val);
@@ -598,10 +598,10 @@ function cast$elemMatch(val) {
598598
if (discriminatorKey != null &&
599599
val[discriminatorKey] != null &&
600600
discriminators[val[discriminatorKey]] != null) {
601-
return cast(discriminators[val[discriminatorKey]], val);
601+
return cast(discriminators[val[discriminatorKey]], val, null, this && this.$$context);
602602
}
603603

604-
return cast(this.casterConstructor.schema, val);
604+
return cast(this.casterConstructor.schema, val, null, this && this.$$context);
605605
}
606606

607607
const handle = SchemaArray.prototype.$conditionalHandlers = {};
@@ -622,7 +622,7 @@ function createLogicalQueryOperatorHandler(op) {
622622

623623
const ret = [];
624624
for (const obj of val) {
625-
ret.push(cast(this.casterConstructor.schema, obj));
625+
ret.push(cast(this.casterConstructor.schema, obj, null, this && this.$$context));
626626
}
627627

628628
return ret;

test/aggregate.test.js

+1
Original file line numberDiff line numberDiff line change
@@ -614,6 +614,7 @@ describe('aggregate: ', function() {
614614

615615
describe('exec', function() {
616616
beforeEach(async function() {
617+
this.timeout(4000); // double the default of 2 seconds
617618
await setupData(db);
618619
});
619620

test/collection.capped.test.js

+8-10
Original file line numberDiff line numberDiff line change
@@ -19,15 +19,12 @@ const Schema = mongoose.Schema;
1919
describe('collections: capped:', function() {
2020
let db;
2121

22-
const connectionsToClose = [];
23-
24-
before(function() {
25-
db = start();
26-
});
27-
28-
after(async function() {
22+
afterEach(async function() {
23+
if (db == null) {
24+
return;
25+
}
2926
await db.close();
30-
await Promise.all(connectionsToClose.map((v) => v.close()));
27+
db = null;
3128
});
3229

3330
it('schemas should have option size', function() {
@@ -41,6 +38,8 @@ describe('collections: capped:', function() {
4138
it('creation', async function() {
4239
this.timeout(15000);
4340

41+
db = start();
42+
4443
await db.dropCollection('Test').catch(() => {});
4544

4645
const capped = new Schema({ key: String });
@@ -54,8 +53,7 @@ describe('collections: capped:', function() {
5453
});
5554

5655
it('skips when setting autoCreate to false (gh-8566)', async function() {
57-
const db = start();
58-
connectionsToClose.push(db);
56+
db = start();
5957
this.timeout(30000);
6058
await db.dropDatabase();
6159

test/collection.test.js

+10-9
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,18 @@ const assert = require('assert');
88
const mongoose = start.mongoose;
99

1010
describe('collections:', function() {
11-
const connectionsToClose = [];
11+
let db = null;
1212

13-
after(async function() {
14-
await Promise.all(connectionsToClose.map((v) => v.close()));
13+
afterEach(async function() {
14+
if (db == null) {
15+
return;
16+
}
17+
await db.close();
18+
db = null;
1519
});
1620

1721
it('should buffer commands until connection is established', function(done) {
18-
const db = mongoose.createConnection();
19-
connectionsToClose.push(db);
22+
db = mongoose.createConnection();
2023
const collection = db.collection('test-buffering-collection');
2124
let connected = false;
2225
let insertedId = undefined;
@@ -49,8 +52,7 @@ describe('collections:', function() {
4952
});
5053

5154
it('returns a promise if buffering and no callback (gh-7676)', function(done) {
52-
const db = mongoose.createConnection();
53-
connectionsToClose.push(db);
55+
db = mongoose.createConnection();
5456
const collection = db.collection('gh7676');
5557

5658
const promise = collection.insertOne({ foo: 'bar' }, {})
@@ -152,8 +154,7 @@ describe('collections:', function() {
152154
});
153155

154156
it('buffers for sync methods (gh-10610)', function(done) {
155-
const db = mongoose.createConnection();
156-
connectionsToClose.push(db);
157+
db = mongoose.createConnection();
157158
const collection = db.collection('gh10610');
158159

159160
collection.find({}, {}, function(err, res) {

test/connection.test.js

+8-8
Original file line numberDiff line numberDiff line change
@@ -773,29 +773,29 @@ describe('connections:', function() {
773773
db2.close();
774774
});
775775

776-
it('cache connections to the same db', function(done) {
776+
it('cache connections to the same db', function() {
777777
const db = start();
778778
const db2 = db.useDb(start.databases[1], { useCache: true });
779779
const db3 = db.useDb(start.databases[1], { useCache: true });
780780

781781
assert.strictEqual(db2, db3);
782-
db.close(done);
782+
return db.close();
783783
});
784784
});
785785

786786
describe('shouldAuthenticate()', function() {
787787
describe('when using standard authentication', function() {
788788
describe('when username and password are undefined', function() {
789-
it('should return false', function(done) {
789+
it('should return false', function() {
790790
const db = mongoose.createConnection(start.uri, {});
791791

792792
assert.equal(db.shouldAuthenticate(), false);
793793

794-
db.close(done);
794+
return db.close();
795795
});
796796
});
797797
describe('when username and password are empty strings', function() {
798-
it('should return false', function(done) {
798+
it('should return false', function() {
799799
const db = mongoose.createConnection(start.uri, {
800800
user: '',
801801
pass: ''
@@ -804,7 +804,7 @@ describe('connections:', function() {
804804

805805
assert.equal(db.shouldAuthenticate(), false);
806806

807-
db.close(done);
807+
return db.close();
808808
});
809809
});
810810
describe('when both username and password are defined', function() {
@@ -823,14 +823,14 @@ describe('connections:', function() {
823823
});
824824
describe('when using MONGODB-X509 authentication', function() {
825825
describe('when username and password are undefined', function() {
826-
it('should return false', function(done) {
826+
it('should return false', function() {
827827
const db = mongoose.createConnection(start.uri, {});
828828
db.on('error', function() {
829829
});
830830

831831
assert.equal(db.shouldAuthenticate(), false);
832832

833-
db.close(done);
833+
return db.close();
834834
});
835835
});
836836
describe('when only username is defined', function() {

0 commit comments

Comments
 (0)