I’m learning Meteor following basic “Todo tutorial” from official website. I have problem with the “Testing” step.
I have basic test of one Method, it looks like this:
if (Meteor.isServer) {
describe('Tasks', () => {
describe('methods', () => {
const userId = Random.id();
let taskId;
beforeEach(() => {
Tasks.remove({});
taskId = Tasks.insert({
text: 'test task',
createdAt: new Date(),
owner: userId,
username: 'tmeasday',
});
});
it('can delete owned task', () => {
const deleteTask = Meteor.server.method_handlers['tasks.remove'];
const invocation = { userId };
deleteTask.apply(invocation, [taskId]);
assert.equal(Tasks.find().count(), 0);
});
});
});
}
This test fails with error:
Error: Meteor.userId can only be invoked in method calls. Use this.userId in publish functions.
at AccountsServer.userId (packages/accounts-base/accounts_server.js:82:13)
at Object.Meteor.userId (packages/accounts-base/accounts_common.js:257:19)
at Object.Meteor.methods.tasks.remove (imports/api/tasks.js:37:35)
at Test.<anonymous> (imports/api/tasks.tests.js:27:28)
at run (packages/practicalmeteor:mocha-core/server.js:34:29)
at Context.wrappedFunction (packages/practicalmeteor:mocha-core/server.js:63:33)
IMO, this error message is controversial, because it says about mistake I didn’t make, because as I can see from line 4 in the error message, stacktrace points to the Method declaration body, this one:
'tasks.remove' (taskId) {
check(taskId, String);
const task = Tasks.findOne(taskId);
if (task.owner !== Meteor.userId()) { // <- ERROR MESSAGE POINTS TO THIS LINE
// If the task is private, make sure only the owner can delete it
throw new Meteor.Error('not-authorized');
}
Tasks.remove(taskId);
},
There is 1 difference between tutorial code and my one: I removed the condition !todo.private
from my if
statements, so in the original tutorial they look like this:
if (!task.private && task.owner !== Meteor.userId()) {...
IMO, this change makes the test reach the expression where it fails, because with the original code the test passes.
I also mentioned that changing Meteor.userId()
to this.userId
makes the test pass and the app also looks to work like before.
So, my question basically is: why the error message shows me controversial (IMO) info and what is the difference between using this.userId
and Meteor.userId()
in Methods?
My full “Todo tutorial” project code can be found at: https://github.com/kemsbe/simple-todo