mongoose-slug-updater
Advanced tools
Comparing version 2.4.0 to 2.5.0
@@ -102,6 +102,6 @@ 'use strict'; | ||
if (schemaType.options.uniqueGroup) { | ||
if (schemaType.options.uniqueGroup instanceof Array) { | ||
slug.uniqueGroup = schemaType.options.uniqueGroup; | ||
if (_.isArray(schemaType.options.uniqueGroup)) { | ||
slug.uniqueGroupFields = schemaType.options.uniqueGroup; | ||
} else { | ||
slug.uniqueGroup = [schemaType.options.uniqueGroup]; | ||
slug.uniqueGroupFields = [schemaType.options.uniqueGroup]; | ||
} | ||
@@ -153,3 +153,3 @@ } | ||
} | ||
let docs = [doc]; | ||
let docs = [_.cloneDeep(doc)]; | ||
@@ -162,6 +162,7 @@ let unwoundSlugs = unwindSlugs( | ||
); | ||
// console.log(_.map(unwoundSlugs,'path')); | ||
if (!unwoundSlugs.length) { | ||
// console.log('no slugs'); | ||
return; | ||
} | ||
// console.log(_.map(unwoundSlugs,'path')); | ||
@@ -175,69 +176,133 @@ let updFields = _.keysDeep(doc); | ||
// console.log("unwoundSlugs",unwoundSlugs); | ||
let missingFields = unwoundSlugs | ||
.reduce((acc, slug) => acc.concat(slug.fields).concat([slug.path]), []) | ||
.filter(val => updPaths.indexOf(val) == -1); | ||
// console.log("missingFields",missingFields); | ||
if (missingFields.length) { | ||
// console.log('some fields are missing ', missingFields); | ||
// console.debug('preupdateOne middle',me.getQuery(), me.getUpdate()); | ||
let missingValuesDocs = await me.model[ | ||
operation == 'updateOne' ? 'findOne' : 'find' | ||
]( | ||
me.getQuery(), | ||
_(missingFields) | ||
.map(k => [k.replace(/\.\d+\./g, '.'), 1]) | ||
.fromPairs() | ||
.value() | ||
); | ||
// console.log("missing projection",_(missingFields).map(k=>[k.replace(/\.\d+\./g,'.'),1]).fromPairs().value()); | ||
// if(!missingValuesDocs){ | ||
// console.log("cannot "+(operation == 'updateOne' ? 'findOne ' : 'find ')+' missing fields ',missingFields,me.getQuery(),missingValuesDocs); | ||
// } | ||
if (missingValuesDocs) { | ||
// console.log("missingValuesDocs",missingValuesDocs); | ||
if (!Array.isArray(missingValuesDocs)) | ||
missingValuesDocs = [missingValuesDocs]; | ||
missingValuesDocs.forEach((missingValuesDoc, i) => { | ||
if (i) docs[i] = { ...doc }; | ||
missingFields.forEach(function(f) { | ||
_.set(docs[i], f, _.get(missingValuesDoc, f)); | ||
let involvedPaths = _.uniq( | ||
unwoundSlugs.reduce( | ||
(acc, slug) => acc.concat(slug.fields).concat([slug.path]), | ||
[] | ||
) | ||
).map(p=>p.replace(/^\//,'')); | ||
// .filter(val => updPaths.indexOf(val) == -1); | ||
// console.log('involvedPaths', involvedPaths); | ||
let involvedValuesDocs = await me.model[ | ||
operation == 'updateOne' ? 'findOne' : 'find' | ||
]( | ||
me.getQuery(), | ||
_(involvedPaths) | ||
.map(k => [k.replace(/\.[$\d]+\./g, '.'), 1]) | ||
.fromPairs() | ||
.value() | ||
); | ||
// console.log("involvedValuesDocs",_.map(involvedValuesDocs,v => v&&v.child&&v.child.subChildren&&v.child.subChildren[4]||"")); | ||
if (involvedValuesDocs) { | ||
if (!_.isArray(involvedValuesDocs)) | ||
involvedValuesDocs = [involvedValuesDocs]; | ||
involvedValuesDocs.forEach((freshDoc, i) => { | ||
if (i) docs[i] = _.cloneDeep(doc); | ||
involvedPaths.forEach(function(f) { | ||
let fs = unwindPath(freshDoc,f,docGet); | ||
_.each(fs,f=>{ | ||
// if(f=="child.slug"){ | ||
// console.log(f); | ||
// console.log(_.get(docs[i], f)); | ||
// console.log(_.get(freshDoc, f)); | ||
// console.log(upd); | ||
// } | ||
if (_.get(docs[i], f) === undefined) | ||
_.set(docs[i], f, _.get(freshDoc, f)); | ||
}); | ||
if (missingValuesDoc && missingValuesDoc._id) | ||
docs[i]._id = missingValuesDoc._id; | ||
}); | ||
// console.log(docs); | ||
if (freshDoc && freshDoc._id) docs[i]._id = freshDoc._id; | ||
}); | ||
} | ||
// console.log("docs",docs); | ||
let slugsUpd = []; | ||
async function findOne(query, sort) { | ||
let res = me.model.findOne(query); | ||
if (sort) { | ||
res = res.sort(sort); | ||
} | ||
} else { | ||
let query = me.getQuery(); | ||
if (query._id) doc._id = query._id; | ||
else { | ||
let missingValuesDocs = await await me.model[ | ||
operation == 'updateOne' ? 'findOne' : 'find' | ||
](me.getQuery(), '_id'); | ||
if (missingValuesDocs) { | ||
if (!Array.isArray(missingValuesDocs)) | ||
missingValuesDocs = [missingValuesDocs]; | ||
missingValuesDocs.forEach((missingValuesDoc, i) => { | ||
if (i) docs[i] = { ...doc }; | ||
if (missingValuesDoc._id) docs[i]._id = missingValuesDoc._id; | ||
}); | ||
res = await res; | ||
if (slugsUpd.length && sort) { | ||
// console.log("findOne res",res); | ||
let field = _.first(_.keys(sort)); | ||
let top = _.maxBy(slugsUpd, (u)=>{ | ||
// if(_.get(u,field)===undefined){ | ||
// console.log(field); | ||
// console.log(u); | ||
// } | ||
return extractCounter(_.get(u,field),options.separator); | ||
}); | ||
// console.log("findOne top",top); | ||
if (_.has(top, field)) { | ||
let localCounter = extractCounter(_.get(top,field),options.separator); | ||
let dbCounter = extractCounter(res.get(field),options.separator); | ||
if(localCounter>dbCounter) | ||
res = top; | ||
} | ||
} | ||
return res; | ||
} | ||
function findOne(query) { | ||
return me.model.findOne(query); | ||
} | ||
// console.log("docs",docs); | ||
// console.log("doc",doc); | ||
for (let i = 0; i < docs.length; i++) { | ||
let currentUnwoundFields = unwindSlugs(docs[i],unwoundSlugs,_.get,updIsModified); | ||
let actualSlugs = currentUnwoundFields; | ||
if (involvedValuesDocs && involvedValuesDocs.length) { | ||
let actualUpdFields = _(updFields) | ||
.filter(f => { | ||
// console.log(_.get(doc, f),_.get(docs[i], f)); | ||
return _.get(doc, f) != _.get(involvedValuesDocs[i], f); | ||
}) | ||
.map(f => _.trim(f.replace(/\["?(.+?)"?\]/g, '.$1'), '.')) | ||
.value(); | ||
// console.log("actualUpdFields",actualUpdFields,updFields); | ||
let slugsUpd = []; | ||
let different = false; | ||
for (let i = 0; i < docs.length; i++) { | ||
await setSlugs(docs[i], unwoundSlugs, options, _.get, _.set, findOne); | ||
actualSlugs = _.filter(currentUnwoundFields, s => { | ||
// if(s.path=="child.slug"){ | ||
// console.log(_.intersection( | ||
// s.fields.concat(s.uniqueGroupFields || []), | ||
// actualUpdFields | ||
// )); | ||
// } | ||
return _.intersection( | ||
_.map(s.fields.concat(s.uniqueGroupFields || []),p=>p.replace(/^\//,'')), | ||
actualUpdFields | ||
).length; | ||
}); | ||
// console.log('child.slug b4',_.filter(actualSlugs,['path','child.slug'])); | ||
// console.log('child.subChildren.4.slug get',_.get(docs[i],'child.subChildren.4.slug')); | ||
// console.log('child.subChildren.4.slug befor',_.filter(unwoundSlugs,['path','child.subChildren.4.slug'])); | ||
// console.log('child.subChildren.4.slug after',_.filter(unwoundSlugs,['path','child.subChildren.4.slug'])); | ||
// console.log("actualSlugs",actualSlugs); | ||
} | ||
// console.log('child.slug',_.indexOf(_.map(unwoundSlugs,'path'),'child.slug')); | ||
// console.log("before setSlugs",actualSlugs); | ||
if (actualSlugs.length){ | ||
await setSlugs(docs[i], actualSlugs, options, _.get, _.set, findOne); | ||
} | ||
// console.log("after setSlugs",docs[i]); | ||
slugsUpd[i] = _.cloneDeep(upd.$set || upd); | ||
unwoundSlugs.forEach(slug => { | ||
actualSlugs.forEach(slug => { | ||
let slugVal = _.get(docs[i], slug.path); | ||
// if(slugVal==="0-am-i-wrong-fallin-in-love-with-you") | ||
// console.log("000 ",slug); | ||
if(slug.path=='child.subChildren.4.slug'){ | ||
// console.log(slug.path,slugVal); | ||
} | ||
if (slugVal != undefined) _.set(slugsUpd[i], slug.path, slugVal); | ||
}); | ||
if (involvedValuesDocs && involvedValuesDocs.length) { | ||
_.each(currentUnwoundFields, us => { | ||
if (_.get(slugsUpd[i], us.path) === undefined) { | ||
let val = _.get(involvedValuesDocs[i], us.path); | ||
if (val !== undefined) _.set(slugsUpd[i], us.path, val); | ||
// else{ | ||
// console.log("not found",us.path); | ||
// console.log(involvedValuesDocs[i]); | ||
// } | ||
} | ||
}); | ||
} | ||
let doUpd = slugsUpd[i]; | ||
if (upd.$set) { | ||
@@ -251,8 +316,8 @@ // console.log(_.indexate(slugsUpd[i],{ leafsOnly: true })); | ||
.value(); | ||
slugsUpd[i] = { $set: slugPaths }; | ||
// console.log('upd',slugsUpd[i]); | ||
doUpd = { $set: slugPaths }; | ||
} | ||
// console.log('upd',doUpd); | ||
if (docs.length == 1) { | ||
me[operation]({}, slugsUpd[i]); | ||
if (slugsUpd[i]) me[operation]({}, doUpd); | ||
// console.log(me.getUpdate()); | ||
@@ -264,3 +329,8 @@ } else { | ||
); | ||
await me.model.updateOne({ _id: docs[i]._id }, slugsUpd[i]); | ||
if (doUpd){ | ||
// if(operation=="updateMany") | ||
// console.log("updateMany"); | ||
// console.log(slugsUpd[i].child&&slugsUpd[i].child.slugShort||null); | ||
await me.model.updateOne({ _id: docs[i]._id }, doUpd); | ||
} | ||
} | ||
@@ -280,3 +350,5 @@ } | ||
let reSlug = false; | ||
// let logslug = _.filter(slugs,['path','children.$.relativeSiblingSlug']); | ||
// if(logslug.length) | ||
// console.log(logslug); | ||
let unwoundSlugs = unwindSlugs( | ||
@@ -288,2 +360,4 @@ doc, | ||
); | ||
// if(logslug.length) | ||
// console.log(_.filter(unwoundSlugs,s=>_.endsWith(s.path,'relativeSiblingSlug'))); | ||
@@ -294,8 +368,17 @@ if (!unwoundSlugs.length) { | ||
// console.log('slugs',slugs); | ||
doc = await setSlugs(doc, unwoundSlugs, options, docGet, docSet, query => { | ||
if (!doc.model) { | ||
throw new Error('Unique nested slugs not implemented yet'); | ||
doc = await setSlugs( | ||
doc, | ||
unwoundSlugs, | ||
options, | ||
docGet, | ||
docSet, | ||
async (query, sort) => { | ||
let res = doc.model(doc.constructor.modelName).findOne(query); | ||
if (sort) res = res.sort(sort); | ||
res = await res; | ||
// console.log("save findOne res", res&&res.get('uniqueSlug')||null); | ||
return res; | ||
} | ||
return doc.model(doc.constructor.modelName).findOne(query); | ||
}); | ||
); | ||
// console.log('slugs set',doc); | ||
}); | ||
@@ -311,37 +394,68 @@ }; | ||
function unwindSlugs(doc, slugs, get, isModified) { | ||
// console.log("unwindSlugs",slugs); | ||
let unwoundSlugs = []; | ||
slugs.forEach(slug => { | ||
let say = false;//slug.path=="children.$.relativeSiblingSlug"; | ||
let slugPaths = unwindPath(doc, slug.path, get); | ||
if(say) | ||
console.log("slugPaths",slugPaths); | ||
if(!slugPaths.length) | ||
slugPaths.push(slug.path); | ||
let basePath = slug.basePath; | ||
// console.log(slug.path,'vs',slug.path); | ||
// console.log(slug.path,slugPaths,doc); | ||
if (_.endsWith(basePath, '.$')) basePath += '.'; | ||
slugPaths.forEach(slugPath => { | ||
let unwoundBasePath = slugPath.replace(/\.[^\.]+$/, ''); | ||
if(say) | ||
console.log("unwoundBasePath",unwoundBasePath); | ||
if (unwoundBasePath == slugPath) unwoundBasePath = ''; | ||
// console.log("unwoundBasePath",unwoundBasePath); | ||
function unwindFieldPath(fieldPath) { | ||
if(say) | ||
console.log(fieldPath+"->"); | ||
let slugValueBasePath = unwoundBasePath; | ||
let originalBasePath = _.trimEnd(basePath,'.'); | ||
while (_.startsWith(fieldPath, ':')) { | ||
// console.log("relative path ",slugValueBasePath,fieldPath); | ||
let prevValueBasePath = slugValueBasePath; | ||
if (slugValueBasePath.match(/\.\d+$/)) { | ||
slugValueBasePath = slugValueBasePath.replace(/\.\d+$/, ''); | ||
let prevOriginalBasePath = originalBasePath; | ||
if (slugValueBasePath.match(/\.[$\d]+$/)) { | ||
slugValueBasePath = slugValueBasePath.replace(/\.[$\d]+$/, ''); | ||
prevValueBasePath = slugValueBasePath; | ||
} | ||
if (originalBasePath.match(/\.[$\d]+$/)) { | ||
originalBasePath = originalBasePath.replace(/\.[$\d]+$/, ''); | ||
prevOriginalBasePath = originalBasePath; | ||
} | ||
if(say){ | ||
console.log(fieldPath); | ||
console.log(slugValueBasePath); | ||
console.log(originalBasePath); | ||
} | ||
slugValueBasePath = slugValueBasePath.replace(/\.[^\.]+$/, ''); | ||
originalBasePath = originalBasePath.replace(/\.[^\.]+$/, ''); | ||
if (slugValueBasePath == prevValueBasePath) slugValueBasePath = ''; | ||
if (originalBasePath == prevOriginalBasePath) originalBasePath = ''; | ||
fieldPath = fieldPath.substr(1); | ||
// console.log("unwind relative path ",slugValueBasePath,fieldPath); | ||
} | ||
if (!_.startsWith(fieldPath, '/')) | ||
fieldPath = | ||
if (!_.startsWith(fieldPath, '/')){ | ||
fieldPath ='/'+ | ||
((slugValueBasePath && slugValueBasePath + '.') || '') + fieldPath; | ||
else fieldPath = fieldPath.substr(1); | ||
} | ||
if(_.startsWith(fieldPath,'/'+originalBasePath)) | ||
fieldPath = fieldPath.replace('/'+originalBasePath,'/'+slugValueBasePath); | ||
if(say) | ||
console.log("->"+fieldPath,originalBasePath,slugValueBasePath); | ||
return fieldPath; | ||
} | ||
let unwoundFields = slug.fields.map(unwindFieldPath); | ||
let unwoundGroupPaths = (slug.uniqueGroup || []).map(unwindFieldPath); | ||
let unwoundGroupPaths = (slug.uniqueGroupFields || []).map( | ||
unwindFieldPath | ||
); | ||
// console.log("unwoundGroupPaths",unwoundGroupPaths); | ||
if ( | ||
_.some(unwoundFields.concat(unwoundGroupPaths), path => { | ||
return isModified(doc, path); | ||
return isModified(doc, path.replace(/^\//,'')); | ||
}) | ||
@@ -353,6 +467,11 @@ ) { | ||
s.fields = unwoundFields; | ||
s.uniqueGroup = unwoundGroupPaths; | ||
s.uniqueGroupFields = unwoundGroupPaths; | ||
unwoundSlugs.push(s); | ||
if(say){ | ||
console.log("YEYE:",s); | ||
} | ||
} else { | ||
// console.log('fields not changed', unwoundFields); | ||
if(slug.path=="child.subChildren.4.slug"){ | ||
// console.log("NONO:",unwoundFields,unwoundGroupPaths); | ||
} | ||
} | ||
@@ -388,3 +507,3 @@ }); | ||
async function setSlugs(doc, slugs, options, get, set, findOne) { | ||
// console.log('setSlugs', slugs); | ||
// console.log('setSlugs',_.filter(slugs,s=>_.startsWith(s.path,'child.subChildren.'))); | ||
await Promise.all( | ||
@@ -395,4 +514,4 @@ slugs.map(async slug => { | ||
slug.fields.forEach(slugField => { | ||
// console.log("get",doc,slugField); | ||
fields.push(get(doc, slugField)); | ||
// console.log("get",slugField,slugField.replace(/^\//,'')); | ||
fields.push(get(doc, slugField.replace(/^\//,''))); | ||
}); | ||
@@ -402,3 +521,3 @@ let oldSlug = get(doc, slug.path); | ||
!(slug.unique || slug.unique_slug) && | ||
(!slug.uniqueGroup || !slug.uniqueGroup.length) | ||
(!slug.uniqueGroupFields || !slug.uniqueGroupFields.length) | ||
) { | ||
@@ -415,5 +534,6 @@ if (!oldSlug || !slug.permanent) { | ||
var query = {}; | ||
if (slug.uniqueGroup) { | ||
slug.uniqueGroup.forEach(function(fieldName) { | ||
query[fieldName] = doc[fieldName]; | ||
if (slug.uniqueGroupFields) { | ||
slug.uniqueGroupFields.forEach(function(fieldName) { | ||
fieldName = fieldName.replace(/^\//,''); | ||
query[fieldName] = get(doc,fieldName); | ||
}); | ||
@@ -435,2 +555,3 @@ // console.log('group query', query); | ||
findOne, | ||
get, | ||
slug.forceShortId | ||
@@ -469,3 +590,12 @@ ) | ||
} | ||
function extractCounter(value,separator) { | ||
let count = 0, | ||
test = new RegExp(separator + '(\\d+)$'), | ||
match = null; | ||
if ((match = value.match(test))) { | ||
count = match[1]; | ||
} | ||
return parseInt(count); | ||
} | ||
async function makeUniqueCounterSlug( | ||
@@ -482,4 +612,2 @@ doc, | ||
count = 0, | ||
match = null, | ||
test = new RegExp(options.separator + '(\\d+)$'), | ||
search = new RegExp('^' + slug + '(' + options.separator + '(\\d+))?$'), | ||
@@ -496,14 +624,18 @@ sort = {}; | ||
query[field] = search; | ||
// console.log("counter slug query after",query); | ||
// field = search and doc != doc | ||
let result = await findOne(query).sort(sort); | ||
let result = await findOne(query, sort); | ||
// if(query["uniqueSlug"]){ | ||
// console.log("counter slug query after",query); | ||
// console.log("counter slug check", result); | ||
// } | ||
if (result) { | ||
// console.log("counter slug check", result); | ||
if ((match = result[field].match(test))) { | ||
count = match[1]; | ||
} | ||
count++; | ||
count = extractCounter(result.get(field),options.separator)+1; | ||
slug += options.separator + pad(count, padding); | ||
// console.log("slug counter inc",slug); | ||
// if(result.n!==undefined && query["children.4.slugCounter"]){ | ||
// console.log(result.n+": "+field); | ||
// console.log(slug); | ||
// } | ||
} | ||
@@ -535,2 +667,3 @@ return slug; | ||
findOne, | ||
get, | ||
forceShortId | ||
@@ -551,9 +684,10 @@ ) { | ||
// console.log('doc already exists', result[field], doc[field],slug); | ||
let oldSlug = get(doc,field); | ||
if ( | ||
//reuse old slug if possible | ||
doc[field] && | ||
doc[field].match(new RegExp('^' + slug + options.separator + '.*$')) | ||
oldSlug && | ||
oldSlug.match(new RegExp('^' + slug + options.separator + '.*$')) | ||
) { | ||
// console.log("reuse old random slug",doc[field]); | ||
slug = doc[field]; | ||
slug = oldSlug; | ||
} else slug += options.separator + shortId.generate(); | ||
@@ -560,0 +694,0 @@ } else { |
{ | ||
"name": "mongoose-slug-updater", | ||
"version": "2.4.0", | ||
"description": "Mongoose plugin to create and update slugs and unique slugs in any field, nested too. Create, Save, Update, FindAndUpdate operations supported, including $set deep paths.", | ||
"version": "2.5.0", | ||
"description": "Sophisticated slugifier plugin for Mongoose:\n- Intuitive schema-based declaration\n- Single or compound slugs, based on any fields of the document\n- Nested docs and arrays support\n- Relative or absolute paths to the related fields\n- Initial generation and updating (or not if permanent) on any change of related fields,\n- create, save, update, updateOne, updateMany or findOneAndUpdate methods supported, and you can switch them on/off.\n- $set update operator support with deep modification paths to any nested doc or array.\n- Unique slugs (with unique index or not), collection-wide or by group, nested too.\n- Updating of unique slugs in case of changed related fields or group criteria.\n- Counter and shortId styles of duplication conflict resolving.\n- Autoloading of missing related data required to build slug correctly.", | ||
"main": "index.js", | ||
@@ -6,0 +6,0 @@ "directories": { |
# mongoose-slug-updater | ||
Mongoose plugin for creating and updating slugs based on mongoose schema fields.<br> | ||
Operations `save`, `update`, `updateOne`, `updateMany` and `findOneAndUpdate` are supported both for creation and modifying.<br> | ||
Nested documents and arrays are supported too with relative/absolute path to any field of the document.<br> | ||
$set deep paths to nested docs and arrays works too, but without other update operators yet. | ||
For example you can create a slug based on a document's title and author's name: _my-post-title-slim-shady_, or unique slugs based on just the title: _my-post-title-Nyiy4wW9l_. | ||
Sophisticated slugifier plugin for Mongoose. | ||
Update operators support and unique mode for nested slugs are coming soon. | ||
Features: | ||
- [Intuitive schema-based declaration](#basic-usage) | ||
- Single or [compound](#multiple-fields-to-create-the-slug) slugs, based on any fields of the document | ||
- [Nested docs and arrays support](#nested-docs-relative-and-absolute-paths) | ||
- [Relative or absolute paths to the related fields](#nested-docs-relative-and-absolute-paths) | ||
- Initial generation and [updating](#updating-slug-or-keeping-it-permanent) (or not if [permanent](#permanent-option)) on any change of related fields, | ||
- `create`, `save`, `update`, `updateOne`, `updateMany` or `findOneAndUpdate` methods supported, and you can [switch them on/off](#updating-slug-or-keeping-it-permanent). | ||
- [$set](#updating-by-deep-path-via-set-operator) update operator support with deep modification paths to any nested doc or array. | ||
- [Unique slugs](#unique-slug-field) (with unique index or not), collection-wide or [by group](#unique-slug-within-a-group), nested too. | ||
- Updating of unique slugs in case of changed related fields or group criteria. | ||
- [Counter](#example-counter) and [shortId](#example-random) styles of duplication conflict resolving. | ||
- Autoloading of missing related data required to build slug correctly. | ||
@@ -103,6 +110,7 @@ ## Installation | ||
If `unique` or `unique_slug` is set, the plugin searches in the mongo database, and if the slug already exists in the collection, it appends to the slug a separator (default: "-") and a random string (generated with the shortid module). | ||
If `unique` or `unique_slug` is set, the plugin searches in the mongo database, and if the slug already exists in the collection, it appends to the slug a separator (default: "-") and a random string (generated with the shortid module). <br> | ||
MongoDB supports unique index for nested arrays elements, but he check for duplication conflict only on per-document basis, so inside document duplicate nested array's elements are still allowed. <br> | ||
Same logic implemented for unique slugs of nested arrays too. | ||
**example random** | ||
#### example random | ||
```js | ||
@@ -125,6 +133,5 @@ mongoose.model('Resource').create({ | ||
Alternatively you can modify this behaviour and instead of appending a random string, an incremental counter will be used. For that to happen, you must use the parameter _slug_padding_size_ specifying the total length of the counter: | ||
Alternatively you can modify this behaviour and instead of appending a random string, an incremental counter will be used. For that to happen, you must use the parameter `slug_padding_size` specifying the total length of the counter: | ||
**example counter** | ||
#### example counter | ||
```js | ||
@@ -252,12 +259,13 @@ var mongoose = require('mongoose'), | ||
Note, that flags will affect both creation and updating of documents, | ||
so if you disabled `save` and still want slug to be generated initially, | ||
use `upsert` option of `update***` methods.<br> | ||
On `update` and `updateMany` multiply affected records also handled, but be careful with performance, | ||
Note, that flags will affect both creation and updating of documents. <br> | ||
If you disabled `save` and still want slug to be generated initially, `create` method will not work, <br> | ||
becacuse mongoose emits `save` event both for `save` and `create` methods. <br> | ||
Use `upsert` option of `update***` methods instead. | ||
For `update` and `updateMany` methods multiply affected records also handled, but be careful with performance, | ||
because one-by-one iteration over affected documents may happen in case of unique slugs.<br> | ||
In this case `_id` field is required.<br> | ||
For `update*` family of operations additional queries may be performed, to retrieve data missing in the query.<br> | ||
For example if compound slug was affected by this update.<br> | ||
So if you already have necessary data - it's better for performance to specify all the fields listed in the compound slug and old slug value in update query. | ||
In this case `_id` field is required. | ||
For `update*` family of operations additional queries may be performed, to retrieve data missing in the query (fields not listed in the query but needed for compound or grouped unique slugs).<br> | ||
#### `permanent` option | ||
@@ -466,4 +474,11 @@ | ||
``` | ||
All the slugs which depend on modified titles will be found and regenerated. | ||
All the slugs which depend on modified titles will be found and regenerated.<br> | ||
This is recommended way to do partial modifications.<br> | ||
When you perform updates by object value instead of path:value list,<br> | ||
unobvious data loss may happen for nested docs or arrays, if they contain slugs affected by your modification.<br> | ||
Plugin always checks will current update operation be made with $set operator or not, and adds extra slug fields to the query as an object fields or $set paths accordingly. | ||
So if you do have whole document you want to change - better use `save`,<br> | ||
but if you dont have it, but you need to update some particular fields - it's more safe to use $set and paths:values. | ||
### Choose your own options | ||
@@ -504,3 +519,3 @@ | ||
Nested docs and arrays support implemented for non-unique slugs. | ||
Nested docs and arrays support implemented. | ||
@@ -511,4 +526,4 @@ Absolute and relative paths added. | ||
All the update operators and unique nested slugs will be implemented soon. | ||
All the update operators will be implemented soon. | ||
Plugin rewritten with modern js and a lot of tests were added. |
@@ -8,9 +8,6 @@ 'use strict'; | ||
const { | ||
ShortId, | ||
Counter | ||
} = require("./../model"); | ||
const { ShortId, Counter } = require('./../model'); | ||
const tellme = require('./../tellme'); | ||
const { nIterations } = require('./../options'); | ||
describe('updateOne', function() { | ||
@@ -109,10 +106,4 @@ beforeEach(async () => { | ||
editedDoc.should.have | ||
.property('slug') | ||
.and.equal( | ||
tellme.getSlug(2,1) | ||
); | ||
editedDoc.should.have | ||
.property('uniqueSlug') | ||
.and.equal(tellme.getSlug(2)); | ||
editedDoc.should.have.property('slug').and.equal(tellme.getSlug(2, 1)); | ||
editedDoc.should.have.property('uniqueSlug').and.equal(tellme.getSlug(2)); | ||
mdf = { | ||
@@ -126,10 +117,4 @@ title: tellme.getText(3), | ||
editedDoc.should.have | ||
.property('slug') | ||
.and.equal( | ||
tellme.getSlug(3,1) | ||
); | ||
editedDoc.should.have | ||
.property('uniqueSlug') | ||
.and.equal(tellme.getSlug(3)); | ||
editedDoc.should.have.property('slug').and.equal(tellme.getSlug(3, 1)); | ||
editedDoc.should.have.property('uniqueSlug').and.equal(tellme.getSlug(3)); | ||
}); | ||
@@ -154,10 +139,4 @@ | ||
editedDoc.should.have | ||
.property('slug') | ||
.and.equal( | ||
tellme.getSlug(0,3) | ||
); | ||
editedDoc.should.have | ||
.property('uniqueSlug') | ||
.and.equal(tellme.getSlug(0)); | ||
editedDoc.should.have.property('slug').and.equal(tellme.getSlug(0, 3)); | ||
editedDoc.should.have.property('uniqueSlug').and.equal(tellme.getSlug(0)); | ||
@@ -175,9 +154,5 @@ editedDoc.should.have | ||
editedDoc.should.have.property('slug').and.equal(tellme.getSlug(0, 4)); | ||
editedDoc.should.have.property('uniqueSlug').and.equal(tellme.getSlug(0)); | ||
editedDoc.should.have | ||
.property('slug') | ||
.and.equal(tellme.getSlug(0,4)); | ||
editedDoc.should.have | ||
.property('uniqueSlug') | ||
.and.equal(tellme.getSlug(0)); | ||
editedDoc.should.have | ||
.property('forcedSlug') | ||
@@ -209,2 +184,33 @@ .match(tellme.getShortRegex(4)) | ||
it("Update watcher fields to the same values and check counter wasn't changed", async () => { | ||
let mdf = { | ||
title: tellme.getText(0), | ||
subtitle: tellme.getText(1), | ||
}; | ||
let docs = []; | ||
for (let i = 0; i < nIterations; i++) { | ||
docs[i] = await Counter.create(mdf); | ||
} | ||
docs[0].should.have.property('title').and.equal(tellme.getText(0)); | ||
docs[0].should.have.property('uniqueSlug').and.equal(tellme.getSlug(0)); | ||
for (let i = 1; i < nIterations; i++) { | ||
docs[i].should.have.property('title').and.equal(tellme.getText(0)); | ||
docs[i].should.have.property('uniqueSlug').and.equal(tellme.getCounterSlug(0, i)); | ||
} | ||
for (let i = 0; i < nIterations; i++) { | ||
await Counter.updateOne({_id:docs[i]._id},mdf); | ||
docs[i] = await Counter.findById(docs[i]._id); | ||
} | ||
docs[0].should.have.property('title').and.equal(tellme.getText(0)); | ||
docs[0].should.have.property('uniqueSlug').and.equal(tellme.getSlug(0)); | ||
for (let i = 1; i < nIterations; i++) { | ||
docs[i].should.have.property('title').and.equal(tellme.getText(0)); | ||
docs[i].should.have.property('uniqueSlug').and.equal(tellme.getCounterSlug(0, i)); | ||
} | ||
}); | ||
it('UpdateOne without _id', async () => { | ||
@@ -224,10 +230,4 @@ let doc = await ShortId.create({ | ||
editedDoc.should.have | ||
.property('slug') | ||
.and.equal( | ||
tellme.getSlug(2,3) | ||
); | ||
editedDoc.should.have | ||
.property('uniqueSlug') | ||
.and.equal(tellme.getSlug(2)); | ||
editedDoc.should.have.property('slug').and.equal(tellme.getSlug(2, 3)); | ||
editedDoc.should.have.property('uniqueSlug').and.equal(tellme.getSlug(2)); | ||
@@ -244,7 +244,5 @@ ({ _id, slug, uniqueSlug } = editedDoc); | ||
editedDoc.should.have | ||
.property('slug') | ||
.and.equal(tellme.getSlug(4,5)); | ||
editedDoc.should.have.property('slug').and.equal(tellme.getSlug(4, 5)); | ||
editedDoc.should.have.property('uniqueSlug').and.equal(tellme.getSlug(4)); | ||
}); | ||
}); | ||
}); |
'use strict'; | ||
const mongoose = require('mongoose'); | ||
const { options, slug_padding_size,nIterations } = require('./../options'); | ||
const { options, slug_padding_size, nIterations } = require('./../options'); | ||
const slugGenerator = require('../../.'); | ||
mongoose.plugin(slugGenerator, options); | ||
const InlineSchema = require('./InlineSchema.js'); | ||
const {SubChildSchema,ChildSchema,ParentSchema} = require('./NestedSchema.js'); | ||
const { | ||
InlineSchema, | ||
SimpleInlineSchema, | ||
InlineUniqueSchema, | ||
} = require('./InlineSchema.js'); | ||
const { | ||
SubChildSchema, | ||
ChildSchema, | ||
ParentSchema, | ||
SimpleChildSchema, | ||
SimpleParentSchema, | ||
UniqueChildSchema, | ||
UniqueParentSchema, | ||
} = require('./NestedSchema.js'); | ||
const { | ||
ResourceGroupedUniqueCounter, | ||
ResourceGroupedUniqueShortId, | ||
} = require('./Grouped.js'); | ||
const CompoundUnique = new mongoose.Schema({ | ||
type:{type: String}, | ||
name:{type: String}, | ||
type: { type: String }, | ||
name: { type: String }, | ||
}); | ||
CompoundUnique.index({ | ||
type:1, | ||
name:1, | ||
},{unique: true}); | ||
CompoundUnique.index( | ||
{ | ||
type: 1, | ||
name: 1, | ||
}, | ||
{ unique: true } | ||
); | ||
@@ -24,3 +45,3 @@ const ResourceShortId = new mongoose.Schema({ | ||
uniqueSlug: { type: String, unique: true, slug: 'title' }, | ||
forcedSlug: { type:String, slug: ['subtitle'], force_id:true } | ||
forcedSlug: { type: String, slug: ['subtitle'], force_id: true }, | ||
}); | ||
@@ -41,28 +62,2 @@ | ||
const ResourceGroupedUniqueCounter = new mongoose.Schema({ | ||
title: { type: String }, | ||
subtitle: { type: String }, | ||
group: { type: String }, | ||
uniqueSlug: { | ||
type: String, | ||
uniqueGroup: ['group'], | ||
slug_padding_size: slug_padding_size, | ||
slug: 'title', | ||
index: true, | ||
}, | ||
}); | ||
const ResourceGroupedUniqueShortId = new mongoose.Schema({ | ||
title: { type: String }, | ||
subtitle: { type: String }, | ||
otherField: { type: String }, | ||
group: { type: String }, | ||
uniqueSlug: { | ||
type: String, | ||
uniqueGroup: ['group'], | ||
slug: 'title', | ||
index: true, | ||
}, | ||
}); | ||
const ResourcePermanent = new mongoose.Schema({ | ||
@@ -96,49 +91,3 @@ title: { type: String }, | ||
const SimpleChildSchema = new mongoose.Schema({ | ||
title: { type: String }, | ||
slug: { type: String, slug: 'title' }, | ||
}); | ||
const SimpleParentSchema = new mongoose.Schema({ | ||
simpleParent: { type: String }, | ||
title: { type: String }, | ||
slug: { type: String, slug: 'title' }, | ||
child: SimpleChildSchema, | ||
children: [SimpleChildSchema], | ||
}); | ||
const SimpleInlineSchema = new mongoose.Schema({ | ||
title: { type: String }, | ||
slug: { type: String, slug: 'title' }, | ||
child:{ | ||
title: { type: String }, | ||
slug: { type: String, slug: 'title' } | ||
}, | ||
children:[ | ||
{ | ||
title: { type: String }, | ||
slug: { type: String, slug: 'title' } | ||
} | ||
] | ||
}); | ||
const InlineUniqueSchema = new mongoose.Schema({ | ||
title: { type: String }, | ||
slug: { type: String, unique: true, slug: 'title' }, | ||
list: { type: Array }, | ||
child: { | ||
title: { type: String }, | ||
slug: { type: String, slug: 'title', unique: true }, | ||
}, | ||
children: [ | ||
{ | ||
title: { type: String, unique: true }, | ||
slug: { type: String, /*slug: 'title',*/ unique: true }, | ||
}, | ||
], | ||
}); | ||
const CompoundU = mongoose.model('CompoundUnique',CompoundUnique); | ||
const CompoundU = mongoose.model('CompoundUnique', CompoundUnique); | ||
const ShortId = mongoose.model('ResourceShortId', ResourceShortId); | ||
@@ -164,2 +113,4 @@ const Counter = mongoose.model('ResourceCounter', ResourceCounter); | ||
const SimpleParent = mongoose.model('SimpleParentSchema', SimpleParentSchema); | ||
const UniqueChild = mongoose.model('UniqueChildSchema', UniqueChildSchema); | ||
const UniqueParent = mongoose.model('UniqueParentSchema', UniqueParentSchema); | ||
@@ -182,2 +133,4 @@ module.exports = { | ||
InlineUnique, | ||
UniqueChild, | ||
UniqueParent, | ||
}; |
@@ -8,4 +8,6 @@ 'use strict'; | ||
const tellme = require('./../tellme'); | ||
const { options, slug_padding_size, nIterations } = require('./../options'); | ||
const InlineSchema = new mongoose.Schema({ | ||
n: { type: Number }, | ||
// root title | ||
@@ -15,2 +17,4 @@ title: { type: String }, | ||
slug: { type: String, slug: 'title' }, | ||
slugShort: { type: String, slug: 'title', unique: true }, | ||
slugCounter: { type: String, slug: 'title', unique: true, slug_padding_size }, | ||
// root slug with absolute path to root title | ||
@@ -22,4 +26,20 @@ absoluteSlug: { type: String, slug: '/title' }, | ||
absoluteChildSlug: { type: String, slug: '/child.title' }, | ||
absoluteChildSlugShort: { | ||
type: String, | ||
slug: '/child.title', | ||
unique: true, | ||
}, | ||
absoluteChildSlugCounter: { | ||
type: String, | ||
slug: '/child.title', | ||
unique: true, | ||
slug_padding_size, | ||
}, | ||
// root slug with relative path to child's subchild title | ||
subChildSlug: { type: String, slug: 'child.subChild.title' }, | ||
subChildSlugShort: { | ||
type: String, | ||
slug: 'child.subChild.title', | ||
unique: true, | ||
}, | ||
// root slug with relative path to the title of first children array element | ||
@@ -29,2 +49,9 @@ childrenSlug0: { type: String, slug: 'children.0.title' }, | ||
childrenSlug4: { type: String, slug: 'children.4.title' }, | ||
childrenSlug4Short: { type: String, slug: 'children.4.title', unique: true }, | ||
childrenSlug4Counter: { | ||
type: String, | ||
slug: 'children.4.title', | ||
unique: true, | ||
slug_padding_size, | ||
}, | ||
// root slug with relative path to the title of 4th subChildren' element of first children array element | ||
@@ -43,2 +70,13 @@ subChildrenSlug3: { type: String, slug: 'children.0.subChildren.3.title' }, | ||
}, | ||
subChildrenSlug2SubChildShort: { | ||
type: String, | ||
slug: 'children.0.subChildren.2.subChild.title', | ||
unique: true, | ||
}, | ||
subChildrenSlug2SubChildCounter: { | ||
type: String, | ||
slug: 'children.0.subChildren.2.subChild.title', | ||
unique: true, | ||
slug_padding_size, | ||
}, | ||
child: { | ||
@@ -94,2 +132,9 @@ title: { type: String }, | ||
relativeParentSlug: { type: String, slug: ':title' }, | ||
relativeParentSlugShort: { type: String, slug: ':title', unique: true }, | ||
relativeParentSlugCounter: { | ||
type: String, | ||
slug: ':title', | ||
unique: true, | ||
slug_padding_size, | ||
}, | ||
// two parents up is a root | ||
@@ -132,4 +177,5 @@ relativeGrandParentSlug: { type: String, slug: '::title' }, | ||
InlineSchema.statics.getNewDoc = function() { | ||
InlineSchema.statics.getNewDoc = function(n) { | ||
return { | ||
n: n || 0, | ||
title: tellme.getText(0), | ||
@@ -257,11 +303,29 @@ child: { | ||
InlineSchema.statics.testNewDoc = function(doc) { | ||
InlineSchema.statics.testNewDoc = function(doc, n) { | ||
n = n || 0; | ||
doc.should.have.property('n').and.equal(n); | ||
doc.should.have.property('title').and.equal(tellme.getText(0)); | ||
doc.should.have.property('slug').and.equal(tellme.getSlug(0)); | ||
doc.should.have.property('slugShort').and.match(tellme.getShortRegex(0, n)); | ||
doc.should.have | ||
.property('slugCounter') | ||
.and.equal(tellme.getCounterSlug(0, n)); | ||
doc.should.have.property('absoluteSlug').and.equal(tellme.getSlug(0)); | ||
doc.should.have.property('childSlug').and.equal(tellme.getSlug(1)); | ||
doc.should.have.property('absoluteChildSlug').and.equal(tellme.getSlug(1)); | ||
doc.should.have | ||
.property('absoluteChildSlugShort') | ||
.and.match(tellme.getShortRegex(1, n)); | ||
doc.should.have | ||
.property('absoluteChildSlugCounter') | ||
.and.equal(tellme.getCounterSlug(1, n)); | ||
doc.should.have.property('subChildSlug').and.equal(tellme.getSlug(7)); | ||
doc.should.have.property('childrenSlug0').and.equal(tellme.getSlug(0)); | ||
doc.should.have.property('childrenSlug4').and.equal(tellme.getSlug(4)); | ||
doc.should.have | ||
.property('childrenSlug4Short') | ||
.and.match(tellme.getShortRegex(4, n)); | ||
doc.should.have | ||
.property('childrenSlug4Counter') | ||
.and.equal(tellme.getCounterSlug(4, n)); | ||
doc.should.have.property('subChildrenSlug3').and.equal(tellme.getSlug(3)); | ||
@@ -275,2 +339,9 @@ doc.should.have.property('subChildrenSlug7').and.equal(tellme.getSlug(7)); | ||
.and.equal(tellme.getSlug(6)); | ||
doc.should.have | ||
.property('subChildrenSlug2SubChildShort') | ||
.and.match(tellme.getShortRegex(6, n)); | ||
doc.should.have | ||
.property('subChildrenSlug2SubChildCounter') | ||
.and.equal(tellme.getCounterSlug(6, n)); | ||
doc.should.have.nested.property('child.title').and.equal(tellme.getText(1)); | ||
@@ -340,2 +411,9 @@ doc.should.have.nested.property('child.slug').and.equal(tellme.getSlug(1)); | ||
doc.should.have.nested | ||
.property(`children[${i}].subChild.relativeParentSlugShort`) | ||
.and.match(tellme.getShortRegex(i,n)); | ||
doc.should.have.nested | ||
.property(`children[${i}].subChild.relativeParentSlugCounter`) | ||
.and.equal(tellme.getCounterSlug(i,n)); | ||
doc.should.have.nested | ||
.property(`children[${i}].subChild.relativeGrandParentSlug`) | ||
@@ -393,3 +471,3 @@ .and.equal(tellme.getSlug(0)); | ||
.mapKeys((v, f) => _.trim(f.replace(/\["?(.+?)"?\]/g, '.$1'), '.')) | ||
.pickBy((v, k) => v !== undefined && !_.isEqual(v,{}) && !_.isEqual(v,[])) | ||
.pickBy((v, k) => v !== undefined && !_.isEqual(v, {}) && !_.isEqual(v, [])) | ||
.value(); | ||
@@ -441,8 +519,18 @@ // console.log(doc); | ||
InlineSchema.statics.testChangedDoc = function(doc) { | ||
InlineSchema.statics.testChangedDoc = function(doc, n = 0) { | ||
doc.should.have.property('title').and.equal(tellme.getText(8)); | ||
doc.should.have.property('slug').and.equal(tellme.getSlug(8)); | ||
doc.should.have.property('slugShort').and.match(tellme.getShortRegex(8, n)); | ||
doc.should.have | ||
.property('slugCounter') | ||
.and.equal(tellme.getCounterSlug(8, n)); | ||
doc.should.have.property('absoluteSlug').and.equal(tellme.getSlug(8)); | ||
doc.should.have.property('childSlug').and.equal(tellme.getSlug(7)); | ||
doc.should.have.property('absoluteChildSlug').and.equal(tellme.getSlug(7)); | ||
doc.should.have | ||
.property('absoluteChildSlugShort') | ||
.and.match(tellme.getShortRegex(7, n)); | ||
doc.should.have | ||
.property('absoluteChildSlugCounter') | ||
.and.equal(tellme.getCounterSlug(7, n)); | ||
doc.should.have.property('subChildSlug').and.equal(tellme.getSlug(6)); | ||
@@ -454,2 +542,8 @@ doc.should.have.nested | ||
doc.should.have.property('childrenSlug4').and.equal(tellme.getSlug(0)); | ||
doc.should.have | ||
.property('childrenSlug4Short') | ||
.and.match(tellme.getShortRegex(0, n)); | ||
doc.should.have | ||
.property('childrenSlug4Counter') | ||
.and.equal(tellme.getCounterSlug(0, n)); | ||
doc.should.have.property('subChildrenSlug3').and.equal(tellme.getSlug(8)); | ||
@@ -463,2 +557,9 @@ doc.should.have.property('subChildrenSlug7').and.equal(tellme.getSlug(2)); | ||
.and.equal(tellme.getSlug(4)); | ||
doc.should.have | ||
.property('subChildrenSlug2SubChildShort') | ||
.and.match(tellme.getShortRegex(4, n)); | ||
doc.should.have | ||
.property('subChildrenSlug2SubChildCounter') | ||
.and.equal(tellme.getCounterSlug(4, n)); | ||
doc.should.have.nested.property('child.title').and.equal(tellme.getText(7)); | ||
@@ -573,4 +674,192 @@ doc.should.have.nested.property('child.slug').and.equal(tellme.getSlug(7)); | ||
.and.equal(tellme.getSlug(8)); | ||
doc.should.have.nested | ||
.property(`children[0].subChild.relativeParentSlugShort`) | ||
.and.match(tellme.getShortRegex(4,n)); | ||
doc.should.have.nested | ||
.property(`children[0].subChild.relativeParentSlugCounter`) | ||
.and.equal(tellme.getCounterSlug(4,n)); | ||
}; | ||
const SimpleInlineSchema = new mongoose.Schema({ | ||
title: { type: String }, | ||
slug: { type: String, slug: 'title' }, | ||
child: { | ||
title: { type: String }, | ||
slug: { type: String, slug: 'title' }, | ||
}, | ||
children: [ | ||
{ | ||
title: { type: String }, | ||
slug: { type: String, slug: 'title' }, | ||
}, | ||
], | ||
}); | ||
module.exports = InlineSchema; | ||
const InlineUniqueSchema = new mongoose.Schema({ | ||
n: { type: Number }, | ||
title: { type: String }, | ||
slugShort: { type: String, unique: true, slug: 'title' }, | ||
slugCounter: { type: String, slug: 'title', unique: true, slug_padding_size }, | ||
child: { | ||
title: { type: String }, | ||
slugShort: { type: String, slug: 'title', unique: true }, | ||
slugCounter: { | ||
type: String, | ||
slug: 'title', | ||
unique: true, | ||
slug_padding_size, | ||
}, | ||
}, | ||
children: [ | ||
{ | ||
title: { type: String }, | ||
slugShort: { type: String, slug: 'title', unique: true }, | ||
slugCounter: { | ||
type: String, | ||
slug: 'title', | ||
unique: true, | ||
slug_padding_size, | ||
}, | ||
}, | ||
], | ||
}); | ||
InlineUniqueSchema.statics.getNewDoc = function(n) { | ||
let res = { | ||
n, | ||
title: tellme.getText(0), | ||
child: { | ||
title: tellme.getText(1), | ||
}, | ||
children: [], | ||
}; | ||
for (let i = 0; i < 8; i++) { | ||
res.children.push({ title: tellme.getText(8 - i) }); | ||
} | ||
return res; | ||
}; | ||
InlineUniqueSchema.statics.testNewDoc = function(doc, n) { | ||
doc.should.have.property('title').and.equal(tellme.getText(0)); | ||
doc.should.have.nested.property('child.title').and.equal(tellme.getText(1)); | ||
if (!n) { | ||
doc.should.have.property('slugShort').and.equal(tellme.getSlug(0)); | ||
doc.should.have.property('slugCounter').and.equal(tellme.getSlug(0)); | ||
doc.should.have.nested | ||
.property('child.slugShort') | ||
.and.equal(tellme.getSlug(1)); | ||
doc.should.have.nested | ||
.property('child.slugCounter') | ||
.and.equal(tellme.getSlug(1)); | ||
} else { | ||
doc.should.have.property('slugShort').and.match(tellme.getShortRegex(0)); | ||
doc.should.have | ||
.property('slugCounter') | ||
.and.equal(tellme.getCounterSlug(0, n)); | ||
doc.should.have.nested | ||
.property('child.slugShort') | ||
.and.match(tellme.getShortRegex(1)); | ||
doc.should.have.nested | ||
.property('child.slugCounter') | ||
.and.equal(tellme.getCounterSlug(1, n)); | ||
} | ||
for (let i = 0; i < 8; i++) { | ||
doc.should.have.nested | ||
.property(`children[${i}].title`) | ||
.and.equal(tellme.getText(8 - i)); | ||
if (!n) { | ||
doc.should.have.nested | ||
.property(`children[${i}].slugShort`) | ||
.and.equal(tellme.getSlug(8 - i)); | ||
doc.should.have.nested | ||
.property(`children[${i}].slugCounter`) | ||
.and.equal(tellme.getSlug(8 - i)); | ||
} else { | ||
doc.should.have.nested | ||
.property(`children[${i}].slugShort`) | ||
.and.match(tellme.getShortRegex(8 - i)); | ||
doc.should.have.nested | ||
.property(`children[${i}].slugCounter`) | ||
.and.equal(tellme.getCounterSlug(8 - i, n)); | ||
} | ||
} | ||
}; | ||
InlineUniqueSchema.statics.changeDocPaths = function(doc) { | ||
doc = this.changeDoc(doc); | ||
// console.log(doc); | ||
doc = _(doc) | ||
.indexate({ leafsOnly: true }) | ||
.mapKeys((v, f) => _.trim(f.replace(/\["?(.+?)"?\]/g, '.$1'), '.')) | ||
.pickBy((v, k) => v !== undefined && !_.isEqual(v, {}) && !_.isEqual(v, [])) | ||
.value(); | ||
// console.log(doc); | ||
return { $set: doc }; | ||
}; | ||
InlineUniqueSchema.statics.changeDoc = function(doc) { | ||
let res = { | ||
title: tellme.getText(8), | ||
child: { | ||
title: tellme.getText(7), | ||
}, | ||
children: [], | ||
}; | ||
for (let i = 0; i < 8; i++) { | ||
res.children.push({ title: tellme.getText(i) }); | ||
} | ||
return _.merge(doc, res); | ||
}; | ||
InlineUniqueSchema.statics.testChangedDoc = function(doc, n) { | ||
doc.should.have.property('title').and.equal(tellme.getText(8)); | ||
doc.should.have.nested.property('child.title').and.equal(tellme.getText(7)); | ||
if (!n) { | ||
doc.should.have.property('slugShort').and.equal(tellme.getSlug(8)); | ||
doc.should.have.property('slugCounter').and.equal(tellme.getSlug(8)); | ||
doc.should.have.nested | ||
.property('child.slugShort') | ||
.and.equal(tellme.getSlug(7)); | ||
doc.should.have.nested | ||
.property('child.slugCounter') | ||
.and.equal(tellme.getSlug(7)); | ||
} else { | ||
doc.should.have.property('slugShort').and.match(tellme.getShortRegex(8)); | ||
doc.should.have | ||
.property('slugCounter') | ||
.and.equal(tellme.getCounterSlug(8, n)); | ||
doc.should.have.nested | ||
.property('child.slugShort') | ||
.and.match(tellme.getShortRegex(7)); | ||
doc.should.have.nested | ||
.property('child.slugCounter') | ||
.and.equal(tellme.getCounterSlug(7, n)); | ||
} | ||
for (let i = 0; i < 8; i++) { | ||
doc.should.have.nested | ||
.property(`children[${i}].title`) | ||
.and.equal(tellme.getText(i)); | ||
if (!n) { | ||
doc.should.have.nested | ||
.property(`children[${i}].slugShort`) | ||
.and.equal(tellme.getSlug(i)); | ||
doc.should.have.nested | ||
.property(`children[${i}].slugCounter`) | ||
.and.equal(tellme.getSlug(i)); | ||
} else { | ||
doc.should.have.nested | ||
.property(`children[${i}].slugShort`) | ||
.and.match(tellme.getShortRegex(i)); | ||
doc.should.have.nested | ||
.property(`children[${i}].slugCounter`) | ||
.and.equal(tellme.getCounterSlug(i, n)); | ||
} | ||
} | ||
}; | ||
module.exports = { | ||
InlineSchema, | ||
SimpleInlineSchema, | ||
InlineUniqueSchema, | ||
}; |
@@ -8,2 +8,3 @@ 'use strict'; | ||
const tellme = require('./../tellme'); | ||
const { options, slug_padding_size, nIterations } = require('./../options'); | ||
@@ -15,4 +16,4 @@ const SubChildSchema = new mongoose.Schema({ | ||
absoluteChildSlug: { type: String, slug: '/child.title' }, | ||
relativeParentSlug: { type: String, slug: ':title' },// child's title | ||
relativeGrandParentSlug: { type: String, slug: '::title' },//parent's title | ||
relativeParentSlug: { type: String, slug: ':title' }, // child's title | ||
relativeGrandParentSlug: { type: String, slug: '::title' }, //parent's title | ||
}); | ||
@@ -28,3 +29,3 @@ | ||
absoluteRootSlug: { type: String, slug: '/title' }, | ||
relativeParentSlug: { type: String, slug: ':title' },//Parent | ||
relativeParentSlug: { type: String, slug: ':title' }, //Parent | ||
subChildrenSlug2: { type: String, slug: 'subChildren.2.title' }, | ||
@@ -203,3 +204,3 @@ subChildrenSlug3: { type: String, slug: 'subChildren.3.title' }, | ||
ParentSchema.statics.changeNewDoc = function(doc) { | ||
ParentSchema.statics.changeDoc = function(doc) { | ||
let changed = { | ||
@@ -285,2 +286,3 @@ title: tellme.getText(8), | ||
.and.equal(tellme.getText(8 - i)); | ||
// console.log(i); | ||
doc.should.have.nested | ||
@@ -352,6 +354,38 @@ .property(`child.subChildren.${i}.slug`) | ||
const SimpleChildSchema = new mongoose.Schema({ | ||
title: { type: String }, | ||
slug: { type: String, slug: 'title' }, | ||
}); | ||
const SimpleParentSchema = new mongoose.Schema({ | ||
simpleParent: { type: String }, | ||
title: { type: String }, | ||
slug: { type: String, slug: 'title' }, | ||
child: SimpleChildSchema, | ||
children: [SimpleChildSchema], | ||
}); | ||
const UniqueChildSchema = new mongoose.Schema({ | ||
title: { type: String }, | ||
slugShort: { type: String, slug: 'title', unique:true }, | ||
slugCounter: { type: String, slug: 'title', unique:true, slug_padding_size }, | ||
}); | ||
const UniqueParentSchema = new mongoose.Schema({ | ||
n: { type: Number }, | ||
title: { type: String }, | ||
slugShort: { type: String, slug: 'title', unique:true }, | ||
slugCounter: { type: String, slug: 'title', unique:true, slug_padding_size }, | ||
child: UniqueChildSchema, | ||
children: [UniqueChildSchema], | ||
}); | ||
module.exports = { | ||
SubChildSchema, | ||
ChildSchema, | ||
ParentSchema | ||
ParentSchema, | ||
SimpleChildSchema, | ||
SimpleParentSchema, | ||
UniqueChildSchema, | ||
UniqueParentSchema, | ||
}; |
@@ -58,3 +58,3 @@ 'use strict'; | ||
Parent.testNewDoc(doc); | ||
doc = Parent.changeNewDoc(doc); | ||
doc = Parent.changeDoc(doc); | ||
@@ -69,3 +69,3 @@ await doc.save(); | ||
Parent.testNewDoc(doc); | ||
let mdf = Parent.changeNewDoc({}); | ||
let mdf = Parent.changeDoc({}); | ||
await Parent.updateOne({ _id: doc._id }, mdf); | ||
@@ -80,3 +80,3 @@ let editedDoc = await Parent.findById(doc._id); | ||
Parent.testNewDoc(doc); | ||
let mdf = Parent.changeNewDoc({}); | ||
let mdf = Parent.changeDoc({}); | ||
await Parent.update({ _id: doc._id }, mdf); | ||
@@ -91,3 +91,3 @@ let editedDoc = await Parent.findById(doc._id); | ||
Parent.testNewDoc(doc); | ||
let mdf = Parent.changeNewDoc({}); | ||
let mdf = Parent.changeDoc({}); | ||
await Parent.updateMany({ _id: doc._id }, mdf); | ||
@@ -104,3 +104,3 @@ let editedDoc = await Parent.findById(doc._id); | ||
Parent.testNewDoc(doc); | ||
let mdf = Parent.changeNewDoc({}); | ||
let mdf = Parent.changeDoc({}); | ||
let editedDoc = await Parent.findOneAndUpdate({ _id: doc._id }, mdf, { | ||
@@ -107,0 +107,0 @@ new: true, |
@@ -6,2 +6,3 @@ 'use strict'; | ||
should = chai.should(), | ||
expect = chai.expect, | ||
assert = require('assert'); | ||
@@ -12,3 +13,2 @@ | ||
const tellme = require('./../tellme'); | ||
/* Tests */ | ||
@@ -114,39 +114,106 @@ describe('Inline Docs', function() { | ||
it('Create/Save nested docs declared inline', async () => { | ||
let docs = []; | ||
for(let i=0;i<nIterations;i++){ | ||
docs[i] = await Inline.create(Inline.getNewDoc(i)); | ||
Inline.testNewDoc(doc,i); | ||
} | ||
for(let i=0;i<nIterations;i++){ | ||
docs[i] = Inline.changeDoc(docs[i],i); | ||
await docs[i].save(); | ||
Inline.testChangedDoc(docs[i],i); | ||
} | ||
let equalDocs = []; | ||
for(let i=0;i<nIterations;i++){ | ||
equalDocs[i] = Inline.changeDoc(docs[i],i); | ||
await equalDocs[i].save(); | ||
Inline.testChangedDoc(equalDocs[i],i); | ||
} | ||
expect(equalDocs).to.deep.equal(docs); | ||
}); | ||
it('UpdateOne nested docs declared inline', async () => { | ||
await Inline.updateOne({},Inline.getNewDoc(),{upsert:true}); | ||
let doc = await Inline.findOne({}); | ||
Inline.testNewDoc(doc); | ||
let docs = []; | ||
for(let i=0;i<nIterations;i++){ | ||
await Inline.updateOne({n:i},Inline.getNewDoc(n),{upsert:true}); | ||
docs[i] = await Inline.findOne({n:i}); | ||
Inline.testNewDoc(docs[i],i); | ||
} | ||
let mdf = Inline.changeDoc({}); | ||
await Inline.updateOne({ _id:doc._id }, mdf); | ||
let editedDoc = await Inline.findById(doc._id); | ||
Inline.testChangedDoc(editedDoc); | ||
for(let i=0;i<nIterations;i++){ | ||
await Inline.updateOne({ n:i }, mdf); | ||
docs[i] = await Inline.findOne({n:i}); | ||
Inline.testChangedDoc(docs[i],n); | ||
} | ||
let equalDocs=[]; | ||
for(let i=0;i<nIterations;i++){ | ||
await Inline.updateOne({ n:i }, mdf); | ||
equalDocs[i] = await Inline.findOne({n:i}); | ||
Inline.testChangedDoc(equalDocs[i],n); | ||
} | ||
expect(equalDocs).to.deep.equal(docs); | ||
}); | ||
it('Update nested docs declared inline', async () => { | ||
await Inline.update({},Inline.getNewDoc(),{upsert:true}); | ||
let doc = await Inline.findOne({}); | ||
Inline.testNewDoc(doc); | ||
let docs = []; | ||
for(let i=0;i<nIterations;i++){ | ||
await Inline.update({n:i},Inline.getNewDoc(n),{upsert:true}); | ||
docs[i] = await Inline.findOne({n:i}); | ||
Inline.testNewDoc(docs[i],i); | ||
} | ||
let mdf = Inline.changeDoc({}); | ||
await Inline.update({ _id:doc._id }, mdf); | ||
let editedDoc = await Inline.findById(doc._id); | ||
Inline.testChangedDoc(editedDoc); | ||
for(let i=0;i<nIterations;i++){ | ||
await Inline.update({ n:i }, mdf); | ||
docs[i] = await Inline.findOne({n:i}); | ||
Inline.testChangedDoc(docs[i],n); | ||
} | ||
let equalDocs=[]; | ||
for(let i=0;i<nIterations;i++){ | ||
await Inline.update({ n:i }, mdf); | ||
equalDocs[i] = await Inline.findOne({n:i}); | ||
Inline.testChangedDoc(equalDocs[i],n); | ||
} | ||
expect(equalDocs).to.deep.equal(docs); | ||
}); | ||
it('UpdateMany nested docs declared inline', async () => { | ||
await Inline.updateMany({},Inline.getNewDoc(),{upsert:true}); | ||
let doc = await Inline.findOne({}); | ||
Inline.testNewDoc(doc); | ||
let mdf = Inline.changeDoc({}); | ||
await Inline.updateMany({ _id:doc._id }, mdf); | ||
let editedDoc = await Inline.findById(doc._id); | ||
Inline.testChangedDoc(editedDoc); | ||
for(let i=0;i<nIterations;i++){ | ||
await Inline.updateMany({n:i},Inline.getNewDoc(n),{upsert:true}); | ||
} | ||
let docs = await Inline.find(); | ||
for(let i=0;i<nIterations;i++){ | ||
Inline.testNewDoc(docs[i],i); | ||
} | ||
let mdf = Inline.changeDocPaths({}); | ||
await Inline.updateMany({}, mdf); | ||
docs = await Inline.find(); | ||
for(let i=0;i<nIterations;i++){ | ||
Inline.testChangedDoc(docs[i],i); | ||
} | ||
await Inline.updateMany({}, mdf); | ||
let equalDocs=await Inline.find(); | ||
for(let i=0;i<nIterations;i++){ | ||
Inline.testChangedDoc(equalDocs[i],i); | ||
} | ||
expect(equalDocs).to.deep.equal(docs); | ||
}); | ||
it('findOneAndUpdate nested docs declared inline', async () => { | ||
let doc = await Inline.findOneAndUpdate({},Inline.getNewDoc(),{upsert:true,new:true}); | ||
Inline.testNewDoc(doc); | ||
let docs = []; | ||
for(let i=0;i<nIterations;i++){ | ||
docs[i] = await Inline.findOneAndUpdate({n:i},Inline.getNewDoc(i),{upsert:true,new:true}); | ||
Inline.testNewDoc(docs[i],i); | ||
} | ||
let mdf = Inline.changeDoc({}); | ||
let editedDoc = await Inline.findOneAndUpdate({ _id:doc._id }, mdf,{new:true}); | ||
Inline.testChangedDoc(editedDoc); | ||
for(let i=0;i<nIterations;i++){ | ||
docs[i] = await Inline.findOneAndUpdate({n:i}, mdf,{new:true}); | ||
Inline.testNewDoc(docs[i],i); | ||
} | ||
let equalDocs=[]; | ||
for(let i=0;i<nIterations;i++){ | ||
equalDocs[i] = await Inline.findOneAndUpdate({n:i}, mdf,{new:true}); | ||
Inline.testNewDoc(equalDocs[i],i); | ||
} | ||
expect(equalDocs).to.deep.equal(docs); | ||
}); | ||
}); |
@@ -29,11 +29,16 @@ 'use strict'; | ||
const regex = slug.map(s => new RegExp('^' + s + options.separator + '.+$')); | ||
const dummyRegex = slug.map(s => new RegExp('^' + s + '$')); | ||
function getCounterSlug(index, n) { | ||
return ( | ||
getSlug(index) + options.separator + _.padStart(n, slug_padding_size, '0') | ||
); | ||
if(n) | ||
return ( | ||
getSlug(index) + options.separator + _.padStart(n, slug_padding_size, '0') | ||
); | ||
return getSlug(index); | ||
} | ||
function getShortRegex(index) { | ||
return regex[index]; | ||
function getShortRegex(index,n) { | ||
if(n!==0) | ||
return regex[index]; | ||
return dummyRegex[index]; | ||
} | ||
@@ -40,0 +45,0 @@ |
'use strict'; | ||
const _ = require('lodash'); | ||
const mongoose = require('mongoose'), | ||
@@ -13,3 +15,3 @@ chai = require('chai'), | ||
GroupedUniqueShortId, | ||
} = require("./model"); | ||
} = require('./model'); | ||
@@ -19,3 +21,2 @@ const tellme = require('./tellme'); | ||
describe('Grouped Resources (Counter)', function() { | ||
@@ -35,6 +36,27 @@ before(async () => { | ||
group: 'group 1', | ||
children: [ | ||
{ | ||
title: tellme.getText(2), | ||
}, | ||
{ | ||
title: tellme.getText(2), | ||
}, | ||
], | ||
}); | ||
doc.should.have | ||
.property('uniqueSlug') | ||
.and.equal(tellme.getSlug(0)); | ||
doc.should.have.property('title').and.equal(tellme.getText(0, 0)); | ||
doc.should.have.nested | ||
.property('children[0].title') | ||
.and.equal(tellme.getText(2, 0)); | ||
doc.should.have.nested | ||
.property('children[1].title') | ||
.and.equal(tellme.getText(2, 0)); | ||
doc.should.have.property('uniqueSlug').and.equal(tellme.getSlug(0)); | ||
doc.should.have.nested | ||
.property('children[0].globalGroupSlug') | ||
.and.equal(tellme.getCounterSlug(2, 0)); | ||
doc.should.have.nested | ||
.property('children[1].globalGroupSlug') | ||
.and.equal(tellme.getCounterSlug(2, 0)); | ||
// console.log(doc); | ||
}); | ||
@@ -47,6 +69,28 @@ | ||
group: 'group 1', | ||
children: [ | ||
{ | ||
title: tellme.getText(2), | ||
}, | ||
{ | ||
title: tellme.getText(2), | ||
}, | ||
], | ||
}); | ||
doc.should.have.property('title').and.equal(tellme.getText(0, 1)); | ||
doc.should.have.nested | ||
.property('children[0].title') | ||
.and.equal(tellme.getText(2, 1)); | ||
doc.should.have.nested | ||
.property('children[1].title') | ||
.and.equal(tellme.getText(2, 1)); | ||
doc.should.have | ||
.property('uniqueSlug') | ||
.and.equal(tellme.getCounterSlug(0,1)); | ||
.and.equal(tellme.getCounterSlug(0, 1)); | ||
doc.should.have.nested | ||
.property('children[0].globalGroupSlug') | ||
.and.equal(tellme.getCounterSlug(2, 1)); | ||
doc.should.have.nested | ||
.property('children[1].globalGroupSlug') | ||
.and.equal(tellme.getCounterSlug(2, 1)); | ||
}); | ||
@@ -59,6 +103,26 @@ | ||
group: 'group 2', | ||
children: [ | ||
{ | ||
title: tellme.getText(2), | ||
}, | ||
{ | ||
title: tellme.getText(2), | ||
}, | ||
], | ||
}); | ||
doc.should.have | ||
.property('uniqueSlug') | ||
.and.equal(tellme.getSlug(0)); | ||
doc.should.have.property('title').and.equal(tellme.getText(0, 0)); | ||
doc.should.have.nested | ||
.property('children[0].title') | ||
.and.equal(tellme.getText(2, 0)); | ||
doc.should.have.nested | ||
.property('children[1].title') | ||
.and.equal(tellme.getText(2, 0)); | ||
doc.should.have.property('uniqueSlug').and.equal(tellme.getSlug(0)); | ||
doc.should.have.nested | ||
.property('children[0].globalGroupSlug') | ||
.and.equal(tellme.getCounterSlug(2, 0)); | ||
doc.should.have.nested | ||
.property('children[1].globalGroupSlug') | ||
.and.equal(tellme.getCounterSlug(2, 0)); | ||
}); | ||
@@ -71,6 +135,29 @@ | ||
group: 'group 2', | ||
children: [ | ||
{ | ||
title: tellme.getText(2), | ||
}, | ||
{ | ||
title: tellme.getText(2), | ||
}, | ||
], | ||
}); | ||
doc.should.have.property('title').and.equal(tellme.getText(0, 1)); | ||
doc.should.have.nested | ||
.property('children[0].title') | ||
.and.equal(tellme.getText(2, 1)); | ||
doc.should.have.nested | ||
.property('children[1].title') | ||
.and.equal(tellme.getText(2, 1)); | ||
doc.should.have | ||
.property('uniqueSlug') | ||
.and.equal(tellme.getCounterSlug(0,1)); | ||
.and.equal(tellme.getCounterSlug(0, 1)); | ||
doc.should.have.nested | ||
.property('children[0].globalGroupSlug') | ||
.and.equal(tellme.getCounterSlug(2, 1)); | ||
doc.should.have.nested | ||
.property('children[1].globalGroupSlug') | ||
.and.equal(tellme.getCounterSlug(2, 1)); | ||
}); | ||
@@ -81,11 +168,41 @@ | ||
group: 'group 2', | ||
uniqueSlug: tellme.getCounterSlug(0,1), | ||
uniqueSlug: tellme.getCounterSlug(0, 1), | ||
}); | ||
doc.should.have.property('title').and.equal(tellme.getText(0, 1)); | ||
doc.should.have.nested | ||
.property('children[0].title') | ||
.and.equal(tellme.getText(2, 1)); | ||
doc.should.have.nested | ||
.property('children[1].title') | ||
.and.equal(tellme.getText(2, 1)); | ||
doc.should.have | ||
.property('uniqueSlug') | ||
.and.equal(tellme.getCounterSlug(0, 1)); | ||
doc.should.have.nested | ||
.property('children[0].globalGroupSlug') | ||
.and.equal(tellme.getCounterSlug(2, 1)); | ||
doc.should.have.nested | ||
.property('children[1].globalGroupSlug') | ||
.and.equal(tellme.getCounterSlug(2, 1)); | ||
doc.group = 'group 1'; | ||
doc = await doc.save(); | ||
// let docs = await GroupedUniqueCounter.find(); | ||
// console.log("grouped docs",docs); | ||
doc.should.have.property('title').and.equal(tellme.getText(0, 2)); | ||
doc.should.have.nested | ||
.property('children[0].title') | ||
.and.equal(tellme.getText(2, 2)); | ||
doc.should.have.nested | ||
.property('children[1].title') | ||
.and.equal(tellme.getText(2, 2)); | ||
doc.should.have | ||
.property('uniqueSlug') | ||
.and.equal(tellme.getCounterSlug(0,2)); | ||
.and.equal(tellme.getCounterSlug(0, 2)); | ||
doc.should.have.nested | ||
.property('children[0].globalGroupSlug') | ||
.and.equal(tellme.getCounterSlug(2, 2)); | ||
doc.should.have.nested | ||
.property('children[1].globalGroupSlug') | ||
.and.equal(tellme.getCounterSlug(2, 2)); | ||
}); | ||
@@ -98,13 +215,51 @@ | ||
group: 'group 2', | ||
children: [ | ||
{ | ||
title: tellme.getText(2), | ||
}, | ||
{ | ||
title: tellme.getText(2), | ||
}, | ||
], | ||
}); | ||
doc.should.have.property('title').and.equal(tellme.getText(0, 1)); | ||
doc.should.have.nested | ||
.property('children[0].title') | ||
.and.equal(tellme.getText(2, 1)); | ||
doc.should.have.nested | ||
.property('children[1].title') | ||
.and.equal(tellme.getText(2, 1)); | ||
doc.should.have | ||
.property('uniqueSlug') | ||
.and.equal(tellme.getCounterSlug(0,1)); | ||
.and.equal(tellme.getCounterSlug(0, 1)); | ||
doc.should.have.nested | ||
.property('children[0].globalGroupSlug') | ||
.and.equal(tellme.getCounterSlug(2, 1)); | ||
doc.should.have.nested | ||
.property('children[1].globalGroupSlug') | ||
.and.equal(tellme.getCounterSlug(2, 1)); | ||
// console.log("---------------updateOne group"); | ||
await GroupedUniqueCounter.updateOne({ _id: doc.id }, { group: 'group 1' }); | ||
let editedDoc = await GroupedUniqueCounter.findById(doc.id); | ||
await GroupedUniqueCounter.updateOne( | ||
{ _id: doc._id }, | ||
{ $set: { group: 'group 1' } } | ||
); | ||
let editedDoc = await GroupedUniqueCounter.findById(doc._id); | ||
editedDoc.should.have.property('title').and.equal(tellme.getText(0, 3)); | ||
editedDoc.should.have.nested | ||
.property('children[0].title') | ||
.and.equal(tellme.getText(2, 3)); | ||
editedDoc.should.have.nested | ||
.property('children[1].title') | ||
.and.equal(tellme.getText(2, 3)); | ||
editedDoc.should.have | ||
.property('uniqueSlug') | ||
.and.equal(tellme.getCounterSlug(0,3)); | ||
.and.equal(tellme.getCounterSlug(0, 3)); | ||
editedDoc.should.have.nested | ||
.property('children[0].globalGroupSlug') | ||
.and.equal(tellme.getCounterSlug(2, 3)); | ||
editedDoc.should.have.nested | ||
.property('children[1].globalGroupSlug') | ||
.and.equal(tellme.getCounterSlug(2, 3)); | ||
}); | ||
@@ -115,9 +270,41 @@ | ||
group: 'group 1', | ||
uniqueSlug: tellme.getCounterSlug(0,2), | ||
uniqueSlug: tellme.getCounterSlug(0, 2), | ||
}); | ||
doc.should.have.property('title').and.equal(tellme.getText(0, 2)); | ||
doc.should.have.nested | ||
.property('children[0].title') | ||
.and.equal(tellme.getText(2, 2)); | ||
doc.should.have.nested | ||
.property('children[1].title') | ||
.and.equal(tellme.getText(2, 2)); | ||
doc.should.have | ||
.property('uniqueSlug') | ||
.and.equal(tellme.getCounterSlug(0, 2)); | ||
doc.should.have.nested | ||
.property('children[0].globalGroupSlug') | ||
.and.equal(tellme.getCounterSlug(2, 2)); | ||
doc.should.have.nested | ||
.property('children[1].globalGroupSlug') | ||
.and.equal(tellme.getCounterSlug(2, 2)); | ||
doc.group = 'group 3'; | ||
doc = await doc.save(); | ||
doc.should.have | ||
.property('uniqueSlug') | ||
.and.equal(tellme.getSlug(0)); | ||
doc.should.have.property('title').and.equal(tellme.getText(0, 0)); | ||
doc.should.have.nested | ||
.property('children[0].title') | ||
.and.equal(tellme.getText(2, 0)); | ||
doc.should.have.nested | ||
.property('children[1].title') | ||
.and.equal(tellme.getText(2, 0)); | ||
doc.should.have.property('uniqueSlug').and.equal(tellme.getSlug(0)); | ||
doc.should.have.nested | ||
.property('children[0].globalGroupSlug') | ||
.and.equal(tellme.getCounterSlug(2, 0)); | ||
doc.should.have.nested | ||
.property('children[1].globalGroupSlug') | ||
.and.equal(tellme.getCounterSlug(2, 0)); | ||
}); | ||
@@ -128,14 +315,46 @@ | ||
group: 'group 1', | ||
uniqueSlug: tellme.getCounterSlug(0,3), | ||
uniqueSlug: tellme.getCounterSlug(0, 3), | ||
}); | ||
await GroupedUniqueCounter.updateOne({ _id: doc.id }, { group: 'group 4' }); | ||
let editedDoc = await GroupedUniqueCounter.findById(doc.id); | ||
editedDoc.should.have | ||
doc.should.have.property('title').and.equal(tellme.getText(0, 3)); | ||
doc.should.have.nested | ||
.property('children[0].title') | ||
.and.equal(tellme.getText(2, 3)); | ||
doc.should.have.nested | ||
.property('children[1].title') | ||
.and.equal(tellme.getText(2, 3)); | ||
doc.should.have | ||
.property('uniqueSlug') | ||
.and.equal(tellme.getSlug(0)); | ||
}); | ||
}); | ||
.and.equal(tellme.getCounterSlug(0, 3)); | ||
doc.should.have.nested | ||
.property('children[0].globalGroupSlug') | ||
.and.equal(tellme.getCounterSlug(2, 3)); | ||
doc.should.have.nested | ||
.property('children[1].globalGroupSlug') | ||
.and.equal(tellme.getCounterSlug(2, 3)); | ||
await GroupedUniqueCounter.updateOne( | ||
{ _id: doc._id }, | ||
{ group: 'group 4' } | ||
); | ||
let editedDoc = await GroupedUniqueCounter.findById(doc._id); | ||
doc.should.have.property('title').and.equal(tellme.getText(0, 0)); | ||
doc.should.have.nested | ||
.property('children[0].title') | ||
.and.equal(tellme.getText(2, 0)); | ||
doc.should.have.nested | ||
.property('children[1].title') | ||
.and.equal(tellme.getText(2, 0)); | ||
editedDoc.should.have.property('uniqueSlug').and.equal(tellme.getSlug(0)); | ||
editedDoc.should.have.nested | ||
.property('children[0].globalGroupSlug') | ||
.and.equal(tellme.getCounterSlug(2, 0)); | ||
editedDoc.should.have.nested | ||
.property('children[1].globalGroupSlug') | ||
.and.equal(tellme.getCounterSlug(2, 0)); | ||
}); | ||
}); | ||
@@ -156,6 +375,28 @@ describe('Grouped Resources (ShortId)', function() { | ||
group: 'group 1', | ||
children: [ | ||
{ | ||
title: tellme.getText(2), | ||
}, | ||
{ | ||
title: tellme.getText(2), | ||
}, | ||
], | ||
}); | ||
doc.should.have.property('title').and.equal(tellme.getText(0)); | ||
doc.should.have.nested | ||
.property('children[0].title') | ||
.and.equal(tellme.getText(2)); | ||
doc.should.have.nested | ||
.property('children[1].title') | ||
.and.equal(tellme.getText(2)); | ||
doc.should.have | ||
.property('uniqueSlug') | ||
.and.equal(tellme.getSlug(0)); | ||
.and.match(tellme.getShortRegex(0, 0)); | ||
doc.should.have.nested | ||
.property('children[0].globalGroupSlug') | ||
.and.match(tellme.getShortRegex(2, 0)); | ||
doc.should.have.nested | ||
.property('children[1].globalGroupSlug') | ||
.and.match(tellme.getShortRegex(2, 0)); | ||
}); | ||
@@ -168,6 +409,28 @@ | ||
group: 'group 1', | ||
children: [ | ||
{ | ||
title: tellme.getText(2), | ||
}, | ||
{ | ||
title: tellme.getText(2), | ||
}, | ||
], | ||
}); | ||
doc.should.have.property('title').and.equal(tellme.getText(0)); | ||
doc.should.have.nested | ||
.property('children[0].title') | ||
.and.equal(tellme.getText(2)); | ||
doc.should.have.nested | ||
.property('children[1].title') | ||
.and.equal(tellme.getText(2)); | ||
doc.should.have | ||
.property('uniqueSlug') | ||
.and.match(tellme.getShortRegex(0)); | ||
.and.match(tellme.getShortRegex(0, 1)); | ||
doc.should.have.nested | ||
.property('children[0].globalGroupSlug') | ||
.and.match(tellme.getShortRegex(2, 1)); | ||
doc.should.have.nested | ||
.property('children[1].globalGroupSlug') | ||
.and.match(tellme.getShortRegex(2, 1)); | ||
}); | ||
@@ -180,6 +443,28 @@ | ||
group: 'group 2', | ||
children: [ | ||
{ | ||
title: tellme.getText(2), | ||
}, | ||
{ | ||
title: tellme.getText(2), | ||
}, | ||
], | ||
}); | ||
doc.should.have.property('title').and.equal(tellme.getText(0)); | ||
doc.should.have.nested | ||
.property('children[0].title') | ||
.and.equal(tellme.getText(2)); | ||
doc.should.have.nested | ||
.property('children[1].title') | ||
.and.equal(tellme.getText(2)); | ||
doc.should.have | ||
.property('uniqueSlug') | ||
.and.equal(tellme.getSlug(0)); | ||
.and.match(tellme.getShortRegex(0, 0)); | ||
doc.should.have.nested | ||
.property('children[0].globalGroupSlug') | ||
.and.match(tellme.getShortRegex(2, 0)); | ||
doc.should.have.nested | ||
.property('children[1].globalGroupSlug') | ||
.and.match(tellme.getShortRegex(2, 0)); | ||
}); | ||
@@ -193,6 +478,28 @@ | ||
otherField: 'to move in group 1', | ||
children: [ | ||
{ | ||
title: tellme.getText(2), | ||
}, | ||
{ | ||
title: tellme.getText(2), | ||
}, | ||
], | ||
}); | ||
doc.should.have.property('title').and.equal(tellme.getText(0)); | ||
doc.should.have.nested | ||
.property('children[0].title') | ||
.and.equal(tellme.getText(2)); | ||
doc.should.have.nested | ||
.property('children[1].title') | ||
.and.equal(tellme.getText(2)); | ||
doc.should.have | ||
.property('uniqueSlug') | ||
.and.match(tellme.getShortRegex(0)); | ||
.and.match(tellme.getShortRegex(0, 1)); | ||
doc.should.have.nested | ||
.property('children[0].globalGroupSlug') | ||
.and.match(tellme.getShortRegex(2, 1)); | ||
doc.should.have.nested | ||
.property('children[1].globalGroupSlug') | ||
.and.match(tellme.getShortRegex(2, 1)); | ||
}); | ||
@@ -207,11 +514,20 @@ | ||
let uniqueSlug = doc.uniqueSlug; | ||
let existingSlug = await GroupedUniqueShortId.findOne({ | ||
let globalGroupSlug0 = doc.children[0].globalGroupSlug; | ||
let globalGroupSlug1 = doc.children[1].globalGroupSlug; | ||
let existingDocs = await GroupedUniqueShortId.find({ | ||
group: 'group 1', | ||
uniqueSlug, | ||
}); | ||
// console.log('exists', existingSlug); | ||
let uniqueSlugExists = _.some(existingDocs, ['uniqueSlug', uniqueSlug]); | ||
let globalGroupSlug0Exists = | ||
_.some(existingDocs, ['children[0].globalGroupSlug', globalGroupSlug0]) || | ||
_.some(existingDocs, ['children[1].globalGroupSlug', globalGroupSlug0]); | ||
let globalGroupSlug1Exists = | ||
_.some(existingDocs, ['children[0].globalGroupSlug', globalGroupSlug1]) || | ||
_.some(existingDocs, ['children[1].globalGroupSlug', globalGroupSlug1]); | ||
doc = await doc.save(); | ||
if (!existingSlug) | ||
if (!uniqueSlugExists) { | ||
doc.should.have.property('uniqueSlug').and.equal(uniqueSlug); | ||
else | ||
} else{ | ||
doc.should.have | ||
@@ -221,2 +537,21 @@ .property('uniqueSlug') | ||
.and.not.equal(uniqueSlug); | ||
} | ||
if(!globalGroupSlug0Exists){ | ||
doc.should.have.nested | ||
.property('children[0].globalGroupSlug') | ||
.and.equal(globalGroupSlug0); | ||
}else{ | ||
doc.should.have.nested.property('children[0].globalGroupSlug') | ||
.and.match(tellme.getShortRegex(2)) | ||
.and.not.equal(globalGroupSlug0Exists); | ||
} | ||
if(!globalGroupSlug1Exists){ | ||
doc.should.have.nested | ||
.property('children[1].globalGroupSlug') | ||
.and.equal(globalGroupSlug1); | ||
}else{ | ||
doc.should.have.nested.property('children[1].globalGroupSlug') | ||
.and.match(tellme.getShortRegex(2)) | ||
.and.not.equal(globalGroupSlug1Exists); | ||
} | ||
}); | ||
@@ -229,20 +564,71 @@ | ||
group: 'group 2', | ||
children: [ | ||
{ | ||
title: tellme.getText(2), | ||
}, | ||
{ | ||
title: tellme.getText(2), | ||
}, | ||
], | ||
}); | ||
doc.should.have | ||
.property('uniqueSlug') | ||
.and.match(tellme.getShortRegex(0)); | ||
doc.should.have.property('uniqueSlug').and.match(tellme.getShortRegex(0)); | ||
doc.should.have.nested | ||
.property('children[0].title') | ||
.and.equal(tellme.getText(2)); | ||
doc.should.have.nested | ||
.property('children[1].title') | ||
.and.equal(tellme.getText(2)); | ||
let existingSlug = await GroupedUniqueShortId.findOne({ | ||
let uniqueSlug = doc.uniqueSlug; | ||
let globalGroupSlug0 = doc.children[0].globalGroupSlug; | ||
let globalGroupSlug1 = doc.children[1].globalGroupSlug; | ||
let existingDocs = await GroupedUniqueShortId.find({ | ||
group: 'group 1', | ||
uniqueSlug: doc.uniqueSlug, | ||
}); | ||
await GroupedUniqueShortId.updateOne({ _id: doc.id }, { group: 'group 1' }); | ||
let editedDoc = await GroupedUniqueShortId.findById(doc.id); | ||
if (!existingSlug) | ||
editedDoc.should.have.property('uniqueSlug').and.equal(doc.uniqueSlug); | ||
else | ||
editedDoc.should.have | ||
let uniqueSlugExists = _.some(existingDocs, ['uniqueSlug', uniqueSlug]); | ||
let globalGroupSlug0Exists = | ||
_.some(existingDocs, ['children[0].globalGroupSlug', globalGroupSlug0]) || | ||
_.some(existingDocs, ['children[1].globalGroupSlug', globalGroupSlug0]); | ||
let globalGroupSlug1Exists = | ||
_.some(existingDocs, ['children[0].globalGroupSlug', globalGroupSlug1]) || | ||
_.some(existingDocs, ['children[1].globalGroupSlug', globalGroupSlug1]); | ||
await GroupedUniqueShortId.updateOne( | ||
{ _id: doc._id }, | ||
{$set:{ group: 'group 1' }} | ||
); | ||
doc = await GroupedUniqueShortId.findById(doc._id); | ||
doc.should.have.property('title').and.equal(tellme.getText(0)); | ||
doc.should.have.nested | ||
.property('children[0].title') | ||
.and.equal(tellme.getText(2)); | ||
doc.should.have.nested | ||
.property('children[1].title') | ||
.and.equal(tellme.getText(2)); | ||
if (!uniqueSlugExists) { | ||
doc.should.have.property('uniqueSlug').and.equal(uniqueSlug); | ||
} else{ | ||
doc.should.have | ||
.property('uniqueSlug') | ||
.and.match(tellme.getShortRegex(0)) | ||
.and.not.equal(doc.uniqueSlug); | ||
.and.not.equal(uniqueSlug); | ||
} | ||
if(!globalGroupSlug0Exists){ | ||
doc.should.have.nested | ||
.property('children[0].globalGroupSlug') | ||
.and.equal(globalGroupSlug0); | ||
}else{ | ||
doc.should.have.nested.property('children[0].globalGroupSlug') | ||
.and.match(tellme.getShortRegex(2)) | ||
.and.not.equal(globalGroupSlug0Exists); | ||
} | ||
if(!globalGroupSlug1Exists){ | ||
doc.should.have.nested | ||
.property('children[1].globalGroupSlug') | ||
.and.equal(globalGroupSlug1); | ||
}else{ | ||
doc.should.have.nested.property('children[1].globalGroupSlug') | ||
.and.match(tellme.getShortRegex(2)) | ||
.and.not.equal(globalGroupSlug1Exists); | ||
} | ||
}); | ||
@@ -259,5 +645,19 @@ | ||
doc = await doc.save(); | ||
doc.should.have.property('title').and.equal(tellme.getText(0)); | ||
doc.should.have.nested | ||
.property('children[0].title') | ||
.and.equal(tellme.getText(2)); | ||
doc.should.have.nested | ||
.property('children[1].title') | ||
.and.equal(tellme.getText(2)); | ||
doc.should.have | ||
.property('uniqueSlug') | ||
.and.equal(tellme.getSlug(0)); | ||
.and.match(tellme.getShortRegex(0, 0)); | ||
doc.should.have.nested | ||
.property('children[0].globalGroupSlug') | ||
.and.match(tellme.getShortRegex(2, 0)); | ||
doc.should.have.nested | ||
.property('children[1].globalGroupSlug') | ||
.and.match(tellme.getShortRegex(2, 0)); | ||
}); | ||
@@ -270,8 +670,25 @@ | ||
}); | ||
await GroupedUniqueShortId.updateOne({ _id: doc.id }, { group: 'group 4' }); | ||
let editedDoc = await GroupedUniqueShortId.findById(doc.id); | ||
editedDoc.should.have | ||
await GroupedUniqueShortId.updateOne( | ||
{ _id: doc._id }, | ||
{$set:{ group: 'group 4' }} | ||
); | ||
doc = await GroupedUniqueShortId.findById(doc._id); | ||
doc.should.have.property('title').and.equal(tellme.getText(0)); | ||
doc.should.have.nested | ||
.property('children[0].title') | ||
.and.equal(tellme.getText(2)); | ||
doc.should.have.nested | ||
.property('children[1].title') | ||
.and.equal(tellme.getText(2)); | ||
doc.should.have | ||
.property('uniqueSlug') | ||
.and.equal(tellme.getSlug(0)); | ||
.and.match(tellme.getShortRegex(0, 0)); | ||
doc.should.have.nested | ||
.property('children[0].globalGroupSlug') | ||
.and.match(tellme.getShortRegex(2, 0)); | ||
doc.should.have.nested | ||
.property('children[1].globalGroupSlug') | ||
.and.match(tellme.getShortRegex(2, 0)); | ||
}); | ||
}); | ||
}); |
181682
25
4463
524