Meteor-Community-Packages / meteor-roles

Authorization package for Meteor, compatible with built-in accounts packages
http://meteor-community-packages.github.io/meteor-roles/
MIT License
921 stars 168 forks source link

Using this package in unit tests #199

Closed ddeklerk closed 5 years ago

ddeklerk commented 8 years ago

How does one go about testing methods that check for roles for example? Whenever I try to test my methods they fail because no user during the test has a role.

ddeklerk commented 8 years ago

Ok, I may have found a solution. Whenever I test a method that checks for your role, I need to define the user in that test itself.

An example:

describe('myMethod', () => {
  it('requires you to be admin', () => {
    const adminUserId = Accounts.createUser(
      email: 'admin@testing',
      password: 'testAdmin',
      username: 'testAdmin',
    });

    Roles.addUsersToRoles(adminUserId, 'admin');

    assert.doesNotThrow(() => {
      // The method in which the role is checked
      myMethod._execute({ userId: adminUserId }, { some, other, params });
    });
  });
});

I have not figured out if I can define the user in a beforeEach block, which would make more sense. But whenever I try I cannot test for the role again.

CaptainChemist commented 8 years ago

Did you ever figure out a better solution to this problem? I get an error that says: Missing 'users' param on the client and

Error: expected [Function] to not throw an error but 'Error: Meteor.userId can only be invoked in method calls. Use this.userId in publish functions.'

on the server. This is my code that I adapted from yours. Thanks for any suggestions you can give!

import { Meteor } from 'meteor/meteor';
import { assert } from 'meteor/practicalmeteor:chai';
import { resetDatabase } from 'meteor/xolvio:cleaner';
import { Factory } from 'meteor/dburles:factory';
import { Sections } from '../sections.js';
import { insertSection } from './methods.js';
  it('inserts a section into the Sections collection', function () {
    const adminUserId = Accounts.createUser({
      email: 'admin@testing',
      password: 'testAdmin',
      username: 'testAdmin',
    });

    Roles.addUsersToRoles(adminUserId, 'admin');

    assert.doesNotThrow(() => {
      insertSection._execute({ userId: adminUserId }, {
        name: 'Basics',
        description: 'Easy Stuff',
        image: 'bla.jpg',
        courseName: 'General Chemistry',
        level: '1',
        seoDescription: 'Stuff',
      });
    });
  });

export const insertSection = new ValidatedMethod({
  name: 'sections.insert',
  validate: new SimpleSchema({
    name: { type: String },
    description: { type: String },
    image: { type: String },
    courseName: { type: String },
    level: { type: String },
    seoDescription: { type: String, optional: true },
  }).validator(),
  run(section) {
    if (Roles.userIsInRole(Meteor.userId(), ['admin'])) {
      try {
        Sections.insert(section);
      } catch (error) {
        throw new Meteor.Error(500, error);
      }
    } else {
      throw new Meteor.Error(500, 'You are not an admin!');
    }
  },
});
brooksbecton commented 6 years ago

I made a Gist of a script I use for creating these 'test' user account. https://gist.github.com/brooksbecton/f763c8f8be754d180c158b848b627dbc

An example of using this file may look like


import {
  users,
  createMockUsers,
} from './createMockUsers';

/**
* Snip
*/

beforeEach(() => {
  createMockUsers();
});

it('inserts an order for a maintainer', () => {
  insertOrder._execute({ userId: users.eve.uid }, {productIds: [1,2,3] });
  const orderCount = Order.find({}).fetch().length;
  assert.equal(orderCount, 1);
});

it("throws error if someone is not a 'maintainer'", () => {
  assert.throws(() =>
    insertOrder._execute({ userId: users.bob.uid }, {productIds: [1,2,3] }));
});

Also the users above are using mdg's validated method. If you also use the loggedin-mixin it can check for user login and also you can Check for user roles with it also

mitar commented 5 years ago

Closing this because it does not look like something which is actionable.