Calling methods from test, but not logged in


#1

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.


#2

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:


#3

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


#4

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.


#5

Thank you, this will give me a good start.