7

I am using validated methods (mdg:validated-method) with LoggedInMixin (tunifight:loggedin-mixin).

Now I have a problem with my unit tests, as they fail with notLogged error, because in the unit tests there is no logged user of course. How do I have to stub that?

method

const resetEdit = new ValidatedMethod({
  name: 'reset',
  mixins: [LoggedInMixin],
  checkLoggedInError: { error: 'notLogged' }, // <- throws error if user is not logged in
  validate: null,

  run ({ id }) {
    // ...
  }
})

unit test

describe('resetEdit', () => {
  it('should reset data', (done) => {
    resetEdit.call({ id: 'IDString' })
  })
})

Unit tests throws Error: [notLogged].

user3142695
  • 15,844
  • 47
  • 176
  • 332
  • have you tried mocking Meteor.user and Meteor.userId? You could also try creating a fixture with a user prior to running the tests, then logging in with that user before running your test – Zack Newsham Sep 29 '17 at 04:28
  • I'm not quite sure how to do that, as I'm doing the unit tests in my CI workflow by using the `meteor test --once` command. So I think I cannot login any user... – user3142695 Sep 29 '17 at 04:36
  • you can, in your test you should be able to do something like `Meteor.loginWithPassword(user, password, function({ resetEdit.call({id: "IDString"}); }));` – Zack Newsham Sep 29 '17 at 04:56
  • 1
    Did you try `resetEdit.call.call({ userId: Random.id() }, { id: 'IDString' })`? – Styx Sep 29 '17 at 04:56

1 Answers1

1

Edit:

validated-method has a built-in way of providing a context and it is documented in the README, exactly for cases like the one in your question.

method#_execute(context: Object, args: Object)

Call this from your test code to simulate calling a method on behalf of a particular user:

(source)

  it('should reset data', (done) => {
      resetEdit._execute({userId: '123'}, { id: 'IDString' });
      done();
  });

Original answer:

I believe that this can be achieved using the DDP._CurrentMethodInvocation meteor environment variable.

If you run the test in a scope where the its value is an object a userId string, it will be merged with the rest of the method invocation context object and the mixin will not fail.

describe('resetEdit', () => {
  it('should reset data', (done) => {
    DDP._CurrentMethodInvocation.withValue({userId: '123'}, function() {
      console.log(DDP._CurrentInvocation.get()); // {userId: '123'}
      resetEdit.call({ id: 'IDString' });
      done();
    })
  });
})
MasterAM
  • 16,283
  • 6
  • 45
  • 66
  • So you would recommend to not use that mixin, but to test for logged user manually in the run function? – user3142695 Oct 10 '17 at 20:06
  • The mixin is fine. I am not sure why `run` cannot be used directly, but I indeed found an easier way to achieve running with a synthetic context. I will update my answer to include it. – MasterAM Oct 10 '17 at 20:23