I'm writing unit test for my Meteor 1.4.2
application, where few of my methods requires authentication before processing.
How should I test these methods?
So far, I've written a test with practicalmeteor:mocha
to create a new user and login with that user.
describe('login method', function () {
let logingKey;
beforeEach(function () {
Meteor.users.remove({});
const createUser = Meteor.server.method_handlers['registerUser'];
let params = {
username: 'testUsername'
}
res = createUser.apply({}, [params]);
logingKey = res.key;
});
it('can provide authentication', function () {
const loginUser = Meteor.server.method_handlers['login'];
let params = {
key: logingKey
}
console.log(params);
loginUser.apply({}, [params]);
});
I've written a custom login handler to login with the generated key which works fine with application, but in test results I'm getting following error.
Error: Cannot read property 'id' of undefined
at AccountsServer.Ap._setLoginToken (packages/accounts-base/accounts_server.js:889:35)
at packages/accounts-base/accounts_server.js:288:10
at Object.Meteor._noYieldsAllowed (packages/meteor.js:671:12)
at AccountsServer.Ap._loginUser (packages/accounts-base/accounts_server.js:287:10)
at AccountsServer.Ap._attemptLogin (packages/accounts-base/accounts_server.js:349:12)
at Object.methods.login (packages/accounts-base/accounts_server.js:533:21)
at Object.methodMap.(anonymous function) (packages/meteorhacks_kadira.js:2731:30)
at Test.<anonymous> (imports/api/methods/loginUser.tests.js:30:17)
at run (packages/practicalmeteor:mocha-core/server.js:34:29)
at Context.wrappedFunction (packages/practicalmeteor:mocha-core/server.js:63:33)
What could be wrong here? any suggestions are welcome, thanks in advance.
UPDATE
Ok! here is my confustion, Let say I've a write a unit test for this method, How should I verify or get the userId here.
Meteor.methods({
userStatus:function(update){
check(update, {online: String})
if (! this.userId) {
throw new Meteor.Error('error-not-authorized','User need to login', {method: "userStatus"})
}
try {
Meteor.users.update(Meteor.userId(),{$set: {'status.online': !!parseInt(update.online)}})
} catch (e) {
console.error("Error",e);
}
}
});
You are directly invoking a method handler without an appropriate context (which should be a Method Invocation object, while you provide an empty object). The
login
method handler attempts to get the connection id and fails to do so.If you want to test the integration of your package with the
accounts-base
package (and basically you do, as you are calling some of its code), you can create a connection and call the method with that connection.Edit (following question edit):
The answer remains pretty much the same. Once you have called the
login
method and logged in the user, the connection state on the server should include the logged-in user's id. Now you can call the methods that require the user to be logged in.Note that you should probably use
this.userId
on all occasions (and notMeteor.userId()
).