-
Notifications
You must be signed in to change notification settings - Fork 9
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Issue #228] consumers to add model hooks #235
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
import db from '../src/models/db'; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As I was creating a dedicated express app I realized the hook tests don't need one -- it is using sequelize to operate on the models directly. But event if it did, it seems to me the issue of enabling the hooks for the hooks tests but not for the other tests is related to the db module (db.js) essentially being a singleton; once it is instantiated and becomes READY, subsequent instantiations will return a promise the the originally instantiated instance. Since the majority of the tests will instantiate the db without the hooks, when the hooks test instantiates the db with a config that has the hooks, the db instance returned will be the one without the hooks because that instance was created first. I don't see a way around that. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You are right! Sorry, I didn't think about that. I guess one way to workaround this would be to use a different db name for these tests... but it is probably not the best solution and definitely not worth the effort. Let's just use The reason why I suggested not using There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I completely agree that modifying the responses of all the tests is not a good idea; in fact, it is a very bad idea :), and it is one reason I like your suggestion for the update case; I will use it for all the hooks. |
||
import * as CONST from './constants'; | ||
import { hookInvoked, resetHooks } from './server'; | ||
|
||
// Database hooks (sequelize) | ||
const dbHooks = [ | ||
'beforeCreate', | ||
'afterCreate', | ||
'beforeDestroy', | ||
'afterDestroy', | ||
'beforeUpdate', | ||
'afterUpdate' | ||
]; | ||
|
||
db().then(models => { | ||
describe('Database hooks', () => { | ||
beforeEach(() => { | ||
resetHooks(); | ||
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 + ' "create" hooks', done => { | ||
models[entity].create(CONST[entity + 'Entity']).then(() => { | ||
dbHooks.slice(0, 2).forEach(hook => { | ||
hookInvoked(hook).should.be.true(); | ||
}); | ||
done(); | ||
}); | ||
}) | ||
}); | ||
|
||
// These tests fail. See: | ||
// https://github.com/mozilla-sensorweb/sensorthings/issues/246 | ||
Object.keys(CONST.entities).forEach(entity => { | ||
xit(entity + ' "destroy" hooks', done => { | ||
models[entity].create(CONST[entity + 'Entity']).then( | ||
instance => { | ||
const id = instance.id; | ||
models[entity].destroy({ | ||
where: { id } }).then(() => { | ||
dbHooks.slice(2, 4).forEach(hook => { | ||
hookInvoked(hook).should.be.true(); | ||
}); | ||
done(); | ||
}); | ||
}); | ||
}) | ||
}); | ||
|
||
Object.keys(CONST.entities).forEach(entity => { | ||
it(entity + ' "update" hooks', done => { | ||
models[entity].create(CONST[entity + 'Entity']).then( | ||
instance => { | ||
models[entity].update({ name: 'newname' }, { | ||
where: { id: instance.id }, | ||
individualHooks: true | ||
}).then(() => { | ||
dbHooks.slice(4).forEach(hook => { | ||
hookInvoked(hook).should.be.true(); | ||
}); | ||
done(); | ||
}); | ||
}); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe try something easier: [CONST.beforeValidate,
CONST.afterValidate,
CONST.beforeCreate,
CONST.afterCreate].forEach(hook => {
instance[hook].should.be.equal(hook);
}); |
||
}) | ||
}); | ||
}); | ||
}); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wasn't able to initialize the db hooks only for the "db hooks" test (because it is essentially a singleton, I don't see a way to initialize the db with hooks for the "db hooks" test and without db hooks for all the other tests). Therefore, many tests fail because instances have properties the tests are not expecting. I will think about possible solutions but I would appreciate your input on this issue.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just don't use
server.js
. Create a dedicated express app for the hook tests insidetest_client_db_hooks.js
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As I'm addressing your other comments it occurs to me the hooks test don't need an express app. The hooks test is using sequelize to create the model instances.
In any event, even if it did use a dedicated express app, I'm finding that doing so results in the hooks not be set on the models. I believe this is because the dedicated express app ends up using the same 'db' module as the common express app (
server.js
) used by the other tests, and the 'db' module acts like a singleton: once it is instantiated and becomes 'READY', it will return a promise containing its instance. The 'db' instance used by the hooks test will not have the hooks in place because the common express app does not specify the hooks and it is the common express app that first instantiates the 'db' module.For now, I will have the common express app create the db hooks (using your suggestion from here: https://github.com/mozilla-sensorweb/sensorthings/pull/235/files#r97766628 so that the hooks won't add additional properties that break other tests).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As I was creating a dedicated express app I realized the hook tests don't need one -- it is using sequelize to operate on the models directly. But event if it did, it seems to me the issue of enabling the hooks for the hooks tests but not for the other tests is related to the db module (db.js) essentially being a singleton; once it is instantiated and becomes READY, subsequent instantiations will return a promise the the originally instantiated instance. Since the majority of the tests will instantiate the db without the hooks, when the hooks test instantiates the db with a config that has the hooks, the db instance returned will be the one without the hooks because that instance was created first. I don't see a way around that.