monastery 1.30.4 → 1.31.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md ADDED
@@ -0,0 +1,23 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
4
+
5
+ ### 1.31.3 (2022-02-15)
6
+
7
+
8
+ ### Bug Fixes
9
+
10
+ * _callAfterFind bug ([e62472c](https://github.com/boycce/monastery/commit/e62472c191119135839b6d9e42b7f060bc7a508d))
11
+ * .eslintrc.json ([5362585](https://github.com/boycce/monastery/commit/53625857bbf798db97eddad9385799cb1ded97e2))
12
+ * docs ([d8f4e15](https://github.com/boycce/monastery/commit/d8f4e15913f672295cc118fda11ec23a412b4c62))
13
+ * docs ([1a5118e](https://github.com/boycce/monastery/commit/1a5118e4b389b55d30bf987991b59638b11613a9))
14
+ * docs ([564572c](https://github.com/boycce/monastery/commit/564572ce33dfb35fdd131e81d1dcc655f024b26e))
15
+ * docs ([12d37d3](https://github.com/boycce/monastery/commit/12d37d3b2d0b5ec577f9ed4deb9c929c8ea52a36))
16
+ * docs and nav links ([0eabcf0](https://github.com/boycce/monastery/commit/0eabcf0cd9a119a6ab1a07b92634e316995a2a83))
17
+ * model-crud ([d421709](https://github.com/boycce/monastery/commit/d421709a70e6611c78e049e98268153c9bafae6d))
18
+ * normalise afterFind ([0ab7f43](https://github.com/boycce/monastery/commit/0ab7f43f25b599e07d9ae751dc3bac8550e53c24))
19
+ * normalised rule arguments and context ([6ba48da](https://github.com/boycce/monastery/commit/6ba48da3b9c643620cebf5442e60bd0318d6780f))
20
+ * package scripts ([f7935af](https://github.com/boycce/monastery/commit/f7935afb0181ddb3e397bf804b34c841589dfcf0))
21
+ * semver ([6f14909](https://github.com/boycce/monastery/commit/6f14909f4405cf26dc04a8603cc3bac232b96798))
22
+ * standard-version ([f553b08](https://github.com/boycce/monastery/commit/f553b08445eb7dd2e85f6bb447e2bb0bc38dda34))
23
+ * util bug, updated tests ([bec1887](https://github.com/boycce/monastery/commit/bec1887f56cb8582b606a066c913c191362a61b0))
package/changelog.md ADDED
File without changes
package/lib/model-crud.js CHANGED
@@ -21,14 +21,14 @@ module.exports = {
21
21
  opts = opts || {}
22
22
  opts.insert = true
23
23
  opts.model = this
24
- let data = opts.data = opts.data || (opts.req? opts.req.body : {})
24
+ let req = opts.req
25
+ let data = opts.data = util.isDefined(opts.data)? opts.data : util.isDefined((req||{}).body) ? req.body : {}
25
26
  let options = util.omit(opts, [
26
27
  'data', 'insert', 'model', 'respond', 'validateUndefined', 'skipValidation', 'blacklist'
27
28
  ])
28
29
  if (cb && !util.isFunction(cb)) {
29
30
  throw new Error(`The callback passed to ${this.name}.insert() is not a function`)
30
31
  }
31
-
32
32
  return util.parseData(data).then(data => {
33
33
  opts.data = data
34
34
  return this.validate(data, { ...opts })
@@ -124,12 +124,16 @@ module.exports = {
124
124
  } else {
125
125
  let modelName = (path.split('.').reduce((o,i) => o[i], this.fields) ||{}).model
126
126
  if (!modelName) {
127
- this.error(`The field "${path}" passed to populate is not of type
128
- model. You would need to add the field option e.g. { model: 'comment' } in your schema.`)
127
+ this.error(
128
+ `The field "${path}" passed to populate is not of type model. You would ` +
129
+ 'need to add the field option e.g. { model: \'comment\' } in your schema.'
130
+ )
129
131
  continue
130
132
  } else if (!this.manager.model[modelName]) {
131
- this.error(`The field's model defined in your schema does not exist:
132
- ${path}: { model: "${modelName}" }`)
133
+ this.error(
134
+ `The field's model defined in your schema does not exist: ${path}: ` +
135
+ `{ model: "${modelName}" }`
136
+ )
133
137
  continue
134
138
  }
135
139
  // Populate model (convert array into document & create lookup)
@@ -212,7 +216,8 @@ module.exports = {
212
216
  opts = this._queryObject(opts)
213
217
  opts.update = true
214
218
  opts.model = this
215
- data = opts.data = opts.data || (opts.req? opts.req.body : null)
219
+ let req = opts.req
220
+ data = opts.data = util.isDefined(opts.data)? opts.data : util.isDefined((req||{}).body) ? req.body : undefined
216
221
  operators = util.pluck(opts, [/^\$/])
217
222
  // Operation options
218
223
  options = util.omit(opts, ['data', 'query', 'respond', 'validateUndefined', 'skipValidation', 'blacklist'])
@@ -224,23 +229,32 @@ module.exports = {
224
229
  let order = (options.sort.match(/:(-?[0-9])/) || [])[1]
225
230
  options.sort = { [name]: parseInt(order || 1) }
226
231
  }
227
- if (operators['$set'] && data) {
228
- throw new Error(`Please only pass options.$set or options.data to ${this.name}.update()`)
229
- }
230
232
  util.parseData(data).then(d => resolve(d))
231
233
 
232
234
  }).then(data => {
233
235
  opts.data = data
234
- if (util.isEmpty(operators)) return this.validate(data, { ...opts })
236
+ if (util.isDefined(data)) return this.validate(data, { ...opts })
237
+ else return Promise.resolve(data)
235
238
 
236
239
  }).then(data => {
237
- if (util.isEmpty(operators) && (!data || util.isEmpty(data))) {
238
- throw new Error(`No valid data passed to ${this.name}.update()`)
240
+ if (util.isDefined(data) && (!data || util.isEmpty(data))) {
241
+ throw new Error(`No valid data passed to ${this.name}.update({ data: .. })`)
242
+ }
243
+ if (!util.isDefined(data) && util.isEmpty(operators)) {
244
+ throw new Error(`Please pass an update operator to ${this.name}.update(), e.g. data, $unset, etc`)
239
245
  }
240
246
  return util.runSeries(this.beforeUpdate.map(f => f.bind(opts, data||{}))).then(() => data)
241
247
 
242
248
  }).then(data => {
243
- if (data) operators['$set'] = data
249
+ if (data && operators['$set']) {
250
+ this.warn(`'$set' fields take precedence over the data fields for \`${this.name}.update()\``)
251
+ }
252
+ if (data || operators['$set']) {
253
+ operators['$set'] = {
254
+ ...data,
255
+ ...(operators['$set'] || {}),
256
+ }
257
+ }
244
258
  return this._update(opts.query, operators, options).then(output => {
245
259
  if (!output.n) return null
246
260
  let response = Object.assign(Object.create({ _output: output }), operators['$set']||{})
@@ -377,7 +391,8 @@ module.exports = {
377
391
  if (!this._pathInProjection(pathWithoutArrays, projection, true)) return
378
392
  // Ignore default
379
393
  let value = util.isFunction(schema.default)? schema.default(this.manager) : schema.default
380
- util.setDeepValue(item.dataRef, path.replace(/\.0(\.|$)/g, '.$$$1'), value, false, true, true)
394
+ // console.log(item.dataRef)
395
+ util.setDeepValue(item.dataRef, path.replace(/\.0(\.|$)/g, '.$$$1'), value, true, false, true)
381
396
  })
382
397
  }
383
398
  // Collect all of the model's afterFind hooks
@@ -140,7 +140,7 @@ module.exports = {
140
140
  let value = util.isArray(fields)? data : (data||{})[fieldName]
141
141
  let indexOrFieldName = util.isArray(fields)? i : fieldName
142
142
  let path2 = `${path}.${indexOrFieldName}`.replace(/^\./, '')
143
- let path3 = path2.replace(/(^|\.)[0-9]+(\.|$)/, '$2') // no numirical keys, e.g. pets.1.name
143
+ let path3 = path2.replace(/(^|\.)[0-9]+(\.|$)/, '$2') // no numerical keys, e.g. pets.1.name
144
144
  let isType = 'is' + util.ucFirst(schema.type)
145
145
  let isTypeRule = this.rules[isType] || rules[isType]
146
146
 
@@ -162,7 +162,7 @@ module.exports = {
162
162
  if (opts.update && schema.insertOnly) return
163
163
  // Ignore virtual fields
164
164
  if (schema.virtual) return
165
- // Type cast the value if tryParse is avaliable, .e.g. isInteger.tryParse
165
+ // Type cast the value if tryParse is available, .e.g. isInteger.tryParse
166
166
  if (isTypeRule && util.isFunction(isTypeRule.tryParse)) {
167
167
  value = isTypeRule.tryParse.call(dataRoot, value, fieldName, this)
168
168
  }
package/lib/model.js CHANGED
@@ -36,6 +36,7 @@ let Model = module.exports = function(name, opts, manager) {
36
36
  beforeValidate: opts.beforeValidate || [],
37
37
  error: manager.error,
38
38
  info: manager.info,
39
+ warn: manager.warn,
39
40
  insertBL: opts.insertBL || [],
40
41
  fields: { ...(util.deepCopy(opts.fields) || {}) },
41
42
  findBL: opts.findBL || ['password'],
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "monastery",
3
3
  "description": "⛪ A straight forward MongoDB ODM built around Monk",
4
4
  "author": "Ricky Boyce",
5
- "version": "1.30.4",
5
+ "version": "1.31.3",
6
6
  "license": "MIT",
7
7
  "repository": "github:boycce/monastery",
8
8
  "homepage": "https://boycce.github.io/monastery/",
@@ -17,14 +17,15 @@
17
17
  "mongo odm"
18
18
  ],
19
19
  "scripts": {
20
- "minor": "standard-version --release-as minor && npm publish",
21
- "patch": "standard-version && npm publish",
22
- "test": "npm run lint && jest",
23
- "test-one-example": "jest -t images",
24
20
  "dev": "npm run lint & DEBUG=-monastery:info jest --watchAll --runInBand --verbose=false",
25
- "lint": "eslint ./lib ./plugins ./test",
26
21
  "docs": "cd docs && bundle exec jekyll serve --livereload --livereload-port 4001",
27
- "mong": "nodemon resources/mong.js"
22
+ "lint": "eslint ./lib ./plugins ./test",
23
+ "mong": "nodemon resources/mong.js",
24
+ "minor": "standard-version --release-as minor && npm publish",
25
+ "patch": "standard-version --release-as patch && npm publish",
26
+ "release": "standard-version && npm publish",
27
+ "test": "npm run lint && jest",
28
+ "test-one-example": "jest -t images"
28
29
  },
29
30
  "dependencies": {
30
31
  "aws-sdk": "2.1062.0",
@@ -48,8 +49,8 @@
48
49
  "releaseCommitMessageFormat": "{{currentTag}}",
49
50
  "sign": true,
50
51
  "skip": {
51
- "changelog": true,
52
- "tag": true
52
+ "changelog": false,
53
+ "tag": false
53
54
  }
54
55
  }
55
56
  }
@@ -1,6 +1,6 @@
1
1
  module.exports = function(monastery, opendb) {
2
2
 
3
- test('Find blacklisting', async () => {
3
+ test('find blacklisting', async () => {
4
4
  // Setup
5
5
  let db = (await opendb(null)).db
6
6
  let bird = db.model('bird', {
@@ -152,7 +152,7 @@ module.exports = function(monastery, opendb) {
152
152
  db.close()
153
153
  })
154
154
 
155
- test('Find blacklisting (default fields)', async () => {
155
+ test('find blacklisting (default fields)', async () => {
156
156
  // Setup
157
157
  let db = (await opendb(null)).db
158
158
  let user = db.model('user', {
@@ -223,7 +223,7 @@ module.exports = function(monastery, opendb) {
223
223
  db.close()
224
224
  })
225
225
 
226
- test('Find blacklisting (populate)', async () => {
226
+ test('find blacklisting (populate)', async () => {
227
227
  // Setup
228
228
  let db = (await opendb(null)).db
229
229
  let bird = db.model('bird', {
@@ -305,7 +305,7 @@ module.exports = function(monastery, opendb) {
305
305
  db.close()
306
306
  })
307
307
 
308
- test('Insert/update blacklisting (validate)', async () => {
308
+ test('insert update blacklisting (validate)', async () => {
309
309
  // Setup
310
310
  let db = (await opendb(null)).db
311
311
  let user = db.model('user', {
package/test/crud.js CHANGED
@@ -2,11 +2,12 @@
2
2
 
3
3
  module.exports = function(monastery, opendb) {
4
4
 
5
- test('Basic operator calls', async () => {
5
+ test('basic operator calls', async () => {
6
6
  let db = (await opendb(null)).db
7
7
  let user = db.model('user', {
8
- fields: { name: { type: 'string' }},
9
- beforeValidate: [(data, next) => { beforeValidateHookCalled = true; next() }]
8
+ fields: {
9
+ name: { type: 'string' },
10
+ },
10
11
  })
11
12
 
12
13
  // Insert one
@@ -79,60 +80,6 @@ module.exports = function(monastery, opendb) {
79
80
  let findOne3 = await user.findOne(inserted2[0]._id.toString())
80
81
  expect(findOne3).toEqual({ _id: inserted2[0]._id, name: 'Martin Luther1' })
81
82
 
82
- // Update
83
- let update = await user.update({
84
- query: inserted._id,
85
- data: { name: 'Martin Luther2' }
86
- })
87
- expect(update).toEqual({
88
- name: 'Martin Luther2'
89
- })
90
-
91
- // Update (no/empty data object)
92
- await expect(user.update({ query: inserted._id, data: {}}))
93
- .rejects.toThrow('No valid data passed to user.update()')
94
-
95
- await expect(user.update({ query: inserted._id }))
96
- .rejects.toThrow('No valid data passed to user.update()')
97
-
98
- // Update (no/empty data object, but has update operators
99
- await expect(user.update({ query: inserted._id, $set: { name: 'bruce' }}))
100
- .resolves.toEqual({ name: 'bruce' })
101
-
102
- await expect(user.update({ query: inserted._id, $pull: { name: 'bruce' }}))
103
- .rejects.toThrow('Cannot apply $pull to a non-array value') // gets passed no valid data check
104
-
105
- // Update (data & $set)
106
- await expect(user.update({ query: inserted._id, data: {}, $set: { name: 'bruce' }}))
107
- .rejects.toThrow('Please only pass options.$set or options.data to user.update()')
108
-
109
- // Update (with operators. Make sure beforeValidate isn't called)
110
- var beforeValidateHookCalled = false
111
- await user.update({ query: inserted._id, data: { name: 'bruce' }})
112
- expect(beforeValidateHookCalled).toEqual(true)
113
- beforeValidateHookCalled = false
114
- await user.update({ query: inserted._id, $set: { name: 'bruce' }})
115
- expect(beforeValidateHookCalled).toEqual(false)
116
-
117
- // Update multiple
118
- await user.update({
119
- query: { _id: { $in: [inserted2[0]._id, inserted2[1]._id] }},
120
- data: { name: 'Martin Luther3' },
121
- multi: true
122
- })
123
- let findUpdated2 = await user.find({
124
- query: { _id: { $in: [inserted2[0]._id, inserted2[1]._id] }}
125
- })
126
- expect(findUpdated2).toEqual([
127
- {
128
- _id: expect.any(Object),
129
- name: 'Martin Luther3'
130
- }, {
131
- _id: expect.any(Object),
132
- name: 'Martin Luther3'
133
- }
134
- ])
135
-
136
83
  // Remove
137
84
  let remove = await user.remove({ query: inserted._id })
138
85
  expect(remove.result).toEqual({ n: 1, ok: 1 })
@@ -140,7 +87,7 @@ module.exports = function(monastery, opendb) {
140
87
  db.close()
141
88
  })
142
89
 
143
- test('Insert defaults', async () => {
90
+ test('insert defaults', async () => {
144
91
  let db = (await opendb(null, { defaultObjects: true, serverSelectionTimeoutMS: 2000 })).db
145
92
  let db2 = (await opendb(null, { useMilliseconds: true, serverSelectionTimeoutMS: 2000 })).db
146
93
  let user = db.model('user', { fields: {
@@ -194,6 +141,65 @@ module.exports = function(monastery, opendb) {
194
141
  db2.close()
195
142
  })
196
143
 
144
+ test('update basics', async () => {
145
+ let db = (await opendb(null)).db
146
+ let user = db.model('user', {
147
+ fields: {
148
+ name: { type: 'string' },
149
+ },
150
+ })
151
+
152
+ // Insert
153
+ let inserted = await user.insert({ data: { name: 'Martin Luther' }})
154
+ expect(inserted).toEqual({
155
+ _id: expect.any(Object),
156
+ name: 'Martin Luther'
157
+ })
158
+
159
+ // Insert multiple
160
+ let inserted2 = await user.insert({ data: [{ name: 'Martin Luther1' }, { name: 'Martin Luther2' }]})
161
+ expect(inserted2).toEqual([
162
+ {
163
+ _id: expect.any(Object),
164
+ name: 'Martin Luther1'
165
+ }, {
166
+ _id: expect.any(Object),
167
+ name: 'Martin Luther2'
168
+ }
169
+ ])
170
+
171
+ // Update
172
+ await expect(user.update({ query: inserted._id, data: { name: 'Martin Luther2' }}))
173
+ .resolves.toEqual({ name: 'Martin Luther2' })
174
+
175
+ // Update (no/empty data object)
176
+ await expect(user.update({ query: inserted._id, data: {}}))
177
+ .rejects.toThrow('No valid data passed to user.update({ data: .. })')
178
+
179
+ await expect(user.update({ query: inserted._id }))
180
+ .rejects.toThrow('Please pass an update operator to user.update(), e.g. data, $unset, etc')
181
+
182
+ // Update multiple
183
+ await user.update({
184
+ query: { _id: { $in: [inserted2[0]._id, inserted2[1]._id] }},
185
+ data: { name: 'Martin Luther3' },
186
+ multi: true
187
+ })
188
+ let findUpdated2 = await user.find({
189
+ query: { _id: { $in: [inserted2[0]._id, inserted2[1]._id] }}
190
+ })
191
+ expect(findUpdated2).toEqual([
192
+ {
193
+ _id: expect.any(Object),
194
+ name: 'Martin Luther3'
195
+ }, {
196
+ _id: expect.any(Object),
197
+ name: 'Martin Luther3'
198
+ }
199
+ ])
200
+ db.close()
201
+ })
202
+
197
203
  test('update defaults', async () => {
198
204
  let db = (await opendb(null, { useMilliseconds: true, serverSelectionTimeoutMS: 2000 })).db
199
205
  let user = db.model('user', {
@@ -235,7 +241,7 @@ module.exports = function(monastery, opendb) {
235
241
  query: inserted._id,
236
242
  data: {},
237
243
  timestamps: false
238
- })).rejects.toThrow('No valid data passed to user.update()')
244
+ })).rejects.toThrow('No valid data passed to user.update({ data: .. })')
239
245
 
240
246
  // UpdatedAt override (wont work)
241
247
  let updated4 = await user.update({
@@ -255,7 +261,51 @@ module.exports = function(monastery, opendb) {
255
261
  db.close()
256
262
  })
257
263
 
258
- test('Insert with id casting', async () => {
264
+ test('update operators', async () => {
265
+ let db = (await opendb(null)).db
266
+ let user = db.model('userOperators', {
267
+ fields: {
268
+ name: { type: 'string', minLength: 5 },
269
+ age: { type: 'number' },
270
+ },
271
+ beforeValidate: [(data, next) => { beforeValidateHookCalled = true; next() }]
272
+ })
273
+
274
+ let inserted = await user.insert({
275
+ data: { name: 'Bruce', age: 12 }
276
+ })
277
+
278
+ // No data object, but has another update operators
279
+ await expect(user.update({ query: inserted._id, $set: { name: 'bruce' }}))
280
+ .resolves.toEqual({ name: 'bruce' })
281
+
282
+ // Mixing data and $set, and $set skips validation (minLength)
283
+ await expect(user.update({ query: inserted._id, data: { name: 'bruce2', age: 12 }, $set: { name: 'john' }}))
284
+ .resolves.toEqual({ age: 12, name: 'john' })
285
+
286
+ // Two operators
287
+ await user.update({ query: inserted._id, $set: { name: 'john' }, $unset: { age: 1 }})
288
+ await expect(user.findOne({ query: inserted._id })).resolves.toEqual({
289
+ _id: expect.any(Object),
290
+ name: 'john',
291
+ })
292
+
293
+ // $pull on a non array (also gets passed no valid data check)
294
+ await expect(user.update({ query: inserted._id, $pull: { name: 'bruce' }}))
295
+ .rejects.toThrow('Cannot apply $pull to a non-array value')
296
+
297
+ // Non-data operators don't call beforeValidate
298
+ var beforeValidateHookCalled = false
299
+ await user.update({ query: inserted._id, data: { name: 'bruce' }})
300
+ expect(beforeValidateHookCalled).toEqual(true)
301
+ beforeValidateHookCalled = false
302
+ await user.update({ query: inserted._id, $set: { name: 'bruce' }})
303
+ expect(beforeValidateHookCalled).toEqual(false)
304
+
305
+ db.close()
306
+ })
307
+
308
+ test('insert with id casting', async () => {
259
309
  let db = (await opendb(null)).db
260
310
  db.model('company', { fields: {
261
311
  name: { type: 'string' }
@@ -279,56 +329,52 @@ module.exports = function(monastery, opendb) {
279
329
  db.close()
280
330
  })
281
331
 
282
- test('Find default field population', async () => {
332
+ test('find default field population', async () => {
283
333
  let db = (await opendb(null)).db
284
334
  let user = db.model('user', {
285
335
  fields: {
286
- name: { type: 'string'},
287
- addresses: [{ city: { type: 'string' }, country: { type: 'string' }}],
336
+ name: { type: 'string', default: 'Martin Luther' },
337
+ addresses: [{ city: { type: 'string' }, country: { type: 'string', default: 'Germany' } }],
338
+ address: { country: { type: 'string', default: 'Germany' }},
288
339
  pet: { dog: { model: 'dog' }},
289
340
  dogs: [{ model: 'dog' }], // virtual association
290
341
  }
291
342
  })
292
343
  let dog = db.model('dog', {
293
344
  fields: {
294
- name: { type: 'string' },
345
+ name: { type: 'string', default: 'Scruff' },
295
346
  user: { model: 'user' }
296
347
  }
297
348
  })
298
349
 
299
- // Insert documents and add
300
- let inserted = await dog.insert({ data: {} })
301
- let inserted2 = await user.insert({ data: {
350
+ // Default field doesn't override null
351
+ let nulldoc1 = await dog.insert({ data: { name: null }})
352
+ let nullfind1 = await dog.findOne({ query: nulldoc1._id })
353
+ expect(nullfind1).toEqual({ _id: nulldoc1._id, name: null })
354
+
355
+ // Default field doesn't override empty string
356
+ let nulldoc2 = await dog.insert({ data: { name: '' }})
357
+ let nullfind2 = await dog.findOne({ query: nulldoc2._id })
358
+ expect(nullfind2).toEqual({ _id: nulldoc2._id, name: '' })
359
+
360
+ // Default field overrides undefined
361
+ let nulldoc3 = await dog.insert({ data: { name: undefined }})
362
+ let nullfind3 = await dog.findOne({ query: nulldoc3._id })
363
+ expect(nullfind3).toEqual({ _id: nullfind3._id, name: 'Scruff' })
364
+
365
+ // Default field population test
366
+ // Note that addresses.1.country shouldn't be overriden
367
+ // Insert documents (without defaults)
368
+ let inserted = await dog._insert({})
369
+ let inserted2 = await user._insert({
302
370
  addresses: [
303
371
  { city: 'Frankfurt' },
304
372
  { city: 'Christchurch', country: 'New Zealand' }
305
373
  ],
306
374
  pet: { dog: inserted._id }
307
- }})
308
- await dog.update({
309
- query: inserted._id,
310
- data: { user: inserted2._id }
311
375
  })
376
+ await dog._update(inserted._id, { $set: { user: inserted2._id }})
312
377
 
313
- // Update models
314
- db.model('user', {
315
- fields: {
316
- name: { type: 'string', default: 'Martin Luther' },
317
- addresses: [{ city: { type: 'string' }, country: { type: 'string', default: 'Germany' } }],
318
- address: { country: { type: 'string', default: 'Germany' }},
319
- pet: { dog: { model: 'dog' }},
320
- dogs: [{ model: 'dog' }], // virtual association
321
- }
322
- })
323
- db.model('dog', {
324
- fields: {
325
- name: { type: 'string', default: 'Scruff' },
326
- user: { model: 'user' }
327
- }
328
- })
329
-
330
- // Default field population test
331
- // Note that addresses.1.country shouldn't be overriden
332
378
  let find1 = await user.findOne({
333
379
  query: inserted2._id,
334
380
  populate: ['pet.dog', {
@@ -369,7 +415,7 @@ module.exports = function(monastery, opendb) {
369
415
  db.close()
370
416
  })
371
417
 
372
- test('Hooks', async () => {
418
+ test('hooks', async () => {
373
419
  let db = (await opendb(null)).db
374
420
  let user = db.model('user', {
375
421
  fields: {
package/test/model.js CHANGED
@@ -1,6 +1,6 @@
1
1
  module.exports = function(monastery, opendb) {
2
2
 
3
- test('Model setup', async () => {
3
+ test('model setup', async () => {
4
4
  // Setup
5
5
  let db = (await opendb(false)).db
6
6
  let user = db.model('user', { fields: {
@@ -68,7 +68,7 @@ module.exports = function(monastery, opendb) {
68
68
  ))
69
69
  })
70
70
 
71
- test('Model setup with default fields', async () => {
71
+ test('model setup with default fields', async () => {
72
72
  // Setup
73
73
  let db = (await opendb(false, { defaultObjects: true })).db
74
74
 
@@ -90,7 +90,7 @@ module.exports = function(monastery, opendb) {
90
90
  })
91
91
  })
92
92
 
93
- test('Model setup with default objects', async () => {
93
+ test('model setup with default objects', async () => {
94
94
  // Setup
95
95
  let db = (await opendb(false, { defaultObjects: true })).db
96
96
  let user = db.model('user', { fields: {
@@ -115,7 +115,7 @@ module.exports = function(monastery, opendb) {
115
115
  })
116
116
  })
117
117
 
118
- test('Model indexes', async () => {
118
+ test('model indexes', async () => {
119
119
  // Setup: Need to test different types of indexes
120
120
  let db = (await opendb(null)).db
121
121
  // Setup: Drop previously tested collections
@@ -189,7 +189,7 @@ module.exports = function(monastery, opendb) {
189
189
  db.close()
190
190
  })
191
191
 
192
- test('Model subdocument indexes', async () => {
192
+ test('model subdocument indexes', async () => {
193
193
  // Setup: Need to test different types of indexes
194
194
  let db = (await opendb(null)).db
195
195
  // Setup: Drop previously tested collections
@@ -234,7 +234,7 @@ module.exports = function(monastery, opendb) {
234
234
  db.close()
235
235
  })
236
236
 
237
- test('Model array indexes', async () => {
237
+ test('model array indexes', async () => {
238
238
  // Setup: Need to test different types of indexes
239
239
  let db = (await opendb(null)).db
240
240
  // Setup: Drop previously tested collections
@@ -279,7 +279,7 @@ module.exports = function(monastery, opendb) {
279
279
  db.close()
280
280
  })
281
281
 
282
- test('Model 2dsphere indexes', async () => {
282
+ test('model 2dsphere indexes', async () => {
283
283
  // Setup. The tested model needs to be unique as race condition issue arises when the same model
284
284
  // with text indexes are setup at the same time
285
285
  let db = (await opendb(null)).db
@@ -339,7 +339,7 @@ module.exports = function(monastery, opendb) {
339
339
  db.close()
340
340
  })
341
341
 
342
- test('Model findBL, findBLProject', async () => {
342
+ test('model findBL findBLProject', async () => {
343
343
  let db = (await opendb(null)).db
344
344
  db.model('bird', { fields: {
345
345
  name: { type: 'string' }
package/test/populate.js CHANGED
@@ -1,6 +1,6 @@
1
1
  module.exports = function(monastery, opendb) {
2
2
 
3
- test('Model populate', async () => {
3
+ test('model populate', async () => {
4
4
  // Setup
5
5
  let db = (await opendb(null)).db
6
6
  let bird = db.model('bird', { fields: {
@@ -82,7 +82,7 @@ module.exports = function(monastery, opendb) {
82
82
  db.close()
83
83
  })
84
84
 
85
- test('Model populate type=any', async () => {
85
+ test('model populate type=any', async () => {
86
86
  let db = (await opendb(null)).db
87
87
  db.model('company', { fields: {
88
88
  address: { type: 'any' }
@@ -132,7 +132,7 @@ module.exports = function(monastery, opendb) {
132
132
  db.close()
133
133
  })
134
134
 
135
- test('Model populate/blacklisting via $lookup', async () => {
135
+ test('model populate or blacklisting via $lookup', async () => {
136
136
  // Setup
137
137
  let db = (await opendb(null)).db
138
138
  let user = db.model('user', {
package/test/util.js CHANGED
@@ -2,7 +2,7 @@ let util = require('../lib/util')
2
2
 
3
3
  module.exports = function(monastery, opendb) {
4
4
 
5
- test('Utilities: formdata', async () => {
5
+ test('utilities formdata', async () => {
6
6
  expect(await util.parseFormData({
7
7
  'name': 'Martin',
8
8
  'pets[]': '',
@@ -31,7 +31,7 @@ module.exports = function(monastery, opendb) {
31
31
  .toEqual('Array items in bracket notation need array indexes "users[][\'name\']", e.g. users[0][name]')
32
32
  })
33
33
 
34
- test('Utilities: isId', async () => {
34
+ test('utilities isId', async () => {
35
35
  let db = (await opendb(false)).db
36
36
  expect(db.isId('')).toEqual(false)
37
37
  expect(db.isId(1234)).toEqual(false)
package/test/validate.js CHANGED
@@ -61,8 +61,10 @@ module.exports = function(monastery, opendb) {
61
61
 
62
62
  // Type error (number)
63
63
  let usernum = db.model('usernum', { fields: { amount: { type: 'number', required: true }}})
64
+ let usernum2 = db.model('usernum2', { fields: { amount: { type: 'number' }}})
64
65
  await expect(usernum.validate({ amount: 0 })).resolves.toEqual({ amount: 0 })
65
66
  await expect(usernum.validate({ amount: '0' })).resolves.toEqual({ amount: 0 })
67
+ await expect(usernum2.validate({ amount: '' })).resolves.toEqual({ amount: null })
66
68
  await expect(usernum.validate({ amount: undefined }, { validateUndefined: false })).resolves.toEqual({})
67
69
  await expect(usernum.validate({ amount: false })).rejects.toEqual([{
68
70
  status: '400',
@@ -116,7 +118,7 @@ module.exports = function(monastery, opendb) {
116
118
  })
117
119
  })
118
120
 
119
- test('Validation subdocument errors', async () => {
121
+ test('validation subdocument errors', async () => {
120
122
  // Setup
121
123
  let db = (await opendb(false)).db
122
124
  let user = db.model('user', { fields: {
@@ -243,7 +245,7 @@ module.exports = function(monastery, opendb) {
243
245
  })
244
246
  })
245
247
 
246
- test('Validation array errors', async () => {
248
+ test('validation array errors', async () => {
247
249
  // Setup
248
250
  let db = (await opendb(false)).db
249
251
  let user = db.model('user', { fields: {
@@ -307,7 +309,7 @@ module.exports = function(monastery, opendb) {
307
309
  .rejects.toContainEqual(error)
308
310
  })
309
311
 
310
- test('Validation getMostSpecificKeyMatchingPath', async () => {
312
+ test('validation getMostSpecificKeyMatchingPath', async () => {
311
313
  let fn = validate._getMostSpecificKeyMatchingPath
312
314
  let mock = {
313
315
  'cats.name': true,
@@ -339,7 +341,7 @@ module.exports = function(monastery, opendb) {
339
341
  expect(fn(mock, 'gulls.1')).toEqual('gulls.$')
340
342
  })
341
343
 
342
- test('Validation default messages', async () => {
344
+ test('validation default messages', async () => {
343
345
  // Setup
344
346
  let db = (await opendb(false)).db
345
347
  let user = db.model('user', {
@@ -391,7 +393,7 @@ module.exports = function(monastery, opendb) {
391
393
  })
392
394
  })
393
395
 
394
- test('Validation custom messages', async () => {
396
+ test('validation custom messages', async () => {
395
397
  // Setup
396
398
  // Todo: Setup testing for array array subdocument field messages
397
399
  let db = (await opendb(false)).db
@@ -433,7 +435,7 @@ module.exports = function(monastery, opendb) {
433
435
  })
434
436
  })
435
437
 
436
- test('Validation custom messages for arrays', async () => {
438
+ test('validation custom messages for arrays', async () => {
437
439
  // Setup
438
440
  // Todo: Setup testing for array array subdocument field messages
439
441
  let db = (await opendb(false)).db
@@ -550,7 +552,7 @@ module.exports = function(monastery, opendb) {
550
552
  })
551
553
  })
552
554
 
553
- test('Validation custom rules', async () => {
555
+ test('validation custom rules', async () => {
554
556
  // Setup
555
557
  let db = (await opendb(false)).db
556
558
  let user = db.model('user', {
@@ -636,7 +638,7 @@ module.exports = function(monastery, opendb) {
636
638
  }])
637
639
  })
638
640
 
639
- test('Validated data', async () => {
641
+ test('validated data', async () => {
640
642
  // Setup
641
643
  let db = (await opendb(false)).db
642
644
  let fields = {
@@ -694,7 +696,7 @@ module.exports = function(monastery, opendb) {
694
696
  .resolves.toEqual({ animals: { dogs: [{}] }})
695
697
  })
696
698
 
697
- test('Schema options', async () => {
699
+ test('schema options', async () => {
698
700
  // Setup
699
701
  let db = (await opendb(false)).db
700
702
  let user = db.model('user', { fields: {
@@ -735,7 +737,7 @@ module.exports = function(monastery, opendb) {
735
737
  })
736
738
  })
737
739
 
738
- test('Schema default rules', async () => {
740
+ test('schema default rules', async () => {
739
741
  // Setup
740
742
  let db = (await opendb(false)).db
741
743
  let user = db.model('user', { fields: {
@@ -816,7 +818,7 @@ module.exports = function(monastery, opendb) {
816
818
  await expect(user.validate({ amount: 'bad' })).rejects.toContainEqual(mock2)
817
819
  })
818
820
 
819
- test('Schema default objects', async () => {
821
+ test('schema default objects', async () => {
820
822
  let db = (await opendb(null, {
821
823
  timestamps: false,
822
824
  defaultObjects: true,
@@ -842,7 +844,7 @@ module.exports = function(monastery, opendb) {
842
844
  db.close()
843
845
  })
844
846
 
845
- test('Schema nullObjects', async () => {
847
+ test('schema nullObjects', async () => {
846
848
  let db = (await opendb(null, {
847
849
  timestamps: false,
848
850
  nullObjects: true,
@@ -868,7 +870,7 @@ module.exports = function(monastery, opendb) {
868
870
  db.close()
869
871
  })
870
872
 
871
- test('Validation options', async () => {
873
+ test('validation options', async () => {
872
874
  let db = (await opendb(false)).db
873
875
  let user = db.model('user', { fields: {
874
876
  name: { type: 'string', required: true }
@@ -953,7 +955,7 @@ module.exports = function(monastery, opendb) {
953
955
  })
954
956
  })
955
957
 
956
- test('Validation hooks', async () => {
958
+ test('validation hooks', async () => {
957
959
  let db = (await opendb(null)).db
958
960
  let user = db.model('user', {
959
961
  fields: {
package/test/virtuals.js CHANGED
@@ -1,6 +1,6 @@
1
1
  module.exports = function(monastery, opendb) {
2
2
 
3
- test('Virtuals', async () => {
3
+ test('virtuals', async () => {
4
4
  // Setup
5
5
  let db = (await opendb(null)).db
6
6
  // Test model setup
@@ -147,7 +147,7 @@ module.exports = function(monastery, opendb) {
147
147
  db.close()
148
148
  })
149
149
 
150
- test('Insert/update virtuals (validate)', async () => {
150
+ test('insert update virtuals (validate)', async () => {
151
151
  // Setup
152
152
  let db = (await opendb(null)).db
153
153
  let user = db.model('user', {