monastery 3.2.1 → 3.4.0

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/test/validate.js CHANGED
@@ -300,7 +300,7 @@ test('validation subdocument errors', async () => {
300
300
  ])
301
301
  )
302
302
 
303
- // Insert: Ignore required subdocument property with a defined parent
303
+ // Insert: Required subdocument property is ignored with a parent/grandparent specificed
304
304
  await expect(user.validate({ animals: {} }, { validateUndefined: false })).resolves.toEqual({
305
305
  animals: {},
306
306
  })
@@ -1181,8 +1181,85 @@ test('validation option validateUndefined', async () => {
1181
1181
  .resolves.toEqual({ names: [{}] })
1182
1182
  })
1183
1183
 
1184
- test('validation hooks', async () => {
1185
- let user = db.model('user', {
1184
+ test('validation update dot notation', async () => {
1185
+ // Only updates the fields that are passed in the data object, similar to $set. They don't
1186
+ // remove subdocument fields that are not present in the data object.
1187
+ const user = db.model('user_partialUpdate1', {
1188
+ fields: {
1189
+ name: { type: 'string' },
1190
+ address: {
1191
+ city: { type: 'string' },
1192
+ country: { type: 'string' },
1193
+ },
1194
+ },
1195
+ })
1196
+ const user2 = db.model('user_partialUpdate2', {
1197
+ fields: {
1198
+ name: { type: 'string' },
1199
+ address: {
1200
+ city: { type: 'string' },
1201
+ country: { type: 'string', required: true },
1202
+ },
1203
+ books: [{
1204
+ title: { type: 'string', required: true },
1205
+ pages: {
1206
+ count: { type: 'number', required: true },
1207
+ },
1208
+ }],
1209
+ },
1210
+ })
1211
+
1212
+ // Partial validate
1213
+ const validated1 = await user.validate({
1214
+ 'address.city': 'Berlin2',
1215
+ 'address': { city: 'Berlin' }, // preserved
1216
+ })
1217
+ expect(validated1).toEqual({
1218
+ 'address': { city: 'Berlin' },
1219
+ 'address.city': 'Berlin2',
1220
+ })
1221
+
1222
+ /// { partialUpdate: true }
1223
+
1224
+ // Order of fields, normal objects are ordered first
1225
+ expect(Object.keys(validated1)).toEqual(['address', 'address.city'])
1226
+
1227
+ // validate (update) throws required error for deep field (as normal)
1228
+ await expect(user2.validate({ 'address': { city: 'Berlin' }}, { update: true }))
1229
+ .rejects.toEqual(expect.any(Array))
1230
+
1231
+ // validate (update) works with dot notatation paths
1232
+ await expect(user2.validate({ 'address.city': 'Berlin2' }, { update: true }))
1233
+ .resolves.toEqual({ 'address.city': 'Berlin2' })
1234
+
1235
+ // validate (insert) still throws required errors, even with dot notatation paths
1236
+ await expect(user2.validate({ 'address.city': 'Berlin2' }))
1237
+ .rejects.toEqual(expect.any(Array))
1238
+
1239
+ // validate (update) works with dot notation array paths, and validates data
1240
+ await expect(user2.validate({ 'books.0.pages.count': '1' }, { update: true }))
1241
+ .resolves.toEqual({ 'books.0.pages.count': 1 })
1242
+
1243
+ // validate (update) works with positional array paths
1244
+ await expect(user2.validate({ 'books.$.pages.count': '2' }, { update: true }))
1245
+ .resolves.toEqual({ 'books.$.pages.count': 2 })
1246
+
1247
+ // Non-field dot notation paths removed
1248
+ await expect(user2.validate({ 'books.0.badfield': 2 }, { update: true }))
1249
+ .resolves.toEqual({})
1250
+
1251
+ // validate (update) should continue on throwing validation errors for dot notation array paths with subdocument values
1252
+ await expect(user2.validate({ 'books.$.pages': {} }, { update: true }))
1253
+ .rejects.toEqual([{
1254
+ 'detail': 'This field is required.',
1255
+ 'meta': { 'detailLong': undefined, 'field': 'count', 'model': 'user_partialUpdate2', 'rule': 'required' },
1256
+ 'status': '400',
1257
+ 'title': 'books.$.pages.count',
1258
+ }])
1259
+ })
1260
+
1261
+ test('validation hooks and option skipHooks', async () => {
1262
+ let user = db.model('user_validation_hooks', {
1186
1263
  fields: {
1187
1264
  first: { type: 'string'},
1188
1265
  last: { type: 'string'},
@@ -1204,6 +1281,7 @@ test('validation hooks', async () => {
1204
1281
  // Catch validate (a)synchronous errors thrown in function or through `next(err)`
1205
1282
  await expect(user.validate({ first: '' })).rejects.toThrow('beforeValidate error 1..')
1206
1283
  await expect(user.validate({ first: 'Martin' })).rejects.toThrow('beforeValidate error 2..')
1284
+ await expect(user.validate({ first: 'Martin' }, { skipHooks: true })).resolves.toEqual({ first: 'Martin' })
1207
1285
  await expect(user.validate({ first: 'Martin', last: 'Luther' })).resolves.toEqual({
1208
1286
  first: 'Martin',
1209
1287
  last: 'Luther',
@@ -1212,6 +1290,10 @@ test('validation hooks', async () => {
1212
1290
  // Catch insert (a)synchronous errors thrown in function or through `next(err)`
1213
1291
  await expect(user.insert({ data: { first: '' } })).rejects.toThrow('beforeValidate error 1..')
1214
1292
  await expect(user.insert({ data: { first: 'Martin' } })).rejects.toThrow('beforeValidate error 2..')
1293
+ await expect(user.insert({ data: { first: 'Martin' }, skipHooks: true })).resolves.toEqual({
1294
+ _id: expect.any(Object),
1295
+ first: 'Martin',
1296
+ })
1215
1297
  await expect(user.insert({ data: { first: 'Martin', last: 'Luther' } })).resolves.toEqual({
1216
1298
  _id: expect.any(Object),
1217
1299
  first: 'Martin',
@@ -1223,6 +1305,8 @@ test('validation hooks', async () => {
1223
1305
  .rejects.toThrow('beforeValidate error 1..')
1224
1306
  await expect(user.update({ query: userDoc._id, data: { first: 'Martin' } }))
1225
1307
  .rejects.toThrow('beforeValidate error 2..')
1308
+ await expect(user.update({ query: userDoc._id, data: { first: 'Martin' }, skipHooks: true }))
1309
+ .resolves.toEqual({ first: 'Martin' })
1226
1310
  await expect(user.update({ query: userDoc._id, data: { first: 'Martin', last: 'Luther' } }))
1227
1311
  .resolves.toEqual({
1228
1312
  first: 'Martin',