monastery 1.28.5 → 1.30.2
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/.eslintrc.json +0 -0
- package/docs/errors.md +0 -0
- package/docs/image-plugin.md +0 -0
- package/docs/manager/model.md +0 -0
- package/docs/manager/models.md +0 -0
- package/docs/model/findOne.md +0 -0
- package/docs/model/index.md +0 -0
- package/docs/model/remove.md +0 -0
- package/docs/readme.md +1 -1
- package/docs/rules.md +0 -0
- package/lib/index.js +0 -0
- package/lib/model-crud.js +4 -4
- package/lib/model-validate.js +16 -17
- package/lib/model.js +11 -8
- package/lib/rules.js +29 -26
- package/lib/util.js +1 -1
- package/package.json +1 -1
- package/plugins/images/index.js +123 -87
- package/test/assets/bad.svg +0 -0
- package/test/assets/image.ico +0 -0
- package/test/assets/image.webp +0 -0
- package/test/assets/lion1.png +0 -0
- package/test/assets/lion2.jpg +0 -0
- package/test/assets/logo.png +0 -0
- package/test/assets/logo2.png +0 -0
- package/test/model.js +92 -3
- package/test/monk.js +0 -0
- package/test/plugin-images.js +153 -6
- package/test/populate.js +0 -0
- package/test/util.js +0 -0
- package/test/validate.js +178 -66
package/plugins/images/index.js
CHANGED
|
@@ -54,8 +54,11 @@ let plugin = module.exports = {
|
|
|
54
54
|
model.imageFields = plugin._findAndTransformImageFields(model.fields, '')
|
|
55
55
|
|
|
56
56
|
if (model.imageFields.length) {
|
|
57
|
-
// Update image fields and whitelists with the new object schema
|
|
58
|
-
//
|
|
57
|
+
// Todo?: Update image fields and whitelists with the new object schema
|
|
58
|
+
// model._setupFieldsAndWhitelists(model.fields)
|
|
59
|
+
model.beforeValidate.push(function(data, n) {
|
|
60
|
+
plugin.keepImagePlacement(this, data).then(() => n(null, data)).catch(e => n(e))
|
|
61
|
+
})
|
|
59
62
|
model.beforeUpdate.push(function(data, n) {
|
|
60
63
|
plugin.removeImages(this, data).then(() => n(null, data)).catch(e => n(e))
|
|
61
64
|
})
|
|
@@ -91,7 +94,9 @@ let plugin = module.exports = {
|
|
|
91
94
|
* @param {object} options - monastery operation options {model, query, files, ..}
|
|
92
95
|
* @param {object} data -
|
|
93
96
|
* @param {boolean} test -
|
|
94
|
-
* @return promise
|
|
97
|
+
* @return promise(
|
|
98
|
+
* {object} data - data object containing new S3 image-object
|
|
99
|
+
* ])
|
|
95
100
|
* @this plugin
|
|
96
101
|
*/
|
|
97
102
|
let { model, query, files } = options
|
|
@@ -167,7 +172,33 @@ let plugin = module.exports = {
|
|
|
167
172
|
})
|
|
168
173
|
},
|
|
169
174
|
|
|
170
|
-
|
|
175
|
+
keepImagePlacement: async function(options, data) {
|
|
176
|
+
/**
|
|
177
|
+
* Hook before update/remove
|
|
178
|
+
* Since monastery removes undefined array items on validate, we need to convert any
|
|
179
|
+
* undefined array items to null where files are located to maintain image ordering
|
|
180
|
+
* Todo: maybe dont remove undefined array items in general
|
|
181
|
+
*
|
|
182
|
+
* E.g.
|
|
183
|
+
* req.body = 'photos[0]' : undefined || non existing (set to null)
|
|
184
|
+
* req.files = 'photos[0]' : { ...binary }
|
|
185
|
+
*
|
|
186
|
+
* @param {object} options - monastery operation options {query, model, files, multi, ..}
|
|
187
|
+
* @return promise
|
|
188
|
+
* @this plugin
|
|
189
|
+
*/
|
|
190
|
+
if (typeof options.files == 'undefined') return
|
|
191
|
+
// Check upload errors and find valid uploaded images
|
|
192
|
+
let files = await plugin._findValidImages(options.files || {}, options.model)
|
|
193
|
+
// Set undefined primative-array items to null where files are located
|
|
194
|
+
for (let filesArray of files) {
|
|
195
|
+
if (filesArray.inputPath.match(/\.[0-9]+$/)) {
|
|
196
|
+
util.setDeepValue(data, filesArray.inputPath, null, true, false, true)
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
},
|
|
200
|
+
|
|
201
|
+
removeImages: async function(options, data, test) {
|
|
171
202
|
/**
|
|
172
203
|
* Hook before update/remove
|
|
173
204
|
* Removes images not found in data, this means you will need to pass the image objects to every update operation
|
|
@@ -179,108 +210,113 @@ let plugin = module.exports = {
|
|
|
179
210
|
*
|
|
180
211
|
* @ref https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/S3.html#deleteObjects-property
|
|
181
212
|
* @param {object} options - monastery operation options {query, model, files, multi, ..}
|
|
182
|
-
* @return promise
|
|
213
|
+
* @return promise([
|
|
214
|
+
* {object} useCount - images that wont be removed, e.g. { lion1: 1 }
|
|
215
|
+
* {array} unused - S3 image uris to be removed, e.g. [{ Key: 'small/lion1.jpg' }, ..]
|
|
216
|
+
* ])
|
|
183
217
|
* @this plugin
|
|
184
218
|
*/
|
|
185
219
|
let pre
|
|
186
220
|
let preExistingImages = []
|
|
187
221
|
let useCount = {}
|
|
188
|
-
if (typeof options.files == 'undefined') return
|
|
222
|
+
if (typeof options.files == 'undefined') return
|
|
189
223
|
|
|
190
224
|
// Find all documents from the same query
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
}
|
|
201
|
-
}
|
|
225
|
+
let docs = await options.model._find(options.query, options)
|
|
226
|
+
|
|
227
|
+
// Find all pre-existing image objects in documents
|
|
228
|
+
for (let doc of util.toArray(docs)) { //x2
|
|
229
|
+
for (let imageField of options.model.imageFields) { //x5
|
|
230
|
+
let images = plugin._findImagesInData(doc, imageField, 0, '').filter(o => o.image)
|
|
231
|
+
for (let image of images) {
|
|
232
|
+
preExistingImages.push(image)
|
|
233
|
+
useCount[image.image.uid] = (useCount[image.image.uid] || 0) + 1
|
|
202
234
|
}
|
|
235
|
+
}
|
|
236
|
+
}
|
|
203
237
|
|
|
204
|
-
|
|
238
|
+
// console.log(1, useCount, preExistingImages)
|
|
205
239
|
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
240
|
+
// Assign pre-existing images within undefined deep objects and missing array items to null,
|
|
241
|
+
// ignore undefined root images
|
|
242
|
+
let dataFilled = util.deepCopy(data)
|
|
243
|
+
for (let key in dataFilled) {
|
|
244
|
+
for (let pre of preExistingImages) {
|
|
245
|
+
if (!pre.dataPath.match(new RegExp('^' + key + '(\\.|$)'))) continue
|
|
246
|
+
util.setDeepValue(dataFilled, pre.dataPath, null, true)
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
// console.log(dataFilled)
|
|
215
250
|
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
let images = plugin._findImagesInData(dataFilled, imageField, 0, '')
|
|
219
|
-
if (!images.length) continue
|
|
220
|
-
// console.log(images)
|
|
251
|
+
// Check upload errors and find valid uploaded images
|
|
252
|
+
let files = await plugin._findValidImages(options.files || {}, options.model)
|
|
221
253
|
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
}
|
|
254
|
+
// Loop all schema image fields
|
|
255
|
+
for (let imageField of options.model.imageFields) { //x5
|
|
256
|
+
let images = plugin._findImagesInData(dataFilled, imageField, 0, '')
|
|
257
|
+
if (!images.length) continue
|
|
258
|
+
// console.log(images)
|
|
228
259
|
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
if (typeof useCount[image.image.uid] == 'undefined') {
|
|
234
|
-
throw `The passed image object for '${image.dataPath}' does not match any pre-existing
|
|
235
|
-
images saved on this document.`
|
|
236
|
-
} else if (pre && pre.image.uid != image.image.uid) {
|
|
237
|
-
useCount[pre.image.uid]--
|
|
238
|
-
useCount[image.image.uid]++
|
|
239
|
-
} else if (!pre) {
|
|
240
|
-
useCount[image.image.uid]++
|
|
241
|
-
}
|
|
242
|
-
}
|
|
243
|
-
}
|
|
260
|
+
// Data contains null images that once had a pre-existing image
|
|
261
|
+
for (let image of images) {
|
|
262
|
+
if (image.image == null && (pre = preExistingImages.find(o => o.dataPath == image.dataPath))) {
|
|
263
|
+
useCount[pre.image.uid]--
|
|
244
264
|
}
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
// Loop images found in the data
|
|
268
|
+
for (let image of images) {
|
|
269
|
+
if (image.image != null) {
|
|
270
|
+
let preExistingImage = preExistingImages.find(o => o.dataPath == image.dataPath)
|
|
271
|
+
// valid image-object?
|
|
272
|
+
if (typeof useCount[image.image.uid] == 'undefined') {
|
|
273
|
+
throw `The passed image object for '${image.dataPath}' does not match any pre-existing
|
|
274
|
+
images saved on this document.`
|
|
275
|
+
// Different image from prexisting image
|
|
276
|
+
} else if (preExistingImage && preExistingImage.image.uid != image.image.uid) {
|
|
277
|
+
useCount[preExistingImage.image.uid]--
|
|
278
|
+
useCount[image.image.uid]++
|
|
279
|
+
// No pre-existing image found
|
|
280
|
+
} else if (!preExistingImage) {
|
|
281
|
+
useCount[image.image.uid]++
|
|
282
|
+
}
|
|
283
|
+
// Any file overriding this image?
|
|
248
284
|
for (let filesArray of files) {
|
|
249
|
-
if (
|
|
250
|
-
useCount[
|
|
285
|
+
if (image.dataPath == filesArray.inputPath) {
|
|
286
|
+
useCount[image.image.uid]--
|
|
251
287
|
}
|
|
252
288
|
}
|
|
253
|
-
})
|
|
254
|
-
|
|
255
|
-
}).then(() => {
|
|
256
|
-
// Retrieve all the unused files
|
|
257
|
-
let unused = []
|
|
258
|
-
// console.log(3, useCount)
|
|
259
|
-
for (let key in useCount) {
|
|
260
|
-
if (useCount[key] > 0) continue
|
|
261
|
-
let pre = preExistingImages.find(o => o.image.uid == key)
|
|
262
|
-
unused.push(
|
|
263
|
-
// original key can have a different extension
|
|
264
|
-
{ Key: pre.image.path },
|
|
265
|
-
{ Key: `small/${key}.jpg` },
|
|
266
|
-
{ Key: `medium/${key}.jpg` },
|
|
267
|
-
{ Key: `large/${key}.jpg` }
|
|
268
|
-
)
|
|
269
|
-
this.manager.info(
|
|
270
|
-
`Removing '${pre.image.filename}' from '${pre.image.bucket}/${pre.image.path}'`
|
|
271
|
-
)
|
|
272
289
|
}
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
// Retrieve all the unused files
|
|
294
|
+
// console.log(3, useCount)
|
|
295
|
+
let unused = []
|
|
296
|
+
for (let key in useCount) {
|
|
297
|
+
if (useCount[key] > 0) continue
|
|
298
|
+
let pre = preExistingImages.find(o => o.image.uid == key)
|
|
299
|
+
unused.push(
|
|
300
|
+
// original key can have a different extension
|
|
301
|
+
{ Key: pre.image.path },
|
|
302
|
+
{ Key: `small/${key}.jpg` },
|
|
303
|
+
{ Key: `medium/${key}.jpg` },
|
|
304
|
+
{ Key: `large/${key}.jpg` }
|
|
305
|
+
)
|
|
306
|
+
this.manager.info(
|
|
307
|
+
`Removing '${pre.image.filename}' from '${pre.image.bucket}/${pre.image.path}'`
|
|
308
|
+
)
|
|
309
|
+
}
|
|
310
|
+
if (test) return [useCount, unused]
|
|
311
|
+
// Delete any unused images from s3. If the image is on a different bucket
|
|
312
|
+
// the file doesnt get deleted, we only delete from plugin.awsBucket.
|
|
313
|
+
if (!unused.length) return
|
|
314
|
+
await new Promise((resolve, reject) => {
|
|
315
|
+
plugin.s3.deleteObjects({ Bucket: plugin.awsBucket, Delete: { Objects: unused }}, (err, data) => {
|
|
316
|
+
if (err) reject(err)
|
|
317
|
+
resolve()
|
|
283
318
|
})
|
|
319
|
+
})
|
|
284
320
|
},
|
|
285
321
|
|
|
286
322
|
_addImageObjectsToData: function(path, data, image) {
|
package/test/assets/bad.svg
CHANGED
|
File without changes
|
package/test/assets/image.ico
CHANGED
|
File without changes
|
package/test/assets/image.webp
CHANGED
|
File without changes
|
package/test/assets/lion1.png
CHANGED
|
File without changes
|
package/test/assets/lion2.jpg
CHANGED
|
File without changes
|
package/test/assets/logo.png
CHANGED
|
File without changes
|
package/test/assets/logo2.png
CHANGED
|
File without changes
|
package/test/model.js
CHANGED
|
@@ -116,10 +116,9 @@ module.exports = function(monastery, opendb) {
|
|
|
116
116
|
})
|
|
117
117
|
|
|
118
118
|
test('Model indexes', async () => {
|
|
119
|
-
// Need to test different types of indexes
|
|
119
|
+
// Setup: Need to test different types of indexes
|
|
120
120
|
let db = (await opendb(null)).db
|
|
121
|
-
|
|
122
|
-
// Drop previously tested collections
|
|
121
|
+
// Setup: Drop previously tested collections
|
|
123
122
|
if ((await db._db.listCollections().toArray()).find(o => o.name == 'userIndexRaw')) {
|
|
124
123
|
await db._db.collection('userIndexRaw').drop()
|
|
125
124
|
}
|
|
@@ -190,6 +189,96 @@ module.exports = function(monastery, opendb) {
|
|
|
190
189
|
db.close()
|
|
191
190
|
})
|
|
192
191
|
|
|
192
|
+
test('Model subdocument indexes', async () => {
|
|
193
|
+
// Setup: Need to test different types of indexes
|
|
194
|
+
let db = (await opendb(null)).db
|
|
195
|
+
// Setup: Drop previously tested collections
|
|
196
|
+
if ((await db._db.listCollections().toArray()).find(o => o.name == 'userIndexSubdoc')) {
|
|
197
|
+
await db._db.collection('userIndexSubdoc').drop()
|
|
198
|
+
}
|
|
199
|
+
// Run
|
|
200
|
+
let userModel = await db.model('userIndexSubdoc', {
|
|
201
|
+
fields: {}
|
|
202
|
+
})
|
|
203
|
+
await expect(userModel._setupIndexes(
|
|
204
|
+
{
|
|
205
|
+
animals: {
|
|
206
|
+
name: { type: 'string', index: 'unique' },
|
|
207
|
+
},
|
|
208
|
+
animals2: {
|
|
209
|
+
names: {
|
|
210
|
+
name: { type: 'string', index: 'unique' },
|
|
211
|
+
},
|
|
212
|
+
},
|
|
213
|
+
animals3: {
|
|
214
|
+
names: {
|
|
215
|
+
name: { type: 'string', index: 'text' },
|
|
216
|
+
},
|
|
217
|
+
},
|
|
218
|
+
}, {
|
|
219
|
+
dryRun: true
|
|
220
|
+
}
|
|
221
|
+
)).resolves.toEqual([{
|
|
222
|
+
'key': { 'animals.name': 1 },
|
|
223
|
+
'name': 'animals.name_1',
|
|
224
|
+
'unique': true,
|
|
225
|
+
}, {
|
|
226
|
+
'key': { 'animals2.names.name': 1 },
|
|
227
|
+
'name': 'animals2.names.name_1',
|
|
228
|
+
'unique': true,
|
|
229
|
+
}, {
|
|
230
|
+
'key': { 'animals3.names.name': 'text' },
|
|
231
|
+
'name': 'text',
|
|
232
|
+
}])
|
|
233
|
+
|
|
234
|
+
db.close()
|
|
235
|
+
})
|
|
236
|
+
|
|
237
|
+
test('Model array indexes', async () => {
|
|
238
|
+
// Setup: Need to test different types of indexes
|
|
239
|
+
let db = (await opendb(null)).db
|
|
240
|
+
// Setup: Drop previously tested collections
|
|
241
|
+
if ((await db._db.listCollections().toArray()).find(o => o.name == 'userIndexArray')) {
|
|
242
|
+
await db._db.collection('userIndexArray').drop()
|
|
243
|
+
}
|
|
244
|
+
// Run
|
|
245
|
+
let userModel = await db.model('userIndexArray', {
|
|
246
|
+
fields: {}
|
|
247
|
+
})
|
|
248
|
+
await expect(userModel._setupIndexes(
|
|
249
|
+
{
|
|
250
|
+
animals: [{
|
|
251
|
+
name: { type: 'string', index: 'unique' },
|
|
252
|
+
}],
|
|
253
|
+
animals2: [{ type: 'string', index: true }],
|
|
254
|
+
animals3: [[{ type: 'string', index: true }]],
|
|
255
|
+
animals4: [{
|
|
256
|
+
names: [{
|
|
257
|
+
name: { type: 'string', index: 'unique' },
|
|
258
|
+
}],
|
|
259
|
+
}],
|
|
260
|
+
}, {
|
|
261
|
+
dryRun: true
|
|
262
|
+
}
|
|
263
|
+
)).resolves.toEqual([{
|
|
264
|
+
'key': { 'animals.name': 1 },
|
|
265
|
+
'name': 'animals.name_1',
|
|
266
|
+
'unique': true,
|
|
267
|
+
}, {
|
|
268
|
+
'key': { 'animals2': 1 },
|
|
269
|
+
'name': 'animals2_1',
|
|
270
|
+
}, {
|
|
271
|
+
'key': { 'animals3.0': 1 },
|
|
272
|
+
'name': 'animals3.0_1',
|
|
273
|
+
}, {
|
|
274
|
+
'key': { 'animals4.names.name': 1 },
|
|
275
|
+
'name': 'animals4.names.name_1',
|
|
276
|
+
'unique': true,
|
|
277
|
+
}])
|
|
278
|
+
|
|
279
|
+
db.close()
|
|
280
|
+
})
|
|
281
|
+
|
|
193
282
|
test('Model 2dsphere indexes', async () => {
|
|
194
283
|
// Setup. The tested model needs to be unique as race condition issue arises when the same model
|
|
195
284
|
// with text indexes are setup at the same time
|
package/test/monk.js
CHANGED
|
File without changes
|
package/test/plugin-images.js
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
let util = require('../lib/util')
|
|
2
|
+
|
|
1
3
|
module.exports = function(monastery, opendb) {
|
|
2
4
|
|
|
3
5
|
// Data no images doesn't throw error
|
|
@@ -299,13 +301,8 @@ module.exports = function(monastery, opendb) {
|
|
|
299
301
|
|
|
300
302
|
plugin.removeImages(options, req.body, true)
|
|
301
303
|
.then(res => {
|
|
302
|
-
expect(res[0]).toEqual({ test1:
|
|
304
|
+
expect(res[0]).toEqual({ test1: 1, test2: 0, test3: 1, test4: 0 })
|
|
303
305
|
expect(res[1]).toEqual([
|
|
304
|
-
{ Key: 'dir/test1.png' },
|
|
305
|
-
{ Key: 'small/test1.jpg' },
|
|
306
|
-
{ Key: 'medium/test1.jpg' },
|
|
307
|
-
{ Key: 'large/test1.jpg' },
|
|
308
|
-
|
|
309
306
|
{ Key: 'dir/test2.png' },
|
|
310
307
|
{ Key: 'small/test2.jpg' },
|
|
311
308
|
{ Key: 'medium/test2.jpg' },
|
|
@@ -560,4 +557,154 @@ module.exports = function(monastery, opendb) {
|
|
|
560
557
|
})()
|
|
561
558
|
})
|
|
562
559
|
|
|
560
|
+
test('images reorder', async () => {
|
|
561
|
+
let db = (await opendb(null, {
|
|
562
|
+
timestamps: false,
|
|
563
|
+
serverSelectionTimeoutMS: 2000,
|
|
564
|
+
imagePlugin: { awsBucket: 'fake', awsAccessKeyId: 'fake', awsSecretAccessKey: 'fake' }
|
|
565
|
+
})).db
|
|
566
|
+
|
|
567
|
+
let user = db.model('user', { fields: {
|
|
568
|
+
logos: [{ type: 'image' }],
|
|
569
|
+
}})
|
|
570
|
+
|
|
571
|
+
let image = {
|
|
572
|
+
bucket: 'test',
|
|
573
|
+
date: 1234,
|
|
574
|
+
filename: 'lion1.png',
|
|
575
|
+
filesize: 1234,
|
|
576
|
+
path: 'test/lion1.png',
|
|
577
|
+
uid: 'lion1'
|
|
578
|
+
}
|
|
579
|
+
|
|
580
|
+
let user1 = await db.user._insert({
|
|
581
|
+
logos: [image],
|
|
582
|
+
})
|
|
583
|
+
|
|
584
|
+
let plugin = db.imagePluginFile
|
|
585
|
+
let supertest = require('supertest')
|
|
586
|
+
let express = require('express')
|
|
587
|
+
let upload = require('express-fileupload')
|
|
588
|
+
let app = express()
|
|
589
|
+
app.use(upload())
|
|
590
|
+
|
|
591
|
+
// Reorder
|
|
592
|
+
app.post('/', async function(req, res) {
|
|
593
|
+
try {
|
|
594
|
+
req.body.logos = JSON.parse(req.body.logos)
|
|
595
|
+
let options = { files: req.files, model: user, query: { _id: user1._id } }
|
|
596
|
+
let response = await plugin.removeImages(options, req.body, true)
|
|
597
|
+
expect(response[0]).toEqual({ lion1: 1 })
|
|
598
|
+
expect(response[1]).toEqual([])
|
|
599
|
+
res.send()
|
|
600
|
+
} catch (e) {
|
|
601
|
+
console.log(e.message || e)
|
|
602
|
+
res.status(500).send()
|
|
603
|
+
}
|
|
604
|
+
})
|
|
605
|
+
await supertest(app)
|
|
606
|
+
.post('/')
|
|
607
|
+
.field('logos', JSON.stringify([ null, image ]))
|
|
608
|
+
.expect(200)
|
|
609
|
+
|
|
610
|
+
db.close()
|
|
611
|
+
})
|
|
612
|
+
|
|
613
|
+
test('images reorder and added image', async () => {
|
|
614
|
+
// latest (2022.02)
|
|
615
|
+
let db = (await opendb(null, {
|
|
616
|
+
timestamps: false,
|
|
617
|
+
serverSelectionTimeoutMS: 2000,
|
|
618
|
+
imagePlugin: { awsBucket: 'fake', awsAccessKeyId: 'fake', awsSecretAccessKey: 'fake' }
|
|
619
|
+
})).db
|
|
620
|
+
|
|
621
|
+
let user = db.model('user', { fields: {
|
|
622
|
+
photos: [{ type: 'image' }],
|
|
623
|
+
}})
|
|
624
|
+
|
|
625
|
+
let image = {
|
|
626
|
+
bucket: 'test',
|
|
627
|
+
date: 1234,
|
|
628
|
+
filename: 'lion1.png',
|
|
629
|
+
filesize: 1234,
|
|
630
|
+
path: 'test/lion1.png',
|
|
631
|
+
uid: 'lion1'
|
|
632
|
+
}
|
|
633
|
+
|
|
634
|
+
let user1 = await db.user._insert({
|
|
635
|
+
photos: [image],
|
|
636
|
+
})
|
|
637
|
+
|
|
638
|
+
let plugin = db.imagePluginFile
|
|
639
|
+
let supertest = require('supertest')
|
|
640
|
+
let express = require('express')
|
|
641
|
+
let upload = require('express-fileupload')
|
|
642
|
+
let app = express()
|
|
643
|
+
app.use(upload())
|
|
644
|
+
|
|
645
|
+
app.post('/', async function(req, res) {
|
|
646
|
+
try {
|
|
647
|
+
// Parse and validate data which is used before in update/insert
|
|
648
|
+
let options = { files: req.files, model: user, query: { _id: user1._id } }
|
|
649
|
+
let data = await util.parseData(req.body)
|
|
650
|
+
data = await user.validate(data, { ...options, update: true })
|
|
651
|
+
|
|
652
|
+
// Empty photo placeholder not removed in validate?
|
|
653
|
+
expect(data.photos[0]).toEqual(null)
|
|
654
|
+
expect(data.photos[1]).toEqual(image)
|
|
655
|
+
|
|
656
|
+
// Remove images
|
|
657
|
+
let response = await plugin.removeImages(options, data, true)
|
|
658
|
+
expect(response[0]).toEqual({ lion1: 1 }) // useCount
|
|
659
|
+
expect(response[1]).toEqual([]) // unused
|
|
660
|
+
|
|
661
|
+
// New file exists
|
|
662
|
+
let validFiles = await plugin._findValidImages(req.files, user)
|
|
663
|
+
expect(((validFiles||[])[0]||{}).inputPath).toEqual('photos.0') // Valid inputPath
|
|
664
|
+
|
|
665
|
+
// Add images
|
|
666
|
+
response = await plugin.addImages(options, data, true)
|
|
667
|
+
expect(response[0]).toEqual({
|
|
668
|
+
photos: [{
|
|
669
|
+
bucket: 'fake',
|
|
670
|
+
date: expect.any(Number),
|
|
671
|
+
filename: 'lion2.jpg',
|
|
672
|
+
filesize: expect.any(Number),
|
|
673
|
+
path: expect.any(String),
|
|
674
|
+
uid: expect.any(String)
|
|
675
|
+
}, {
|
|
676
|
+
bucket: 'test', // still the same image-object reference (nothing new)
|
|
677
|
+
date: expect.any(Number),
|
|
678
|
+
filename: 'lion1.png',
|
|
679
|
+
filesize: expect.any(Number),
|
|
680
|
+
path: expect.any(String),
|
|
681
|
+
uid: expect.any(String)
|
|
682
|
+
},],
|
|
683
|
+
})
|
|
684
|
+
|
|
685
|
+
res.send()
|
|
686
|
+
} catch (e) {
|
|
687
|
+
console.log(e.message || e)
|
|
688
|
+
res.status(500).send()
|
|
689
|
+
}
|
|
690
|
+
})
|
|
691
|
+
|
|
692
|
+
await supertest(app)
|
|
693
|
+
.post('/')
|
|
694
|
+
// Mock multipart/form-data syntax which is not supported by supertest (formdata sent with axios)
|
|
695
|
+
// E.g.
|
|
696
|
+
// req.body = 'photos[1][bucket]' : '...'
|
|
697
|
+
// req.files = 'photos[0]' : { ...binary }
|
|
698
|
+
.field('photos[1][bucket]', image.bucket)
|
|
699
|
+
.field('photos[1][date]', image.date)
|
|
700
|
+
.field('photos[1][filename]', image.filename)
|
|
701
|
+
.field('photos[1][filesize]', image.filesize)
|
|
702
|
+
.field('photos[1][path]', image.path)
|
|
703
|
+
.field('photos[1][uid]', image.uid)
|
|
704
|
+
.attach('photos[0]', `${__dirname}/assets/lion2.jpg`)
|
|
705
|
+
.expect(200)
|
|
706
|
+
|
|
707
|
+
db.close()
|
|
708
|
+
})
|
|
709
|
+
|
|
563
710
|
}
|
package/test/populate.js
CHANGED
|
File without changes
|
package/test/util.js
CHANGED
|
File without changes
|