不要怂,就是干,撸起袖子干!

Commit 02fb3faa by Sushant Committed by Jan Aagaard Meier

Fix #5880, deletedAt compare against NOW (#5897)

* test to check if deletedAt allow future dates

* compare deletedAt with NOW() rather than IS NULL

* fixed tests which depends upon old deletedAt behaviour

* fixed findAndCountAll test which depend upon deletedAt old behaviour
1 parent 8e0fd546
......@@ -5,6 +5,7 @@
- [CHANGED] Throw `bluebird.AggregateError` instead of array from `bulkCreate` when validation fails
- [FIXED] `$notIn: []` is now converted to `NOT IN (NULL)` [#4859](https://github.com/sequelize/sequelize/issues/4859)
- [FIXED] Add `raw` support to `instance.get()` [#5815](https://github.com/sequelize/sequelize/issues/5815)
- [ADDED] Compare deletedAt against current timestamp when using paranoid [#5880](https://github.com/sequelize/sequelize/pull/5880)
## BC breaks:
- `hookValidate` removed in favor of `validate` with `hooks: true | false`. `validate` returns a promise which is rejected if validation fails
......
......@@ -139,6 +139,8 @@ var paranoidClause = function(model, options) {
, deletedAtObject = {}
, deletedAtDefaultValue = deletedAtAttribute.hasOwnProperty('defaultValue') ? deletedAtAttribute.defaultValue : null;
deletedAtDefaultValue = deletedAtDefaultValue || { $or: { $gte: model.sequelize.literal('CURRENT_TIMESTAMP'), $eq: null } };
deletedAtObject[deletedAtAttribute.field || deletedAtCol] = deletedAtDefaultValue;
if (Utils._.isEmpty(options.where)) {
......
......@@ -2,11 +2,21 @@
var chai = require('chai')
, expect = chai.expect
, sinon = require('sinon')
, Support = require(__dirname + '/../support')
, DataTypes = require(__dirname + '/../../../lib/data-types')
, Promise = require('bluebird');
describe(Support.getTestDialectTeaser('Include'), function() {
before(function () {
this.clock = sinon.useFakeTimers();
});
after(function () {
this.clock.restore();
});
describe('findAndCountAll', function() {
it('should be able to include a required model. Result rows should match count', function() {
var User = this.sequelize.define('User', { name: DataTypes.STRING(40) }, { paranoid: true }),
......@@ -19,6 +29,8 @@ describe(Support.getTestDialectTeaser('Include'), function() {
B = this.sequelize.define('B', { name: DataTypes.STRING(40) }, { paranoid: true }),
C = this.sequelize.define('C', { name: DataTypes.STRING(40) }, { paranoid: true });
var self = this;
// Associate them
User.hasMany(SomeConnection, { foreignKey: 'u', constraints: false });
......@@ -84,13 +96,13 @@ describe(Support.getTestDialectTeaser('Include'), function() {
{ name: 'because we only want A' }
])
).then(function () {
// Delete some of conns to prove the concept
return SomeConnection.destroy({where: {
m: 'A',
u: 1,
fk: [1, 2]
}}).then(function() {
self.clock.tick(1000);
// Last and most important queries ( we connected 4, but deleted 2, witch means we must get 2 only )
return A.findAndCountAll({
include: [{
......
......@@ -2,6 +2,7 @@
var chai = require('chai')
, expect = chai.expect
, sinon = require('sinon')
, Support = require(__dirname + '/../support')
, DataTypes = require(__dirname + '/../../../lib/data-types');
......@@ -31,6 +32,14 @@ describe(Support.getTestDialectTeaser('Paranoid'), function() {
return S.sync({ force: true });
});
before(function () {
this.clock = sinon.useFakeTimers();
});
after(function () {
this.clock.restore();
});
it('paranoid with timestamps: false should be ignored / not crash', function() {
var S = this.sequelize
, Test = S.define('Test', {
......@@ -108,6 +117,9 @@ describe(Support.getTestDialectTeaser('Paranoid'), function() {
}).then(function () {
return this.y.destroy();
}).then(function () {
//prevent CURRENT_TIMESTAMP to be same
this.clock.tick(1000);
return X.findAll({
include: [Y]
}).get(0);
......
......@@ -2,6 +2,7 @@
/* jshint -W030 */
var chai = require('chai')
, sinon = require('sinon')
, Sequelize = require('../../../../index')
, Promise = Sequelize.Promise
, expect = chai.expect
......@@ -10,6 +11,15 @@ var chai = require('chai')
, dialect = Support.getTestDialect();
describe(Support.getTestDialectTeaser('Model'), function() {
before(function () {
this.clock = sinon.useFakeTimers();
});
after(function () {
this.clock.restore();
});
describe('attributes', function() {
describe('field', function() {
beforeEach(function() {
......@@ -523,16 +533,22 @@ describe(Support.getTestDialectTeaser('Model'), function() {
paranoid: true
});
return User.sync({force: true}).then(function () {
return User.create().then(function (user) {
return User.sync({force: true})
.bind(this)
.then(function () {
return User.create();
})
.then(function (user) {
return user.destroy();
}).then(function () {
return User.findAll().then(function (users) {
})
.then(function () {
this.clock.tick(1000);
return User.findAll();
})
.then(function (users) {
expect(users.length).to.equal(0);
});
});
});
});
it('should work with paranoid Model.destroy()', function () {
var User = this.sequelize.define('User', {
......
......@@ -7,6 +7,7 @@ var chai = require('chai')
, Sequelize = require('../../../index')
, Promise = Sequelize.Promise
, expect = chai.expect
, moment = require('moment')
, Support = require(__dirname + '/../support')
, DataTypes = require(__dirname + '/../../../lib/data-types')
, config = require(__dirname + '/../../config/config')
......@@ -987,5 +988,28 @@ describe(Support.getTestDialectTeaser('Model'), function() {
});
it('should find records where deletedAt set to future', function() {
var User = this.sequelize.define('paranoiduser', {
username: Sequelize.STRING
}, { paranoid: true });
return User.sync({ force: true }).then(function() {
return User.bulkCreate([
{username: 'Bob'},
{username: 'Tobi', deletedAt: moment().add(30, 'minutes').format()},
{username: 'Max', deletedAt: moment().add(30, 'days').format()},
{username: 'Tony', deletedAt: moment().subtract(30, 'days').format()}
]);
}).then(function() {
return User.find({ where: {username: 'Tobi'} });
}).then(function(tobi) {
expect(tobi).not.to.be.null;
}).then(function() {
return User.findAll();
}).then(function(users) {
expect(users.length).to.be.eql(3);
});
});
});
});
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!