0
Fork 0
mirror of https://github.com/TryGhost/Ghost.git synced 2025-01-27 22:49:56 -05:00

Fixed transactions for Tag.destroy

no issue

- if you pass a transaction to `Tag.destroy`, it would freeze
- because `detach(null, options)` was missing
- added a new test
This commit is contained in:
kirrg001 2018-03-21 21:25:02 +01:00 committed by Katharina Irrgang
parent e7529de773
commit 0ae6cbe34d
2 changed files with 91 additions and 70 deletions

View file

@ -103,8 +103,12 @@ Tag = ghostBookshelf.Model.extend({
var options = this.filterOptions(unfilteredOptions, 'destroy', {extraAllowedProperties: ['id']}); var options = this.filterOptions(unfilteredOptions, 'destroy', {extraAllowedProperties: ['id']});
options.withRelated = ['posts']; options.withRelated = ['posts'];
return this.forge({id: options.id}).fetch(options).then(function destroyTagsAndPost(tag) { return this.forge({id: options.id})
return tag.related('posts').detach().then(function destroyTags() { .fetch(options)
.then(function destroyTagsAndPost(tag) {
return tag.related('posts')
.detach(null, options)
.then(function destroyTags() {
return tag.destroy(options); return tag.destroy(options);
}); });
}); });

View file

@ -1,14 +1,13 @@
var should = require('should'), var should = require('should'),
sinon = require('sinon'), sinon = require('sinon'),
_ = require('lodash'),
testUtils = require('../../utils'), testUtils = require('../../utils'),
// Stuff we are testing // Stuff we are testing
ModelsTag = require('../../../server/models/tag'), db = require('../../../server/data/db'),
ModelsPost = require('../../../server/models/post'), models = require('../../../server/models'),
common = require('../../../server/lib/common'), common = require('../../../server/lib/common'),
context = testUtils.context.admin, context = testUtils.context.admin,
TagModel,
PostModel,
sandbox = sinon.sandbox.create(); sandbox = sinon.sandbox.create();
describe('Tag Model', function () { describe('Tag Model', function () {
@ -17,65 +16,60 @@ describe('Tag Model', function () {
// Keep the DB clean // Keep the DB clean
before(testUtils.teardown); before(testUtils.teardown);
afterEach(testUtils.teardown); afterEach(testUtils.teardown);
beforeEach(testUtils.setup('users:roles')); beforeEach(testUtils.setup('users:roles', 'posts'));
afterEach(function () { afterEach(function () {
sandbox.restore(); sandbox.restore();
}); });
beforeEach(function () { beforeEach(function () {
eventSpy = sandbox.spy(common.events, 'emit'); eventSpy = sandbox.spy(common.events, 'emit');
}); });
before(function () { describe('add', function () {
TagModel = ModelsTag.Tag;
PostModel = ModelsPost.Post;
should.exist(TagModel);
should.exist(PostModel);
});
it('uses Date objects for dateTime fields', function (done) { it('uses Date objects for dateTime fields', function (done) {
TagModel.add(testUtils.DataGenerator.forModel.tags[0], context).then(function (tag) { models.Tag.add(_.omit(testUtils.DataGenerator.forModel.tags[0], 'id'), context)
return TagModel.findOne({id: tag.id}); .then(function (tag) {
}).then(function (tag) { return models.Tag.findOne({id: tag.id});
})
.then(function (tag) {
should.exist(tag); should.exist(tag);
tag.get('created_at').should.be.an.instanceof(Date); tag.get('created_at').should.be.an.instanceof(Date);
done(); done();
}).catch(done); })
.catch(done);
}); });
it('returns count.posts if include count.posts', function (done) { it('returns count.posts if include count.posts', function (done) {
testUtils.fixtures.insertPostsAndTags().then(function () { models.Tag.findOne({slug: 'kitchen-sink'}, {withRelated: ['count.posts']})
TagModel.findOne({slug: 'kitchen-sink'}, {withRelated: ['count.posts']}).then(function (tag) { .then(function (tag) {
should.exist(tag); should.exist(tag);
tag.toJSON().count.posts.should.equal(2); tag.toJSON().count.posts.should.equal(2);
done(); done();
}).catch(done); })
.catch(done);
}); });
}); });
describe('findPage', function () { describe('findPage', function () {
beforeEach(function (done) {
testUtils.fixtures.insertPostsAndTags().then(function () {
done();
}).catch(done);
});
it('with limit all', function (done) { it('with limit all', function (done) {
TagModel.findPage({limit: 'all'}).then(function (results) { models.Tag.findPage({limit: 'all'})
.then(function (results) {
results.meta.pagination.page.should.equal(1); results.meta.pagination.page.should.equal(1);
results.meta.pagination.limit.should.equal('all'); results.meta.pagination.limit.should.equal('all');
results.meta.pagination.pages.should.equal(1); results.meta.pagination.pages.should.equal(1);
results.tags.length.should.equal(5); results.tags.length.should.equal(5);
done(); done();
}).catch(done); })
.catch(done);
}); });
it('with include count.posts', function (done) { it('with include count.posts', function (done) {
TagModel.findPage({limit: 'all', withRelated: ['count.posts']}).then(function (results) { models.Tag.findPage({limit: 'all', withRelated: ['count.posts']})
.then(function (results) {
results.meta.pagination.page.should.equal(1); results.meta.pagination.page.should.equal(1);
results.meta.pagination.limit.should.equal('all'); results.meta.pagination.limit.should.equal('all');
results.meta.pagination.pages.should.equal(1); results.meta.pagination.pages.should.equal(1);
@ -83,32 +77,55 @@ describe('Tag Model', function () {
should.exist(results.tags[0].count.posts); should.exist(results.tags[0].count.posts);
done(); done();
}).catch(done); })
.catch(done);
}); });
}); });
describe('findOne', function () { describe('findOne', function () {
beforeEach(function (done) {
testUtils.fixtures.insertPostsAndTags().then(function () {
done();
}).catch(done);
});
it('with slug', function (done) { it('with slug', function (done) {
var firstTag; var firstTag;
TagModel.findPage().then(function (results) { models.Tag.findPage()
.then(function (results) {
should.exist(results); should.exist(results);
should.exist(results.tags); should.exist(results.tags);
results.tags.length.should.be.above(0); results.tags.length.should.be.above(0);
firstTag = results.tags[0]; firstTag = results.tags[0];
return TagModel.findOne({slug: firstTag.slug}); return models.Tag.findOne({slug: firstTag.slug});
}).then(function (found) { })
.then(function (found) {
should.exist(found); should.exist(found);
done(); done();
}).catch(done); })
.catch(done);
});
});
describe('destroy', function () {
it('can destroy Tag (using transaction)', function () {
var firstTag = testUtils.DataGenerator.Content.tags[0].id;
return db.knex('posts_tags').where('tag_id', firstTag)
.then(function (response) {
response.length.should.eql(2);
})
.then(function () {
return db.knex.transaction(function (transacting) {
return models.Tag.destroy({
id: firstTag,
transacting: transacting
});
});
})
.then(function () {
return db.knex('posts_tags').where('tag_id', firstTag);
})
.then(function (response) {
response.length.should.eql(0);
});
}); });
}); });
}); });