Skip to content

Commit

Permalink
[Issue #228] consumers to add model hooks
Browse files Browse the repository at this point in the history
  • Loading branch information
Russ Nicoletti committed Jan 26, 2017
1 parent adf2fd8 commit 9d653f2
Show file tree
Hide file tree
Showing 4 changed files with 126 additions and 3 deletions.
11 changes: 10 additions & 1 deletion example/example.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,16 @@ const config = {
port: 5432,
name: 'sensorthingsexample',
user: 'postgres',
password: '12345678'
password: '12345678',
hooks: {
'beforeCreate': (instance, options) => {
if (instance.$modelOptions.name.plural === 'Things') {
instance.properties = Object.assign({}, instance.properties, {
MozillaSensorWebOwner: 'client-name'
});
}
}
}
}
};

Expand Down
18 changes: 18 additions & 0 deletions src/models/db.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,17 @@ const IDLE = 0
const INITIALIZING = 1;
const READY = 2;

const hooks = [
'beforeValidate',
'afterValidate',
'beforeCreate',
'afterCreate',
'beforeDestroy',
'afterDestroy',
'beforeUpdate',
'afterUpdate'
];

const Deferred = function Deferred () {
this.promise = new Promise((resolve, reject) => {
this.resolve = resolve;
Expand Down Expand Up @@ -84,6 +95,13 @@ export default config => {
}
});

hooks.forEach(hook => {
const clientHook = config.hooks[hook];
if (clientHook) {
sequelize.addHook(hook, clientHook);
}
});

db.sequelize = sequelize;
db.Sequelize = Sequelize;

Expand Down
38 changes: 36 additions & 2 deletions test/server.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,43 @@ const config = {
port: 5432,
name: 'sensorthingstest',
user: 'postgres',
pass: '12345678'
pass: '12345678',
hooks: {
'beforeValidate': instance => {
instance.beforeValidate = 'beforeValidate';
},
'afterValidate': instance => {
instance.afterValidate = 'afterValidate';
},
'beforeCreate': instance => {
instance.beforeCreate = 'beforeCreate';
},
'afterCreate': instance => {
instance.afterCreate = 'afterCreate';
},
// From Sequelize documentation:
// (http://docs.sequelizejs.com/en/latest/docs/hooks/)
// "The only way to call beforeDestroy/afterDestroy hooks are on
// associations with `onDelete: 'cascade'` and the option `hooks: true`"
// TBD It seems our ST API implementation does not exercise these hooks.
// Perhaps we should not implement them.
/*
'beforeDestroy': () => {
},
'afterDestroy': () => {
},
*/
'beforeUpdate': (instance) => {
// TODO Updating an instance does not return the instance. Therefore,
// it still needs to be determined how to test this hook.
},
'afterUpdate': (instance) => {
// TODO Updating an instance does not return the instance. Therefore,
// it still needs to be determined how to test this hook.
}
}
}
};
}

app.use('/', SensorThings(config));

Expand Down
62 changes: 62 additions & 0 deletions test/test_client_db_hooks.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import db from '../src/models/db';
import * as CONST from './constants';

db().then(models => {
describe('db hooks', () => {
beforeEach(() => {
return models.sequelize.transaction(transaction => {
return Promise.all(Object.keys(CONST.entities).map(name => {
return models[name].destroy({ transaction, where: {} });
}));
});
});

Object.keys(CONST.entities).forEach(entity => {
it(entity + ' db "create" hooks', done => {
models[entity].create(CONST[entity + 'Entity']).then(instance => {
[
'beforeValidate',
'afterValidate',
'beforeCreate',
'afterCreate'
].forEach(hook => {
hook.should.be.equal(instance[hook]);
});
});
done();
})
});

// This test does not cause the before/afterDestroy hooks to be run.
// From Sequelize documentation:
// (http://docs.sequelizejs.com/en/latest/docs/hooks/)
// "The only way to call beforeDestroy/afterDestroy hooks are on
// associations with `onDelete: 'cascade'` and the option `hooks: true`"
// TBD It seems our ST API implementation does not exercise these hooks.
// Perhaps we should not implement them.
xit('db "destroy" hooks', done => {
models[CONST.things].create(CONST.ThingsEntity).then(instance => {
const id = instance.id;
models[CONST.things].destroy({ where: { id } }).then(() => {
done();
});
});
})

xit('db "update" hooks', done => {
// TODO The 'before/afterUpdate' hooks are not being run during this
// test. Why not?
models[CONST.datastreams].create(CONST.DatastreamsEntity).then(
instance => {
const id = instance.id;
const entity = Object.assign({}, CONST.DatastreamsEntity);
entity.name = 'russ';
models[CONST.datastreams].update(entity, { where: { id: id } }).then(
() => {
done();
});
});
})
});
});

0 comments on commit 9d653f2

Please sign in to comment.