Skip to content

Commit

Permalink
fix(model): handle true timestamp fields correctly (#12580)
Browse files Browse the repository at this point in the history
Co-authored-by: Pedro Augusto de Paula Barbosa <papb1996@gmail.com>
  • Loading branch information
vishal-sood and papb committed Aug 1, 2020
1 parent 6c99ba0 commit 0a86b15
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 3 deletions.
18 changes: 15 additions & 3 deletions lib/model.js
Original file line number Diff line number Diff line change
Expand Up @@ -1022,16 +1022,28 @@ class Model {

// setup names of timestamp attributes
if (this.options.timestamps) {
for (const key of ['createdAt', 'updatedAt', 'deletedAt']) {
if (!['undefined', 'string', 'boolean'].includes(typeof this.options[key])) {
throw new Error(`Value for "${key}" option must be a string or a boolean, got ${typeof this.options[key]}`);
}
if (this.options[key] === '') {
throw new Error(`Value for "${key}" option cannot be an empty string`);
}
}

if (this.options.createdAt !== false) {
this._timestampAttributes.createdAt = this.options.createdAt || 'createdAt';
this._timestampAttributes.createdAt =
typeof this.options.createdAt === 'string' ? this.options.createdAt : 'createdAt';
this._readOnlyAttributes.add(this._timestampAttributes.createdAt);
}
if (this.options.updatedAt !== false) {
this._timestampAttributes.updatedAt = this.options.updatedAt || 'updatedAt';
this._timestampAttributes.updatedAt =
typeof this.options.updatedAt === 'string' ? this.options.updatedAt : 'updatedAt';
this._readOnlyAttributes.add(this._timestampAttributes.updatedAt);
}
if (this.options.paranoid && this.options.deletedAt !== false) {
this._timestampAttributes.deletedAt = this.options.deletedAt || 'deletedAt';
this._timestampAttributes.deletedAt =
typeof this.options.deletedAt === 'string' ? this.options.deletedAt : 'deletedAt';
this._readOnlyAttributes.add(this._timestampAttributes.deletedAt);
}
}
Expand Down
40 changes: 40 additions & 0 deletions test/integration/model.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,46 @@ describe(Support.getTestDialectTeaser('Model'), () => {
expect(defaultFunction.callCount).to.equal(2);
});

it('should throw `TypeError` when value for updatedAt, createdAt, or deletedAt is neither string nor boolean', async function () {
const modelName = 'UserCol';
const attributes = { aNumber: Sequelize.INTEGER };

expect(() => {
this.sequelize.define(modelName, attributes, { timestamps: true, updatedAt: {} });
}).to.throw(Error, 'Value for "updatedAt" option must be a string or a boolean, got object');
expect(() => {
this.sequelize.define(modelName, attributes, { timestamps: true, createdAt: 100 });
}).to.throw(Error, 'Value for "createdAt" option must be a string or a boolean, got number');
expect(() => {
this.sequelize.define(modelName, attributes, { timestamps: true, deletedAt: () => {} });
}).to.throw(Error, 'Value for "deletedAt" option must be a string or a boolean, got function');
});

it('should allow me to use `true` as a value for updatedAt, createdAt, and deletedAt fields', async function () {
const UserTable = this.sequelize.define(
'UserCol',
{
aNumber: Sequelize.INTEGER
},
{
timestamps: true,
updatedAt: true,
createdAt: true,
deletedAt: true,
paranoid: true
}
);

await UserTable.sync({ force: true });
const user = await UserTable.create({ aNumber: 4 });
expect(user['true']).to.not.exist;
expect(user.updatedAt).to.exist;
expect(user.createdAt).to.exist;
await user.destroy();
await user.reload({ paranoid: false });
expect(user.deletedAt).to.exist;
});

it('should allow me to override updatedAt, createdAt, and deletedAt fields', async function() {
const UserTable = this.sequelize.define('UserCol', {
aNumber: Sequelize.INTEGER
Expand Down

0 comments on commit 0a86b15

Please sign in to comment.