mirror of
https://github.com/TryGhost/Ghost.git
synced 2025-01-04 17:04:59 +03:00
Merge pull request #6920 from ErisDS/tag-save-fix
Fix post model deletes tags when editing post only
This commit is contained in:
commit
cf0835c829
@ -141,7 +141,8 @@ Post = ghostBookshelf.Model.extend({
|
||||
prevTitle = this._previousAttributes.title,
|
||||
prevSlug = this._previousAttributes.slug,
|
||||
tagsToCheck = this.get('tags'),
|
||||
publishedAt = this.get('published_at');
|
||||
publishedAt = this.get('published_at'),
|
||||
tags = [];
|
||||
|
||||
// both page and post can get scheduled
|
||||
if (newStatus === 'scheduled') {
|
||||
@ -164,18 +165,22 @@ Post = ghostBookshelf.Model.extend({
|
||||
}
|
||||
}
|
||||
|
||||
// keep tags for 'saved' event and deduplicate upper/lowercase tags
|
||||
this.myTags = [];
|
||||
|
||||
_.each(tagsToCheck, function each(item) {
|
||||
for (i = 0; i < self.myTags.length; i = i + 1) {
|
||||
if (self.myTags[i].name.toLocaleLowerCase() === item.name.toLocaleLowerCase()) {
|
||||
return;
|
||||
// If we have a tags property passed in
|
||||
if (!_.isUndefined(tagsToCheck) && !_.isNull(tagsToCheck)) {
|
||||
// and deduplicate upper/lowercase tags
|
||||
_.each(tagsToCheck, function each(item) {
|
||||
for (i = 0; i < tags.length; i = i + 1) {
|
||||
if (tags[i].name.toLocaleLowerCase() === item.name.toLocaleLowerCase()) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
self.myTags.push(item);
|
||||
});
|
||||
tags.push(item);
|
||||
});
|
||||
|
||||
// keep tags for 'saved' event
|
||||
this.tagsToSave = tags;
|
||||
}
|
||||
|
||||
ghostBookshelf.Model.prototype.saving.call(this, model, attr, options);
|
||||
|
||||
@ -252,7 +257,12 @@ Post = ghostBookshelf.Model.extend({
|
||||
* @return {Promise(ghostBookshelf.Models.Post)} Updated Post model
|
||||
*/
|
||||
updateTags: function updateTags(savedModel, response, options) {
|
||||
var newTags = this.myTags,
|
||||
if (_.isUndefined(this.tagsToSave)) {
|
||||
// The tag property was not set, so we shouldn't be doing any playing with tags on this request
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
var newTags = this.tagsToSave,
|
||||
TagModel = ghostBookshelf.model('Tag');
|
||||
|
||||
options = options || {};
|
||||
|
@ -584,4 +584,161 @@ describe('Post API', function () {
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('Edit', function () {
|
||||
// These tests are for #6920
|
||||
it('should update post & not delete tags with `tags` not included', function (done) {
|
||||
var options = {context: {user: 1}, id: 1},
|
||||
includeOptions = {include: 'tags'},
|
||||
startTags;
|
||||
|
||||
// Step 1, fetch a post from the API with tags
|
||||
PostAPI.read(_.extend({}, options, includeOptions)).then(function (results) {
|
||||
var postWithoutTags = results.posts[0];
|
||||
should.exist(results.posts[0]);
|
||||
should.exist(results.posts[0].tags);
|
||||
results.posts[0].tags.should.have.lengthOf(2);
|
||||
|
||||
// Save the tags for testing against later
|
||||
startTags = _.clone(results.posts[0].tags);
|
||||
|
||||
// Remove the tags from the object we're sending - we'll send no `tags` property at all
|
||||
delete postWithoutTags.tags;
|
||||
|
||||
// Update a single property so we can see the post does get updated
|
||||
postWithoutTags.title = 'HTML Ipsum Updated';
|
||||
|
||||
// Step 2, call edit but don't include tags in the response
|
||||
return PostAPI.edit({posts: [postWithoutTags]}, options);
|
||||
}).then(function (results) {
|
||||
should.exist(results.posts[0]);
|
||||
should.not.exist(results.posts[0].tags);
|
||||
results.posts[0].title.should.eql('HTML Ipsum Updated');
|
||||
|
||||
// Step 3, request the post with its tags again, to check they are still present
|
||||
return PostAPI.read(_.extend({}, options, includeOptions));
|
||||
}).then(function (results) {
|
||||
should.exist(results.posts[0]);
|
||||
should.exist(results.posts[0].tags);
|
||||
results.posts[0].tags.should.have.lengthOf(2);
|
||||
results.posts[0].tags.should.eql(startTags);
|
||||
|
||||
done();
|
||||
}).catch(done);
|
||||
});
|
||||
|
||||
it('should update post & not delete tags with `tags` set to undefined', function (done) {
|
||||
var options = {context: {user: 1}, id: 1},
|
||||
includeOptions = {include: 'tags'},
|
||||
startTags;
|
||||
|
||||
// Step 1, fetch a post from the API with tags
|
||||
PostAPI.read(_.extend({}, options, includeOptions)).then(function (results) {
|
||||
var postWithoutTags = results.posts[0];
|
||||
should.exist(results.posts[0]);
|
||||
should.exist(results.posts[0].tags);
|
||||
results.posts[0].tags.should.have.lengthOf(2);
|
||||
|
||||
// Save the tags for testing against later
|
||||
startTags = _.clone(results.posts[0].tags);
|
||||
|
||||
// Remove the tags from the object we're sending - we'll send no `tags` property at all
|
||||
postWithoutTags.tags = undefined;
|
||||
|
||||
// Update a single property so we can see the post does get updated
|
||||
postWithoutTags.title = 'HTML Ipsum Updated';
|
||||
|
||||
// Step 2, call edit but don't include tags in the response
|
||||
return PostAPI.edit({posts: [postWithoutTags]}, options);
|
||||
}).then(function (results) {
|
||||
should.exist(results.posts[0]);
|
||||
should.not.exist(results.posts[0].tags);
|
||||
results.posts[0].title.should.eql('HTML Ipsum Updated');
|
||||
|
||||
// Step 3, request the post with its tags again, to check they are still present
|
||||
return PostAPI.read(_.extend({}, options, includeOptions));
|
||||
}).then(function (results) {
|
||||
should.exist(results.posts[0]);
|
||||
should.exist(results.posts[0].tags);
|
||||
results.posts[0].tags.should.have.lengthOf(2);
|
||||
results.posts[0].tags.should.eql(startTags);
|
||||
|
||||
done();
|
||||
}).catch(done);
|
||||
});
|
||||
|
||||
it('should update post & not delete tags with `tags` set to null', function (done) {
|
||||
var options = {context: {user: 1}, id: 1},
|
||||
includeOptions = {include: 'tags'},
|
||||
startTags;
|
||||
|
||||
// Step 1, fetch a post from the API with tags
|
||||
PostAPI.read(_.extend({}, options, includeOptions)).then(function (results) {
|
||||
var postWithoutTags = results.posts[0];
|
||||
should.exist(results.posts[0]);
|
||||
should.exist(results.posts[0].tags);
|
||||
results.posts[0].tags.should.have.lengthOf(2);
|
||||
|
||||
// Save the tags for testing against later
|
||||
startTags = _.clone(results.posts[0].tags);
|
||||
|
||||
// Remove the tags from the object we're sending - we'll send no `tags` property at all
|
||||
postWithoutTags.tags = null;
|
||||
|
||||
// Update a single property so we can see the post does get updated
|
||||
postWithoutTags.title = 'HTML Ipsum Updated';
|
||||
|
||||
// Step 2, call edit but don't include tags in the response
|
||||
return PostAPI.edit({posts: [postWithoutTags]}, options);
|
||||
}).then(function (results) {
|
||||
should.exist(results.posts[0]);
|
||||
should.not.exist(results.posts[0].tags);
|
||||
results.posts[0].title.should.eql('HTML Ipsum Updated');
|
||||
|
||||
// Step 3, request the post with its tags again, to check they are still present
|
||||
return PostAPI.read(_.extend({}, options, includeOptions));
|
||||
}).then(function (results) {
|
||||
should.exist(results.posts[0]);
|
||||
should.exist(results.posts[0].tags);
|
||||
results.posts[0].tags.should.have.lengthOf(2);
|
||||
results.posts[0].tags.should.eql(startTags);
|
||||
|
||||
done();
|
||||
}).catch(done);
|
||||
});
|
||||
|
||||
it('should update post & should delete tags with `tags` set to []', function (done) {
|
||||
var options = {context: {user: 1}, id: 1},
|
||||
includeOptions = {include: 'tags'};
|
||||
|
||||
// Step 1, fetch a post from the API with tags
|
||||
PostAPI.read(_.extend({}, options, includeOptions)).then(function (results) {
|
||||
var postWithoutTags = results.posts[0];
|
||||
should.exist(results.posts[0]);
|
||||
should.exist(results.posts[0].tags);
|
||||
results.posts[0].tags.should.have.lengthOf(2);
|
||||
|
||||
// Remove the tags from the object we're sending - we'll send no `tags` property at all
|
||||
postWithoutTags.tags = [];
|
||||
|
||||
// Update a single property so we can see the post does get updated
|
||||
postWithoutTags.title = 'HTML Ipsum Updated';
|
||||
|
||||
// Step 2, call edit but don't include tags in the response
|
||||
return PostAPI.edit({posts: [postWithoutTags]}, options);
|
||||
}).then(function (results) {
|
||||
should.exist(results.posts[0]);
|
||||
should.not.exist(results.posts[0].tags);
|
||||
results.posts[0].title.should.eql('HTML Ipsum Updated');
|
||||
|
||||
// Step 3, request the post with its tags again, to check they are still present
|
||||
return PostAPI.read(_.extend({}, options, includeOptions));
|
||||
}).then(function (results) {
|
||||
should.exist(results.posts[0]);
|
||||
results.posts[0].tags.should.eql([]);
|
||||
|
||||
done();
|
||||
}).catch(done);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -3,39 +3,47 @@ var testUtils = require('../../utils'),
|
||||
should = require('should'),
|
||||
moment = require('moment'),
|
||||
_ = require('lodash'),
|
||||
Promise = require('bluebird'),
|
||||
sinon = require('sinon'),
|
||||
|
||||
// Stuff we are testing
|
||||
sequence = require('../../../server/utils/sequence'),
|
||||
ghostBookshelf = require('../../../server/models/base'),
|
||||
PostModel = require('../../../server/models/post').Post,
|
||||
TagModel = require('../../../server/models/tag').Tag,
|
||||
events = require('../../../server/events'),
|
||||
errors = require('../../../server/errors'),
|
||||
DataGenerator = testUtils.DataGenerator,
|
||||
context = testUtils.context.owner,
|
||||
sandbox = sinon.sandbox.create(),
|
||||
|
||||
config = require('../../../server/config'),
|
||||
origConfig = _.cloneDeep(config);
|
||||
configUtils = require('../../utils/configUtils'),
|
||||
|
||||
sandbox = sinon.sandbox.create();
|
||||
|
||||
describe('Post Model', function () {
|
||||
var eventSpy;
|
||||
|
||||
// Keep the DB clean
|
||||
before(testUtils.teardown);
|
||||
afterEach(testUtils.teardown);
|
||||
|
||||
beforeEach(function () {
|
||||
eventSpy = sandbox.spy(events, 'emit');
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
sandbox.restore();
|
||||
});
|
||||
|
||||
should.exist(TagModel);
|
||||
should.exist(PostModel);
|
||||
|
||||
describe('Single author posts', function () {
|
||||
var eventSpy;
|
||||
|
||||
before(testUtils.teardown);
|
||||
afterEach(testUtils.teardown);
|
||||
afterEach(function () {
|
||||
sandbox.restore();
|
||||
config.set(origConfig);
|
||||
configUtils.restore();
|
||||
});
|
||||
beforeEach(testUtils.setup('owner', 'posts', 'apps'));
|
||||
|
||||
beforeEach(function () {
|
||||
should.exist(PostModel);
|
||||
eventSpy = sandbox.spy(events, 'emit');
|
||||
});
|
||||
beforeEach(testUtils.setup('owner', 'posts', 'apps'));
|
||||
|
||||
function extractFirstPost(posts) {
|
||||
return _.filter(posts, {id: 1})[0];
|
||||
@ -61,7 +69,7 @@ describe('Post Model', function () {
|
||||
|
||||
describe('findAll', function () {
|
||||
beforeEach(function () {
|
||||
config.set({theme: {
|
||||
configUtils.set({theme: {
|
||||
permalinks: '/:slug/'
|
||||
}});
|
||||
});
|
||||
@ -96,7 +104,7 @@ describe('Post Model', function () {
|
||||
|
||||
describe('findPage', function () {
|
||||
beforeEach(function () {
|
||||
config.set({theme: {
|
||||
configUtils.set({theme: {
|
||||
permalinks: '/:slug/'
|
||||
}});
|
||||
});
|
||||
@ -287,7 +295,7 @@ describe('Post Model', function () {
|
||||
|
||||
describe('findOne', function () {
|
||||
beforeEach(function () {
|
||||
config.set({theme: {
|
||||
configUtils.set({theme: {
|
||||
permalinks: '/:slug/'
|
||||
}});
|
||||
});
|
||||
@ -345,7 +353,7 @@ describe('Post Model', function () {
|
||||
yyyy = today.getFullYear(),
|
||||
postLink = '/' + yyyy + '/' + mm + '/' + dd + '/html-ipsum/';
|
||||
|
||||
config.set({theme: {
|
||||
configUtils.set({theme: {
|
||||
permalinks: '/:year/:month/:day/:slug/'
|
||||
}});
|
||||
|
||||
@ -1316,10 +1324,6 @@ describe('Post Model', function () {
|
||||
afterEach(testUtils.teardown);
|
||||
beforeEach(testUtils.setup('posts:mu'));
|
||||
|
||||
before(function () {
|
||||
should.exist(PostModel);
|
||||
});
|
||||
|
||||
it('can destroy multiple posts by author', function (done) {
|
||||
// We're going to delete all posts by user 1
|
||||
var authorData = {id: 1};
|
||||
@ -1340,6 +1344,892 @@ describe('Post Model', function () {
|
||||
});
|
||||
});
|
||||
|
||||
describe('Post tag handling', function () {
|
||||
beforeEach(testUtils.setup());
|
||||
|
||||
describe('Post with tags', function () {
|
||||
var postJSON,
|
||||
tagJSON,
|
||||
editOptions,
|
||||
createTag = testUtils.DataGenerator.forKnex.createTag;
|
||||
|
||||
beforeEach(function (done) {
|
||||
tagJSON = [];
|
||||
|
||||
var post = _.cloneDeep(testUtils.DataGenerator.forModel.posts[0]),
|
||||
postTags = [
|
||||
createTag({name: 'tag1'}),
|
||||
createTag({name: 'tag2'}),
|
||||
createTag({name: 'tag3'})
|
||||
],
|
||||
extraTags = [
|
||||
createTag({name: 'existing tag a'}),
|
||||
createTag({name: 'existing-tag-b'}),
|
||||
createTag({name: 'existing_tag_c'})
|
||||
];
|
||||
|
||||
post.tags = postTags;
|
||||
post.status = 'published';
|
||||
|
||||
return Promise.props({
|
||||
post: PostModel.add(post, _.extend({}, context, {withRelated: ['tags']})),
|
||||
tag1: TagModel.add(extraTags[0], context),
|
||||
tag2: TagModel.add(extraTags[1], context),
|
||||
tag3: TagModel.add(extraTags[2], context)
|
||||
}).then(function (result) {
|
||||
postJSON = result.post.toJSON({include: ['tags']});
|
||||
tagJSON.push(result.tag1.toJSON());
|
||||
tagJSON.push(result.tag2.toJSON());
|
||||
tagJSON.push(result.tag3.toJSON());
|
||||
editOptions = _.extend({}, context, {id: postJSON.id, withRelated: ['tags']});
|
||||
|
||||
// reset the eventSpy here
|
||||
sandbox.restore();
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should create the test data correctly', function (done) {
|
||||
// creates a test tag
|
||||
should.exist(tagJSON);
|
||||
tagJSON.should.be.an.Array().with.lengthOf(3);
|
||||
tagJSON.should.have.enumerable(0).with.property('name', 'existing tag a');
|
||||
tagJSON.should.have.enumerable(1).with.property('name', 'existing-tag-b');
|
||||
tagJSON.should.have.enumerable(2).with.property('name', 'existing_tag_c');
|
||||
|
||||
// creates a test post with an array of tags in the correct order
|
||||
should.exist(postJSON);
|
||||
postJSON.title.should.eql('HTML Ipsum');
|
||||
should.exist(postJSON.tags);
|
||||
postJSON.tags.should.be.an.Array().and.have.lengthOf(3);
|
||||
postJSON.tags.should.have.enumerable(0).with.property('name', 'tag1');
|
||||
postJSON.tags.should.have.enumerable(1).with.property('name', 'tag2');
|
||||
postJSON.tags.should.have.enumerable(2).with.property('name', 'tag3');
|
||||
|
||||
done();
|
||||
});
|
||||
|
||||
describe('Adding brand new tags', function () {
|
||||
it('can add a single tag to the end of the tags array', function (done) {
|
||||
var newJSON = _.cloneDeep(postJSON);
|
||||
|
||||
// Add a single tag to the end of the array
|
||||
newJSON.tags.push(createTag({name: 'tag4'}));
|
||||
|
||||
// Edit the post
|
||||
return PostModel.edit(newJSON, editOptions).then(function (updatedPost) {
|
||||
updatedPost = updatedPost.toJSON({include: ['tags']});
|
||||
|
||||
updatedPost.tags.should.have.lengthOf(4);
|
||||
updatedPost.tags.should.have.enumerable(0).with.properties({
|
||||
name: 'tag1',
|
||||
id: postJSON.tags[0].id
|
||||
});
|
||||
updatedPost.tags.should.have.enumerable(1).with.properties({
|
||||
name: 'tag2',
|
||||
id: postJSON.tags[1].id
|
||||
});
|
||||
updatedPost.tags.should.have.enumerable(2).with.properties({
|
||||
name: 'tag3',
|
||||
id: postJSON.tags[2].id
|
||||
});
|
||||
updatedPost.tags.should.have.enumerable(3).with.property('name', 'tag4');
|
||||
|
||||
done();
|
||||
}).catch(done);
|
||||
});
|
||||
|
||||
it('can add a single tag to the beginning of the tags array', function (done) {
|
||||
var newJSON = _.cloneDeep(postJSON);
|
||||
|
||||
// Add a single tag to the beginning of the array
|
||||
newJSON.tags = [createTag({name: 'tag4'})].concat(postJSON.tags);
|
||||
|
||||
// Edit the post
|
||||
return PostModel.edit(newJSON, editOptions).then(function (updatedPost) {
|
||||
updatedPost = updatedPost.toJSON({include: ['tags']});
|
||||
|
||||
updatedPost.tags.should.have.lengthOf(4);
|
||||
updatedPost.tags.should.have.enumerable(0).with.property('name', 'tag4');
|
||||
updatedPost.tags.should.have.enumerable(1).with.properties({
|
||||
name: 'tag1',
|
||||
id: postJSON.tags[0].id
|
||||
});
|
||||
updatedPost.tags.should.have.enumerable(2).with.properties({
|
||||
name: 'tag2',
|
||||
id: postJSON.tags[1].id
|
||||
});
|
||||
updatedPost.tags.should.have.enumerable(3).with.properties({
|
||||
name: 'tag3',
|
||||
id: postJSON.tags[2].id
|
||||
});
|
||||
|
||||
done();
|
||||
}).catch(done);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Adding pre-existing tags', function () {
|
||||
it('can add a single tag to the end of the tags array', function (done) {
|
||||
var newJSON = _.cloneDeep(postJSON);
|
||||
|
||||
// Add a single pre-existing tag to the end of the array
|
||||
newJSON.tags.push(tagJSON[0]);
|
||||
|
||||
// Edit the post
|
||||
return PostModel.edit(newJSON, editOptions).then(function (updatedPost) {
|
||||
updatedPost = updatedPost.toJSON({include: ['tags']});
|
||||
|
||||
updatedPost.tags.should.have.lengthOf(4);
|
||||
updatedPost.tags.should.have.enumerable(0).with.properties({
|
||||
name: 'tag1',
|
||||
id: postJSON.tags[0].id
|
||||
});
|
||||
updatedPost.tags.should.have.enumerable(1).with.properties({
|
||||
name: 'tag2',
|
||||
id: postJSON.tags[1].id
|
||||
});
|
||||
updatedPost.tags.should.have.enumerable(2).with.properties({
|
||||
name: 'tag3',
|
||||
id: postJSON.tags[2].id
|
||||
});
|
||||
updatedPost.tags.should.have.enumerable(3).with.properties({
|
||||
name: 'existing tag a',
|
||||
id: tagJSON[0].id
|
||||
});
|
||||
|
||||
done();
|
||||
}).catch(done);
|
||||
});
|
||||
|
||||
it('can add a single tag to the beginning of the tags array', function (done) {
|
||||
var newJSON = _.cloneDeep(postJSON);
|
||||
|
||||
// Add an existing tag to the beginning of the array
|
||||
newJSON.tags = [tagJSON[0]].concat(postJSON.tags);
|
||||
|
||||
// Edit the post
|
||||
return PostModel.edit(newJSON, editOptions).then(function (updatedPost) {
|
||||
updatedPost = updatedPost.toJSON({include: ['tags']});
|
||||
|
||||
updatedPost.tags.should.have.lengthOf(4);
|
||||
updatedPost.tags.should.have.enumerable(0).with.properties({
|
||||
name: 'existing tag a',
|
||||
id: tagJSON[0].id
|
||||
});
|
||||
updatedPost.tags.should.have.enumerable(1).with.properties({
|
||||
name: 'tag1',
|
||||
id: postJSON.tags[0].id
|
||||
});
|
||||
updatedPost.tags.should.have.enumerable(2).with.properties({
|
||||
name: 'tag2',
|
||||
id: postJSON.tags[1].id
|
||||
});
|
||||
updatedPost.tags.should.have.enumerable(3).with.properties({
|
||||
name: 'tag3',
|
||||
id: postJSON.tags[2].id
|
||||
});
|
||||
|
||||
done();
|
||||
}).catch(done);
|
||||
});
|
||||
|
||||
it('can add a single tag to the middle of the tags array', function (done) {
|
||||
var newJSON = _.cloneDeep(postJSON);
|
||||
|
||||
// Add a single pre-existing tag to the middle of the array
|
||||
newJSON.tags = postJSON.tags.slice(0, 1).concat([tagJSON[0]]).concat(postJSON.tags.slice(1));
|
||||
|
||||
// Edit the post
|
||||
return PostModel.edit(newJSON, editOptions).then(function (updatedPost) {
|
||||
updatedPost = updatedPost.toJSON({include: ['tags']});
|
||||
|
||||
updatedPost.tags.should.have.lengthOf(4);
|
||||
updatedPost.tags.should.have.enumerable(0).with.properties({
|
||||
name: 'tag1',
|
||||
id: postJSON.tags[0].id
|
||||
});
|
||||
updatedPost.tags.should.have.enumerable(1).with.properties({
|
||||
name: 'existing tag a',
|
||||
id: tagJSON[0].id
|
||||
});
|
||||
updatedPost.tags.should.have.enumerable(2).with.properties({
|
||||
name: 'tag2',
|
||||
id: postJSON.tags[1].id
|
||||
});
|
||||
updatedPost.tags.should.have.enumerable(3).with.properties({
|
||||
name: 'tag3',
|
||||
id: postJSON.tags[2].id
|
||||
});
|
||||
|
||||
done();
|
||||
}).catch(done);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Removing tags', function () {
|
||||
it('can remove a single tag from the end of the tags array', function (done) {
|
||||
var newJSON = _.cloneDeep(postJSON);
|
||||
|
||||
// Remove a single tag from the end of the array
|
||||
newJSON.tags = postJSON.tags.slice(0, -1);
|
||||
|
||||
// Edit the post
|
||||
return PostModel.edit(newJSON, editOptions).then(function (updatedPost) {
|
||||
updatedPost = updatedPost.toJSON({include: ['tags']});
|
||||
|
||||
updatedPost.tags.should.have.lengthOf(2);
|
||||
updatedPost.tags.should.have.enumerable(0).with.properties({
|
||||
name: 'tag1',
|
||||
id: postJSON.tags[0].id
|
||||
});
|
||||
updatedPost.tags.should.have.enumerable(1).with.properties({
|
||||
name: 'tag2',
|
||||
id: postJSON.tags[1].id
|
||||
});
|
||||
|
||||
done();
|
||||
}).catch(done);
|
||||
});
|
||||
|
||||
it('can remove a single tag from the beginning of the tags array', function (done) {
|
||||
var newJSON = _.cloneDeep(postJSON);
|
||||
|
||||
// Remove a single tag from the beginning of the array
|
||||
newJSON.tags = postJSON.tags.slice(1);
|
||||
|
||||
// Edit the post
|
||||
return PostModel.edit(newJSON, editOptions).then(function (updatedPost) {
|
||||
updatedPost = updatedPost.toJSON({include: ['tags']});
|
||||
|
||||
updatedPost.tags.should.have.lengthOf(2);
|
||||
updatedPost.tags.should.have.enumerable(0).with.properties({
|
||||
name: 'tag2',
|
||||
id: postJSON.tags[1].id
|
||||
});
|
||||
updatedPost.tags.should.have.enumerable(1).with.properties({
|
||||
name: 'tag3',
|
||||
id: postJSON.tags[2].id
|
||||
});
|
||||
|
||||
done();
|
||||
}).catch(done);
|
||||
});
|
||||
|
||||
it('can remove all tags', function (done) {
|
||||
var newJSON = _.cloneDeep(postJSON);
|
||||
|
||||
// Remove all the tags
|
||||
newJSON.tags = [];
|
||||
|
||||
// Edit the post
|
||||
return PostModel.edit(newJSON, editOptions).then(function (updatedPost) {
|
||||
updatedPost = updatedPost.toJSON({include: ['tags']});
|
||||
|
||||
updatedPost.tags.should.have.lengthOf(0);
|
||||
|
||||
done();
|
||||
}).catch(done);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Reordering tags', function () {
|
||||
it('can reorder the first tag to be the last', function (done) {
|
||||
var newJSON = _.cloneDeep(postJSON),
|
||||
firstTag = [postJSON.tags[0]];
|
||||
|
||||
// Reorder the tags, so that the first tag is moved to the end
|
||||
newJSON.tags = postJSON.tags.slice(1).concat(firstTag);
|
||||
|
||||
// Edit the post
|
||||
return PostModel.edit(newJSON, editOptions).then(function (updatedPost) {
|
||||
updatedPost = updatedPost.toJSON({include: ['tags']});
|
||||
|
||||
updatedPost.tags.should.have.lengthOf(3);
|
||||
updatedPost.tags.should.have.enumerable(0).with.properties({
|
||||
name: 'tag2',
|
||||
id: postJSON.tags[1].id
|
||||
});
|
||||
updatedPost.tags.should.have.enumerable(1).with.properties({
|
||||
name: 'tag3',
|
||||
id: postJSON.tags[2].id
|
||||
});
|
||||
updatedPost.tags.should.have.enumerable(2).with.properties({
|
||||
name: 'tag1',
|
||||
id: postJSON.tags[0].id
|
||||
});
|
||||
|
||||
done();
|
||||
}).catch(done);
|
||||
});
|
||||
|
||||
it('can reorder the last tag to be the first', function (done) {
|
||||
var newJSON = _.cloneDeep(postJSON),
|
||||
lastTag = [postJSON.tags[2]];
|
||||
|
||||
// Reorder the tags, so that the last tag is moved to the beginning
|
||||
newJSON.tags = lastTag.concat(postJSON.tags.slice(0, -1));
|
||||
|
||||
// Edit the post
|
||||
return PostModel.edit(newJSON, editOptions).then(function (updatedPost) {
|
||||
updatedPost = updatedPost.toJSON({include: ['tags']});
|
||||
|
||||
updatedPost.tags.should.have.lengthOf(3);
|
||||
updatedPost.tags.should.have.enumerable(0).with.properties({
|
||||
name: 'tag3',
|
||||
id: postJSON.tags[2].id
|
||||
});
|
||||
updatedPost.tags.should.have.enumerable(1).with.properties({
|
||||
name: 'tag1',
|
||||
id: postJSON.tags[0].id
|
||||
});
|
||||
updatedPost.tags.should.have.enumerable(2).with.properties({
|
||||
name: 'tag2',
|
||||
id: postJSON.tags[1].id
|
||||
});
|
||||
|
||||
done();
|
||||
}).catch(done);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Edit post', function () {
|
||||
// These tests are for #6920
|
||||
it('can edit a post SAFELY when tags are not included', function (done) {
|
||||
var postId = postJSON.id,
|
||||
toJSONOpts = {include: ['tags']},
|
||||
startTags;
|
||||
|
||||
// Step 1, fetch a post with its tags, just to see what tags we have
|
||||
PostModel.findOne({id: postId}, {withRelated: ['tags']}).then(function (results) {
|
||||
var post = results.toJSON(toJSONOpts);
|
||||
should.exist(results);
|
||||
post.title.should.not.equal('new title');
|
||||
post.tags.should.have.lengthOf(3);
|
||||
|
||||
// Save a copy of these tags to test later
|
||||
startTags = _.cloneDeep(post.tags);
|
||||
|
||||
// Step 2, edit a single property of the post... we aren't doing anything with tags here...
|
||||
return PostModel.edit({title: 'new title'}, _.extend({}, context, {id: postId}));
|
||||
}).then(function (edited) {
|
||||
should.exist(edited);
|
||||
var post = edited.toJSON(toJSONOpts);
|
||||
|
||||
post.title.should.equal('new title');
|
||||
// edit didn't include tags, so they should be blank
|
||||
should.not.exist(post.tags);
|
||||
|
||||
// Step 3, request the same post again, including tags... they should still be present
|
||||
return PostModel.findOne({id: postId}, {withRelated: ['tags']}).then(function (results) {
|
||||
var post = results.toJSON(toJSONOpts);
|
||||
post.tags.should.have.lengthOf(3);
|
||||
post.tags.should.eql(startTags);
|
||||
|
||||
done();
|
||||
});
|
||||
}).catch(done);
|
||||
});
|
||||
|
||||
it('can edit a post SAFELY when tags is undefined', function (done) {
|
||||
var postId = postJSON.id,
|
||||
toJSONOpts = {include: ['tags']},
|
||||
startTags;
|
||||
|
||||
// Step 1, fetch a post with its tags, just to see what tags we have
|
||||
PostModel.findOne({id: postId}, {withRelated: ['tags']}).then(function (results) {
|
||||
var post = results.toJSON(toJSONOpts);
|
||||
should.exist(results);
|
||||
post.title.should.not.equal('new title');
|
||||
post.tags.should.have.lengthOf(3);
|
||||
|
||||
// Save a copy of these tags to test later
|
||||
startTags = _.cloneDeep(post.tags);
|
||||
|
||||
// Step 2, edit a single property of the post... we aren't doing anything with tags here...
|
||||
return PostModel.edit({title: 'new title', tags: undefined}, _.extend({}, context, {id: postId}));
|
||||
}).then(function (edited) {
|
||||
should.exist(edited);
|
||||
var post = edited.toJSON(toJSONOpts);
|
||||
|
||||
post.title.should.equal('new title');
|
||||
// edit didn't include tags, so they should be blank
|
||||
should.not.exist(post.tags);
|
||||
|
||||
// Step 3, request the same post again, including tags... they should still be present
|
||||
return PostModel.findOne({id: postId}, {withRelated: ['tags']}).then(function (results) {
|
||||
var post = results.toJSON(toJSONOpts);
|
||||
post.tags.should.have.lengthOf(3);
|
||||
post.tags.should.eql(startTags);
|
||||
|
||||
done();
|
||||
});
|
||||
}).catch(done);
|
||||
});
|
||||
|
||||
it('can edit a post SAFELY when tags is null', function (done) {
|
||||
var postId = postJSON.id,
|
||||
toJSONOpts = {include: ['tags']},
|
||||
startTags;
|
||||
|
||||
// Step 1, fetch a post with its tags, just to see what tags we have
|
||||
PostModel.findOne({id: postId}, {withRelated: ['tags']}).then(function (results) {
|
||||
var post = results.toJSON(toJSONOpts);
|
||||
should.exist(results);
|
||||
post.title.should.not.equal('new title');
|
||||
post.tags.should.have.lengthOf(3);
|
||||
|
||||
// Save a copy of these tags to test later
|
||||
startTags = _.cloneDeep(post.tags);
|
||||
|
||||
// Step 2, edit a single property of the post... we aren't doing anything with tags here...
|
||||
return PostModel.edit({title: 'new title', tags: null}, _.extend({}, context, {id: postId}));
|
||||
}).then(function (edited) {
|
||||
should.exist(edited);
|
||||
var post = edited.toJSON(toJSONOpts);
|
||||
|
||||
post.title.should.equal('new title');
|
||||
// edit didn't include tags, so they should be blank
|
||||
should.not.exist(post.tags);
|
||||
|
||||
// Step 3, request the same post again, including tags... they should still be present
|
||||
return PostModel.findOne({id: postId}, {withRelated: ['tags']}).then(function (results) {
|
||||
var post = results.toJSON(toJSONOpts);
|
||||
post.tags.should.have.lengthOf(3);
|
||||
post.tags.should.eql(startTags);
|
||||
|
||||
done();
|
||||
});
|
||||
}).catch(done);
|
||||
});
|
||||
|
||||
it('can remove all tags when sent an empty array', function (done) {
|
||||
var postId = postJSON.id,
|
||||
toJSONOpts = {include: ['tags']};
|
||||
|
||||
// Step 1, fetch a post with its tags, just to see what tags we have
|
||||
PostModel.findOne({id: postId}, {withRelated: ['tags']}).then(function (results) {
|
||||
var post = results.toJSON(toJSONOpts);
|
||||
should.exist(results);
|
||||
post.title.should.not.equal('new title');
|
||||
post.tags.should.have.lengthOf(3);
|
||||
|
||||
// Step 2, edit a single property of the post... we aren't doing anything with tags here...
|
||||
return PostModel.edit({title: 'new title', tags: []}, _.extend({}, context, {id: postId}));
|
||||
}).then(function (edited) {
|
||||
should.exist(edited);
|
||||
var post = edited.toJSON(toJSONOpts);
|
||||
|
||||
post.title.should.equal('new title');
|
||||
// edit didn't include tags, so they should be blank
|
||||
should.not.exist(post.tags);
|
||||
|
||||
// Step 3, request the same post again, including tags... they should be gone
|
||||
return PostModel.findOne({id: postId}, {withRelated: ['tags']}).then(function (results) {
|
||||
var post = results.toJSON(toJSONOpts);
|
||||
// Tags should be gone
|
||||
post.tags.should.eql([]);
|
||||
|
||||
done();
|
||||
});
|
||||
}).catch(done);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Combination updates', function () {
|
||||
it('can add a combination of new and pre-existing tags', function (done) {
|
||||
var newJSON = _.cloneDeep(postJSON);
|
||||
|
||||
// Push a bunch of new and existing tags to the end of the array
|
||||
newJSON.tags.push({name: 'tag4'});
|
||||
newJSON.tags.push({name: 'existing tag a'});
|
||||
newJSON.tags.push({name: 'tag5'});
|
||||
newJSON.tags.push({name: 'existing-tag-b'});
|
||||
newJSON.tags.push({name: 'bob'});
|
||||
newJSON.tags.push({name: 'existing_tag_c'});
|
||||
|
||||
// Edit the post
|
||||
return PostModel.edit(newJSON, editOptions).then(function (updatedPost) {
|
||||
updatedPost = updatedPost.toJSON({include: ['tags']});
|
||||
|
||||
updatedPost.tags.should.have.lengthOf(9);
|
||||
updatedPost.tags.should.have.enumerable(0).with.properties({
|
||||
name: 'tag1',
|
||||
id: postJSON.tags[0].id
|
||||
});
|
||||
updatedPost.tags.should.have.enumerable(1).with.properties({
|
||||
name: 'tag2',
|
||||
id: postJSON.tags[1].id
|
||||
});
|
||||
updatedPost.tags.should.have.enumerable(2).with.properties({
|
||||
name: 'tag3',
|
||||
id: postJSON.tags[2].id
|
||||
});
|
||||
updatedPost.tags.should.have.enumerable(3).with.property('name', 'tag4');
|
||||
updatedPost.tags.should.have.enumerable(4).with.properties({
|
||||
name: 'existing tag a',
|
||||
id: tagJSON[0].id
|
||||
});
|
||||
updatedPost.tags.should.have.enumerable(5).with.property('name', 'tag5');
|
||||
updatedPost.tags.should.have.enumerable(6).with.properties({
|
||||
name: 'existing-tag-b',
|
||||
id: tagJSON[1].id
|
||||
});
|
||||
updatedPost.tags.should.have.enumerable(7).with.property('name', 'bob');
|
||||
updatedPost.tags.should.have.enumerable(8).with.properties({
|
||||
name: 'existing_tag_c',
|
||||
id: tagJSON[2].id
|
||||
});
|
||||
|
||||
done();
|
||||
}).catch(done);
|
||||
});
|
||||
|
||||
it('can reorder the first tag to be the last and add a tag to the beginning', function (done) {
|
||||
var newJSON = _.cloneDeep(postJSON),
|
||||
firstTag = [postJSON.tags[0]];
|
||||
|
||||
// Add a new tag to the beginning, and move the original first tag to the end
|
||||
newJSON.tags = [tagJSON[0]].concat(postJSON.tags.slice(1)).concat(firstTag);
|
||||
|
||||
// Edit the post
|
||||
return PostModel.edit(newJSON, editOptions).then(function (updatedPost) {
|
||||
updatedPost = updatedPost.toJSON({include: ['tags']});
|
||||
|
||||
updatedPost.tags.should.have.lengthOf(4);
|
||||
updatedPost.tags.should.have.enumerable(0).with.properties({
|
||||
name: 'existing tag a',
|
||||
id: tagJSON[0].id
|
||||
});
|
||||
updatedPost.tags.should.have.enumerable(1).with.properties({
|
||||
name: 'tag2',
|
||||
id: postJSON.tags[1].id
|
||||
});
|
||||
updatedPost.tags.should.have.enumerable(2).with.properties({
|
||||
name: 'tag3',
|
||||
id: postJSON.tags[2].id
|
||||
});
|
||||
updatedPost.tags.should.have.enumerable(3).with.properties({
|
||||
name: 'tag1',
|
||||
id: postJSON.tags[0].id
|
||||
});
|
||||
|
||||
done();
|
||||
}).catch(done);
|
||||
});
|
||||
|
||||
it('can reorder the first tag to be the last, remove the original last tag & add a tag to the beginning', function (done) {
|
||||
var newJSON = _.cloneDeep(postJSON),
|
||||
firstTag = [newJSON.tags[0]];
|
||||
|
||||
// And an existing tag to the beginning of the array, move the original first tag to the end and remove the original last tag
|
||||
newJSON.tags = [tagJSON[0]].concat(newJSON.tags.slice(1, -1)).concat(firstTag);
|
||||
|
||||
// Edit the post
|
||||
return PostModel.edit(newJSON, editOptions).then(function (updatedPost) {
|
||||
updatedPost = updatedPost.toJSON({include: ['tags']});
|
||||
|
||||
updatedPost.tags.should.have.lengthOf(3);
|
||||
updatedPost.tags.should.have.enumerable(0).with.properties({
|
||||
name: 'existing tag a',
|
||||
id: tagJSON[0].id
|
||||
});
|
||||
updatedPost.tags.should.have.enumerable(1).with.properties({
|
||||
name: 'tag2',
|
||||
id: postJSON.tags[1].id
|
||||
});
|
||||
updatedPost.tags.should.have.enumerable(2).with.properties({
|
||||
name: 'tag1',
|
||||
id: postJSON.tags[0].id
|
||||
});
|
||||
|
||||
done();
|
||||
}).catch(done);
|
||||
});
|
||||
|
||||
it('can reorder original tags, remove one, and add new and existing tags', function (done) {
|
||||
var newJSON = _.cloneDeep(postJSON),
|
||||
firstTag = [newJSON.tags[0]];
|
||||
|
||||
// Reorder original 3 so that first is at the end
|
||||
newJSON.tags = newJSON.tags.slice(1).concat(firstTag);
|
||||
|
||||
// add an existing tag in the middle
|
||||
newJSON.tags = newJSON.tags.slice(0, 1).concat({name: 'existing-tag-b'}).concat(newJSON.tags.slice(1));
|
||||
|
||||
// add a brand new tag in the middle
|
||||
newJSON.tags = newJSON.tags.slice(0, 3).concat({name: 'betty'}).concat(newJSON.tags.slice(3));
|
||||
|
||||
// Add some more tags to the end
|
||||
newJSON.tags.push({name: 'bob'});
|
||||
newJSON.tags.push({name: 'existing tag a'});
|
||||
|
||||
// Edit the post
|
||||
return PostModel.edit(newJSON, editOptions).then(function (updatedPost) {
|
||||
updatedPost = updatedPost.toJSON({include: ['tags']});
|
||||
|
||||
updatedPost.tags.should.have.lengthOf(7);
|
||||
|
||||
updatedPost.tags.should.have.enumerable(0).with.properties({
|
||||
name: 'tag2',
|
||||
id: postJSON.tags[1].id
|
||||
});
|
||||
updatedPost.tags.should.have.enumerable(1).with.properties({
|
||||
name: 'existing-tag-b',
|
||||
id: tagJSON[1].id
|
||||
});
|
||||
updatedPost.tags.should.have.enumerable(2).with.properties({
|
||||
name: 'tag3',
|
||||
id: postJSON.tags[2].id
|
||||
});
|
||||
updatedPost.tags.should.have.enumerable(3).with.property('name', 'betty');
|
||||
updatedPost.tags.should.have.enumerable(4).with.properties({
|
||||
name: 'tag1',
|
||||
id: postJSON.tags[0].id
|
||||
});
|
||||
updatedPost.tags.should.have.enumerable(5).with.property('name', 'bob');
|
||||
updatedPost.tags.should.have.enumerable(6).with.properties({
|
||||
name: 'existing tag a',
|
||||
id: tagJSON[0].id
|
||||
});
|
||||
|
||||
done();
|
||||
}).catch(done);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('Posts with NO tags', function () {
|
||||
var postJSON,
|
||||
tagJSON,
|
||||
editOptions,
|
||||
createTag = testUtils.DataGenerator.forKnex.createTag;
|
||||
|
||||
beforeEach(function (done) {
|
||||
tagJSON = [];
|
||||
|
||||
var post = _.cloneDeep(testUtils.DataGenerator.forModel.posts[0]),
|
||||
extraTag1 = createTag({name: 'existing tag a'}),
|
||||
extraTag2 = createTag({name: 'existing-tag-b'}),
|
||||
extraTag3 = createTag({name: 'existing_tag_c'});
|
||||
|
||||
return Promise.props({
|
||||
post: PostModel.add(post, _.extend({}, context, {withRelated: ['tags']})),
|
||||
tag1: TagModel.add(extraTag1, context),
|
||||
tag2: TagModel.add(extraTag2, context),
|
||||
tag3: TagModel.add(extraTag3, context)
|
||||
}).then(function (result) {
|
||||
postJSON = result.post.toJSON({include: ['tags']});
|
||||
tagJSON.push(result.tag1.toJSON());
|
||||
tagJSON.push(result.tag2.toJSON());
|
||||
tagJSON.push(result.tag3.toJSON());
|
||||
editOptions = _.extend({}, context, {id: postJSON.id, withRelated: ['tags']});
|
||||
|
||||
done();
|
||||
}).catch(done);
|
||||
});
|
||||
|
||||
it('should create the test data correctly', function () {
|
||||
// creates two test tags
|
||||
should.exist(tagJSON);
|
||||
tagJSON.should.be.an.Array().with.lengthOf(3);
|
||||
tagJSON.should.have.enumerable(0).with.property('name', 'existing tag a');
|
||||
tagJSON.should.have.enumerable(1).with.property('name', 'existing-tag-b');
|
||||
tagJSON.should.have.enumerable(2).with.property('name', 'existing_tag_c');
|
||||
|
||||
// creates a test post with no tags
|
||||
should.exist(postJSON);
|
||||
postJSON.title.should.eql('HTML Ipsum');
|
||||
should.exist(postJSON.tags);
|
||||
});
|
||||
|
||||
describe('Adding brand new tags', function () {
|
||||
it('can add a single tag', function (done) {
|
||||
var newJSON = _.cloneDeep(postJSON);
|
||||
|
||||
// Add a single tag to the end of the array
|
||||
newJSON.tags.push(createTag({name: 'tag1'}));
|
||||
|
||||
// Edit the post
|
||||
return PostModel.edit(newJSON, editOptions).then(function (updatedPost) {
|
||||
updatedPost = updatedPost.toJSON({include: ['tags']});
|
||||
|
||||
updatedPost.tags.should.have.lengthOf(1);
|
||||
updatedPost.tags.should.have.enumerable(0).with.property('name', 'tag1');
|
||||
|
||||
done();
|
||||
}).catch(done);
|
||||
});
|
||||
|
||||
it('can add multiple tags', function (done) {
|
||||
var newJSON = _.cloneDeep(postJSON);
|
||||
|
||||
// Add a bunch of tags to the end of the array
|
||||
newJSON.tags.push(createTag({name: 'tag1'}));
|
||||
newJSON.tags.push(createTag({name: 'tag2'}));
|
||||
newJSON.tags.push(createTag({name: 'tag3'}));
|
||||
newJSON.tags.push(createTag({name: 'tag4'}));
|
||||
newJSON.tags.push(createTag({name: 'tag5'}));
|
||||
|
||||
// Edit the post
|
||||
return PostModel.edit(newJSON, editOptions).then(function (updatedPost) {
|
||||
updatedPost = updatedPost.toJSON({include: ['tags']});
|
||||
|
||||
updatedPost.tags.should.have.lengthOf(5);
|
||||
updatedPost.tags.should.have.enumerable(0).with.property('name', 'tag1');
|
||||
updatedPost.tags.should.have.enumerable(1).with.property('name', 'tag2');
|
||||
updatedPost.tags.should.have.enumerable(2).with.property('name', 'tag3');
|
||||
updatedPost.tags.should.have.enumerable(3).with.property('name', 'tag4');
|
||||
updatedPost.tags.should.have.enumerable(4).with.property('name', 'tag5');
|
||||
|
||||
done();
|
||||
}).catch(done);
|
||||
});
|
||||
|
||||
it('can add multiple tags with conflicting slugs', function (done) {
|
||||
var newJSON = _.cloneDeep(postJSON);
|
||||
|
||||
// Add conflicting tags to the end of the array
|
||||
newJSON.tags.push({name: 'C'});
|
||||
newJSON.tags.push({name: 'C++'});
|
||||
newJSON.tags.push({name: 'C#'});
|
||||
|
||||
// Edit the post
|
||||
return PostModel.edit(newJSON, editOptions).then(function (updatedPost) {
|
||||
updatedPost = updatedPost.toJSON({include: ['tags']});
|
||||
|
||||
updatedPost.tags.should.have.lengthOf(3);
|
||||
updatedPost.tags.should.have.enumerable(0).with.properties({name: 'C', slug: 'c'});
|
||||
updatedPost.tags.should.have.enumerable(1).with.properties({name: 'C++', slug: 'c-2'});
|
||||
updatedPost.tags.should.have.enumerable(2).with.properties({name: 'C#', slug: 'c-3'});
|
||||
|
||||
done();
|
||||
}).catch(done);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Adding pre-existing tags', function () {
|
||||
it('can add a single tag', function (done) {
|
||||
var newJSON = _.cloneDeep(postJSON);
|
||||
|
||||
// Add a single pre-existing tag
|
||||
newJSON.tags.push(tagJSON[0]);
|
||||
|
||||
// Edit the post
|
||||
return PostModel.edit(newJSON, editOptions).then(function (updatedPost) {
|
||||
updatedPost = updatedPost.toJSON({include: ['tags']});
|
||||
|
||||
updatedPost.tags.should.have.lengthOf(1);
|
||||
updatedPost.tags.should.have.enumerable(0).with.properties({
|
||||
name: 'existing tag a',
|
||||
id: tagJSON[0].id
|
||||
});
|
||||
|
||||
done();
|
||||
}).catch(done);
|
||||
});
|
||||
|
||||
it('can add multiple tags', function (done) {
|
||||
var newJSON = _.cloneDeep(postJSON);
|
||||
|
||||
// Add many preexisting tags
|
||||
newJSON.tags.push(tagJSON[0]);
|
||||
newJSON.tags.push(tagJSON[1]);
|
||||
newJSON.tags.push(tagJSON[2]);
|
||||
|
||||
// Edit the post
|
||||
return PostModel.edit(newJSON, editOptions).then(function (updatedPost) {
|
||||
updatedPost = updatedPost.toJSON({include: ['tags']});
|
||||
|
||||
updatedPost.tags.should.have.lengthOf(3);
|
||||
updatedPost.tags.should.have.enumerable(0).with.properties({
|
||||
name: 'existing tag a',
|
||||
id: tagJSON[0].id
|
||||
});
|
||||
updatedPost.tags.should.have.enumerable(1).with.properties({
|
||||
name: 'existing-tag-b',
|
||||
id: tagJSON[1].id
|
||||
});
|
||||
updatedPost.tags.should.have.enumerable(2).with.properties({
|
||||
name: 'existing_tag_c',
|
||||
id: tagJSON[2].id
|
||||
});
|
||||
|
||||
done();
|
||||
}).catch(done);
|
||||
});
|
||||
|
||||
it('can add multiple tags in wrong order', function (done) {
|
||||
var newJSON = _.cloneDeep(postJSON);
|
||||
|
||||
// Add tags to the array
|
||||
newJSON.tags.push(tagJSON[2]);
|
||||
newJSON.tags.push(tagJSON[0]);
|
||||
newJSON.tags.push(tagJSON[1]);
|
||||
|
||||
// Edit the post
|
||||
return PostModel.edit(newJSON, editOptions).then(function (updatedPost) {
|
||||
updatedPost = updatedPost.toJSON({include: ['tags']});
|
||||
|
||||
updatedPost.tags.should.have.lengthOf(3);
|
||||
updatedPost.tags.should.have.enumerable(0).with.properties({
|
||||
name: 'existing_tag_c',
|
||||
id: tagJSON[2].id
|
||||
});
|
||||
updatedPost.tags.should.have.enumerable(1).with.properties({
|
||||
name: 'existing tag a',
|
||||
id: tagJSON[0].id
|
||||
});
|
||||
updatedPost.tags.should.have.enumerable(2).with.properties({
|
||||
name: 'existing-tag-b',
|
||||
id: tagJSON[1].id
|
||||
});
|
||||
|
||||
done();
|
||||
}).catch(done);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Adding combinations', function () {
|
||||
it('can add a combination of new and pre-existing tags', function (done) {
|
||||
var newJSON = _.cloneDeep(postJSON);
|
||||
|
||||
// Add a bunch of new and existing tags to the array
|
||||
newJSON.tags.push({name: 'tag1'});
|
||||
newJSON.tags.push({name: 'existing tag a'});
|
||||
newJSON.tags.push({name: 'tag3'});
|
||||
newJSON.tags.push({name: 'existing-tag-b'});
|
||||
newJSON.tags.push({name: 'tag5'});
|
||||
newJSON.tags.push({name: 'existing_tag_c'});
|
||||
|
||||
// Edit the post
|
||||
return PostModel.edit(newJSON, editOptions).then(function (updatedPost) {
|
||||
updatedPost = updatedPost.toJSON({include: ['tags']});
|
||||
|
||||
updatedPost.tags.should.have.lengthOf(6);
|
||||
updatedPost.tags.should.have.enumerable(0).with.property('name', 'tag1');
|
||||
updatedPost.tags.should.have.enumerable(1).with.properties({
|
||||
name: 'existing tag a',
|
||||
id: tagJSON[0].id
|
||||
});
|
||||
updatedPost.tags.should.have.enumerable(2).with.property('name', 'tag3');
|
||||
updatedPost.tags.should.have.enumerable(3).with.properties({
|
||||
name: 'existing-tag-b',
|
||||
id: tagJSON[1].id
|
||||
});
|
||||
updatedPost.tags.should.have.enumerable(4).with.property('name', 'tag5');
|
||||
updatedPost.tags.should.have.enumerable(5).with.properties({
|
||||
name: 'existing_tag_c',
|
||||
id: tagJSON[2].id
|
||||
});
|
||||
|
||||
done();
|
||||
}).catch(done);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// disabling sanitization until we can implement a better version
|
||||
// it('should sanitize the title', function (done) {
|
||||
// new PostModel().fetch().then(function (model) {
|
||||
|
@ -2,8 +2,6 @@
|
||||
var testUtils = require('../../utils'),
|
||||
should = require('should'),
|
||||
sinon = require('sinon'),
|
||||
Promise = require('bluebird'),
|
||||
_ = require('lodash'),
|
||||
|
||||
// Stuff we are testing
|
||||
ModelsTag = require('../../../server/models/tag'),
|
||||
@ -114,570 +112,4 @@ describe('Tag Model', function () {
|
||||
}).catch(done);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Post tag handling, post with NO tags', function () {
|
||||
var postJSON,
|
||||
tagJSON,
|
||||
editOptions,
|
||||
createTag = testUtils.DataGenerator.forKnex.createTag;
|
||||
|
||||
beforeEach(function (done) {
|
||||
tagJSON = [];
|
||||
|
||||
var post = testUtils.DataGenerator.forModel.posts[0],
|
||||
extraTag1 = createTag({name: 'existing tag a'}),
|
||||
extraTag2 = createTag({name: 'existing-tag-b'}),
|
||||
extraTag3 = createTag({name: 'existing_tag_c'});
|
||||
|
||||
return Promise.props({
|
||||
post: PostModel.add(post, _.extend({}, context, {withRelated: ['tags']})),
|
||||
tag1: TagModel.add(extraTag1, context),
|
||||
tag2: TagModel.add(extraTag2, context),
|
||||
tag3: TagModel.add(extraTag3, context)
|
||||
}).then(function (result) {
|
||||
postJSON = result.post.toJSON({include: ['tags']});
|
||||
tagJSON.push(result.tag1.toJSON());
|
||||
tagJSON.push(result.tag2.toJSON());
|
||||
tagJSON.push(result.tag3.toJSON());
|
||||
editOptions = _.extend({}, context, {id: postJSON.id, withRelated: ['tags']});
|
||||
|
||||
done();
|
||||
}).catch(done);
|
||||
});
|
||||
|
||||
it('should create the test data correctly', function () {
|
||||
// creates two test tags
|
||||
should.exist(tagJSON);
|
||||
tagJSON.should.be.an.Array().with.lengthOf(3);
|
||||
tagJSON.should.have.enumerable(0).with.property('name', 'existing tag a');
|
||||
tagJSON.should.have.enumerable(1).with.property('name', 'existing-tag-b');
|
||||
tagJSON.should.have.enumerable(2).with.property('name', 'existing_tag_c');
|
||||
|
||||
// creates a test post with no tags
|
||||
should.exist(postJSON);
|
||||
postJSON.title.should.eql('HTML Ipsum');
|
||||
should.exist(postJSON.tags);
|
||||
});
|
||||
|
||||
describe('Adding brand new tags', function () {
|
||||
it('can add a single tag', function (done) {
|
||||
var newJSON = _.cloneDeep(postJSON);
|
||||
|
||||
// Add a single tag to the end of the array
|
||||
newJSON.tags.push(createTag({name: 'tag1'}));
|
||||
|
||||
// Edit the post
|
||||
return PostModel.edit(newJSON, editOptions).then(function (updatedPost) {
|
||||
updatedPost = updatedPost.toJSON({include: ['tags']});
|
||||
|
||||
updatedPost.tags.should.have.lengthOf(1);
|
||||
updatedPost.tags.should.have.enumerable(0).with.property('name', 'tag1');
|
||||
|
||||
done();
|
||||
}).catch(done);
|
||||
});
|
||||
|
||||
it('can add multiple tags', function (done) {
|
||||
var newJSON = _.cloneDeep(postJSON);
|
||||
|
||||
// Add a bunch of tags to the end of the array
|
||||
newJSON.tags.push(createTag({name: 'tag1'}));
|
||||
newJSON.tags.push(createTag({name: 'tag2'}));
|
||||
newJSON.tags.push(createTag({name: 'tag3'}));
|
||||
newJSON.tags.push(createTag({name: 'tag4'}));
|
||||
newJSON.tags.push(createTag({name: 'tag5'}));
|
||||
|
||||
// Edit the post
|
||||
return PostModel.edit(newJSON, editOptions).then(function (updatedPost) {
|
||||
updatedPost = updatedPost.toJSON({include: ['tags']});
|
||||
|
||||
updatedPost.tags.should.have.lengthOf(5);
|
||||
updatedPost.tags.should.have.enumerable(0).with.property('name', 'tag1');
|
||||
updatedPost.tags.should.have.enumerable(1).with.property('name', 'tag2');
|
||||
updatedPost.tags.should.have.enumerable(2).with.property('name', 'tag3');
|
||||
updatedPost.tags.should.have.enumerable(3).with.property('name', 'tag4');
|
||||
updatedPost.tags.should.have.enumerable(4).with.property('name', 'tag5');
|
||||
|
||||
done();
|
||||
}).catch(done);
|
||||
});
|
||||
|
||||
it('can add multiple tags with conflicting slugs', function (done) {
|
||||
var newJSON = _.cloneDeep(postJSON);
|
||||
|
||||
// Add conflicting tags to the end of the array
|
||||
newJSON.tags.push({name: 'C'});
|
||||
newJSON.tags.push({name: 'C++'});
|
||||
newJSON.tags.push({name: 'C#'});
|
||||
|
||||
// Edit the post
|
||||
return PostModel.edit(newJSON, editOptions).then(function (updatedPost) {
|
||||
updatedPost = updatedPost.toJSON({include: ['tags']});
|
||||
|
||||
updatedPost.tags.should.have.lengthOf(3);
|
||||
updatedPost.tags.should.have.enumerable(0).with.properties({name: 'C', slug: 'c'});
|
||||
updatedPost.tags.should.have.enumerable(1).with.properties({name: 'C++', slug: 'c-2'});
|
||||
updatedPost.tags.should.have.enumerable(2).with.properties({name: 'C#', slug: 'c-3'});
|
||||
|
||||
done();
|
||||
}).catch(done);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Adding pre-existing tags', function () {
|
||||
it('can add a single tag', function (done) {
|
||||
var newJSON = _.cloneDeep(postJSON);
|
||||
|
||||
// Add a single pre-existing tag
|
||||
newJSON.tags.push(tagJSON[0]);
|
||||
|
||||
// Edit the post
|
||||
return PostModel.edit(newJSON, editOptions).then(function (updatedPost) {
|
||||
updatedPost = updatedPost.toJSON({include: ['tags']});
|
||||
|
||||
updatedPost.tags.should.have.lengthOf(1);
|
||||
updatedPost.tags.should.have.enumerable(0).with.properties({name: 'existing tag a', id: tagJSON[0].id});
|
||||
|
||||
done();
|
||||
}).catch(done);
|
||||
});
|
||||
|
||||
it('can add multiple tags', function (done) {
|
||||
var newJSON = _.cloneDeep(postJSON);
|
||||
|
||||
// Add many preexisting tags
|
||||
newJSON.tags.push(tagJSON[0]);
|
||||
newJSON.tags.push(tagJSON[1]);
|
||||
newJSON.tags.push(tagJSON[2]);
|
||||
|
||||
// Edit the post
|
||||
return PostModel.edit(newJSON, editOptions).then(function (updatedPost) {
|
||||
updatedPost = updatedPost.toJSON({include: ['tags']});
|
||||
|
||||
updatedPost.tags.should.have.lengthOf(3);
|
||||
updatedPost.tags.should.have.enumerable(0).with.properties({name: 'existing tag a', id: tagJSON[0].id});
|
||||
updatedPost.tags.should.have.enumerable(1).with.properties({name: 'existing-tag-b', id: tagJSON[1].id});
|
||||
updatedPost.tags.should.have.enumerable(2).with.properties({name: 'existing_tag_c', id: tagJSON[2].id});
|
||||
|
||||
done();
|
||||
}).catch(done);
|
||||
});
|
||||
|
||||
it('can add multiple tags in wrong order', function (done) {
|
||||
var newJSON = _.cloneDeep(postJSON);
|
||||
|
||||
// Add tags to the array
|
||||
newJSON.tags.push(tagJSON[2]);
|
||||
newJSON.tags.push(tagJSON[0]);
|
||||
newJSON.tags.push(tagJSON[1]);
|
||||
|
||||
// Edit the post
|
||||
return PostModel.edit(newJSON, editOptions).then(function (updatedPost) {
|
||||
updatedPost = updatedPost.toJSON({include: ['tags']});
|
||||
|
||||
updatedPost.tags.should.have.lengthOf(3);
|
||||
updatedPost.tags.should.have.enumerable(0).with.properties({name: 'existing_tag_c', id: tagJSON[2].id});
|
||||
updatedPost.tags.should.have.enumerable(1).with.properties({name: 'existing tag a', id: tagJSON[0].id});
|
||||
updatedPost.tags.should.have.enumerable(2).with.properties({name: 'existing-tag-b', id: tagJSON[1].id});
|
||||
|
||||
done();
|
||||
}).catch(done);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Adding combinations', function () {
|
||||
it('can add a combination of new and pre-existing tags', function (done) {
|
||||
var newJSON = _.cloneDeep(postJSON);
|
||||
|
||||
// Add a bunch of new and existing tags to the array
|
||||
newJSON.tags.push({name: 'tag1'});
|
||||
newJSON.tags.push({name: 'existing tag a'});
|
||||
newJSON.tags.push({name: 'tag3'});
|
||||
newJSON.tags.push({name: 'existing-tag-b'});
|
||||
newJSON.tags.push({name: 'tag5'});
|
||||
newJSON.tags.push({name: 'existing_tag_c'});
|
||||
|
||||
// Edit the post
|
||||
return PostModel.edit(newJSON, editOptions).then(function (updatedPost) {
|
||||
updatedPost = updatedPost.toJSON({include: ['tags']});
|
||||
|
||||
updatedPost.tags.should.have.lengthOf(6);
|
||||
updatedPost.tags.should.have.enumerable(0).with.property('name', 'tag1');
|
||||
updatedPost.tags.should.have.enumerable(1).with.properties({name: 'existing tag a', id: tagJSON[0].id});
|
||||
updatedPost.tags.should.have.enumerable(2).with.property('name', 'tag3');
|
||||
updatedPost.tags.should.have.enumerable(3).with.properties({name: 'existing-tag-b', id: tagJSON[1].id});
|
||||
updatedPost.tags.should.have.enumerable(4).with.property('name', 'tag5');
|
||||
updatedPost.tags.should.have.enumerable(5).with.properties({name: 'existing_tag_c', id: tagJSON[2].id});
|
||||
|
||||
done();
|
||||
}).catch(done);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('Post tag handling, post with tags', function () {
|
||||
var postJSON,
|
||||
tagJSON,
|
||||
editOptions,
|
||||
createTag = testUtils.DataGenerator.forKnex.createTag;
|
||||
|
||||
beforeEach(function (done) {
|
||||
tagJSON = [];
|
||||
|
||||
var post = testUtils.DataGenerator.forModel.posts[0],
|
||||
postTags = [
|
||||
createTag({name: 'tag1'}),
|
||||
createTag({name: 'tag2'}),
|
||||
createTag({name: 'tag3'})
|
||||
],
|
||||
extraTags = [
|
||||
createTag({name: 'existing tag a'}),
|
||||
createTag({name: 'existing-tag-b'}),
|
||||
createTag({name: 'existing_tag_c'})
|
||||
];
|
||||
|
||||
post.tags = postTags;
|
||||
|
||||
return Promise.props({
|
||||
post: PostModel.add(post, _.extend({}, context, {withRelated: ['tags']})),
|
||||
tag1: TagModel.add(extraTags[0], context),
|
||||
tag2: TagModel.add(extraTags[1], context),
|
||||
tag3: TagModel.add(extraTags[2], context)
|
||||
}).then(function (result) {
|
||||
postJSON = result.post.toJSON({include: ['tags']});
|
||||
tagJSON.push(result.tag1.toJSON());
|
||||
tagJSON.push(result.tag2.toJSON());
|
||||
tagJSON.push(result.tag3.toJSON());
|
||||
editOptions = _.extend({}, context, {id: postJSON.id, withRelated: ['tags']});
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should create the test data correctly', function () {
|
||||
// creates a test tag
|
||||
should.exist(tagJSON);
|
||||
tagJSON.should.be.an.Array().with.lengthOf(3);
|
||||
tagJSON.should.have.enumerable(0).with.property('name', 'existing tag a');
|
||||
tagJSON.should.have.enumerable(1).with.property('name', 'existing-tag-b');
|
||||
tagJSON.should.have.enumerable(2).with.property('name', 'existing_tag_c');
|
||||
|
||||
// creates a test post with an array of tags in the correct order
|
||||
should.exist(postJSON);
|
||||
postJSON.title.should.eql('HTML Ipsum');
|
||||
should.exist(postJSON.tags);
|
||||
postJSON.tags.should.be.an.Array().and.have.lengthOf(3);
|
||||
postJSON.tags.should.have.enumerable(0).with.property('name', 'tag1');
|
||||
postJSON.tags.should.have.enumerable(1).with.property('name', 'tag2');
|
||||
postJSON.tags.should.have.enumerable(2).with.property('name', 'tag3');
|
||||
});
|
||||
|
||||
describe('Adding brand new tags', function () {
|
||||
it('can add a single tag to the end of the tags array', function (done) {
|
||||
var newJSON = _.cloneDeep(postJSON);
|
||||
|
||||
// Add a single tag to the end of the array
|
||||
newJSON.tags.push(createTag({name: 'tag4'}));
|
||||
|
||||
// Edit the post
|
||||
return PostModel.edit(newJSON, editOptions).then(function (updatedPost) {
|
||||
updatedPost = updatedPost.toJSON({include: ['tags']});
|
||||
|
||||
updatedPost.tags.should.have.lengthOf(4);
|
||||
updatedPost.tags.should.have.enumerable(0).with.properties({name: 'tag1', id: postJSON.tags[0].id});
|
||||
updatedPost.tags.should.have.enumerable(1).with.properties({name: 'tag2', id: postJSON.tags[1].id});
|
||||
updatedPost.tags.should.have.enumerable(2).with.properties({name: 'tag3', id: postJSON.tags[2].id});
|
||||
updatedPost.tags.should.have.enumerable(3).with.property('name', 'tag4');
|
||||
|
||||
done();
|
||||
}).catch(done);
|
||||
});
|
||||
|
||||
it('can add a single tag to the beginning of the tags array', function (done) {
|
||||
var newJSON = _.cloneDeep(postJSON);
|
||||
|
||||
// Add a single tag to the beginning of the array
|
||||
newJSON.tags = [createTag({name: 'tag4'})].concat(postJSON.tags);
|
||||
|
||||
// Edit the post
|
||||
return PostModel.edit(newJSON, editOptions).then(function (updatedPost) {
|
||||
updatedPost = updatedPost.toJSON({include: ['tags']});
|
||||
|
||||
updatedPost.tags.should.have.lengthOf(4);
|
||||
updatedPost.tags.should.have.enumerable(0).with.property('name', 'tag4');
|
||||
updatedPost.tags.should.have.enumerable(1).with.properties({name: 'tag1', id: postJSON.tags[0].id});
|
||||
updatedPost.tags.should.have.enumerable(2).with.properties({name: 'tag2', id: postJSON.tags[1].id});
|
||||
updatedPost.tags.should.have.enumerable(3).with.properties({name: 'tag3', id: postJSON.tags[2].id});
|
||||
|
||||
done();
|
||||
}).catch(done);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Adding pre-existing tags', function () {
|
||||
it('can add a single tag to the end of the tags array', function (done) {
|
||||
var newJSON = _.cloneDeep(postJSON);
|
||||
|
||||
// Add a single pre-existing tag to the end of the array
|
||||
newJSON.tags.push(tagJSON[0]);
|
||||
|
||||
// Edit the post
|
||||
return PostModel.edit(newJSON, editOptions).then(function (updatedPost) {
|
||||
updatedPost = updatedPost.toJSON({include: ['tags']});
|
||||
|
||||
updatedPost.tags.should.have.lengthOf(4);
|
||||
updatedPost.tags.should.have.enumerable(0).with.properties({name: 'tag1', id: postJSON.tags[0].id});
|
||||
updatedPost.tags.should.have.enumerable(1).with.properties({name: 'tag2', id: postJSON.tags[1].id});
|
||||
updatedPost.tags.should.have.enumerable(2).with.properties({name: 'tag3', id: postJSON.tags[2].id});
|
||||
updatedPost.tags.should.have.enumerable(3).with.properties({name: 'existing tag a', id: tagJSON[0].id});
|
||||
|
||||
done();
|
||||
}).catch(done);
|
||||
});
|
||||
|
||||
it('can add a single tag to the beginning of the tags array', function (done) {
|
||||
var newJSON = _.cloneDeep(postJSON);
|
||||
|
||||
// Add an existing tag to the beginning of the array
|
||||
newJSON.tags = [tagJSON[0]].concat(postJSON.tags);
|
||||
|
||||
// Edit the post
|
||||
return PostModel.edit(newJSON, editOptions).then(function (updatedPost) {
|
||||
updatedPost = updatedPost.toJSON({include: ['tags']});
|
||||
|
||||
updatedPost.tags.should.have.lengthOf(4);
|
||||
updatedPost.tags.should.have.enumerable(0).with.properties({name: 'existing tag a', id: tagJSON[0].id});
|
||||
updatedPost.tags.should.have.enumerable(1).with.properties({name: 'tag1', id: postJSON.tags[0].id});
|
||||
updatedPost.tags.should.have.enumerable(2).with.properties({name: 'tag2', id: postJSON.tags[1].id});
|
||||
updatedPost.tags.should.have.enumerable(3).with.properties({name: 'tag3', id: postJSON.tags[2].id});
|
||||
|
||||
done();
|
||||
}).catch(done);
|
||||
});
|
||||
|
||||
it('can add a single tag to the middle of the tags array', function (done) {
|
||||
var newJSON = _.cloneDeep(postJSON);
|
||||
|
||||
// Add a single pre-existing tag to the middle of the array
|
||||
newJSON.tags = postJSON.tags.slice(0, 1).concat([tagJSON[0]]).concat(postJSON.tags.slice(1));
|
||||
|
||||
// Edit the post
|
||||
return PostModel.edit(newJSON, editOptions).then(function (updatedPost) {
|
||||
updatedPost = updatedPost.toJSON({include: ['tags']});
|
||||
|
||||
updatedPost.tags.should.have.lengthOf(4);
|
||||
updatedPost.tags.should.have.enumerable(0).with.properties({name: 'tag1', id: postJSON.tags[0].id});
|
||||
updatedPost.tags.should.have.enumerable(1).with.properties({name: 'existing tag a', id: tagJSON[0].id});
|
||||
updatedPost.tags.should.have.enumerable(2).with.properties({name: 'tag2', id: postJSON.tags[1].id});
|
||||
updatedPost.tags.should.have.enumerable(3).with.properties({name: 'tag3', id: postJSON.tags[2].id});
|
||||
|
||||
done();
|
||||
}).catch(done);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Removing tags', function () {
|
||||
it('can remove a single tag from the end of the tags array', function (done) {
|
||||
var newJSON = _.cloneDeep(postJSON);
|
||||
|
||||
// Remove a single tag from the end of the array
|
||||
newJSON.tags = postJSON.tags.slice(0, -1);
|
||||
|
||||
// Edit the post
|
||||
return PostModel.edit(newJSON, editOptions).then(function (updatedPost) {
|
||||
updatedPost = updatedPost.toJSON({include: ['tags']});
|
||||
|
||||
updatedPost.tags.should.have.lengthOf(2);
|
||||
updatedPost.tags.should.have.enumerable(0).with.properties({name: 'tag1', id: postJSON.tags[0].id});
|
||||
updatedPost.tags.should.have.enumerable(1).with.properties({name: 'tag2', id: postJSON.tags[1].id});
|
||||
|
||||
done();
|
||||
}).catch(done);
|
||||
});
|
||||
|
||||
it('can remove a single tag from the beginning of the tags array', function (done) {
|
||||
var newJSON = _.cloneDeep(postJSON);
|
||||
|
||||
// Remove a single tag from the beginning of the array
|
||||
newJSON.tags = postJSON.tags.slice(1);
|
||||
|
||||
// Edit the post
|
||||
return PostModel.edit(newJSON, editOptions).then(function (updatedPost) {
|
||||
updatedPost = updatedPost.toJSON({include: ['tags']});
|
||||
|
||||
updatedPost.tags.should.have.lengthOf(2);
|
||||
updatedPost.tags.should.have.enumerable(0).with.properties({name: 'tag2', id: postJSON.tags[1].id});
|
||||
updatedPost.tags.should.have.enumerable(1).with.properties({name: 'tag3', id: postJSON.tags[2].id});
|
||||
|
||||
done();
|
||||
}).catch(done);
|
||||
});
|
||||
|
||||
it('can remove all tags', function (done) {
|
||||
var newJSON = _.cloneDeep(postJSON);
|
||||
|
||||
// Remove all the tags
|
||||
newJSON.tags = [];
|
||||
|
||||
// Edit the post
|
||||
return PostModel.edit(newJSON, editOptions).then(function (updatedPost) {
|
||||
updatedPost = updatedPost.toJSON({include: ['tags']});
|
||||
|
||||
updatedPost.tags.should.have.lengthOf(0);
|
||||
|
||||
done();
|
||||
}).catch(done);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Reordering tags', function () {
|
||||
it('can reorder the first tag to be the last', function (done) {
|
||||
var newJSON = _.cloneDeep(postJSON),
|
||||
firstTag = [postJSON.tags[0]];
|
||||
|
||||
// Reorder the tags, so that the first tag is moved to the end
|
||||
newJSON.tags = postJSON.tags.slice(1).concat(firstTag);
|
||||
|
||||
// Edit the post
|
||||
return PostModel.edit(newJSON, editOptions).then(function (updatedPost) {
|
||||
updatedPost = updatedPost.toJSON({include: ['tags']});
|
||||
|
||||
updatedPost.tags.should.have.lengthOf(3);
|
||||
updatedPost.tags.should.have.enumerable(0).with.properties({name: 'tag2', id: postJSON.tags[1].id});
|
||||
updatedPost.tags.should.have.enumerable(1).with.properties({name: 'tag3', id: postJSON.tags[2].id});
|
||||
updatedPost.tags.should.have.enumerable(2).with.properties({name: 'tag1', id: postJSON.tags[0].id});
|
||||
|
||||
done();
|
||||
}).catch(done);
|
||||
});
|
||||
|
||||
it('can reorder the last tag to be the first', function (done) {
|
||||
var newJSON = _.cloneDeep(postJSON),
|
||||
lastTag = [postJSON.tags[2]];
|
||||
|
||||
// Reorder the tags, so that the last tag is moved to the beginning
|
||||
newJSON.tags = lastTag.concat(postJSON.tags.slice(0, -1));
|
||||
|
||||
// Edit the post
|
||||
return PostModel.edit(newJSON, editOptions).then(function (updatedPost) {
|
||||
updatedPost = updatedPost.toJSON({include: ['tags']});
|
||||
|
||||
updatedPost.tags.should.have.lengthOf(3);
|
||||
updatedPost.tags.should.have.enumerable(0).with.properties({name: 'tag3', id: postJSON.tags[2].id});
|
||||
updatedPost.tags.should.have.enumerable(1).with.properties({name: 'tag1', id: postJSON.tags[0].id});
|
||||
updatedPost.tags.should.have.enumerable(2).with.properties({name: 'tag2', id: postJSON.tags[1].id});
|
||||
|
||||
done();
|
||||
}).catch(done);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Combination updates', function () {
|
||||
it('can add a combination of new and pre-existing tags', function (done) {
|
||||
var newJSON = _.cloneDeep(postJSON);
|
||||
|
||||
// Push a bunch of new and existing tags to the end of the array
|
||||
newJSON.tags.push({name: 'tag4'});
|
||||
newJSON.tags.push({name: 'existing tag a'});
|
||||
newJSON.tags.push({name: 'tag5'});
|
||||
newJSON.tags.push({name: 'existing-tag-b'});
|
||||
newJSON.tags.push({name: 'bob'});
|
||||
newJSON.tags.push({name: 'existing_tag_c'});
|
||||
|
||||
// Edit the post
|
||||
return PostModel.edit(newJSON, editOptions).then(function (updatedPost) {
|
||||
updatedPost = updatedPost.toJSON({include: ['tags']});
|
||||
|
||||
updatedPost.tags.should.have.lengthOf(9);
|
||||
updatedPost.tags.should.have.enumerable(0).with.properties({name: 'tag1', id: postJSON.tags[0].id});
|
||||
updatedPost.tags.should.have.enumerable(1).with.properties({name: 'tag2', id: postJSON.tags[1].id});
|
||||
updatedPost.tags.should.have.enumerable(2).with.properties({name: 'tag3', id: postJSON.tags[2].id});
|
||||
updatedPost.tags.should.have.enumerable(3).with.property('name', 'tag4');
|
||||
updatedPost.tags.should.have.enumerable(4).with.properties({name: 'existing tag a', id: tagJSON[0].id});
|
||||
updatedPost.tags.should.have.enumerable(5).with.property('name', 'tag5');
|
||||
updatedPost.tags.should.have.enumerable(6).with.properties({name: 'existing-tag-b', id: tagJSON[1].id});
|
||||
updatedPost.tags.should.have.enumerable(7).with.property('name', 'bob');
|
||||
updatedPost.tags.should.have.enumerable(8).with.properties({name: 'existing_tag_c', id: tagJSON[2].id});
|
||||
|
||||
done();
|
||||
}).catch(done);
|
||||
});
|
||||
|
||||
it('can reorder the first tag to be the last and add a tag to the beginning', function (done) {
|
||||
var newJSON = _.cloneDeep(postJSON),
|
||||
firstTag = [postJSON.tags[0]];
|
||||
|
||||
// Add a new tag to the beginning, and move the original first tag to the end
|
||||
newJSON.tags = [tagJSON[0]].concat(postJSON.tags.slice(1)).concat(firstTag);
|
||||
|
||||
// Edit the post
|
||||
return PostModel.edit(newJSON, editOptions).then(function (updatedPost) {
|
||||
updatedPost = updatedPost.toJSON({include: ['tags']});
|
||||
|
||||
updatedPost.tags.should.have.lengthOf(4);
|
||||
updatedPost.tags.should.have.enumerable(0).with.properties({name: 'existing tag a', id: tagJSON[0].id});
|
||||
updatedPost.tags.should.have.enumerable(1).with.properties({name: 'tag2', id: postJSON.tags[1].id});
|
||||
updatedPost.tags.should.have.enumerable(2).with.properties({name: 'tag3', id: postJSON.tags[2].id});
|
||||
updatedPost.tags.should.have.enumerable(3).with.properties({name: 'tag1', id: postJSON.tags[0].id});
|
||||
|
||||
done();
|
||||
}).catch(done);
|
||||
});
|
||||
|
||||
it('can reorder the first tag to be the last, remove the original last tag & add a tag to the beginning', function (done) {
|
||||
var newJSON = _.cloneDeep(postJSON),
|
||||
firstTag = [newJSON.tags[0]];
|
||||
|
||||
// And an existing tag to the beginning of the array, move the original first tag to the end and remove the original last tag
|
||||
newJSON.tags = [tagJSON[0]].concat(newJSON.tags.slice(1, -1)).concat(firstTag);
|
||||
|
||||
// Edit the post
|
||||
return PostModel.edit(newJSON, editOptions).then(function (updatedPost) {
|
||||
updatedPost = updatedPost.toJSON({include: ['tags']});
|
||||
|
||||
updatedPost.tags.should.have.lengthOf(3);
|
||||
updatedPost.tags.should.have.enumerable(0).with.properties({name: 'existing tag a', id: tagJSON[0].id});
|
||||
updatedPost.tags.should.have.enumerable(1).with.properties({name: 'tag2', id: postJSON.tags[1].id});
|
||||
updatedPost.tags.should.have.enumerable(2).with.properties({name: 'tag1', id: postJSON.tags[0].id});
|
||||
|
||||
done();
|
||||
}).catch(done);
|
||||
});
|
||||
|
||||
it('can reorder original tags, remove one, and add new and existing tags', function (done) {
|
||||
var newJSON = _.cloneDeep(postJSON),
|
||||
firstTag = [newJSON.tags[0]];
|
||||
|
||||
// Reorder original 3 so that first is at the end
|
||||
newJSON.tags = newJSON.tags.slice(1).concat(firstTag);
|
||||
|
||||
// add an existing tag in the middle
|
||||
newJSON.tags = newJSON.tags.slice(0, 1).concat({name: 'existing-tag-b'}).concat(newJSON.tags.slice(1));
|
||||
|
||||
// add a brand new tag in the middle
|
||||
newJSON.tags = newJSON.tags.slice(0, 3).concat({name: 'betty'}).concat(newJSON.tags.slice(3));
|
||||
|
||||
// Add some more tags to the end
|
||||
newJSON.tags.push({name: 'bob'});
|
||||
newJSON.tags.push({name: 'existing tag a'});
|
||||
|
||||
// Edit the post
|
||||
return PostModel.edit(newJSON, editOptions).then(function (updatedPost) {
|
||||
updatedPost = updatedPost.toJSON({include: ['tags']});
|
||||
|
||||
updatedPost.tags.should.have.lengthOf(7);
|
||||
|
||||
updatedPost.tags.should.have.enumerable(0).with.properties({name: 'tag2', id: postJSON.tags[1].id});
|
||||
updatedPost.tags.should.have.enumerable(1).with.properties({name: 'existing-tag-b', id: tagJSON[1].id});
|
||||
updatedPost.tags.should.have.enumerable(2).with.properties({name: 'tag3', id: postJSON.tags[2].id});
|
||||
updatedPost.tags.should.have.enumerable(3).with.property('name', 'betty');
|
||||
updatedPost.tags.should.have.enumerable(4).with.properties({name: 'tag1', id: postJSON.tags[0].id});
|
||||
updatedPost.tags.should.have.enumerable(5).with.property('name', 'bob');
|
||||
updatedPost.tags.should.have.enumerable(6).with.properties({name: 'existing tag a', id: tagJSON[0].id});
|
||||
|
||||
done();
|
||||
}).catch(done);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user