I’m just wondering and curious if, and if so, how do you test your publications? What frameworks, patterns do you use?
I’m going to bump this because I think it’s an important topic. Pub/sub in most meteor apps constitutes most of the who-can-see-what security.
I have some tests which use this style of testing publications:
#coffeescript
publicationName = 'foo'
publicationHandler = Meteor.server.publish_handlers[publicationName]
thisContext = {userId: 'bob'}
publishParams = ['some', 'params']
publishedCursor = thePublicationFunction.apply(thisContext, publishParams)
#followed by some test code inspecting the records in the cursor.
This allows me to test the contents of the cursor returned from the publish function as a user would see it. The problem is this only works with “simple” publish functions that returns a cursor, like this:
Meteor.publish({
foo: function() {
if (!this.userId) return;
return FooCollection.find({userId: this.userId})
}
});
If foo
is more complicated (ex. calls observeChanges
, this.added
, this.changed
, this.removed
), I don’t know a good way to test the publication. Anyone else?
Am very interested in seeing what other people come up w/ on this as well. One package that I’ve been using which might help is practicalmeteor:munit
.
Given @mark’s publication, you could probably use a sinon.stub()
on Meteor.server.publish_handlers
. Perhaps something like:
describe('test the publication', function() {
var context;
beforeAll(function() {
sinon.stub(FooCollection, 'find').returns('cursor');
});
afterAll(function() {
FooCollection.find.restore();
});
beforeEach(function() {
context = { userId: "bob" };
FooCollection.find.reset();
});
it('should call .find() on collection with correct params and return the cursor', function() {
var params = ['some', 'params'];
var result = Meteor.server.publish_handlers.foo.apply(context, params);
assert.isTrue(FooCollection.find.calledWithExactly({ userId: "bob" }), 'FooCollection.find() was not called with correct params');
assert.equal(result, 'cursor', 'The publication function did not return the cursor');
});
});
For more complex publication logic, you could fake a return object with .added()
, .changed()
and .removed()
stubbed out as well.