mardi 31 mars 2015

How can I get Jasmine to wait for a Meteor method call to complete without resorting to setTimeout?

I'm writing a client integration test to verify a particular user can change roles on other users via the front-end.



it('should be able to change user roles', function(done) {
var newUser = Meteor.users.findOne({ emails: { $elemMatch: { address: 'devon@radworks.io' } } });
$('#user-' + newUser._id + '-roles').val('manage-users').change();
expect(Roles.userIsInRole(newUser, 'manage-users')).toBe(true);
expect(Roles.userIsInRole(newUser, 'edit-any')).toBe(false);
done();
});


The change() event is bound to a function that calls a Meteor method to change the roles.



Template.users.events({
'change .change-roles': function(e) {
e.preventDefault();
var newRoles = $(e.target).val() || [];
Meteor.call('changeRoles', this._id, newRoles);
}
});


Here's the Meteor method:



Meteor.methods({
'changeRoles': function (userToChangeId, newRoles) {
check(this.userId, String);
check(userToChangeId, String);

if (!Roles.userIsInRole(this.userId, 'manage-users')) {
throw new Meteor.Error('Not authorized to manage user roles');
}

// If the current logged in user is the one we are changing, add manage-users back to
// the list of new roles.
if (userToChangeId === this.userId) {
newRoles.push('manage-users');
}

if (Meteor.users.find(userToChangeId).count() !== 1) {
throw new Meteor.Error('invalid', 'Unable to find the user you want to change');
}

Roles.setUserRoles(userToChangeId, newRoles);
}
});


My test fails even though I can run the test manually and get the expected results. I believe it fails because Roles.setUserRoles has not yet completed by the time I run the expect in my test. I want to wait on the method to complete without simply putting the expect behind a setTimeout. What's the pattern for doing this?


Aucun commentaire:

Enregistrer un commentaire