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

Commit b49a24d4 by Andy Edwards Committed by GitHub

fix(test/integration/hooks): asyncify (#12251)

1 parent 4dbfb5d1
......@@ -8,7 +8,7 @@ const chai = require('chai'),
dialect = Support.getTestDialect();
describe(Support.getTestDialectTeaser('Hooks'), () => {
beforeEach(function() {
beforeEach(async function() {
this.User = this.sequelize.define('User', {
username: {
type: DataTypes.STRING,
......@@ -30,14 +30,14 @@ describe(Support.getTestDialectTeaser('Hooks'), () => {
paranoid: true
});
return this.sequelize.sync({ force: true });
await this.sequelize.sync({ force: true });
});
describe('associations', () => {
describe('1:1', () => {
describe('cascade onUpdate', () => {
beforeEach(function() {
beforeEach(async function() {
this.Projects = this.sequelize.define('Project', {
title: DataTypes.STRING
});
......@@ -49,54 +49,49 @@ describe(Support.getTestDialectTeaser('Hooks'), () => {
this.Projects.hasOne(this.Tasks, { onUpdate: 'cascade', hooks: true });
this.Tasks.belongsTo(this.Projects);
return this.Projects.sync({ force: true }).then(() => {
return this.Tasks.sync({ force: true });
});
await this.Projects.sync({ force: true });
await this.Tasks.sync({ force: true });
});
it('on success', function() {
it('on success', async function() {
let beforeHook = false,
afterHook = false;
this.Tasks.beforeUpdate(() => {
this.Tasks.beforeUpdate(async () => {
beforeHook = true;
return Promise.resolve();
});
this.Tasks.afterUpdate(() => {
this.Tasks.afterUpdate(async () => {
afterHook = true;
return Promise.resolve();
});
return this.Projects.create({ title: 'New Project' }).then(project => {
return this.Tasks.create({ title: 'New Task' }).then(task => {
return project.setTask(task).then(() => {
return project.update({ id: 2 }).then(() => {
const project = await this.Projects.create({ title: 'New Project' });
const task = await this.Tasks.create({ title: 'New Task' });
await project.setTask(task);
await project.update({ id: 2 });
expect(beforeHook).to.be.true;
expect(afterHook).to.be.true;
});
});
});
});
});
it('on error', function() {
this.Tasks.afterUpdate(() => {
return Promise.reject(new Error('Whoops!'));
it('on error', async function() {
this.Tasks.afterUpdate(async () => {
throw new Error('Whoops!');
});
return this.Projects.create({ title: 'New Project' }).then(project => {
return this.Tasks.create({ title: 'New Task' }).then(task => {
return project.setTask(task).catch(err => {
const project = await this.Projects.create({ title: 'New Project' });
const task = await this.Tasks.create({ title: 'New Task' });
try {
await project.setTask(task);
} catch (err) {
expect(err).to.be.instanceOf(Error);
});
});
});
}
});
});
describe('cascade onDelete', () => {
beforeEach(function() {
beforeEach(async function() {
this.Projects = this.sequelize.define('Project', {
title: DataTypes.STRING
});
......@@ -108,11 +103,11 @@ describe(Support.getTestDialectTeaser('Hooks'), () => {
this.Projects.hasOne(this.Tasks, { onDelete: 'CASCADE', hooks: true });
this.Tasks.belongsTo(this.Projects);
return this.sequelize.sync({ force: true });
await this.sequelize.sync({ force: true });
});
describe('#remove', () => {
it('with no errors', function() {
it('with no errors', async function() {
const beforeProject = sinon.spy(),
afterProject = sinon.spy(),
beforeTask = sinon.spy(),
......@@ -123,51 +118,44 @@ describe(Support.getTestDialectTeaser('Hooks'), () => {
this.Tasks.beforeDestroy(beforeTask);
this.Tasks.afterDestroy(afterTask);
return this.Projects.create({ title: 'New Project' }).then(project => {
return this.Tasks.create({ title: 'New Task' }).then(task => {
return project.setTask(task).then(() => {
return project.destroy().then(() => {
const project = await this.Projects.create({ title: 'New Project' });
const task = await this.Tasks.create({ title: 'New Task' });
await project.setTask(task);
await project.destroy();
expect(beforeProject).to.have.been.calledOnce;
expect(afterProject).to.have.been.calledOnce;
expect(beforeTask).to.have.been.calledOnce;
expect(afterTask).to.have.been.calledOnce;
});
});
});
});
});
it('with errors', function() {
it('with errors', async function() {
const CustomErrorText = 'Whoops!';
let beforeProject = false,
afterProject = false,
beforeTask = false,
afterTask = false;
this.Projects.beforeCreate(() => {
this.Projects.beforeCreate(async () => {
beforeProject = true;
return Promise.resolve();
});
this.Projects.afterCreate(() => {
this.Projects.afterCreate(async () => {
afterProject = true;
return Promise.resolve();
});
this.Tasks.beforeDestroy(() => {
this.Tasks.beforeDestroy(async () => {
beforeTask = true;
return Promise.reject(new Error(CustomErrorText));
throw new Error(CustomErrorText);
});
this.Tasks.afterDestroy(() => {
this.Tasks.afterDestroy(async () => {
afterTask = true;
return Promise.resolve();
});
return this.Projects.create({ title: 'New Project' }).then(project => {
return this.Tasks.create({ title: 'New Task' }).then(task => {
return project.setTask(task).then(() => {
return expect(project.destroy()).to.eventually.be.rejectedWith(CustomErrorText).then(() => {
const project = await this.Projects.create({ title: 'New Project' });
const task = await this.Tasks.create({ title: 'New Task' });
await project.setTask(task);
await expect(project.destroy()).to.eventually.be.rejectedWith(CustomErrorText);
expect(beforeProject).to.be.true;
expect(afterProject).to.be.true;
expect(beforeTask).to.be.true;
......@@ -175,13 +163,9 @@ describe(Support.getTestDialectTeaser('Hooks'), () => {
});
});
});
});
});
});
});
describe('no cascade update', () => {
beforeEach(function() {
beforeEach(async function() {
this.Projects = this.sequelize.define('Project', {
title: DataTypes.STRING
});
......@@ -193,45 +177,40 @@ describe(Support.getTestDialectTeaser('Hooks'), () => {
this.Projects.hasOne(this.Tasks);
this.Tasks.belongsTo(this.Projects);
return this.Projects.sync({ force: true }).then(() => {
return this.Tasks.sync({ force: true });
});
await this.Projects.sync({ force: true });
await this.Tasks.sync({ force: true });
});
it('on success', function() {
it('on success', async function() {
const beforeHook = sinon.spy(),
afterHook = sinon.spy();
this.Tasks.beforeUpdate(beforeHook);
this.Tasks.afterUpdate(afterHook);
return this.Projects.create({ title: 'New Project' }).then(project => {
return this.Tasks.create({ title: 'New Task' }).then(task => {
return project.setTask(task).then(() => {
return project.update({ id: 2 }).then(() => {
const project = await this.Projects.create({ title: 'New Project' });
const task = await this.Tasks.create({ title: 'New Task' });
await project.setTask(task);
await project.update({ id: 2 });
expect(beforeHook).to.have.been.calledOnce;
expect(afterHook).to.have.been.calledOnce;
});
});
});
});
});
it('on error', function() {
it('on error', async function() {
this.Tasks.afterUpdate(() => {
throw new Error('Whoops!');
});
return this.Projects.create({ title: 'New Project' }).then(project => {
return this.Tasks.create({ title: 'New Task' }).then(task => {
return expect(project.setTask(task)).to.be.rejected;
});
});
const project = await this.Projects.create({ title: 'New Project' });
const task = await this.Tasks.create({ title: 'New Task' });
await expect(project.setTask(task)).to.be.rejected;
});
});
describe('no cascade delete', () => {
beforeEach(function() {
beforeEach(async function() {
this.Projects = this.sequelize.define('Project', {
title: DataTypes.STRING
});
......@@ -243,13 +222,13 @@ describe(Support.getTestDialectTeaser('Hooks'), () => {
this.Projects.hasMany(this.Tasks);
this.Tasks.belongsTo(this.Projects);
return this.Projects.sync({ force: true }).then(() => {
return this.Tasks.sync({ force: true });
});
await this.Projects.sync({ force: true });
await this.Tasks.sync({ force: true });
});
describe('#remove', () => {
it('with no errors', function() {
it('with no errors', async function() {
const beforeProject = sinon.spy(),
afterProject = sinon.spy(),
beforeTask = sinon.spy(),
......@@ -260,21 +239,17 @@ describe(Support.getTestDialectTeaser('Hooks'), () => {
this.Tasks.beforeUpdate(beforeTask);
this.Tasks.afterUpdate(afterTask);
return this.Projects.create({ title: 'New Project' }).then(project => {
return this.Tasks.create({ title: 'New Task' }).then(task => {
return project.addTask(task).then(() => {
return project.removeTask(task).then(() => {
const project = await this.Projects.create({ title: 'New Project' });
const task = await this.Tasks.create({ title: 'New Task' });
await project.addTask(task);
await project.removeTask(task);
expect(beforeProject).to.have.been.called;
expect(afterProject).to.have.been.called;
expect(beforeTask).not.to.have.been.called;
expect(afterTask).not.to.have.been.called;
});
});
});
});
});
it('with errors', function() {
it('with errors', async function() {
const beforeProject = sinon.spy(),
afterProject = sinon.spy(),
beforeTask = sinon.spy(),
......@@ -288,17 +263,18 @@ describe(Support.getTestDialectTeaser('Hooks'), () => {
});
this.Tasks.afterUpdate(afterTask);
return this.Projects.create({ title: 'New Project' }).then(project => {
return this.Tasks.create({ title: 'New Task' }).then(task => {
return project.addTask(task).catch(err => {
const project = await this.Projects.create({ title: 'New Project' });
const task = await this.Tasks.create({ title: 'New Task' });
try {
await project.addTask(task);
} catch (err) {
expect(err).to.be.instanceOf(Error);
expect(beforeProject).to.have.been.calledOnce;
expect(afterProject).to.have.been.calledOnce;
expect(beforeTask).to.have.been.calledOnce;
expect(afterTask).not.to.have.been.called;
});
});
});
}
});
});
});
......@@ -306,7 +282,7 @@ describe(Support.getTestDialectTeaser('Hooks'), () => {
describe('1:M', () => {
describe('cascade', () => {
beforeEach(function() {
beforeEach(async function() {
this.Projects = this.sequelize.define('Project', {
title: DataTypes.STRING
});
......@@ -318,13 +294,13 @@ describe(Support.getTestDialectTeaser('Hooks'), () => {
this.Projects.hasMany(this.Tasks, { onDelete: 'cascade', hooks: true });
this.Tasks.belongsTo(this.Projects, { hooks: true });
return this.Projects.sync({ force: true }).then(() => {
return this.Tasks.sync({ force: true });
});
await this.Projects.sync({ force: true });
await this.Tasks.sync({ force: true });
});
describe('#remove', () => {
it('with no errors', function() {
it('with no errors', async function() {
const beforeProject = sinon.spy(),
afterProject = sinon.spy(),
beforeTask = sinon.spy(),
......@@ -335,65 +311,58 @@ describe(Support.getTestDialectTeaser('Hooks'), () => {
this.Tasks.beforeDestroy(beforeTask);
this.Tasks.afterDestroy(afterTask);
return this.Projects.create({ title: 'New Project' }).then(project => {
return this.Tasks.create({ title: 'New Task' }).then(task => {
return project.addTask(task).then(() => {
return project.destroy().then(() => {
const project = await this.Projects.create({ title: 'New Project' });
const task = await this.Tasks.create({ title: 'New Task' });
await project.addTask(task);
await project.destroy();
expect(beforeProject).to.have.been.calledOnce;
expect(afterProject).to.have.been.calledOnce;
expect(beforeTask).to.have.been.calledOnce;
expect(afterTask).to.have.been.calledOnce;
});
});
});
});
});
it('with errors', function() {
it('with errors', async function() {
let beforeProject = false,
afterProject = false,
beforeTask = false,
afterTask = false;
this.Projects.beforeCreate(() => {
this.Projects.beforeCreate(async () => {
beforeProject = true;
return Promise.resolve();
});
this.Projects.afterCreate(() => {
this.Projects.afterCreate(async () => {
afterProject = true;
return Promise.resolve();
});
this.Tasks.beforeDestroy(() => {
this.Tasks.beforeDestroy(async () => {
beforeTask = true;
return Promise.reject(new Error('Whoops!'));
throw new Error('Whoops!');
});
this.Tasks.afterDestroy(() => {
this.Tasks.afterDestroy(async () => {
afterTask = true;
return Promise.resolve();
});
return this.Projects.create({ title: 'New Project' }).then(project => {
return this.Tasks.create({ title: 'New Task' }).then(task => {
return project.addTask(task).then(() => {
return project.destroy().catch(err => {
const project = await this.Projects.create({ title: 'New Project' });
const task = await this.Tasks.create({ title: 'New Task' });
await project.addTask(task);
try {
await project.destroy();
} catch (err) {
expect(err).to.be.instanceOf(Error);
expect(beforeProject).to.be.true;
expect(afterProject).to.be.true;
expect(beforeTask).to.be.true;
expect(afterTask).to.be.false;
});
});
});
});
}
});
});
});
describe('no cascade', () => {
beforeEach(function() {
beforeEach(async function() {
this.Projects = this.sequelize.define('Project', {
title: DataTypes.STRING
});
......@@ -405,11 +374,11 @@ describe(Support.getTestDialectTeaser('Hooks'), () => {
this.Projects.hasMany(this.Tasks);
this.Tasks.belongsTo(this.Projects);
return this.sequelize.sync({ force: true });
await this.sequelize.sync({ force: true });
});
describe('#remove', () => {
it('with no errors', function() {
it('with no errors', async function() {
const beforeProject = sinon.spy(),
afterProject = sinon.spy(),
beforeTask = sinon.spy(),
......@@ -420,57 +389,51 @@ describe(Support.getTestDialectTeaser('Hooks'), () => {
this.Tasks.beforeUpdate(beforeTask);
this.Tasks.afterUpdate(afterTask);
return this.Projects.create({ title: 'New Project' }).then(project => {
return this.Tasks.create({ title: 'New Task' }).then(task => {
return project.addTask(task).then(() => {
return project.removeTask(task).then(() => {
const project = await this.Projects.create({ title: 'New Project' });
const task = await this.Tasks.create({ title: 'New Task' });
await project.addTask(task);
await project.removeTask(task);
expect(beforeProject).to.have.been.called;
expect(afterProject).to.have.been.called;
expect(beforeTask).not.to.have.been.called;
expect(afterTask).not.to.have.been.called;
});
});
});
});
});
it('with errors', function() {
it('with errors', async function() {
let beforeProject = false,
afterProject = false,
beforeTask = false,
afterTask = false;
this.Projects.beforeCreate(() => {
this.Projects.beforeCreate(async () => {
beforeProject = true;
return Promise.resolve();
});
this.Projects.afterCreate(() => {
this.Projects.afterCreate(async () => {
afterProject = true;
return Promise.resolve();
});
this.Tasks.beforeUpdate(() => {
this.Tasks.beforeUpdate(async () => {
beforeTask = true;
return Promise.reject(new Error('Whoops!'));
throw new Error('Whoops!');
});
this.Tasks.afterUpdate(() => {
this.Tasks.afterUpdate(async () => {
afterTask = true;
return Promise.resolve();
});
return this.Projects.create({ title: 'New Project' }).then(project => {
return this.Tasks.create({ title: 'New Task' }).then(task => {
return project.addTask(task).catch(err => {
const project = await this.Projects.create({ title: 'New Project' });
const task = await this.Tasks.create({ title: 'New Task' });
try {
await project.addTask(task);
} catch (err) {
expect(err).to.be.instanceOf(Error);
expect(beforeProject).to.be.true;
expect(afterProject).to.be.true;
expect(beforeTask).to.be.true;
expect(afterTask).to.be.false;
});
});
});
}
});
});
});
......@@ -478,7 +441,7 @@ describe(Support.getTestDialectTeaser('Hooks'), () => {
describe('M:M', () => {
describe('cascade', () => {
beforeEach(function() {
beforeEach(async function() {
this.Projects = this.sequelize.define('Project', {
title: DataTypes.STRING
});
......@@ -490,11 +453,11 @@ describe(Support.getTestDialectTeaser('Hooks'), () => {
this.Projects.belongsToMany(this.Tasks, { cascade: 'onDelete', through: 'projects_and_tasks', hooks: true });
this.Tasks.belongsToMany(this.Projects, { cascade: 'onDelete', through: 'projects_and_tasks', hooks: true });
return this.sequelize.sync({ force: true });
await this.sequelize.sync({ force: true });
});
describe('#remove', () => {
it('with no errors', function() {
it('with no errors', async function() {
const beforeProject = sinon.spy(),
afterProject = sinon.spy(),
beforeTask = sinon.spy(),
......@@ -505,51 +468,44 @@ describe(Support.getTestDialectTeaser('Hooks'), () => {
this.Tasks.beforeDestroy(beforeTask);
this.Tasks.afterDestroy(afterTask);
return this.Projects.create({ title: 'New Project' }).then(project => {
return this.Tasks.create({ title: 'New Task' }).then(task => {
return project.addTask(task).then(() => {
return project.destroy().then(() => {
const project = await this.Projects.create({ title: 'New Project' });
const task = await this.Tasks.create({ title: 'New Task' });
await project.addTask(task);
await project.destroy();
expect(beforeProject).to.have.been.calledOnce;
expect(afterProject).to.have.been.calledOnce;
// Since Sequelize does not cascade M:M, these should be false
expect(beforeTask).not.to.have.been.called;
expect(afterTask).not.to.have.been.called;
});
});
});
});
});
it('with errors', function() {
it('with errors', async function() {
let beforeProject = false,
afterProject = false,
beforeTask = false,
afterTask = false;
this.Projects.beforeCreate(() => {
this.Projects.beforeCreate(async () => {
beforeProject = true;
return Promise.resolve();
});
this.Projects.afterCreate(() => {
this.Projects.afterCreate(async () => {
afterProject = true;
return Promise.resolve();
});
this.Tasks.beforeDestroy(() => {
this.Tasks.beforeDestroy(async () => {
beforeTask = true;
return Promise.reject(new Error('Whoops!'));
throw new Error('Whoops!');
});
this.Tasks.afterDestroy(() => {
this.Tasks.afterDestroy(async () => {
afterTask = true;
return Promise.resolve();
});
return this.Projects.create({ title: 'New Project' }).then(project => {
return this.Tasks.create({ title: 'New Task' }).then(task => {
return project.addTask(task).then(() => {
return project.destroy().then(() => {
const project = await this.Projects.create({ title: 'New Project' });
const task = await this.Tasks.create({ title: 'New Task' });
await project.addTask(task);
await project.destroy();
expect(beforeProject).to.be.true;
expect(afterProject).to.be.true;
expect(beforeTask).to.be.false;
......@@ -557,13 +513,9 @@ describe(Support.getTestDialectTeaser('Hooks'), () => {
});
});
});
});
});
});
});
describe('no cascade', () => {
beforeEach(function() {
beforeEach(async function() {
this.Projects = this.sequelize.define('Project', {
title: DataTypes.STRING
});
......@@ -575,11 +527,11 @@ describe(Support.getTestDialectTeaser('Hooks'), () => {
this.Projects.belongsToMany(this.Tasks, { hooks: true, through: 'project_tasks' });
this.Tasks.belongsToMany(this.Projects, { hooks: true, through: 'project_tasks' });
return this.sequelize.sync({ force: true });
await this.sequelize.sync({ force: true });
});
describe('#remove', () => {
it('with no errors', function() {
it('with no errors', async function() {
const beforeProject = sinon.spy(),
afterProject = sinon.spy(),
beforeTask = sinon.spy(),
......@@ -590,49 +542,42 @@ describe(Support.getTestDialectTeaser('Hooks'), () => {
this.Tasks.beforeUpdate(beforeTask);
this.Tasks.afterUpdate(afterTask);
return this.Projects.create({ title: 'New Project' }).then(project => {
return this.Tasks.create({ title: 'New Task' }).then(task => {
return project.addTask(task).then(() => {
return project.removeTask(task).then(() => {
const project = await this.Projects.create({ title: 'New Project' });
const task = await this.Tasks.create({ title: 'New Task' });
await project.addTask(task);
await project.removeTask(task);
expect(beforeProject).to.have.been.calledOnce;
expect(afterProject).to.have.been.calledOnce;
expect(beforeTask).not.to.have.been.called;
expect(afterTask).not.to.have.been.called;
});
});
});
});
});
it('with errors', function() {
it('with errors', async function() {
let beforeProject = false,
afterProject = false,
beforeTask = false,
afterTask = false;
this.Projects.beforeCreate(() => {
this.Projects.beforeCreate(async () => {
beforeProject = true;
return Promise.resolve();
});
this.Projects.afterCreate(() => {
this.Projects.afterCreate(async () => {
afterProject = true;
return Promise.resolve();
});
this.Tasks.beforeUpdate(() => {
this.Tasks.beforeUpdate(async () => {
beforeTask = true;
return Promise.reject(new Error('Whoops!'));
throw new Error('Whoops!');
});
this.Tasks.afterUpdate(() => {
this.Tasks.afterUpdate(async () => {
afterTask = true;
return Promise.resolve();
});
return this.Projects.create({ title: 'New Project' }).then(project => {
return this.Tasks.create({ title: 'New Task' }).then(task => {
return project.addTask(task).then(() => {
const project = await this.Projects.create({ title: 'New Project' });
const task = await this.Tasks.create({ title: 'New Task' });
await project.addTask(task);
expect(beforeProject).to.be.true;
expect(afterProject).to.be.true;
expect(beforeTask).to.be.false;
......@@ -641,16 +586,13 @@ describe(Support.getTestDialectTeaser('Hooks'), () => {
});
});
});
});
});
});
// NOTE: Reenable when FK constraints create table query is fixed when using hooks
if (dialect !== 'mssql') {
describe('multiple 1:M', () => {
describe('cascade', () => {
beforeEach(function() {
beforeEach(async function() {
this.Projects = this.sequelize.define('Project', {
title: DataTypes.STRING
});
......@@ -672,11 +614,11 @@ describe(Support.getTestDialectTeaser('Hooks'), () => {
this.MiniTasks.belongsTo(this.Projects, { hooks: true });
this.MiniTasks.belongsTo(this.Tasks, { hooks: true });
return this.sequelize.sync({ force: true });
await this.sequelize.sync({ force: true });
});
describe('#remove', () => {
it('with no errors', function() {
it('with no errors', async function() {
let beforeProject = false,
afterProject = false,
beforeTask = false,
......@@ -684,44 +626,37 @@ describe(Support.getTestDialectTeaser('Hooks'), () => {
beforeMiniTask = false,
afterMiniTask = false;
this.Projects.beforeCreate(() => {
this.Projects.beforeCreate(async () => {
beforeProject = true;
return Promise.resolve();
});
this.Projects.afterCreate(() => {
this.Projects.afterCreate(async () => {
afterProject = true;
return Promise.resolve();
});
this.Tasks.beforeDestroy(() => {
this.Tasks.beforeDestroy(async () => {
beforeTask = true;
return Promise.resolve();
});
this.Tasks.afterDestroy(() => {
this.Tasks.afterDestroy(async () => {
afterTask = true;
return Promise.resolve();
});
this.MiniTasks.beforeDestroy(() => {
this.MiniTasks.beforeDestroy(async () => {
beforeMiniTask = true;
return Promise.resolve();
});
this.MiniTasks.afterDestroy(() => {
this.MiniTasks.afterDestroy(async () => {
afterMiniTask = true;
return Promise.resolve();
});
return Promise.all([
const [project0, minitask] = await Promise.all([
this.Projects.create({ title: 'New Project' }),
this.MiniTasks.create({ mini_title: 'New MiniTask' })
]).then(([project, minitask]) => {
return project.addMiniTask(minitask);
}).then(project => {
return project.destroy();
}).then(() => {
]);
const project = await project0.addMiniTask(minitask);
await project.destroy();
expect(beforeProject).to.be.true;
expect(afterProject).to.be.true;
expect(beforeTask).to.be.false;
......@@ -730,9 +665,7 @@ describe(Support.getTestDialectTeaser('Hooks'), () => {
expect(afterMiniTask).to.be.true;
});
});
it('with errors', function() {
it('with errors', async function() {
let beforeProject = false,
afterProject = false,
beforeTask = false,
......@@ -740,51 +673,47 @@ describe(Support.getTestDialectTeaser('Hooks'), () => {
beforeMiniTask = false,
afterMiniTask = false;
this.Projects.beforeCreate(() => {
this.Projects.beforeCreate(async () => {
beforeProject = true;
return Promise.resolve();
});
this.Projects.afterCreate(() => {
this.Projects.afterCreate(async () => {
afterProject = true;
return Promise.resolve();
});
this.Tasks.beforeDestroy(() => {
this.Tasks.beforeDestroy(async () => {
beforeTask = true;
return Promise.resolve();
});
this.Tasks.afterDestroy(() => {
this.Tasks.afterDestroy(async () => {
afterTask = true;
return Promise.resolve();
});
this.MiniTasks.beforeDestroy(() => {
this.MiniTasks.beforeDestroy(async () => {
beforeMiniTask = true;
return Promise.reject(new Error('Whoops!'));
throw new Error('Whoops!');
});
this.MiniTasks.afterDestroy(() => {
this.MiniTasks.afterDestroy(async () => {
afterMiniTask = true;
return Promise.resolve();
});
return Promise.all([
try {
const [project0, minitask] = await Promise.all([
this.Projects.create({ title: 'New Project' }),
this.MiniTasks.create({ mini_title: 'New MiniTask' })
]).then(([project, minitask]) => {
return project.addMiniTask(minitask);
}).then(project => {
return project.destroy();
}).catch(() => {
]);
const project = await project0.addMiniTask(minitask);
await project.destroy();
} catch (err) {
expect(beforeProject).to.be.true;
expect(afterProject).to.be.true;
expect(beforeTask).to.be.false;
expect(afterTask).to.be.false;
expect(beforeMiniTask).to.be.true;
expect(afterMiniTask).to.be.false;
});
}
});
});
});
......@@ -792,7 +721,7 @@ describe(Support.getTestDialectTeaser('Hooks'), () => {
describe('multiple 1:M sequential hooks', () => {
describe('cascade', () => {
beforeEach(function() {
beforeEach(async function() {
this.Projects = this.sequelize.define('Project', {
title: DataTypes.STRING
});
......@@ -814,11 +743,11 @@ describe(Support.getTestDialectTeaser('Hooks'), () => {
this.MiniTasks.belongsTo(this.Projects, { hooks: true });
this.MiniTasks.belongsTo(this.Tasks, { hooks: true });
return this.sequelize.sync({ force: true });
await this.sequelize.sync({ force: true });
});
describe('#remove', () => {
it('with no errors', function() {
it('with no errors', async function() {
let beforeProject = false,
afterProject = false,
beforeTask = false,
......@@ -826,48 +755,43 @@ describe(Support.getTestDialectTeaser('Hooks'), () => {
beforeMiniTask = false,
afterMiniTask = false;
this.Projects.beforeCreate(() => {
this.Projects.beforeCreate(async () => {
beforeProject = true;
return Promise.resolve();
});
this.Projects.afterCreate(() => {
this.Projects.afterCreate(async () => {
afterProject = true;
return Promise.resolve();
});
this.Tasks.beforeDestroy(() => {
this.Tasks.beforeDestroy(async () => {
beforeTask = true;
return Promise.resolve();
});
this.Tasks.afterDestroy(() => {
this.Tasks.afterDestroy(async () => {
afterTask = true;
return Promise.resolve();
});
this.MiniTasks.beforeDestroy(() => {
this.MiniTasks.beforeDestroy(async () => {
beforeMiniTask = true;
return Promise.resolve();
});
this.MiniTasks.afterDestroy(() => {
this.MiniTasks.afterDestroy(async () => {
afterMiniTask = true;
return Promise.resolve();
});
return Promise.all([
const [project0, task, minitask] = await Promise.all([
this.Projects.create({ title: 'New Project' }),
this.Tasks.create({ title: 'New Task' }),
this.MiniTasks.create({ mini_title: 'New MiniTask' })
]).then(([project, task, minitask]) => {
return Promise.all([
]);
await Promise.all([
task.addMiniTask(minitask),
project.addTask(task)
]).then(() => project);
}).then(project => {
return project.destroy();
}).then(() => {
project0.addTask(task)
]);
const project = project0;
await project.destroy();
expect(beforeProject).to.be.true;
expect(afterProject).to.be.true;
expect(beforeTask).to.be.true;
......@@ -875,9 +799,8 @@ describe(Support.getTestDialectTeaser('Hooks'), () => {
expect(beforeMiniTask).to.be.true;
expect(afterMiniTask).to.be.true;
});
});
it('with errors', function() {
it('with errors', async function() {
let beforeProject = false,
afterProject = false,
beforeTask = false,
......@@ -911,17 +834,19 @@ describe(Support.getTestDialectTeaser('Hooks'), () => {
afterMiniTask = true;
});
return Promise.all([
const [project0, task, minitask] = await Promise.all([
this.Projects.create({ title: 'New Project' }),
this.Tasks.create({ title: 'New Task' }),
this.MiniTasks.create({ mini_title: 'New MiniTask' })
]).then(([project, task, minitask]) => {
return Promise.all([
]);
await Promise.all([
task.addMiniTask(minitask),
project.addTask(task)
]).then(() => project);
}).then(project => {
return expect(project.destroy()).to.eventually.be.rejectedWith(CustomErrorText).then(() => {
project0.addTask(task)
]);
const project = project0;
await expect(project.destroy()).to.eventually.be.rejectedWith(CustomErrorText);
expect(beforeProject).to.be.true;
expect(afterProject).to.be.true;
expect(beforeTask).to.be.true;
......@@ -932,8 +857,6 @@ describe(Support.getTestDialectTeaser('Hooks'), () => {
});
});
});
});
});
}
});
......
......@@ -7,7 +7,7 @@ const chai = require('chai'),
sinon = require('sinon');
describe(Support.getTestDialectTeaser('Hooks'), () => {
beforeEach(function() {
beforeEach(async function() {
this.User = this.sequelize.define('User', {
username: {
type: DataTypes.STRING,
......@@ -29,12 +29,12 @@ describe(Support.getTestDialectTeaser('Hooks'), () => {
paranoid: true
});
return this.sequelize.sync({ force: true });
await this.sequelize.sync({ force: true });
});
describe('#bulkCreate', () => {
describe('on success', () => {
it('should run hooks', function() {
it('should run hooks', async function() {
const beforeBulk = sinon.spy(),
afterBulk = sinon.spy();
......@@ -42,34 +42,34 @@ describe(Support.getTestDialectTeaser('Hooks'), () => {
this.User.afterBulkCreate(afterBulk);
return this.User.bulkCreate([
await this.User.bulkCreate([
{ username: 'Cheech', mood: 'sad' },
{ username: 'Chong', mood: 'sad' }
]).then(() => {
]);
expect(beforeBulk).to.have.been.calledOnce;
expect(afterBulk).to.have.been.calledOnce;
});
});
});
describe('on error', () => {
it('should return an error from before', function() {
it('should return an error from before', async function() {
this.User.beforeBulkCreate(() => {
throw new Error('Whoops!');
});
return expect(this.User.bulkCreate([
await expect(this.User.bulkCreate([
{ username: 'Cheech', mood: 'sad' },
{ username: 'Chong', mood: 'sad' }
])).to.be.rejected;
});
it('should return an error from after', function() {
it('should return an error from after', async function() {
this.User.afterBulkCreate(() => {
throw new Error('Whoops!');
});
return expect(this.User.bulkCreate([
await expect(this.User.bulkCreate([
{ username: 'Cheech', mood: 'sad' },
{ username: 'Chong', mood: 'sad' }
])).to.be.rejected;
......@@ -77,7 +77,7 @@ describe(Support.getTestDialectTeaser('Hooks'), () => {
});
describe('with the {individualHooks: true} option', () => {
beforeEach(function() {
beforeEach(async function() {
this.User = this.sequelize.define('User', {
username: {
type: DataTypes.STRING,
......@@ -93,34 +93,30 @@ describe(Support.getTestDialectTeaser('Hooks'), () => {
}
});
return this.User.sync({ force: true });
await this.User.sync({ force: true });
});
it('should run the afterCreate/beforeCreate functions for each item created successfully', function() {
it('should run the afterCreate/beforeCreate functions for each item created successfully', async function() {
let beforeBulkCreate = false,
afterBulkCreate = false;
this.User.beforeBulkCreate(() => {
this.User.beforeBulkCreate(async () => {
beforeBulkCreate = true;
return Promise.resolve();
});
this.User.afterBulkCreate(() => {
this.User.afterBulkCreate(async () => {
afterBulkCreate = true;
return Promise.resolve();
});
this.User.beforeCreate(user => {
this.User.beforeCreate(async user => {
user.beforeHookTest = true;
return Promise.resolve();
});
this.User.afterCreate(user => {
this.User.afterCreate(async user => {
user.username = `User${user.id}`;
return Promise.resolve();
});
return this.User.bulkCreate([{ aNumber: 5 }, { aNumber: 7 }, { aNumber: 3 }], { fields: ['aNumber'], individualHooks: true }).then(records => {
const records = await this.User.bulkCreate([{ aNumber: 5 }, { aNumber: 7 }, { aNumber: 3 }], { fields: ['aNumber'], individualHooks: true });
records.forEach(record => {
expect(record.username).to.equal(`User${record.id}`);
expect(record.beforeHookTest).to.be.true;
......@@ -128,91 +124,88 @@ describe(Support.getTestDialectTeaser('Hooks'), () => {
expect(beforeBulkCreate).to.be.true;
expect(afterBulkCreate).to.be.true;
});
});
it('should run the afterCreate/beforeCreate functions for each item created with an error', function() {
it('should run the afterCreate/beforeCreate functions for each item created with an error', async function() {
let beforeBulkCreate = false,
afterBulkCreate = false;
this.User.beforeBulkCreate(() => {
this.User.beforeBulkCreate(async () => {
beforeBulkCreate = true;
return Promise.resolve();
});
this.User.afterBulkCreate(() => {
this.User.afterBulkCreate(async () => {
afterBulkCreate = true;
return Promise.resolve();
});
this.User.beforeCreate(() => {
return Promise.reject(new Error('You shall not pass!'));
this.User.beforeCreate(async () => {
throw new Error('You shall not pass!');
});
this.User.afterCreate(user => {
this.User.afterCreate(async user => {
user.username = `User${user.id}`;
return Promise.resolve();
});
return this.User.bulkCreate([{ aNumber: 5 }, { aNumber: 7 }, { aNumber: 3 }], { fields: ['aNumber'], individualHooks: true }).catch(err => {
try {
await this.User.bulkCreate([{ aNumber: 5 }, { aNumber: 7 }, { aNumber: 3 }], { fields: ['aNumber'], individualHooks: true });
} catch (err) {
expect(err).to.be.instanceOf(Error);
expect(beforeBulkCreate).to.be.true;
expect(afterBulkCreate).to.be.false;
});
}
});
});
});
describe('#bulkUpdate', () => {
describe('on success', () => {
it('should run hooks', function() {
it('should run hooks', async function() {
const beforeBulk = sinon.spy(),
afterBulk = sinon.spy();
this.User.beforeBulkUpdate(beforeBulk);
this.User.afterBulkUpdate(afterBulk);
return this.User.bulkCreate([
await this.User.bulkCreate([
{ username: 'Cheech', mood: 'sad' },
{ username: 'Chong', mood: 'sad' }
]).then(() => {
return this.User.update({ mood: 'happy' }, { where: { mood: 'sad' } }).then(() => {
]);
await this.User.update({ mood: 'happy' }, { where: { mood: 'sad' } });
expect(beforeBulk).to.have.been.calledOnce;
expect(afterBulk).to.have.been.calledOnce;
});
});
});
});
describe('on error', () => {
it('should return an error from before', function() {
it('should return an error from before', async function() {
this.User.beforeBulkUpdate(() => {
throw new Error('Whoops!');
});
return this.User.bulkCreate([
await this.User.bulkCreate([
{ username: 'Cheech', mood: 'sad' },
{ username: 'Chong', mood: 'sad' }
]).then(() => {
return expect(this.User.update({ mood: 'happy' }, { where: { mood: 'sad' } })).to.be.rejected;
});
]);
await expect(this.User.update({ mood: 'happy' }, { where: { mood: 'sad' } })).to.be.rejected;
});
it('should return an error from after', function() {
it('should return an error from after', async function() {
this.User.afterBulkUpdate(() => {
throw new Error('Whoops!');
});
return this.User.bulkCreate([
await this.User.bulkCreate([
{ username: 'Cheech', mood: 'sad' },
{ username: 'Chong', mood: 'sad' }
]).then(() => {
return expect(this.User.update({ mood: 'happy' }, { where: { mood: 'sad' } })).to.be.rejected;
});
]);
await expect(this.User.update({ mood: 'happy' }, { where: { mood: 'sad' } })).to.be.rejected;
});
});
describe('with the {individualHooks: true} option', () => {
beforeEach(function() {
beforeEach(async function() {
this.User = this.sequelize.define('User', {
username: {
type: DataTypes.STRING,
......@@ -228,10 +221,10 @@ describe(Support.getTestDialectTeaser('Hooks'), () => {
}
});
return this.User.sync({ force: true });
await this.User.sync({ force: true });
});
it('should run the after/before functions for each item created successfully', function() {
it('should run the after/before functions for each item created successfully', async function() {
const beforeBulk = sinon.spy(),
afterBulk = sinon.spy();
......@@ -248,10 +241,11 @@ describe(Support.getTestDialectTeaser('Hooks'), () => {
user.username = `User${user.id}`;
});
return this.User.bulkCreate([
await this.User.bulkCreate([
{ aNumber: 1 }, { aNumber: 1 }, { aNumber: 1 }
]).then(() => {
return this.User.update({ aNumber: 10 }, { where: { aNumber: 1 }, individualHooks: true }).then(([, records]) => {
]);
const [, records] = await this.User.update({ aNumber: 10 }, { where: { aNumber: 1 }, individualHooks: true });
records.forEach(record => {
expect(record.username).to.equal(`User${record.id}`);
expect(record.beforeHookTest).to.be.true;
......@@ -259,10 +253,8 @@ describe(Support.getTestDialectTeaser('Hooks'), () => {
expect(beforeBulk).to.have.been.calledOnce;
expect(afterBulk).to.have.been.calledOnce;
});
});
});
it('should run the after/before functions for each item created successfully changing some data before updating', function() {
it('should run the after/before functions for each item created successfully changing some data before updating', async function() {
this.User.beforeUpdate(user => {
expect(user.changed()).to.not.be.empty;
if (user.get('id') === 1) {
......@@ -270,18 +262,17 @@ describe(Support.getTestDialectTeaser('Hooks'), () => {
}
});
return this.User.bulkCreate([
await this.User.bulkCreate([
{ aNumber: 1 }, { aNumber: 1 }, { aNumber: 1 }
]).then(() => {
return this.User.update({ aNumber: 10 }, { where: { aNumber: 1 }, individualHooks: true }).then(([, records]) => {
]);
const [, records] = await this.User.update({ aNumber: 10 }, { where: { aNumber: 1 }, individualHooks: true });
records.forEach(record => {
expect(record.aNumber).to.equal(10 + (record.id === 1 ? 3 : 0));
});
});
});
});
it('should run the after/before functions for each item created with an error', function() {
it('should run the after/before functions for each item created with an error', async function() {
const beforeBulk = sinon.spy(),
afterBulk = sinon.spy();
......@@ -297,54 +288,55 @@ describe(Support.getTestDialectTeaser('Hooks'), () => {
user.username = `User${user.id}`;
});
return this.User.bulkCreate([{ aNumber: 1 }, { aNumber: 1 }, { aNumber: 1 }], { fields: ['aNumber'] }).then(() => {
return this.User.update({ aNumber: 10 }, { where: { aNumber: 1 }, individualHooks: true }).catch(err => {
await this.User.bulkCreate([{ aNumber: 1 }, { aNumber: 1 }, { aNumber: 1 }], { fields: ['aNumber'] });
try {
await this.User.update({ aNumber: 10 }, { where: { aNumber: 1 }, individualHooks: true });
} catch (err) {
expect(err).to.be.instanceOf(Error);
expect(err.message).to.be.equal('You shall not pass!');
expect(beforeBulk).to.have.been.calledOnce;
expect(afterBulk).not.to.have.been.called;
});
});
}
});
});
});
describe('#bulkDestroy', () => {
describe('on success', () => {
it('should run hooks', function() {
it('should run hooks', async function() {
const beforeBulk = sinon.spy(),
afterBulk = sinon.spy();
this.User.beforeBulkDestroy(beforeBulk);
this.User.afterBulkDestroy(afterBulk);
return this.User.destroy({ where: { username: 'Cheech', mood: 'sad' } }).then(() => {
await this.User.destroy({ where: { username: 'Cheech', mood: 'sad' } });
expect(beforeBulk).to.have.been.calledOnce;
expect(afterBulk).to.have.been.calledOnce;
});
});
});
describe('on error', () => {
it('should return an error from before', function() {
it('should return an error from before', async function() {
this.User.beforeBulkDestroy(() => {
throw new Error('Whoops!');
});
return expect(this.User.destroy({ where: { username: 'Cheech', mood: 'sad' } })).to.be.rejected;
await expect(this.User.destroy({ where: { username: 'Cheech', mood: 'sad' } })).to.be.rejected;
});
it('should return an error from after', function() {
it('should return an error from after', async function() {
this.User.afterBulkDestroy(() => {
throw new Error('Whoops!');
});
return expect(this.User.destroy({ where: { username: 'Cheech', mood: 'sad' } })).to.be.rejected;
await expect(this.User.destroy({ where: { username: 'Cheech', mood: 'sad' } })).to.be.rejected;
});
});
describe('with the {individualHooks: true} option', () => {
beforeEach(function() {
beforeEach(async function() {
this.User = this.sequelize.define('User', {
username: {
type: DataTypes.STRING,
......@@ -360,131 +352,124 @@ describe(Support.getTestDialectTeaser('Hooks'), () => {
}
});
return this.User.sync({ force: true });
await this.User.sync({ force: true });
});
it('should run the after/before functions for each item created successfully', function() {
it('should run the after/before functions for each item created successfully', async function() {
let beforeBulk = false,
afterBulk = false,
beforeHook = false,
afterHook = false;
this.User.beforeBulkDestroy(() => {
this.User.beforeBulkDestroy(async () => {
beforeBulk = true;
return Promise.resolve();
});
this.User.afterBulkDestroy(() => {
this.User.afterBulkDestroy(async () => {
afterBulk = true;
return Promise.resolve();
});
this.User.beforeDestroy(() => {
this.User.beforeDestroy(async () => {
beforeHook = true;
return Promise.resolve();
});
this.User.afterDestroy(() => {
this.User.afterDestroy(async () => {
afterHook = true;
return Promise.resolve();
});
return this.User.bulkCreate([
await this.User.bulkCreate([
{ aNumber: 1 }, { aNumber: 1 }, { aNumber: 1 }
]).then(() => {
return this.User.destroy({ where: { aNumber: 1 }, individualHooks: true }).then(() => {
]);
await this.User.destroy({ where: { aNumber: 1 }, individualHooks: true });
expect(beforeBulk).to.be.true;
expect(afterBulk).to.be.true;
expect(beforeHook).to.be.true;
expect(afterHook).to.be.true;
});
});
});
it('should run the after/before functions for each item created with an error', function() {
it('should run the after/before functions for each item created with an error', async function() {
let beforeBulk = false,
afterBulk = false,
beforeHook = false,
afterHook = false;
this.User.beforeBulkDestroy(() => {
this.User.beforeBulkDestroy(async () => {
beforeBulk = true;
return Promise.resolve();
});
this.User.afterBulkDestroy(() => {
this.User.afterBulkDestroy(async () => {
afterBulk = true;
return Promise.resolve();
});
this.User.beforeDestroy(() => {
this.User.beforeDestroy(async () => {
beforeHook = true;
return Promise.reject(new Error('You shall not pass!'));
throw new Error('You shall not pass!');
});
this.User.afterDestroy(() => {
this.User.afterDestroy(async () => {
afterHook = true;
return Promise.resolve();
});
return this.User.bulkCreate([{ aNumber: 1 }, { aNumber: 1 }, { aNumber: 1 }], { fields: ['aNumber'] }).then(() => {
return this.User.destroy({ where: { aNumber: 1 }, individualHooks: true }).catch(err => {
await this.User.bulkCreate([{ aNumber: 1 }, { aNumber: 1 }, { aNumber: 1 }], { fields: ['aNumber'] });
try {
await this.User.destroy({ where: { aNumber: 1 }, individualHooks: true });
} catch (err) {
expect(err).to.be.instanceOf(Error);
expect(beforeBulk).to.be.true;
expect(beforeHook).to.be.true;
expect(afterBulk).to.be.false;
expect(afterHook).to.be.false;
});
});
}
});
});
});
describe('#bulkRestore', () => {
beforeEach(function() {
return this.ParanoidUser.bulkCreate([
beforeEach(async function() {
await this.ParanoidUser.bulkCreate([
{ username: 'adam', mood: 'happy' },
{ username: 'joe', mood: 'sad' }
]).then(() => {
return this.ParanoidUser.destroy({ truncate: true });
});
]);
await this.ParanoidUser.destroy({ truncate: true });
});
describe('on success', () => {
it('should run hooks', function() {
it('should run hooks', async function() {
const beforeBulk = sinon.spy(),
afterBulk = sinon.spy();
this.ParanoidUser.beforeBulkRestore(beforeBulk);
this.ParanoidUser.afterBulkRestore(afterBulk);
return this.ParanoidUser.restore({ where: { username: 'adam', mood: 'happy' } }).then(() => {
await this.ParanoidUser.restore({ where: { username: 'adam', mood: 'happy' } });
expect(beforeBulk).to.have.been.calledOnce;
expect(afterBulk).to.have.been.calledOnce;
});
});
});
describe('on error', () => {
it('should return an error from before', function() {
it('should return an error from before', async function() {
this.ParanoidUser.beforeBulkRestore(() => {
throw new Error('Whoops!');
});
return expect(this.ParanoidUser.restore({ where: { username: 'adam', mood: 'happy' } })).to.be.rejected;
await expect(this.ParanoidUser.restore({ where: { username: 'adam', mood: 'happy' } })).to.be.rejected;
});
it('should return an error from after', function() {
it('should return an error from after', async function() {
this.ParanoidUser.afterBulkRestore(() => {
throw new Error('Whoops!');
});
return expect(this.ParanoidUser.restore({ where: { username: 'adam', mood: 'happy' } })).to.be.rejected;
await expect(this.ParanoidUser.restore({ where: { username: 'adam', mood: 'happy' } })).to.be.rejected;
});
});
describe('with the {individualHooks: true} option', () => {
beforeEach(function() {
beforeEach(async function() {
this.ParanoidUser = this.sequelize.define('ParanoidUser', {
aNumber: {
type: DataTypes.INTEGER,
......@@ -494,10 +479,10 @@ describe(Support.getTestDialectTeaser('Hooks'), () => {
paranoid: true
});
return this.ParanoidUser.sync({ force: true });
await this.ParanoidUser.sync({ force: true });
});
it('should run the after/before functions for each item restored successfully', function() {
it('should run the after/before functions for each item restored successfully', async function() {
const beforeBulk = sinon.spy(),
afterBulk = sinon.spy(),
beforeHook = sinon.spy(),
......@@ -508,21 +493,19 @@ describe(Support.getTestDialectTeaser('Hooks'), () => {
this.ParanoidUser.beforeRestore(beforeHook);
this.ParanoidUser.afterRestore(afterHook);
return this.ParanoidUser.bulkCreate([
await this.ParanoidUser.bulkCreate([
{ aNumber: 1 }, { aNumber: 1 }, { aNumber: 1 }
]).then(() => {
return this.ParanoidUser.destroy({ where: { aNumber: 1 } });
}).then(() => {
return this.ParanoidUser.restore({ where: { aNumber: 1 }, individualHooks: true });
}).then(() => {
]);
await this.ParanoidUser.destroy({ where: { aNumber: 1 } });
await this.ParanoidUser.restore({ where: { aNumber: 1 }, individualHooks: true });
expect(beforeBulk).to.have.been.calledOnce;
expect(afterBulk).to.have.been.calledOnce;
expect(beforeHook).to.have.been.calledThrice;
expect(afterHook).to.have.been.calledThrice;
});
});
it('should run the after/before functions for each item restored with an error', function() {
it('should run the after/before functions for each item restored with an error', async function() {
const beforeBulk = sinon.spy(),
afterBulk = sinon.spy(),
beforeHook = sinon.spy(),
......@@ -530,24 +513,24 @@ describe(Support.getTestDialectTeaser('Hooks'), () => {
this.ParanoidUser.beforeBulkRestore(beforeBulk);
this.ParanoidUser.afterBulkRestore(afterBulk);
this.ParanoidUser.beforeRestore(() => {
this.ParanoidUser.beforeRestore(async () => {
beforeHook();
return Promise.reject(new Error('You shall not pass!'));
throw new Error('You shall not pass!');
});
this.ParanoidUser.afterRestore(afterHook);
return this.ParanoidUser.bulkCreate([{ aNumber: 1 }, { aNumber: 1 }, { aNumber: 1 }], { fields: ['aNumber'] }).then(() => {
return this.ParanoidUser.destroy({ where: { aNumber: 1 } });
}).then(() => {
return this.ParanoidUser.restore({ where: { aNumber: 1 }, individualHooks: true });
}).catch(err => {
try {
await this.ParanoidUser.bulkCreate([{ aNumber: 1 }, { aNumber: 1 }, { aNumber: 1 }], { fields: ['aNumber'] });
await this.ParanoidUser.destroy({ where: { aNumber: 1 } });
await this.ParanoidUser.restore({ where: { aNumber: 1 }, individualHooks: true });
} catch (err) {
expect(err).to.be.instanceOf(Error);
expect(beforeBulk).to.have.been.calledOnce;
expect(beforeHook).to.have.been.calledThrice;
expect(afterBulk).not.to.have.been.called;
expect(afterHook).not.to.have.been.called;
});
}
});
});
});
......
......@@ -6,7 +6,7 @@ const chai = require('chai'),
DataTypes = require('../../../lib/data-types');
describe(Support.getTestDialectTeaser('Hooks'), () => {
beforeEach(function() {
beforeEach(async function() {
this.User = this.sequelize.define('User', {
username: {
type: DataTypes.STRING,
......@@ -17,12 +17,12 @@ describe(Support.getTestDialectTeaser('Hooks'), () => {
values: ['happy', 'sad', 'neutral']
}
});
return this.sequelize.sync({ force: true });
await this.sequelize.sync({ force: true });
});
describe('#count', () => {
beforeEach(function() {
return this.User.bulkCreate([
beforeEach(async function() {
await this.User.bulkCreate([
{ username: 'adam', mood: 'happy' },
{ username: 'joe', mood: 'sad' },
{ username: 'joe', mood: 'happy' }
......@@ -30,35 +30,34 @@ describe(Support.getTestDialectTeaser('Hooks'), () => {
});
describe('on success', () => {
it('hook runs', function() {
it('hook runs', async function() {
let beforeHook = false;
this.User.beforeCount(() => {
beforeHook = true;
});
return this.User.count().then(count => {
const count = await this.User.count();
expect(count).to.equal(3);
expect(beforeHook).to.be.true;
});
});
it('beforeCount hook can change options', function() {
it('beforeCount hook can change options', async function() {
this.User.beforeCount(options => {
options.where.username = 'adam';
});
return expect(this.User.count({ where: { username: 'joe' } })).to.eventually.equal(1);
await expect(this.User.count({ where: { username: 'joe' } })).to.eventually.equal(1);
});
});
describe('on error', () => {
it('in beforeCount hook returns error', function() {
it('in beforeCount hook returns error', async function() {
this.User.beforeCount(() => {
throw new Error('Oops!');
});
return expect(this.User.count({ where: { username: 'adam' } })).to.be.rejectedWith('Oops!');
await expect(this.User.count({ where: { username: 'adam' } })).to.be.rejectedWith('Oops!');
});
});
});
......
......@@ -8,7 +8,7 @@ const chai = require('chai'),
sinon = require('sinon');
describe(Support.getTestDialectTeaser('Hooks'), () => {
beforeEach(function() {
beforeEach(async function() {
this.User = this.sequelize.define('User', {
username: {
type: DataTypes.STRING,
......@@ -19,12 +19,12 @@ describe(Support.getTestDialectTeaser('Hooks'), () => {
values: ['happy', 'sad', 'neutral']
}
});
return this.sequelize.sync({ force: true });
await this.sequelize.sync({ force: true });
});
describe('#create', () => {
describe('on success', () => {
it('should run hooks', function() {
it('should run hooks', async function() {
const beforeHook = sinon.spy(),
afterHook = sinon.spy(),
beforeSave = sinon.spy(),
......@@ -35,17 +35,16 @@ describe(Support.getTestDialectTeaser('Hooks'), () => {
this.User.beforeSave(beforeSave);
this.User.afterSave(afterSave);
return this.User.create({ username: 'Toni', mood: 'happy' }).then(() => {
await this.User.create({ username: 'Toni', mood: 'happy' });
expect(beforeHook).to.have.been.calledOnce;
expect(afterHook).to.have.been.calledOnce;
expect(beforeSave).to.have.been.calledOnce;
expect(afterSave).to.have.been.calledOnce;
});
});
});
describe('on error', () => {
it('should return an error from before', function() {
it('should return an error from before', async function() {
const beforeHook = sinon.spy(),
beforeSave = sinon.spy(),
afterHook = sinon.spy(),
......@@ -59,15 +58,14 @@ describe(Support.getTestDialectTeaser('Hooks'), () => {
this.User.beforeSave(beforeSave);
this.User.afterSave(afterSave);
return expect(this.User.create({ username: 'Toni', mood: 'happy' })).to.be.rejected.then(() => {
await expect(this.User.create({ username: 'Toni', mood: 'happy' })).to.be.rejected;
expect(beforeHook).to.have.been.calledOnce;
expect(afterHook).not.to.have.been.called;
expect(beforeSave).not.to.have.been.called;
expect(afterSave).not.to.have.been.called;
});
});
it('should return an error from after', function() {
it('should return an error from after', async function() {
const beforeHook = sinon.spy(),
beforeSave = sinon.spy(),
afterHook = sinon.spy(),
......@@ -82,16 +80,15 @@ describe(Support.getTestDialectTeaser('Hooks'), () => {
this.User.beforeSave(beforeSave);
this.User.afterSave(afterSave);
return expect(this.User.create({ username: 'Toni', mood: 'happy' })).to.be.rejected.then(() => {
await expect(this.User.create({ username: 'Toni', mood: 'happy' })).to.be.rejected;
expect(beforeHook).to.have.been.calledOnce;
expect(afterHook).to.have.been.calledOnce;
expect(beforeSave).to.have.been.calledOnce;
expect(afterSave).not.to.have.been.called;
});
});
});
it('should not trigger hooks on parent when using N:M association setters', function() {
it('should not trigger hooks on parent when using N:M association setters', async function() {
const A = this.sequelize.define('A', {
name: Sequelize.STRING
});
......@@ -101,28 +98,26 @@ describe(Support.getTestDialectTeaser('Hooks'), () => {
let hookCalled = 0;
A.addHook('afterCreate', () => {
A.addHook('afterCreate', async () => {
hookCalled++;
return Promise.resolve();
});
B.belongsToMany(A, { through: 'a_b' });
A.belongsToMany(B, { through: 'a_b' });
return this.sequelize.sync({ force: true }).then(() => {
return Promise.all([
await this.sequelize.sync({ force: true });
const [a, b] = await Promise.all([
A.create({ name: 'a' }),
B.create({ name: 'b' })
]).then(([a, b]) => {
return a.addB(b).then(() => {
]);
await a.addB(b);
expect(hookCalled).to.equal(1);
});
});
});
});
describe('preserves changes to instance', () => {
it('beforeValidate', function() {
it('beforeValidate', async function() {
let hookCalled = 0;
this.User.beforeValidate(user => {
......@@ -130,14 +125,13 @@ describe(Support.getTestDialectTeaser('Hooks'), () => {
hookCalled++;
});
return this.User.create({ mood: 'sad', username: 'leafninja' }).then(user => {
const user = await this.User.create({ mood: 'sad', username: 'leafninja' });
expect(user.mood).to.equal('happy');
expect(user.username).to.equal('leafninja');
expect(hookCalled).to.equal(1);
});
});
it('afterValidate', function() {
it('afterValidate', async function() {
let hookCalled = 0;
this.User.afterValidate(user => {
......@@ -145,14 +139,13 @@ describe(Support.getTestDialectTeaser('Hooks'), () => {
hookCalled++;
});
return this.User.create({ mood: 'sad', username: 'fireninja' }).then(user => {
const user = await this.User.create({ mood: 'sad', username: 'fireninja' });
expect(user.mood).to.equal('neutral');
expect(user.username).to.equal('fireninja');
expect(hookCalled).to.equal(1);
});
});
it('beforeCreate', function() {
it('beforeCreate', async function() {
let hookCalled = 0;
this.User.beforeCreate(user => {
......@@ -160,14 +153,13 @@ describe(Support.getTestDialectTeaser('Hooks'), () => {
hookCalled++;
});
return this.User.create({ username: 'akira' }).then(user => {
const user = await this.User.create({ username: 'akira' });
expect(user.mood).to.equal('happy');
expect(user.username).to.equal('akira');
expect(hookCalled).to.equal(1);
});
});
it('beforeSave', function() {
it('beforeSave', async function() {
let hookCalled = 0;
this.User.beforeSave(user => {
......@@ -175,14 +167,13 @@ describe(Support.getTestDialectTeaser('Hooks'), () => {
hookCalled++;
});
return this.User.create({ username: 'akira' }).then(user => {
const user = await this.User.create({ username: 'akira' });
expect(user.mood).to.equal('happy');
expect(user.username).to.equal('akira');
expect(hookCalled).to.equal(1);
});
});
it('beforeSave with beforeCreate', function() {
it('beforeSave with beforeCreate', async function() {
let hookCalled = 0;
this.User.beforeCreate(user => {
......@@ -195,12 +186,11 @@ describe(Support.getTestDialectTeaser('Hooks'), () => {
hookCalled++;
});
return this.User.create({ username: 'akira' }).then(user => {
const user = await this.User.create({ username: 'akira' });
expect(user.mood).to.equal('happy');
expect(user.username).to.equal('akira');
expect(hookCalled).to.equal(2);
});
});
});
});
});
......@@ -7,7 +7,7 @@ const chai = require('chai'),
sinon = require('sinon');
describe(Support.getTestDialectTeaser('Hooks'), () => {
beforeEach(function() {
beforeEach(async function() {
this.User = this.sequelize.define('User', {
username: {
type: DataTypes.STRING,
......@@ -18,29 +18,27 @@ describe(Support.getTestDialectTeaser('Hooks'), () => {
values: ['happy', 'sad', 'neutral']
}
});
return this.sequelize.sync({ force: true });
await this.sequelize.sync({ force: true });
});
describe('#destroy', () => {
describe('on success', () => {
it('should run hooks', function() {
it('should run hooks', async function() {
const beforeHook = sinon.spy(),
afterHook = sinon.spy();
this.User.beforeDestroy(beforeHook);
this.User.afterDestroy(afterHook);
return this.User.create({ username: 'Toni', mood: 'happy' }).then(user => {
return user.destroy().then(() => {
const user = await this.User.create({ username: 'Toni', mood: 'happy' });
await user.destroy();
expect(beforeHook).to.have.been.calledOnce;
expect(afterHook).to.have.been.calledOnce;
});
});
});
});
describe('on error', () => {
it('should return an error from before', function() {
it('should return an error from before', async function() {
const beforeHook = sinon.spy(),
afterHook = sinon.spy();
......@@ -50,15 +48,13 @@ describe(Support.getTestDialectTeaser('Hooks'), () => {
});
this.User.afterDestroy(afterHook);
return this.User.create({ username: 'Toni', mood: 'happy' }).then(user => {
return expect(user.destroy()).to.be.rejected.then(() => {
const user = await this.User.create({ username: 'Toni', mood: 'happy' });
await expect(user.destroy()).to.be.rejected;
expect(beforeHook).to.have.been.calledOnce;
expect(afterHook).not.to.have.been.called;
});
});
});
it('should return an error from after', function() {
it('should return an error from after', async function() {
const beforeHook = sinon.spy(),
afterHook = sinon.spy();
......@@ -68,14 +64,12 @@ describe(Support.getTestDialectTeaser('Hooks'), () => {
throw new Error('Whoops!');
});
return this.User.create({ username: 'Toni', mood: 'happy' }).then(user => {
return expect(user.destroy()).to.be.rejected.then(() => {
const user = await this.User.create({ username: 'Toni', mood: 'happy' });
await expect(user.destroy()).to.be.rejected;
expect(beforeHook).to.have.been.calledOnce;
expect(afterHook).to.have.been.calledOnce;
});
});
});
});
describe('with paranoid mode enabled', () => {
beforeEach(function() {
......@@ -96,28 +90,24 @@ describe(Support.getTestDialectTeaser('Hooks'), () => {
});
});
it('sets other changed values when soft deleting and a beforeDestroy hooks kicks in', function() {
return this.ParanoidUser.sync({ force: true })
.then(() => this.ParanoidUser.create({ username: 'user1' }))
.then(user => user.destroy())
.then(() => this.ParanoidUser.findOne({ paranoid: false }))
.then(user => {
it('sets other changed values when soft deleting and a beforeDestroy hooks kicks in', async function() {
await this.ParanoidUser.sync({ force: true });
const user0 = await this.ParanoidUser.create({ username: 'user1' });
await user0.destroy();
const user = await this.ParanoidUser.findOne({ paranoid: false });
expect(user.updatedBy).to.equal(1);
});
});
it('should not throw error when a beforeDestroy hook changes a virtual column', function() {
it('should not throw error when a beforeDestroy hook changes a virtual column', async function() {
this.ParanoidUser.beforeDestroy(instance => instance.virtualField = 2);
return this.ParanoidUser.sync({ force: true })
.then(() => this.ParanoidUser.create({ username: 'user1' }))
.then(user => user.destroy())
.then(() => this.ParanoidUser.findOne({ paranoid: false }))
.then(user => {
await this.ParanoidUser.sync({ force: true });
const user0 = await this.ParanoidUser.create({ username: 'user1' });
await user0.destroy();
const user = await this.ParanoidUser.findOne({ paranoid: false });
expect(user.virtualField).to.equal(0);
});
});
});
});
});
......@@ -6,7 +6,7 @@ const chai = require('chai'),
DataTypes = require('../../../lib/data-types');
describe(Support.getTestDialectTeaser('Hooks'), () => {
beforeEach(function() {
beforeEach(async function() {
this.User = this.sequelize.define('User', {
username: {
type: DataTypes.STRING,
......@@ -18,28 +18,28 @@ describe(Support.getTestDialectTeaser('Hooks'), () => {
}
});
return this.sequelize.sync({ force: true });
await this.sequelize.sync({ force: true });
});
describe('#find', () => {
beforeEach(function() {
return this.User.bulkCreate([
beforeEach(async function() {
await this.User.bulkCreate([
{ username: 'adam', mood: 'happy' },
{ username: 'joe', mood: 'sad' }
]);
});
it('allow changing attributes via beforeFind #5675', function() {
it('allow changing attributes via beforeFind #5675', async function() {
this.User.beforeFind(options => {
options.attributes = {
include: [['id', 'my_id']]
};
});
return this.User.findAll({});
await this.User.findAll({});
});
describe('on success', () => {
it('all hooks run', function() {
it('all hooks run', async function() {
let beforeHook = false,
beforeHook2 = false,
beforeHook3 = false,
......@@ -61,95 +61,98 @@ describe(Support.getTestDialectTeaser('Hooks'), () => {
afterHook = true;
});
return this.User.findOne({ where: { username: 'adam' } }).then(user => {
const user = await this.User.findOne({ where: { username: 'adam' } });
expect(user.mood).to.equal('happy');
expect(beforeHook).to.be.true;
expect(beforeHook2).to.be.true;
expect(beforeHook3).to.be.true;
expect(afterHook).to.be.true;
});
});
it('beforeFind hook can change options', function() {
it('beforeFind hook can change options', async function() {
this.User.beforeFind(options => {
options.where.username = 'joe';
});
return this.User.findOne({ where: { username: 'adam' } }).then(user => {
const user = await this.User.findOne({ where: { username: 'adam' } });
expect(user.mood).to.equal('sad');
});
});
it('beforeFindAfterExpandIncludeAll hook can change options', function() {
it('beforeFindAfterExpandIncludeAll hook can change options', async function() {
this.User.beforeFindAfterExpandIncludeAll(options => {
options.where.username = 'joe';
});
return this.User.findOne({ where: { username: 'adam' } }).then(user => {
const user = await this.User.findOne({ where: { username: 'adam' } });
expect(user.mood).to.equal('sad');
});
});
it('beforeFindAfterOptions hook can change options', function() {
it('beforeFindAfterOptions hook can change options', async function() {
this.User.beforeFindAfterOptions(options => {
options.where.username = 'joe';
});
return this.User.findOne({ where: { username: 'adam' } }).then(user => {
const user = await this.User.findOne({ where: { username: 'adam' } });
expect(user.mood).to.equal('sad');
});
});
it('afterFind hook can change results', function() {
it('afterFind hook can change results', async function() {
this.User.afterFind(user => {
user.mood = 'sad';
});
return this.User.findOne({ where: { username: 'adam' } }).then(user => {
const user = await this.User.findOne({ where: { username: 'adam' } });
expect(user.mood).to.equal('sad');
});
});
});
describe('on error', () => {
it('in beforeFind hook returns error', function() {
it('in beforeFind hook returns error', async function() {
this.User.beforeFind(() => {
throw new Error('Oops!');
});
return this.User.findOne({ where: { username: 'adam' } }).catch(err => {
try {
await this.User.findOne({ where: { username: 'adam' } });
} catch (err) {
expect(err.message).to.equal('Oops!');
});
}
});
it('in beforeFindAfterExpandIncludeAll hook returns error', function() {
it('in beforeFindAfterExpandIncludeAll hook returns error', async function() {
this.User.beforeFindAfterExpandIncludeAll(() => {
throw new Error('Oops!');
});
return this.User.findOne({ where: { username: 'adam' } }).catch(err => {
try {
await this.User.findOne({ where: { username: 'adam' } });
} catch (err) {
expect(err.message).to.equal('Oops!');
});
}
});
it('in beforeFindAfterOptions hook returns error', function() {
it('in beforeFindAfterOptions hook returns error', async function() {
this.User.beforeFindAfterOptions(() => {
throw new Error('Oops!');
});
return this.User.findOne({ where: { username: 'adam' } }).catch(err => {
try {
await this.User.findOne({ where: { username: 'adam' } });
} catch (err) {
expect(err.message).to.equal('Oops!');
});
}
});
it('in afterFind hook returns error', function() {
it('in afterFind hook returns error', async function() {
this.User.afterFind(() => {
throw new Error('Oops!');
});
return this.User.findOne({ where: { username: 'adam' } }).catch(err => {
try {
await this.User.findOne({ where: { username: 'adam' } });
} catch (err) {
expect(err.message).to.equal('Oops!');
});
}
});
});
});
......
......@@ -9,7 +9,7 @@ const chai = require('chai'),
sinon = require('sinon');
describe(Support.getTestDialectTeaser('Hooks'), () => {
beforeEach(function() {
beforeEach(async function() {
this.User = this.sequelize.define('User', {
username: {
type: DataTypes.STRING,
......@@ -31,7 +31,7 @@ describe(Support.getTestDialectTeaser('Hooks'), () => {
paranoid: true
});
return this.sequelize.sync({ force: true });
await this.sequelize.sync({ force: true });
});
describe('#define', () => {
......@@ -104,163 +104,143 @@ describe(Support.getTestDialectTeaser('Hooks'), () => {
describe('passing DAO instances', () => {
describe('beforeValidate / afterValidate', () => {
it('should pass a DAO instance to the hook', function() {
it('should pass a DAO instance to the hook', async function() {
let beforeHooked = false;
let afterHooked = false;
const User = this.sequelize.define('User', {
username: DataTypes.STRING
}, {
hooks: {
beforeValidate(user) {
async beforeValidate(user) {
expect(user).to.be.instanceof(User);
beforeHooked = true;
return Promise.resolve();
},
afterValidate(user) {
async afterValidate(user) {
expect(user).to.be.instanceof(User);
afterHooked = true;
return Promise.resolve();
}
}
});
return User.sync({ force: true }).then(() => {
return User.create({ username: 'bob' }).then(() => {
await User.sync({ force: true });
await User.create({ username: 'bob' });
expect(beforeHooked).to.be.true;
expect(afterHooked).to.be.true;
});
});
});
});
describe('beforeCreate / afterCreate', () => {
it('should pass a DAO instance to the hook', function() {
it('should pass a DAO instance to the hook', async function() {
let beforeHooked = false;
let afterHooked = false;
const User = this.sequelize.define('User', {
username: DataTypes.STRING
}, {
hooks: {
beforeCreate(user) {
async beforeCreate(user) {
expect(user).to.be.instanceof(User);
beforeHooked = true;
return Promise.resolve();
},
afterCreate(user) {
async afterCreate(user) {
expect(user).to.be.instanceof(User);
afterHooked = true;
return Promise.resolve();
}
}
});
return User.sync({ force: true }).then(() => {
return User.create({ username: 'bob' }).then(() => {
await User.sync({ force: true });
await User.create({ username: 'bob' });
expect(beforeHooked).to.be.true;
expect(afterHooked).to.be.true;
});
});
});
});
describe('beforeDestroy / afterDestroy', () => {
it('should pass a DAO instance to the hook', function() {
it('should pass a DAO instance to the hook', async function() {
let beforeHooked = false;
let afterHooked = false;
const User = this.sequelize.define('User', {
username: DataTypes.STRING
}, {
hooks: {
beforeDestroy(user) {
async beforeDestroy(user) {
expect(user).to.be.instanceof(User);
beforeHooked = true;
return Promise.resolve();
},
afterDestroy(user) {
async afterDestroy(user) {
expect(user).to.be.instanceof(User);
afterHooked = true;
return Promise.resolve();
}
}
});
return User.sync({ force: true }).then(() => {
return User.create({ username: 'bob' }).then(user => {
return user.destroy().then(() => {
await User.sync({ force: true });
const user = await User.create({ username: 'bob' });
await user.destroy();
expect(beforeHooked).to.be.true;
expect(afterHooked).to.be.true;
});
});
});
});
});
describe('beforeUpdate / afterUpdate', () => {
it('should pass a DAO instance to the hook', function() {
it('should pass a DAO instance to the hook', async function() {
let beforeHooked = false;
let afterHooked = false;
const User = this.sequelize.define('User', {
username: DataTypes.STRING
}, {
hooks: {
beforeUpdate(user) {
async beforeUpdate(user) {
expect(user).to.be.instanceof(User);
beforeHooked = true;
return Promise.resolve();
},
afterUpdate(user) {
async afterUpdate(user) {
expect(user).to.be.instanceof(User);
afterHooked = true;
return Promise.resolve();
}
}
});
return User.sync({ force: true }).then(() => {
return User.create({ username: 'bob' }).then(user => {
await User.sync({ force: true });
const user = await User.create({ username: 'bob' });
user.username = 'bawb';
return user.save({ fields: ['username'] }).then(() => {
await user.save({ fields: ['username'] });
expect(beforeHooked).to.be.true;
expect(afterHooked).to.be.true;
});
});
});
});
});
});
describe('Model#sync', () => {
describe('on success', () => {
it('should run hooks', function() {
it('should run hooks', async function() {
const beforeHook = sinon.spy(),
afterHook = sinon.spy();
this.User.beforeSync(beforeHook);
this.User.afterSync(afterHook);
return this.User.sync().then(() => {
await this.User.sync();
expect(beforeHook).to.have.been.calledOnce;
expect(afterHook).to.have.been.calledOnce;
});
});
it('should not run hooks when "hooks = false" option passed', function() {
it('should not run hooks when "hooks = false" option passed', async function() {
const beforeHook = sinon.spy(),
afterHook = sinon.spy();
this.User.beforeSync(beforeHook);
this.User.afterSync(afterHook);
return this.User.sync({ hooks: false }).then(() => {
await this.User.sync({ hooks: false });
expect(beforeHook).to.not.have.been.called;
expect(afterHook).to.not.have.been.called;
});
});
});
describe('on error', () => {
it('should return an error from before', function() {
it('should return an error from before', async function() {
const beforeHook = sinon.spy(),
afterHook = sinon.spy();
......@@ -270,13 +250,12 @@ describe(Support.getTestDialectTeaser('Hooks'), () => {
});
this.User.afterSync(afterHook);
return expect(this.User.sync()).to.be.rejected.then(() => {
await expect(this.User.sync()).to.be.rejected;
expect(beforeHook).to.have.been.calledOnce;
expect(afterHook).not.to.have.been.called;
});
});
it('should return an error from after', function() {
it('should return an error from after', async function() {
const beforeHook = sinon.spy(),
afterHook = sinon.spy();
......@@ -286,17 +265,16 @@ describe(Support.getTestDialectTeaser('Hooks'), () => {
throw new Error('Whoops!');
});
return expect(this.User.sync()).to.be.rejected.then(() => {
await expect(this.User.sync()).to.be.rejected;
expect(beforeHook).to.have.been.calledOnce;
expect(afterHook).to.have.been.calledOnce;
});
});
});
});
describe('sequelize#sync', () => {
describe('on success', () => {
it('should run hooks', function() {
it('should run hooks', async function() {
const beforeHook = sinon.spy(),
afterHook = sinon.spy(),
modelBeforeHook = sinon.spy(),
......@@ -307,15 +285,14 @@ describe(Support.getTestDialectTeaser('Hooks'), () => {
this.User.afterSync(modelAfterHook);
this.sequelize.afterBulkSync(afterHook);
return this.sequelize.sync().then(() => {
await this.sequelize.sync();
expect(beforeHook).to.have.been.calledOnce;
expect(modelBeforeHook).to.have.been.calledOnce;
expect(modelAfterHook).to.have.been.calledOnce;
expect(afterHook).to.have.been.calledOnce;
});
});
it('should not run hooks if "hooks = false" option passed', function() {
it('should not run hooks if "hooks = false" option passed', async function() {
const beforeHook = sinon.spy(),
afterHook = sinon.spy(),
modelBeforeHook = sinon.spy(),
......@@ -326,13 +303,12 @@ describe(Support.getTestDialectTeaser('Hooks'), () => {
this.User.afterSync(modelAfterHook);
this.sequelize.afterBulkSync(afterHook);
return this.sequelize.sync({ hooks: false }).then(() => {
await this.sequelize.sync({ hooks: false });
expect(beforeHook).to.not.have.been.called;
expect(modelBeforeHook).to.not.have.been.called;
expect(modelAfterHook).to.not.have.been.called;
expect(afterHook).to.not.have.been.called;
});
});
afterEach(function() {
this.sequelize.options.hooks = {};
......@@ -342,7 +318,7 @@ describe(Support.getTestDialectTeaser('Hooks'), () => {
describe('on error', () => {
it('should return an error from before', function() {
it('should return an error from before', async function() {
const beforeHook = sinon.spy(),
afterHook = sinon.spy();
this.sequelize.beforeBulkSync(() => {
......@@ -351,13 +327,12 @@ describe(Support.getTestDialectTeaser('Hooks'), () => {
});
this.sequelize.afterBulkSync(afterHook);
return expect(this.sequelize.sync()).to.be.rejected.then(() => {
await expect(this.sequelize.sync()).to.be.rejected;
expect(beforeHook).to.have.been.calledOnce;
expect(afterHook).not.to.have.been.called;
});
});
it('should return an error from after', function() {
it('should return an error from after', async function() {
const beforeHook = sinon.spy(),
afterHook = sinon.spy();
......@@ -367,11 +342,10 @@ describe(Support.getTestDialectTeaser('Hooks'), () => {
throw new Error('Whoops!');
});
return expect(this.sequelize.sync()).to.be.rejected.then(() => {
await expect(this.sequelize.sync()).to.be.rejected;
expect(beforeHook).to.have.been.calledOnce;
expect(afterHook).to.have.been.calledOnce;
});
});
afterEach(function() {
this.sequelize.options.hooks = {};
......@@ -381,58 +355,52 @@ describe(Support.getTestDialectTeaser('Hooks'), () => {
});
describe('#removal', () => {
it('should be able to remove by name', function() {
it('should be able to remove by name', async function() {
const sasukeHook = sinon.spy(),
narutoHook = sinon.spy();
this.User.addHook('beforeCreate', 'sasuke', sasukeHook);
this.User.addHook('beforeCreate', 'naruto', narutoHook);
return this.User.create({ username: 'makunouchi' }).then(() => {
await this.User.create({ username: 'makunouchi' });
expect(sasukeHook).to.have.been.calledOnce;
expect(narutoHook).to.have.been.calledOnce;
this.User.removeHook('beforeCreate', 'sasuke');
return this.User.create({ username: 'sendo' });
}).then(() => {
await this.User.create({ username: 'sendo' });
expect(sasukeHook).to.have.been.calledOnce;
expect(narutoHook).to.have.been.calledTwice;
});
});
it('should be able to remove by reference', function() {
it('should be able to remove by reference', async function() {
const sasukeHook = sinon.spy(),
narutoHook = sinon.spy();
this.User.addHook('beforeCreate', sasukeHook);
this.User.addHook('beforeCreate', narutoHook);
return this.User.create({ username: 'makunouchi' }).then(() => {
await this.User.create({ username: 'makunouchi' });
expect(sasukeHook).to.have.been.calledOnce;
expect(narutoHook).to.have.been.calledOnce;
this.User.removeHook('beforeCreate', sasukeHook);
return this.User.create({ username: 'sendo' });
}).then(() => {
await this.User.create({ username: 'sendo' });
expect(sasukeHook).to.have.been.calledOnce;
expect(narutoHook).to.have.been.calledTwice;
});
});
it('should be able to remove proxies', function() {
it('should be able to remove proxies', async function() {
const sasukeHook = sinon.spy(),
narutoHook = sinon.spy();
this.User.addHook('beforeSave', sasukeHook);
this.User.addHook('beforeSave', narutoHook);
return this.User.create({ username: 'makunouchi' }).then(user => {
const user = await this.User.create({ username: 'makunouchi' });
expect(sasukeHook).to.have.been.calledOnce;
expect(narutoHook).to.have.been.calledOnce;
this.User.removeHook('beforeSave', sasukeHook);
return user.update({ username: 'sendo' });
}).then(() => {
await user.update({ username: 'sendo' });
expect(sasukeHook).to.have.been.calledOnce;
expect(narutoHook).to.have.been.calledTwice;
});
});
});
});
......@@ -7,7 +7,7 @@ const chai = require('chai'),
sinon = require('sinon');
describe(Support.getTestDialectTeaser('Hooks'), () => {
beforeEach(function() {
beforeEach(async function() {
this.User = this.sequelize.define('User', {
username: {
type: DataTypes.STRING,
......@@ -29,31 +29,28 @@ describe(Support.getTestDialectTeaser('Hooks'), () => {
paranoid: true
});
return this.sequelize.sync({ force: true });
await this.sequelize.sync({ force: true });
});
describe('#restore', () => {
describe('on success', () => {
it('should run hooks', function() {
it('should run hooks', async function() {
const beforeHook = sinon.spy(),
afterHook = sinon.spy();
this.ParanoidUser.beforeRestore(beforeHook);
this.ParanoidUser.afterRestore(afterHook);
return this.ParanoidUser.create({ username: 'Toni', mood: 'happy' }).then(user => {
return user.destroy().then(() => {
return user.restore().then(() => {
const user = await this.ParanoidUser.create({ username: 'Toni', mood: 'happy' });
await user.destroy();
await user.restore();
expect(beforeHook).to.have.been.calledOnce;
expect(afterHook).to.have.been.calledOnce;
});
});
});
});
});
describe('on error', () => {
it('should return an error from before', function() {
it('should return an error from before', async function() {
const beforeHook = sinon.spy(),
afterHook = sinon.spy();
......@@ -63,17 +60,14 @@ describe(Support.getTestDialectTeaser('Hooks'), () => {
});
this.ParanoidUser.afterRestore(afterHook);
return this.ParanoidUser.create({ username: 'Toni', mood: 'happy' }).then(user => {
return user.destroy().then(() => {
return expect(user.restore()).to.be.rejected.then(() => {
const user = await this.ParanoidUser.create({ username: 'Toni', mood: 'happy' });
await user.destroy();
await expect(user.restore()).to.be.rejected;
expect(beforeHook).to.have.been.calledOnce;
expect(afterHook).not.to.have.been.called;
});
});
});
});
it('should return an error from after', function() {
it('should return an error from after', async function() {
const beforeHook = sinon.spy(),
afterHook = sinon.spy();
......@@ -83,16 +77,13 @@ describe(Support.getTestDialectTeaser('Hooks'), () => {
throw new Error('Whoops!');
});
return this.ParanoidUser.create({ username: 'Toni', mood: 'happy' }).then(user => {
return user.destroy().then(() => {
return expect(user.restore()).to.be.rejected.then(() => {
const user = await this.ParanoidUser.create({ username: 'Toni', mood: 'happy' });
await user.destroy();
await expect(user.restore()).to.be.rejected;
expect(beforeHook).to.have.been.calledOnce;
expect(afterHook).to.have.been.calledOnce;
});
});
});
});
});
});
});
......@@ -7,7 +7,7 @@ const chai = require('chai'),
sinon = require('sinon');
describe(Support.getTestDialectTeaser('Hooks'), () => {
beforeEach(function() {
beforeEach(async function() {
this.User = this.sequelize.define('User', {
username: {
type: DataTypes.STRING,
......@@ -18,12 +18,12 @@ describe(Support.getTestDialectTeaser('Hooks'), () => {
values: ['happy', 'sad', 'neutral']
}
});
return this.sequelize.sync({ force: true });
await this.sequelize.sync({ force: true });
});
describe('#update', () => {
describe('on success', () => {
it('should run hooks', function() {
it('should run hooks', async function() {
const beforeHook = sinon.spy(),
afterHook = sinon.spy(),
beforeSave = sinon.spy(),
......@@ -34,20 +34,18 @@ describe(Support.getTestDialectTeaser('Hooks'), () => {
this.User.beforeSave(beforeSave);
this.User.afterSave(afterSave);
return this.User.create({ username: 'Toni', mood: 'happy' }).then(user => {
return user.update({ username: 'Chong' }).then(user => {
const user = await this.User.create({ username: 'Toni', mood: 'happy' });
const user0 = await user.update({ username: 'Chong' });
expect(beforeHook).to.have.been.calledOnce;
expect(afterHook).to.have.been.calledOnce;
expect(beforeSave).to.have.been.calledTwice;
expect(afterSave).to.have.been.calledTwice;
expect(user.username).to.equal('Chong');
});
});
expect(user0.username).to.equal('Chong');
});
});
describe('on error', () => {
it('should return an error from before', function() {
it('should return an error from before', async function() {
const beforeHook = sinon.spy(),
afterHook = sinon.spy(),
beforeSave = sinon.spy(),
......@@ -61,17 +59,15 @@ describe(Support.getTestDialectTeaser('Hooks'), () => {
this.User.beforeSave(beforeSave);
this.User.afterSave(afterSave);
return this.User.create({ username: 'Toni', mood: 'happy' }).then(user => {
return expect(user.update({ username: 'Chong' })).to.be.rejected.then(() => {
const user = await this.User.create({ username: 'Toni', mood: 'happy' });
await expect(user.update({ username: 'Chong' })).to.be.rejected;
expect(beforeHook).to.have.been.calledOnce;
expect(beforeSave).to.have.been.calledOnce;
expect(afterHook).not.to.have.been.called;
expect(afterSave).to.have.been.calledOnce;
});
});
});
it('should return an error from after', function() {
it('should return an error from after', async function() {
const beforeHook = sinon.spy(),
afterHook = sinon.spy(),
beforeSave = sinon.spy(),
......@@ -85,47 +81,39 @@ describe(Support.getTestDialectTeaser('Hooks'), () => {
this.User.beforeSave(beforeSave);
this.User.afterSave(afterSave);
return this.User.create({ username: 'Toni', mood: 'happy' }).then(user => {
return expect(user.update({ username: 'Chong' })).to.be.rejected.then(() => {
const user = await this.User.create({ username: 'Toni', mood: 'happy' });
await expect(user.update({ username: 'Chong' })).to.be.rejected;
expect(beforeHook).to.have.been.calledOnce;
expect(afterHook).to.have.been.calledOnce;
expect(beforeSave).to.have.been.calledTwice;
expect(afterSave).to.have.been.calledOnce;
});
});
});
});
describe('preserves changes to instance', () => {
it('beforeValidate', function() {
it('beforeValidate', async function() {
this.User.beforeValidate(user => {
user.mood = 'happy';
});
return this.User.create({ username: 'fireninja', mood: 'invalid' }).then(user => {
return user.update({ username: 'hero' });
}).then(user => {
const user0 = await this.User.create({ username: 'fireninja', mood: 'invalid' });
const user = await user0.update({ username: 'hero' });
expect(user.username).to.equal('hero');
expect(user.mood).to.equal('happy');
});
});
it('afterValidate', function() {
it('afterValidate', async function() {
this.User.afterValidate(user => {
user.mood = 'sad';
});
return this.User.create({ username: 'fireninja', mood: 'nuetral' }).then(user => {
return user.update({ username: 'spider' });
}).then(user => {
const user0 = await this.User.create({ username: 'fireninja', mood: 'nuetral' });
const user = await user0.update({ username: 'spider' });
expect(user.username).to.equal('spider');
expect(user.mood).to.equal('sad');
});
});
it('beforeSave', function() {
it('beforeSave', async function() {
let hookCalled = 0;
this.User.beforeSave(user => {
......@@ -133,16 +121,14 @@ describe(Support.getTestDialectTeaser('Hooks'), () => {
hookCalled++;
});
return this.User.create({ username: 'fireninja', mood: 'nuetral' }).then(user => {
return user.update({ username: 'spider', mood: 'sad' });
}).then(user => {
const user0 = await this.User.create({ username: 'fireninja', mood: 'nuetral' });
const user = await user0.update({ username: 'spider', mood: 'sad' });
expect(user.username).to.equal('spider');
expect(user.mood).to.equal('happy');
expect(hookCalled).to.equal(2);
});
});
it('beforeSave with beforeUpdate', function() {
it('beforeSave with beforeUpdate', async function() {
let hookCalled = 0;
this.User.beforeUpdate(user => {
......@@ -155,14 +141,12 @@ describe(Support.getTestDialectTeaser('Hooks'), () => {
hookCalled++;
});
return this.User.create({ username: 'akira' }).then(user => {
return user.update({ username: 'spider', mood: 'sad' });
}).then(user => {
const user0 = await this.User.create({ username: 'akira' });
const user = await user0.update({ username: 'spider', mood: 'sad' });
expect(user.mood).to.equal('happy');
expect(user.username).to.equal('spider');
expect(hookCalled).to.equal(3);
});
});
});
});
});
......@@ -8,7 +8,7 @@ const chai = require('chai'),
if (Support.sequelize.dialect.supports.upserts) {
describe(Support.getTestDialectTeaser('Hooks'), () => {
beforeEach(function() {
beforeEach(async function() {
this.User = this.sequelize.define('User', {
username: {
type: DataTypes.STRING,
......@@ -20,27 +20,26 @@ if (Support.sequelize.dialect.supports.upserts) {
values: ['happy', 'sad', 'neutral']
}
});
return this.sequelize.sync({ force: true });
await this.sequelize.sync({ force: true });
});
describe('#upsert', () => {
describe('on success', () => {
it('should run hooks', function() {
it('should run hooks', async function() {
const beforeHook = sinon.spy(),
afterHook = sinon.spy();
this.User.beforeUpsert(beforeHook);
this.User.afterUpsert(afterHook);
return this.User.upsert({ username: 'Toni', mood: 'happy' }).then(() => {
await this.User.upsert({ username: 'Toni', mood: 'happy' });
expect(beforeHook).to.have.been.calledOnce;
expect(afterHook).to.have.been.calledOnce;
});
});
});
describe('on error', () => {
it('should return an error from before', function() {
it('should return an error from before', async function() {
const beforeHook = sinon.spy(),
afterHook = sinon.spy();
......@@ -50,13 +49,12 @@ if (Support.sequelize.dialect.supports.upserts) {
});
this.User.afterUpsert(afterHook);
return expect(this.User.upsert({ username: 'Toni', mood: 'happy' })).to.be.rejected.then(() => {
await expect(this.User.upsert({ username: 'Toni', mood: 'happy' })).to.be.rejected;
expect(beforeHook).to.have.been.calledOnce;
expect(afterHook).not.to.have.been.called;
});
});
it('should return an error from after', function() {
it('should return an error from after', async function() {
const beforeHook = sinon.spy(),
afterHook = sinon.spy();
......@@ -66,15 +64,14 @@ if (Support.sequelize.dialect.supports.upserts) {
throw new Error('Whoops!');
});
return expect(this.User.upsert({ username: 'Toni', mood: 'happy' })).to.be.rejected.then(() => {
await expect(this.User.upsert({ username: 'Toni', mood: 'happy' })).to.be.rejected;
expect(beforeHook).to.have.been.calledOnce;
expect(afterHook).to.have.been.calledOnce;
});
});
});
describe('preserves changes to values', () => {
it('beforeUpsert', function() {
it('beforeUpsert', async function() {
let hookCalled = 0;
const valuesOriginal = { mood: 'sad', username: 'leafninja' };
......@@ -83,12 +80,11 @@ if (Support.sequelize.dialect.supports.upserts) {
hookCalled++;
});
return this.User.upsert(valuesOriginal).then(() => {
await this.User.upsert(valuesOriginal);
expect(valuesOriginal.mood).to.equal('happy');
expect(hookCalled).to.equal(1);
});
});
});
});
});
}
......@@ -7,7 +7,7 @@ const Support = require('../support');
const DataTypes = require('../../../lib/data-types');
describe(Support.getTestDialectTeaser('Hooks'), () => {
beforeEach(function() {
beforeEach(async function() {
this.User = this.sequelize.define('User', {
username: {
type: DataTypes.STRING,
......@@ -18,12 +18,12 @@ describe(Support.getTestDialectTeaser('Hooks'), () => {
values: ['happy', 'sad', 'neutral']
}
});
return this.sequelize.sync({ force: true });
await this.sequelize.sync({ force: true });
});
describe('#validate', () => {
describe('#create', () => {
it('should return the user', function() {
it('should return the user', async function() {
this.User.beforeValidate(user => {
user.username = 'Bob';
user.mood = 'happy';
......@@ -33,15 +33,14 @@ describe(Support.getTestDialectTeaser('Hooks'), () => {
user.username = 'Toni';
});
return this.User.create({ mood: 'ecstatic' }).then(user => {
const user = await this.User.create({ mood: 'ecstatic' });
expect(user.mood).to.equal('happy');
expect(user.username).to.equal('Toni');
});
});
});
describe('#3534, hooks modifications', () => {
it('fields modified in hooks are saved', function() {
it('fields modified in hooks are saved', async function() {
this.User.afterValidate(user => {
//if username is defined and has more than 5 char
user.username = user.username
......@@ -56,7 +55,7 @@ describe(Support.getTestDialectTeaser('Hooks'), () => {
});
return this.User.create({ username: 'T', mood: 'neutral' }).then(user => {
const user = await this.User.create({ username: 'T', mood: 'neutral' });
expect(user.mood).to.equal('neutral');
expect(user.username).to.equal('Samorost 3');
......@@ -64,87 +63,77 @@ describe(Support.getTestDialectTeaser('Hooks'), () => {
user.mood = 'sad';
user.username = 'Samorost Good One';
return user.save();
}).then(uSaved => {
expect(uSaved.mood).to.equal('sad');
expect(uSaved.username).to.equal('Samorost Good One');
const uSaved0 = await user.save();
expect(uSaved0.mood).to.equal('sad');
expect(uSaved0.username).to.equal('Samorost Good One');
//change attributes, expect to be replaced by hooks
uSaved.username = 'One';
uSaved0.username = 'One';
return uSaved.save();
}).then(uSaved => {
const uSaved = await uSaved0.save();
//attributes were replaced by hooks ?
expect(uSaved.mood).to.equal('sad');
expect(uSaved.username).to.equal('Samorost 3');
return this.User.findByPk(uSaved.id);
}).then(uFetched => {
expect(uFetched.mood).to.equal('sad');
expect(uFetched.username).to.equal('Samorost 3');
const uFetched0 = await this.User.findByPk(uSaved.id);
expect(uFetched0.mood).to.equal('sad');
expect(uFetched0.username).to.equal('Samorost 3');
uFetched.mood = null;
uFetched.username = 'New Game is Needed';
uFetched0.mood = null;
uFetched0.username = 'New Game is Needed';
return uFetched.save();
}).then(uFetchedSaved => {
expect(uFetchedSaved.mood).to.equal('neutral');
expect(uFetchedSaved.username).to.equal('New Game is Needed');
const uFetchedSaved0 = await uFetched0.save();
expect(uFetchedSaved0.mood).to.equal('neutral');
expect(uFetchedSaved0.username).to.equal('New Game is Needed');
return this.User.findByPk(uFetchedSaved.id);
}).then(uFetched => {
const uFetched = await this.User.findByPk(uFetchedSaved0.id);
expect(uFetched.mood).to.equal('neutral');
expect(uFetched.username).to.equal('New Game is Needed');
//expect to be replaced by hooks
uFetched.username = 'New';
uFetched.mood = 'happy';
return uFetched.save();
}).then(uFetchedSaved => {
const uFetchedSaved = await uFetched.save();
expect(uFetchedSaved.mood).to.equal('happy');
expect(uFetchedSaved.username).to.equal('Samorost 3');
});
});
});
describe('on error', () => {
it('should emit an error from after hook', function() {
it('should emit an error from after hook', async function() {
this.User.afterValidate(user => {
user.mood = 'ecstatic';
throw new Error('Whoops! Changed user.mood!');
});
return expect(this.User.create({ username: 'Toni', mood: 'happy' })).to.be.rejectedWith('Whoops! Changed user.mood!');
await expect(this.User.create({ username: 'Toni', mood: 'happy' })).to.be.rejectedWith('Whoops! Changed user.mood!');
});
it('should call validationFailed hook', function() {
it('should call validationFailed hook', async function() {
const validationFailedHook = sinon.spy();
this.User.validationFailed(validationFailedHook);
return expect(this.User.create({ mood: 'happy' })).to.be.rejected.then(() => {
await expect(this.User.create({ mood: 'happy' })).to.be.rejected;
expect(validationFailedHook).to.have.been.calledOnce;
});
});
it('should not replace the validation error in validationFailed hook by default', function() {
it('should not replace the validation error in validationFailed hook by default', async function() {
const validationFailedHook = sinon.stub();
this.User.validationFailed(validationFailedHook);
return expect(this.User.create({ mood: 'happy' })).to.be.rejected.then(err => {
const err = await expect(this.User.create({ mood: 'happy' })).to.be.rejected;
expect(err.name).to.equal('SequelizeValidationError');
});
});
it('should replace the validation error if validationFailed hook creates a new error', function() {
it('should replace the validation error if validationFailed hook creates a new error', async function() {
const validationFailedHook = sinon.stub().throws(new Error('Whoops!'));
this.User.validationFailed(validationFailedHook);
return expect(this.User.create({ mood: 'happy' })).to.be.rejected.then(err => {
const err = await expect(this.User.create({ mood: 'happy' })).to.be.rejected;
expect(err.message).to.equal('Whoops!');
});
});
});
});
});
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!