Calling methods from test, but not logged in

I’m just starting to use the meteortesting:mocha package. I’ve looked at some tutorials online, and have a test method that works and passes, but it isn’t really what I through testing should be.

I have a class called alertSeverity that takes a name and 2 color inputs.

In the method for insert, I also get the userId, current Date, and some other user related information to insert. None of this is passed to the method when called though.

So, from the tutorial, I generate some test data using faker for name and the 2 colors. Then I just create to const for the other user info.

The issue is this just tests if I can write to the collection.

I have the following in alertSeverity.test.js:

if (Meteor.isServer) {
    describe('Add Severity', () => {
        it('can add a severity', () => {
            const severityName = faker.hacker.adjective(20);
            const severityColor = faker.commerce.color();
            const severityText = faker.commerce.color();
            const severityEntityParent = "Global";
            const severityUserEntity = "Global";

            AlertSeverity.insert({
                severityName,
                severityColor,
                severityText,
                severityEntityParent,
                severityUserEntity,
                addedBy: "bmcgonag",
                addedOn: new Date(),
            });
        });
    });
}

Instead of inserting from inside the test, I figured it made more sense to call my method int he alertSeverity.js file.

my alertSeverity.js method below:

Meteor.methods({
    'add.alertSeverity' (severityName, severityColor, textColor) {
        check(severityName, String);
        check(severityColor, String);
        check(textColor, String);

        if (!this.userId) {
            throw new Meteor.Error('User is not authorized to add alert severity levels. Check to ensure you are logged in.');
        }

        let userEntity = Meteor.users.findOne(this.userId).profile.usersEntity;
        let entityInfo = Entities.findOne({ entityName: userEntity });
        let parentEntity = entityInfo.entityParent;

        return AlertSeverity.insert({
            severityName: severityName,
            severityColor: severityColor,
            severityText: textColor,
            severityEntityParent: parentEntity,
            severityUserEntity: userEntity,
            addedBy: Meteor.users.findOne(this.userId).username,
            addedOn: new Date(),
        });
    },

and I would then change my test to be:

if (Meteor.isServer) {
    describe('Add Severity', () => {
        it('can add a severity', () => {
            const severityName = faker.hacker.adjective(20);
            const severityColor = faker.commerce.color();
            const severityText = faker.commerce.color();

            Meteor.call('add.alertSeverity', severityName, severityColor, severityText);
        });
    });
}

When I do this, however, I get an error (which is good) that I’m not logged in, and therefore it can’t run my test. So, it’s good because I want the method to only be accessible when a user is logged in, but I also want to be able to test it.

I guess I’m missing something, but how do I get the test to run if I can’t use the UI to log in?

As always, any help is greatly appreciated.

When you run your test, the flag Meteor.isTest is set to true. You may use this flag in your method.
// I don’t have any experience of testing :joy:

Apologies, but I don’t think I’m following.

I havent tested with plain methods I use validated methods and run tests using the .execute function that allows to pass a context object. But that can also be done with plain methods, you can find more info on this thread.

Basically you can do it like this:

it('can delete owned task', () => {
  // Find the internal implementation of the task method so we can
  // test it in isolation
  const deleteTask = Meteor.server.method_handlers['tasks.remove'];

  // Set up a fake method context that looks like what the method expects
  const context = { userId };

  // Run the method with `this` set to the fake context
  deleteTask.apply(context, [taskId]);

  // Verify that the method does what we expected
  assert.equal(Tasks.find().count(), 0);
});

Hope this helps.

2 Likes

Thank you, this will give me a good start.

1 Like