From 466e849f95f456aaef6ac70fb7b190b282285173 Mon Sep 17 00:00:00 2001 From: denihs Date: Mon, 11 Nov 2024 11:01:21 -0400 Subject: [PATCH 1/3] - Migrate all the tests from Roles to Tinytests --- .envrc | 4 +- .travis.yml | 2 +- .../force-ssl-common/.npm/package/.gitignore | 1 - packages/force-ssl-common/.npm/package/README | 7 - packages/roles/package.js | 16 +- packages/roles/roles_server.js | 2 +- packages/roles/tests/client.js | 240 +- packages/roles/tests/clientAsync.js | 261 +- packages/roles/tests/serverAsync.js | 4458 ++++++++++------- 9 files changed, 2946 insertions(+), 2045 deletions(-) delete mode 100644 packages/force-ssl-common/.npm/package/.gitignore delete mode 100644 packages/force-ssl-common/.npm/package/README diff --git a/.envrc b/.envrc index 0ea9402d01..b1f3cbd76f 100644 --- a/.envrc +++ b/.envrc @@ -20,7 +20,7 @@ function @get-ready { } function @test-packages { - TINYTEST_FILTER="$1" @meteor test-packages --exclude-archs=web.browser.legacy,web.cordova --exclude=roles + TINYTEST_FILTER="$1" @meteor test-packages --exclude-archs=web.browser.legacy,web.cordova } function @test-self { @@ -54,4 +54,4 @@ function @docs-start { function @docs-migration-start { npm run docs:dev --prefix "$ROOT_DIR/v3-docs/v3-migration-docs" -} \ No newline at end of file +} diff --git a/.travis.yml b/.travis.yml index 7120c09376..6d58476294 100644 --- a/.travis.yml +++ b/.travis.yml @@ -16,7 +16,7 @@ env: - CXX=g++-12 - phantom=false - PUPPETEER_DOWNLOAD_PATH=~/.npm/chromium - - TEST_PACKAGES_EXCLUDE=roles,stylus + - TEST_PACKAGES_EXCLUDE=stylus addons: apt: sources: diff --git a/packages/force-ssl-common/.npm/package/.gitignore b/packages/force-ssl-common/.npm/package/.gitignore deleted file mode 100644 index 3c3629e647..0000000000 --- a/packages/force-ssl-common/.npm/package/.gitignore +++ /dev/null @@ -1 +0,0 @@ -node_modules diff --git a/packages/force-ssl-common/.npm/package/README b/packages/force-ssl-common/.npm/package/README deleted file mode 100644 index 3d492553a4..0000000000 --- a/packages/force-ssl-common/.npm/package/README +++ /dev/null @@ -1,7 +0,0 @@ -This directory and the files immediately inside it are automatically generated -when you change this package's NPM dependencies. Commit the files in this -directory (npm-shrinkwrap.json, .gitignore, and this README) to source control -so that others run the same versions of sub-dependencies. - -You should NOT check in the node_modules directory that Meteor automatically -creates; if you are using git, the .gitignore file tells git to ignore it. diff --git a/packages/roles/package.js b/packages/roles/package.js index 3652a5975d..d7bfdf7b83 100644 --- a/packages/roles/package.js +++ b/packages/roles/package.js @@ -27,18 +27,14 @@ Package.onUse(function (api) { }); Package.onTest(function (api) { - // Add code coverage - api.use([ - "lmieulet:meteor-legacy-coverage", - "lmieulet:meteor-coverage@4.1.0 || 5.0.0", - "meteortesting:mocha@2.1.0 || 3.2.0", - ]); - const both = ["client", "server"]; - // `accounts-password` is included so `Meteor.users` exists - - api.use(["ecmascript", "alanning:roles", "mongo"], both); + api.use([ + "tinytest", + "ecmascript", + "mongo", + "roles" + ], both); api.addFiles("tests/serverAsync.js", "server"); api.addFiles("tests/client.js", "client"); diff --git a/packages/roles/roles_server.js b/packages/roles/roles_server.js index 451d8c8db9..436c26cfc7 100644 --- a/packages/roles/roles_server.js +++ b/packages/roles/roles_server.js @@ -1,4 +1,4 @@ -import { RolesCollection, RoleAssignmentCollection } from 'packages/roles/roles_common_async' +import { RolesCollection, RoleAssignmentCollection } from './roles_common_async'; const indexFnAssignment = RoleAssignmentCollection.createIndexAsync.bind(RoleAssignmentCollection) const indexFnRoles = RolesCollection.createIndexAsync.bind(RolesCollection) diff --git a/packages/roles/tests/client.js b/packages/roles/tests/client.js index f8ef4e2e52..824e5702d9 100644 --- a/packages/roles/tests/client.js +++ b/packages/roles/tests/client.js @@ -1,138 +1,152 @@ /* eslint-env mocha */ /* global Roles */ -import { Meteor } from 'meteor/meteor' -import { assert } from 'chai' +import { Meteor } from "meteor/meteor"; +import { Tinytest } from "meteor/tinytest"; // To ensure that the files are loaded for coverage -import 'packages/roles/roles_client' +import "../roles_client"; const safeInsert = (collection, data) => { try { - collection.insert(data) + collection.insert(data); } catch (e) {} +}; + +const roles = ["admin", "editor", "user"]; +const users = { + eve: { + _id: "eve", + }, + bob: { + _id: "bob", + }, + joe: { + _id: "joe", + }, +}; + +function testUser(test, username, expectedRoles, scope) { + const user = users[username]; + + // test using user object rather than userId to avoid mocking + for (const role of roles) { + const expected = expectedRoles.includes(role); + const msg = + username + " expected to have '" + role + "' permission but does not"; + const nmsg = username + " had un-expected permission " + role; + + if (expected) { + test.isTrue(Roles.userIsInRole(user, role, scope), msg); + } else { + test.isFalse(Roles.userIsInRole(user, role, scope), nmsg); + } + } } -describe('roles', function () { - const roles = ['admin', 'editor', 'user'] - const users = { - eve: { - _id: 'eve' - }, - bob: { - _id: 'bob' - }, - joe: { - _id: 'joe' - } - } +function setupRoles() { + safeInsert(Meteor.roleAssignment, { + user: users.eve, + role: { _id: "admin" }, + inheritedRoles: [{ _id: "admin" }], + }); + safeInsert(Meteor.roleAssignment, { + user: users.eve, + role: { _id: "editor" }, + inheritedRoles: [{ _id: "editor" }], + }); - function testUser (username, expectedRoles, scope) { - const user = users[username] + safeInsert(Meteor.roleAssignment, { + user: users.bob, + role: { _id: "user" }, + inheritedRoles: [{ _id: "user" }], + scope: "group1", + }); + safeInsert(Meteor.roleAssignment, { + user: users.bob, + role: { _id: "editor" }, + inheritedRoles: [{ _id: "editor" }], + scope: "group2", + }); - // test using user object rather than userId to avoid mocking - for (const role of roles) { - const expected = expectedRoles.includes(role) - const msg = username + ' expected to have \'' + role + '\' permission but does not' - const nmsg = username + ' had un-expected permission ' + role - - if (expected) { - assert.isTrue(Roles.userIsInRole(user, role, scope), msg) - } else { - assert.isFalse(Roles.userIsInRole(user, role, scope), nmsg) - } - } - } - - let meteorUserMethod - before(() => { - meteorUserMethod = Meteor.user - // Mock Meteor.user() for isInRole handlebars helper testing - Meteor.user = function () { - return users.eve - } - }) - - after(() => { - Meteor.user = meteorUserMethod - }) - - beforeEach(() => { - safeInsert(Meteor.roleAssignment, { - user: users.eve, - role: { _id: 'admin' }, - inheritedRoles: [{ _id: 'admin' }] - }) - safeInsert(Meteor.roleAssignment, { - user: users.eve, - role: { _id: 'editor' }, - inheritedRoles: [{ _id: 'editor' }] - }) - - safeInsert(Meteor.roleAssignment, { - user: users.bob, - role: { _id: 'user' }, - inheritedRoles: [{ _id: 'user' }], - scope: 'group1' - }) - safeInsert(Meteor.roleAssignment, { - user: users.bob, - role: { _id: 'editor' }, - inheritedRoles: [{ _id: 'editor' }], - scope: 'group2' - }) - - safeInsert(Meteor.roleAssignment, { - user: users.joe, - role: { _id: 'admin' }, - inheritedRoles: [{ _id: 'admin' }] - }) - safeInsert(Meteor.roleAssignment, { - user: users.joe, - role: { _id: 'editor' }, - inheritedRoles: [{ _id: 'editor' }], - scope: 'group1' - }) - }) - - it('can check current users roles via template helper', function () { - let expected - let actual + safeInsert(Meteor.roleAssignment, { + user: users.joe, + role: { _id: "admin" }, + inheritedRoles: [{ _id: "admin" }], + }); + safeInsert(Meteor.roleAssignment, { + user: users.joe, + role: { _id: "editor" }, + inheritedRoles: [{ _id: "editor" }], + scope: "group1", + }); +} +Tinytest.add( + "roles - can check current users roles via template helper", + (test) => { if (!Roles._handlebarsHelpers) { // probably running package tests outside of a Meteor app. // skip this test. - return + return; } - const isInRole = Roles._handlebarsHelpers.isInRole - assert.equal(typeof isInRole, 'function', "'isInRole' helper not registered") + const meteorUserMethod = Meteor.user; + Meteor.user = function () { + return users.eve; + }; - expected = true - actual = isInRole('admin, editor') - assert.equal(actual, expected) + setupRoles(); - expected = true - actual = isInRole('admin') - assert.equal(actual, expected) + const isInRole = Roles._handlebarsHelpers.isInRole; + test.equal(typeof isInRole, "function", "'isInRole' helper not registered"); - expected = false - actual = isInRole('unknown') - assert.equal(actual, expected) - }) + test.equal(isInRole("admin, editor"), true); + test.equal(isInRole("admin"), true); + test.equal(isInRole("unknown"), false); - it('can check if user is in role', function () { - testUser('eve', ['admin', 'editor']) - }) + Meteor.user = meteorUserMethod; + } +); - it('can check if user is in role by group', function () { - testUser('bob', ['user'], 'group1') - testUser('bob', ['editor'], 'group2') - }) +Tinytest.add("roles - can check if user is in role", (test) => { + const meteorUserMethod = Meteor.user; + Meteor.user = function () { + return users.eve; + }; - it('can check if user is in role with Roles.GLOBAL_GROUP', function () { - testUser('joe', ['admin']) - testUser('joe', ['admin'], Roles.GLOBAL_GROUP) - testUser('joe', ['admin', 'editor'], 'group1') - }) -}) + setupRoles(); + testUser(test, "eve", ["admin", "editor"]); + + Meteor.user = meteorUserMethod; +}); + +Tinytest.add("roles - can check if user is in role by group", (test) => { + const meteorUserMethod = Meteor.user; + Meteor.user = function () { + return users.eve; + }; + + setupRoles(); + testUser(test, "bob", ["user"], "group1"); + testUser(test, "bob", ["editor"], "group2"); + + Meteor.user = meteorUserMethod; +}); + +Tinytest.add( + "roles - can check if user is in role with Roles.GLOBAL_GROUP", + (test) => { + const meteorUserMethod = Meteor.user; + Meteor.user = function () { + return users.eve; + }; + + setupRoles(); + testUser(test, "joe", ["admin"]); + testUser(test, "joe", ["admin"], Roles.GLOBAL_GROUP); + testUser(test, "joe", ["admin", "editor"], "group1"); + + Meteor.user = meteorUserMethod; + } +); diff --git a/packages/roles/tests/clientAsync.js b/packages/roles/tests/clientAsync.js index 6df81cbaf4..1de707d668 100644 --- a/packages/roles/tests/clientAsync.js +++ b/packages/roles/tests/clientAsync.js @@ -1,142 +1,159 @@ -/* eslint-env mocha */ -/* global Roles */ - -import { Meteor } from 'meteor/meteor' -import chai, { assert } from 'chai' -import chaiAsPromised from 'chai-as-promised' +import { Meteor } from "meteor/meteor"; +import { Tinytest } from "meteor/tinytest"; // To ensure that the files are loaded for coverage -import 'packages/roles/roles_client' -import 'packages/roles/roles_common_async' - -chai.use(chaiAsPromised) +import "../roles_client"; +import "../roles_common_async"; const safeInsert = async (collection, data) => { - return await collection.insertAsync(data).catch(e => console.error(e)) + return await collection.insertAsync(data).catch((e) => console.error(e)); +}; + +const roles = ["admin", "editor", "user"]; +const users = { + eve: { + _id: "eve", + }, + bob: { + _id: "bob", + }, + joe: { + _id: "joe", + }, +}; + +async function testUser(test, username, expectedRoles, scope) { + const user = users[username]; + + // test using user object rather than userId to avoid mocking + for (const role of roles) { + const expected = expectedRoles.includes(role); + const msg = + username + " expected to have '" + role + "' permission but does not"; + const nmsg = username + " had un-expected permission " + role; + + const result = await Roles.userIsInRoleAsync(user._id, role, scope); + if (expected) { + test.isTrue(result, msg); + } else { + test.isFalse(result, nmsg); + } + } } -describe('roles async', function () { - const roles = ['admin', 'editor', 'user'] - const users = { - eve: { - _id: 'eve' - }, - bob: { - _id: 'bob' - }, - joe: { - _id: 'joe' - } - } +async function setupRoles() { + await safeInsert(Meteor.roleAssignment, { + user: users.eve, + role: { _id: "admin" }, + inheritedRoles: [{ _id: "admin" }], + }); + await safeInsert(Meteor.roleAssignment, { + user: users.eve, + role: { _id: "editor" }, + inheritedRoles: [{ _id: "editor" }], + }); - async function testUser (username, expectedRoles, scope) { - const user = users[username] + await safeInsert(Meteor.roleAssignment, { + user: users.bob, + role: { _id: "user" }, + inheritedRoles: [{ _id: "user" }], + scope: "group1", + }); + await safeInsert(Meteor.roleAssignment, { + user: users.bob, + role: { _id: "editor" }, + inheritedRoles: [{ _id: "editor" }], + scope: "group2", + }); - // test using user object rather than userId to avoid mocking - for (const role of roles) { - const expected = expectedRoles.includes(role) - const msg = username + ' expected to have \'' + role + '\' permission but does not' - const nmsg = username + ' had un-expected permission ' + role - - const result = await Roles.userIsInRoleAsync(user._id, role, scope) - if (expected) { - assert.isTrue(result, msg) - } else { - assert.isFalse(result, nmsg) - } - } - } - - let meteorUserMethod - before(() => { - meteorUserMethod = Meteor.user - // Mock Meteor.user() for isInRole handlebars helper testing - Meteor.user = function () { - return users.eve - } - Meteor.subscribe('client_assignments') - }) - - after(() => { - Meteor.user = meteorUserMethod - }) - - beforeEach(async () => { - await safeInsert(Meteor.roleAssignment, { - user: users.eve, - role: { _id: 'admin' }, - inheritedRoles: [{ _id: 'admin' }] - }) - await safeInsert(Meteor.roleAssignment, { - user: users.eve, - role: { _id: 'editor' }, - inheritedRoles: [{ _id: 'editor' }] - }) - - await safeInsert(Meteor.roleAssignment, { - user: users.bob, - role: { _id: 'user' }, - inheritedRoles: [{ _id: 'user' }], - scope: 'group1' - }) - await safeInsert(Meteor.roleAssignment, { - user: users.bob, - role: { _id: 'editor' }, - inheritedRoles: [{ _id: 'editor' }], - scope: 'group2' - }) - - await safeInsert(Meteor.roleAssignment, { - user: users.joe, - role: { _id: 'admin' }, - inheritedRoles: [{ _id: 'admin' }] - }) - await safeInsert(Meteor.roleAssignment, { - user: users.joe, - role: { _id: 'editor' }, - inheritedRoles: [{ _id: 'editor' }], - scope: 'group1' - }) - }) - - it('can check current users roles via template helper', function () { - let expected - let actual + await safeInsert(Meteor.roleAssignment, { + user: users.joe, + role: { _id: "admin" }, + inheritedRoles: [{ _id: "admin" }], + }); + await safeInsert(Meteor.roleAssignment, { + user: users.joe, + role: { _id: "editor" }, + inheritedRoles: [{ _id: "editor" }], + scope: "group1", + }); +} +Tinytest.addAsync( + "roles async - can check current users roles via template helper", + async (test) => { if (!Roles._handlebarsHelpers) { // probably running package tests outside of a Meteor app. // skip this test. - return + return; } - const isInRole = Roles._handlebarsHelpers.isInRole - assert.equal(typeof isInRole, 'function', "'isInRole' helper not registered") + const meteorUserMethod = Meteor.user; + Meteor.user = function () { + return users.eve; + }; + Meteor.subscribe("client_assignments"); - expected = true - actual = isInRole('admin, editor') - assert.equal(actual, expected) + await setupRoles(); - expected = true - actual = isInRole('admin') - assert.equal(actual, expected) + const isInRole = Roles._handlebarsHelpers.isInRole; + test.equal(typeof isInRole, "function", "'isInRole' helper not registered"); - expected = false - actual = isInRole('unknown') - assert.equal(actual, expected) - }) + test.equal(isInRole("admin, editor"), true); + test.equal(isInRole("admin"), true); + test.equal(isInRole("unknown"), false); - it('can check if user is in role', async function () { - await testUser('eve', ['admin', 'editor']) - }) + Meteor.user = meteorUserMethod; + } +); - it('can check if user is in role by group', async function () { - await testUser('bob', ['user'], 'group1') - await testUser('bob', ['editor'], 'group2') - }) +Tinytest.addAsync( + "roles async - can check if user is in role", + async (test) => { + const meteorUserMethod = Meteor.user; + Meteor.user = function () { + return users.eve; + }; + Meteor.subscribe("client_assignments"); - it('can check if user is in role with Roles.GLOBAL_GROUP', async function () { - await testUser('joe', ['admin']) - await testUser('joe', ['admin'], Roles.GLOBAL_GROUP) - await testUser('joe', ['admin', 'editor'], 'group1') - }) -}) + await setupRoles(); + await testUser(test, "eve", ["admin", "editor"]); + + Meteor.user = meteorUserMethod; + } +); + +Tinytest.addAsync( + "roles async - can check if user is in role by group", + async (test) => { + const meteorUserMethod = Meteor.user; + Meteor.user = function () { + return users.eve; + }; + Meteor.subscribe("client_assignments"); + + await setupRoles(); + await testUser(test, "bob", ["user"], "group1"); + await testUser(test, "bob", ["editor"], "group2"); + + Meteor.user = meteorUserMethod; + } +); + +Tinytest.addAsync( + "roles async - can check if user is in role with Roles.GLOBAL_GROUP", + async (test) => { + const meteorUserMethod = Meteor.user; + Meteor.user = function () { + return users.eve; + }; + Meteor.subscribe("client_assignments"); + + await setupRoles(); + await testUser(test, "joe", ["admin"]); + await testUser(test, "joe", ["admin"], Roles.GLOBAL_GROUP); + await testUser(test, "joe", ["admin", "editor"], "group1"); + + Meteor.user = meteorUserMethod; + } +); diff --git a/packages/roles/tests/serverAsync.js b/packages/roles/tests/serverAsync.js index a381fc896a..1d207adeea 100644 --- a/packages/roles/tests/serverAsync.js +++ b/packages/roles/tests/serverAsync.js @@ -1,2146 +1,3028 @@ -/* eslint-env mocha */ -/* global Roles */ - -import { Meteor } from 'meteor/meteor' -import chai, { assert } from 'chai' -import chaiAsPromised from 'chai-as-promised' +import { Meteor } from "meteor/meteor"; +import { Tinytest } from "meteor/tinytest"; // To ensure that the files are loaded for coverage -import 'packages/roles/roles_common_async' - -chai.use(chaiAsPromised) +import "../roles_common_async"; // Publication for the client tests -Meteor.publish('client_assignments', async () => { - return Meteor.roleAssignment.find() -}) +Meteor.publish("client_assignments", async () => { + return Meteor.roleAssignment.find(); +}); // To allow inserting on the client, needed for testing. -if (Meteor.release.split('@')[1][0] === '2') { - Meteor.roleAssignment.allow({ - insert () { return true }, - update () { return true }, - remove () { return true } - }) -} else { - // Meteor 3+ - Meteor.roleAssignment.allow({ - insert () { return true }, - insertAsync () { return true }, - update () { return true }, - updateAsync () { return true }, - remove () { return true }, - removeAsync () { return true } - }) +Meteor.roleAssignment.allow({ + insert() { + return true; + }, + insertAsync() { + return true; + }, + update() { + return true; + }, + updateAsync() { + return true; + }, + remove() { + return true; + }, + removeAsync() { + return true; + }, +}); + +const hasAnyKeys = (test, obj, keys) => { + if (typeof keys === "string") { + keys = [keys]; + } + const hasKey = keys.some((key) => + Object.prototype.hasOwnProperty.call(obj, key) + ); + test.equal( + hasKey, + true, + `Object should have at least one of these keys: ${keys.join(", ")}` + ); +}; + +const sameMembers = (test, value, expected) => { + // Sort arrays to ensure consistent order + const sortedValue = [...value].sort(); + const sortedExpected = [...expected].sort(); + + test.equal( + JSON.stringify(sortedValue), + JSON.stringify(sortedExpected), + "Arrays should have the same members" + ); +}; + +const sameDeepMembers = (test, value, expected) => { + // Helper to sort object keys recursively + const sortObjectKeys = (obj) => { + if (Array.isArray(obj)) { + return obj.map(sortObjectKeys); + } + if (obj && typeof obj === "object") { + return Object.keys(obj) + .sort() + .reduce((sorted, key) => { + sorted[key] = sortObjectKeys(obj[key]); + return sorted; + }, {}); + } + return obj; + }; + + const sortedValue = sortObjectKeys(value); + const sortedExpected = sortObjectKeys(expected); + + test.equal( + JSON.stringify(sortedValue), + JSON.stringify(sortedExpected), + "Role assignments should match expected structure" + ); +}; + +const hasProp = (target, prop) => Object.hasOwnProperty.call(target, prop); + +let users = {}; +const roles = ["admin", "editor", "user"]; + +Meteor.publish("_roleAssignments", function () { + const loggedInUserId = this.userId; + if (!loggedInUserId) { + this.ready(); + return; + } + return Meteor.roleAssignment.find({ _id: loggedInUserId }); +}); + +async function addUser(name) { + return await Meteor.users.insertAsync({ username: name }); } -const hasProp = (target, prop) => Object.hasOwnProperty.call(target, prop) +async function testUser(test, username, expectedRoles, scope) { + const userId = users[username]; + const userObj = await Meteor.users.findOneAsync({ _id: userId }); -describe('roles async', async function () { - let users = {} - const roles = ['admin', 'editor', 'user'] + // check using user ids (makes db calls) + await _innerTest(test, userId, username, expectedRoles, scope); - Meteor.publish('_roleAssignments', function () { - const loggedInUserId = this.userId + // check using passed-in user object + await _innerTest(test, userObj, username, expectedRoles, scope); +} - if (!loggedInUserId) { - this.ready() - return - } +async function _innerTest(test, userParam, username, expectedRoles, scope) { + // test that user has only the roles expected and no others + for (const role of roles) { + const expected = expectedRoles.includes(role); + const msg = username + " expected to have '" + role + "' role but does not"; + const nmsg = username + " had the following un-expected role: " + role; - return Meteor.roleAssignment.find({ _id: loggedInUserId }) - }) - - async function addUser (name) { - return await Meteor.users.insertAsync({ username: name }) - } - - async function testUser (username, expectedRoles, scope) { - const userId = users[username] - const userObj = await Meteor.users.findOneAsync({ _id: userId }) - - // check using user ids (makes db calls) - await _innerTest(userId, username, expectedRoles, scope) - - // check using passed-in user object - await _innerTest(userObj, username, expectedRoles, scope) - } - - async function _innerTest (userParam, username, expectedRoles, scope) { - // test that user has only the roles expected and no others - for (const role of roles) { - const expected = expectedRoles.includes(role) - const msg = username + ' expected to have \'' + role + '\' role but does not' - const nmsg = username + ' had the following un-expected role: ' + role - - if (expected) { - assert.isTrue(await Roles.userIsInRoleAsync(userParam, role, scope), msg) - } else { - assert.isFalse(await Roles.userIsInRoleAsync(userParam, role, scope), nmsg) - } + const result = await Roles.userIsInRoleAsync(userParam, role, scope); + if (expected) { + test.equal(result, true, msg); + } else { + test.equal(result, false, nmsg); } } +} - beforeEach(async function () { - await Meteor.roles.removeAsync({}) - await Meteor.roleAssignment.removeAsync({}) - await Meteor.users.removeAsync({}) +async function clearData() { + await Meteor.roles.removeAsync({}); + await Meteor.roleAssignment.removeAsync({}); + await Meteor.users.removeAsync({}); - users = { - eve: await addUser('eve'), - bob: await addUser('bob'), - joe: await addUser('joe') - } - }) + users = { + eve: await addUser("eve"), + bob: await addUser("bob"), + joe: await addUser("joe"), + }; +} - it('can create and delete roles', async function () { - const role1Id = await Roles.createRoleAsync('test1') - const test1a = await Meteor.roles.findOneAsync() - const test1b = await Meteor.roles.findOneAsync(role1Id) - assert.equal(test1a._id, 'test1') - assert.equal(test1b._id, 'test1') +Tinytest.addAsync("roles -can create and delete roles", async function (test) { + await clearData(); + const role1Id = await Roles.createRoleAsync("test1"); + const test1a = await Meteor.roles.findOneAsync(); + const test1b = await Meteor.roles.findOneAsync(role1Id); + test.equal(test1a._id, "test1"); + test.equal(test1b._id, "test1"); - const role2Id = await Roles.createRoleAsync('test2') - const test2a = await Meteor.roles.findOneAsync({ _id: 'test2' }) - const test2b = await Meteor.roles.findOneAsync(role2Id) - assert.equal(test2a._id, 'test2') - assert.equal(test2b._id, 'test2') + const role2Id = await Roles.createRoleAsync("test2"); + const test2a = await Meteor.roles.findOneAsync({ _id: "test2" }); + const test2b = await Meteor.roles.findOneAsync(role2Id); + test.equal(test2a._id, "test2"); + test.equal(test2b._id, "test2"); - assert.equal(await Meteor.roles.countDocuments(), 2) + test.equal(await Meteor.roles.countDocuments(), 2); - await Roles.deleteRoleAsync('test1') - const undefinedTest = await Meteor.roles.findOneAsync({ _id: 'test1' }) - assert.equal(typeof undefinedTest, 'undefined') + await Roles.deleteRoleAsync("test1"); + const undefinedTest = await Meteor.roles.findOneAsync({ _id: "test1" }); + test.equal(typeof undefinedTest, "undefined"); - await Roles.deleteRoleAsync('test2') - const undefinedTest2 = await Meteor.roles.findOneAsync() - assert.equal(typeof undefinedTest2, 'undefined') - }) + await Roles.deleteRoleAsync("test2"); + const undefinedTest2 = await Meteor.roles.findOneAsync(); + test.equal(typeof undefinedTest2, "undefined"); +}); - it('can try to remove non-existing roles without crashing', async function () { +Tinytest.addAsync( + "roles -can try to remove non-existing roles without crashing", + async function (test) { + await clearData(); try { - await Roles.deleteRoleAsync('non-existing-role') + await Roles.deleteRoleAsync("non-existing-role"); } catch (e) { - assert.notExists(e) + test.notExists(e); } // Roles.deleteRoleAsync('non-existing-role').should.be.fulfilled - }) + } +); + +Tinytest.addAsync("roles -can't create duplicate roles", async function (test) { + await clearData(); + try { + await Roles.createRoleAsync("test1"); + } catch (e) { + test.notExists(e); + } + try { + await Roles.createRoleAsync("test1"); + } catch (e) { + test.exists(e); + } + test.isNull(await Roles.createRoleAsync("test1", { unlessExists: true })); +}); + +Tinytest.addAsync( + "roles - can't create role with empty names", + async (test) => { + await clearData(); - it('can\'t create duplicate roles', async function () { try { - await Roles.createRoleAsync('test1') + await Roles.createRoleAsync(""); + test.fail("Should throw error for empty name"); } catch (e) { - assert.notExists(e) + test.matches(e.message, /Invalid role name/); } - // assert.eventually.throws(Roles.createRoleAsync('test1')) + try { - await Roles.createRoleAsync('test1') + await Roles.createRoleAsync(null); + test.fail("Should throw error for null name"); } catch (e) { - assert.exists(e) + test.matches(e.message, /Invalid role name/); } - assert.isNull(await Roles.createRoleAsync('test1', { unlessExists: true })) - }) - it('can\'t create role with empty names', async function () { - await assert.isRejected(Roles.createRoleAsync(''), /Invalid role name/) - await assert.isRejected(Roles.createRoleAsync(null), /Invalid role name/) - await assert.isRejected(Roles.createRoleAsync(' '), /Invalid role name/) - await assert.isRejected(Roles.createRoleAsync(' foobar'), /Invalid role name/) - await assert.isRejected(Roles.createRoleAsync(' foobar '), /Invalid role name/) - }) + try { + await Roles.createRoleAsync(" "); + test.fail("Should throw error for space name"); + } catch (e) { + test.matches(e.message, /Invalid role name/); + } - it('can\'t use invalid scope names', async function () { - await Roles.createRoleAsync('admin') - await Roles.createRoleAsync('user') - await Roles.createRoleAsync('editor') - await Roles.addUsersToRolesAsync(users.eve, ['admin', 'user'], 'scope1') - await Roles.addUsersToRolesAsync(users.eve, ['editor'], 'scope2') + try { + await Roles.createRoleAsync(" foobar"); + test.fail("Should throw error for leading space"); + } catch (e) { + test.matches(e.message, /Invalid role name/); + } - await assert.isRejected(Roles.addUsersToRolesAsync(users.eve, ['admin', 'user'], ''), /Invalid scope name/) - await assert.isRejected(Roles.addUsersToRolesAsync(users.eve, ['admin', 'user'], ' '), /Invalid scope name/) - await assert.isRejected(Roles.addUsersToRolesAsync(users.eve, ['admin', 'user'], ' foobar'), /Invalid scope name/) - await assert.isRejected(Roles.addUsersToRolesAsync(users.eve, ['admin', 'user'], ' foobar '), /Invalid scope name/) - await assert.isRejected(Roles.addUsersToRolesAsync(users.eve, ['admin', 'user'], 42), /Invalid scope name/) - }) + try { + await Roles.createRoleAsync(" foobar "); + test.fail("Should throw error for trailing space"); + } catch (e) { + test.matches(e.message, /Invalid role name/); + } + } +); - it('can check if user is in role', async function () { - await Roles.createRoleAsync('admin') - await Roles.createRoleAsync('user') - await Roles.addUsersToRolesAsync(users.eve, ['admin', 'user']) +Tinytest.addAsync("roles - can't use invalid scope names", async (test) => { + await clearData(); + await Roles.createRoleAsync("admin"); + await Roles.createRoleAsync("user"); + await Roles.createRoleAsync("editor"); + await Roles.addUsersToRolesAsync(users.eve, ["admin", "user"], "scope1"); + await Roles.addUsersToRolesAsync(users.eve, ["editor"], "scope2"); - await testUser('eve', ['admin', 'user']) - }) + try { + await Roles.addUsersToRolesAsync(users.eve, ["admin", "user"], ""); + test.fail("Should throw error for empty scope"); + } catch (e) { + test.matches(e.message, /Invalid scope name/); + } - it('can check if user is in role by scope', async function () { - await Roles.createRoleAsync('admin') - await Roles.createRoleAsync('user') - await Roles.createRoleAsync('editor') - await Roles.addUsersToRolesAsync(users.eve, ['admin', 'user'], 'scope1') - await Roles.addUsersToRolesAsync(users.eve, ['editor'], 'scope2') + try { + await Roles.addUsersToRolesAsync(users.eve, ["admin", "user"], " "); + test.fail("Should throw error for space scope"); + } catch (e) { + test.matches(e.message, /Invalid scope name/); + } - testUser('eve', ['admin', 'user'], 'scope1') - testUser('eve', ['editor'], 'scope2') + try { + await Roles.addUsersToRolesAsync(users.eve, ["admin", "user"], " foobar"); + test.fail("Should throw error for leading space in scope"); + } catch (e) { + test.matches(e.message, /Invalid scope name/); + } +}); - assert.isFalse(await Roles.userIsInRoleAsync(users.eve, ['admin', 'user'], 'scope2')) - assert.isFalse(await Roles.userIsInRoleAsync(users.eve, ['editor'], 'scope1')) +Tinytest.addAsync("roles -can check if user is in role", async function (test) { + await clearData(); + await Roles.createRoleAsync("admin"); + await Roles.createRoleAsync("user"); + await Roles.addUsersToRolesAsync(users.eve, ["admin", "user"]); - assert.isTrue(await Roles.userIsInRoleAsync(users.eve, ['admin', 'user'], { anyScope: true })) - assert.isTrue(await Roles.userIsInRoleAsync(users.eve, ['editor'], { anyScope: true })) - }) + await testUser(test, "eve", ["admin", "user"]); +}); - it('can check if user is in role by scope through options', async function () { - await Roles.createRoleAsync('admin') - await Roles.createRoleAsync('user') - await Roles.createRoleAsync('editor') - await Roles.addUsersToRolesAsync(users.eve, ['admin', 'user'], { scope: 'scope1' }) - await Roles.addUsersToRolesAsync(users.eve, ['editor'], { scope: 'scope2' }) +Tinytest.addAsync( + "roles -can check if user is in role by scope", + async function (test) { + await clearData(); + await Roles.createRoleAsync("admin"); + await Roles.createRoleAsync("user"); + await Roles.createRoleAsync("editor"); + await Roles.addUsersToRolesAsync(users.eve, ["admin", "user"], "scope1"); + await Roles.addUsersToRolesAsync(users.eve, ["editor"], "scope2"); - await testUser('eve', ['admin', 'user'], { scope: 'scope1' }) - await testUser('eve', ['editor'], { scope: 'scope2' }) - }) + await testUser(test, "eve", ["admin", "user"], "scope1"); + await testUser(test, "eve", ["editor"], "scope2"); - it('can check if user is in role by scope with global role', async function () { - await Roles.createRoleAsync('admin') - await Roles.createRoleAsync('user') - await Roles.createRoleAsync('editor') - await Roles.addUsersToRolesAsync(users.eve, ['admin', 'user'], 'scope1') - await Roles.addUsersToRolesAsync(users.eve, ['editor'], 'scope2') - await Roles.addUsersToRolesAsync(users.eve, ['admin']) + test.isFalse( + await Roles.userIsInRoleAsync(users.eve, ["admin", "user"], "scope2") + ); + test.isFalse( + await Roles.userIsInRoleAsync(users.eve, ["editor"], "scope1") + ); - assert.isTrue(await Roles.userIsInRoleAsync(users.eve, ['user'], 'scope1')) - assert.isTrue(await Roles.userIsInRoleAsync(users.eve, ['editor'], 'scope2')) + test.isTrue( + await Roles.userIsInRoleAsync(users.eve, ["admin", "user"], { + anyScope: true, + }) + ); + test.isTrue( + await Roles.userIsInRoleAsync(users.eve, ["editor"], { anyScope: true }) + ); + } +); - assert.isFalse(await Roles.userIsInRoleAsync(users.eve, ['user'])) - assert.isFalse(await Roles.userIsInRoleAsync(users.eve, ['editor'])) - assert.isFalse(await Roles.userIsInRoleAsync(users.eve, ['user'], null)) - assert.isFalse(await Roles.userIsInRoleAsync(users.eve, ['editor'], null)) +Tinytest.addAsync( + "roles -can check if user is in role by scope through options", + async function (test) { + await clearData(); + await Roles.createRoleAsync("admin"); + await Roles.createRoleAsync("user"); + await Roles.createRoleAsync("editor"); + await Roles.addUsersToRolesAsync(users.eve, ["admin", "user"], { + scope: "scope1", + }); + await Roles.addUsersToRolesAsync(users.eve, ["editor"], { + scope: "scope2", + }); - assert.isFalse(await Roles.userIsInRoleAsync(users.eve, ['user'], 'scope2')) - assert.isFalse(await Roles.userIsInRoleAsync(users.eve, ['editor'], 'scope1')) + await testUser(test, "eve", ["admin", "user"], { scope: "scope1" }); + await testUser(test, "eve", ["editor"], { scope: "scope2" }); + } +); - assert.isTrue(await Roles.userIsInRoleAsync(users.eve, ['admin'], 'scope2')) - assert.isTrue(await Roles.userIsInRoleAsync(users.eve, ['admin'], 'scope1')) - assert.isTrue(await Roles.userIsInRoleAsync(users.eve, ['admin'])) - assert.isTrue(await Roles.userIsInRoleAsync(users.eve, ['admin'], null)) - }) +Tinytest.addAsync( + "roles -can check if user is in role by scope with global role", + async function (test) { + await clearData(); + await Roles.createRoleAsync("admin"); + await Roles.createRoleAsync("user"); + await Roles.createRoleAsync("editor"); + await Roles.addUsersToRolesAsync(users.eve, ["admin", "user"], "scope1"); + await Roles.addUsersToRolesAsync(users.eve, ["editor"], "scope2"); + await Roles.addUsersToRolesAsync(users.eve, ["admin"]); - it('renaming scopes', async function () { - await Roles.createRoleAsync('admin') - await Roles.createRoleAsync('user') - await Roles.createRoleAsync('editor') - await Roles.addUsersToRolesAsync(users.eve, ['admin', 'user'], 'scope1') - await Roles.addUsersToRolesAsync(users.eve, ['editor'], 'scope2') + test.isTrue(await Roles.userIsInRoleAsync(users.eve, ["user"], "scope1")); + test.isTrue(await Roles.userIsInRoleAsync(users.eve, ["editor"], "scope2")); - await testUser('eve', ['admin', 'user'], 'scope1') - await testUser('eve', ['editor'], 'scope2') + test.isFalse(await Roles.userIsInRoleAsync(users.eve, ["user"])); + test.isFalse(await Roles.userIsInRoleAsync(users.eve, ["editor"])); + test.isFalse(await Roles.userIsInRoleAsync(users.eve, ["user"], null)); + test.isFalse(await Roles.userIsInRoleAsync(users.eve, ["editor"], null)); - await Roles.renameScopeAsync('scope1', 'scope3') + test.isFalse(await Roles.userIsInRoleAsync(users.eve, ["user"], "scope2")); + test.isFalse( + await Roles.userIsInRoleAsync(users.eve, ["editor"], "scope1") + ); - await testUser('eve', ['admin', 'user'], 'scope3') - await testUser('eve', ['editor'], 'scope2') + test.isTrue(await Roles.userIsInRoleAsync(users.eve, ["admin"], "scope2")); + test.isTrue(await Roles.userIsInRoleAsync(users.eve, ["admin"], "scope1")); + test.isTrue(await Roles.userIsInRoleAsync(users.eve, ["admin"])); + test.isTrue(await Roles.userIsInRoleAsync(users.eve, ["admin"], null)); + } +); - assert.isFalse(await Roles.userIsInRoleAsync(users.eve, ['admin', 'user'], 'scope1')) - assert.isFalse(await Roles.userIsInRoleAsync(users.eve, ['admin', 'user'], 'scope2')) +Tinytest.addAsync("roles -renaming scopes", async function (test) { + await clearData(); + await Roles.createRoleAsync("admin"); + await Roles.createRoleAsync("user"); + await Roles.createRoleAsync("editor"); + await Roles.addUsersToRolesAsync(users.eve, ["admin", "user"], "scope1"); + await Roles.addUsersToRolesAsync(users.eve, ["editor"], "scope2"); - await assert.isRejected(Roles.renameScopeAsync('scope3'), /Invalid scope name/) + await testUser(test, "eve", ["admin", "user"], "scope1"); + await testUser(test, "eve", ["editor"], "scope2"); - await Roles.renameScopeAsync('scope3', null) + await Roles.renameScopeAsync("scope1", "scope3"); - await testUser('eve', ['admin', 'user', 'editor'], 'scope2') + await testUser(test, "eve", ["admin", "user"], "scope3"); + await testUser(test, "eve", ["editor"], "scope2"); - assert.isFalse(await Roles.userIsInRoleAsync(users.eve, ['editor'])) - assert.isTrue(await Roles.userIsInRoleAsync(users.eve, ['admin'])) - assert.isTrue(await Roles.userIsInRoleAsync(users.eve, ['user'])) - assert.isFalse(await Roles.userIsInRoleAsync(users.eve, ['editor'], null)) - assert.isTrue(await Roles.userIsInRoleAsync(users.eve, ['admin'], null)) - assert.isTrue(await Roles.userIsInRoleAsync(users.eve, ['user'], null)) + test.isFalse( + await Roles.userIsInRoleAsync(users.eve, ["admin", "user"], "scope1") + ); + test.isFalse( + await Roles.userIsInRoleAsync(users.eve, ["admin", "user"], "scope2") + ); - await Roles.renameScopeAsync(null, 'scope2') + try { + await Roles.renameScopeAsync("scope3"); + test.fail("Should throw error for invalid scope name"); + } catch (e) { + test.matches(e.message, /Invalid scope name/); + } - await testUser('eve', ['admin', 'user', 'editor'], 'scope2') + await Roles.renameScopeAsync("scope3", null); - assert.isFalse(await Roles.userIsInRoleAsync(users.eve, ['editor'])) - assert.isFalse(await Roles.userIsInRoleAsync(users.eve, ['admin'])) - assert.isFalse(await Roles.userIsInRoleAsync(users.eve, ['user'])) - assert.isFalse(await Roles.userIsInRoleAsync(users.eve, ['editor'], null)) - assert.isFalse(await Roles.userIsInRoleAsync(users.eve, ['admin'], null)) - assert.isFalse(await Roles.userIsInRoleAsync(users.eve, ['user'], null)) - }) + await testUser(test, "eve", ["admin", "user", "editor"], "scope2"); - it('removing scopes', async function () { - await Roles.createRoleAsync('admin') - await Roles.createRoleAsync('user') - await Roles.createRoleAsync('editor') - await Roles.addUsersToRolesAsync(users.eve, ['admin', 'user'], 'scope1') - await Roles.addUsersToRolesAsync(users.eve, ['editor'], 'scope2') + test.isFalse(await Roles.userIsInRoleAsync(users.eve, ["editor"])); + test.isTrue(await Roles.userIsInRoleAsync(users.eve, ["admin"])); + test.isTrue(await Roles.userIsInRoleAsync(users.eve, ["user"])); + test.isFalse(await Roles.userIsInRoleAsync(users.eve, ["editor"], null)); + test.isTrue(await Roles.userIsInRoleAsync(users.eve, ["admin"], null)); + test.isTrue(await Roles.userIsInRoleAsync(users.eve, ["user"], null)); - await testUser('eve', ['admin', 'user'], 'scope1') - await testUser('eve', ['editor'], 'scope2') + await Roles.renameScopeAsync(null, "scope2"); - await Roles.removeScopeAsync('scope1') + await testUser(test, "eve", ["admin", "user", "editor"], "scope2"); - await testUser('eve', ['editor'], 'scope2') + test.isFalse(await Roles.userIsInRoleAsync(users.eve, ["editor"])); + test.isFalse(await Roles.userIsInRoleAsync(users.eve, ["admin"])); + test.isFalse(await Roles.userIsInRoleAsync(users.eve, ["user"])); + test.isFalse(await Roles.userIsInRoleAsync(users.eve, ["editor"], null)); + test.isFalse(await Roles.userIsInRoleAsync(users.eve, ["admin"], null)); + test.isFalse(await Roles.userIsInRoleAsync(users.eve, ["user"], null)); +}); - assert.isFalse(await Roles.userIsInRoleAsync(users.eve, ['admin', 'user'], 'scope1')) - assert.isFalse(await Roles.userIsInRoleAsync(users.eve, ['admin', 'user'], 'scope2')) - }) +Tinytest.addAsync("roles -removing scopes", async function (test) { + await clearData(); + await Roles.createRoleAsync("admin"); + await Roles.createRoleAsync("user"); + await Roles.createRoleAsync("editor"); + await Roles.addUsersToRolesAsync(users.eve, ["admin", "user"], "scope1"); + await Roles.addUsersToRolesAsync(users.eve, ["editor"], "scope2"); - it('can check if non-existant user is in role', async function () { - assert.isFalse(await Roles.userIsInRoleAsync('1', 'admin')) - }) + await testUser(test, "eve", ["admin", "user"], "scope1"); + await testUser(test, "eve", ["editor"], "scope2"); - it('can check if null user is in role', async function () { - assert.isFalse(await Roles.userIsInRoleAsync(null, 'admin')) - }) + await Roles.removeScopeAsync("scope1"); - it('can check user against several roles at once', async function () { - await Roles.createRoleAsync('admin') - await Roles.createRoleAsync('user') + await testUser(test, "eve", ["editor"], "scope2"); - await Roles.addUsersToRolesAsync(users.eve, ['admin', 'user']) - const user = await Meteor.users.findOneAsync({ _id: users.eve }) + test.isFalse( + await Roles.userIsInRoleAsync(users.eve, ["admin", "user"], "scope1") + ); + test.isFalse( + await Roles.userIsInRoleAsync(users.eve, ["admin", "user"], "scope2") + ); +}); + +Tinytest.addAsync( + "roles -can check if non-existant user is in role", + async function (test) { + await clearData(); + test.isFalse(await Roles.userIsInRoleAsync("1", "admin")); + } +); + +Tinytest.addAsync( + "roles -can check if null user is in role", + async function (test) { + await clearData(); + test.isFalse(await Roles.userIsInRoleAsync(null, "admin")); + } +); + +Tinytest.addAsync( + "roles -can check user against several roles at once", + async function (test) { + await clearData(); + await Roles.createRoleAsync("admin"); + await Roles.createRoleAsync("user"); + + await Roles.addUsersToRolesAsync(users.eve, ["admin", "user"]); + const user = await Meteor.users.findOneAsync({ _id: users.eve }); // we can check the non-existing role - assert.isTrue(await Roles.userIsInRoleAsync(user, ['editor', 'admin'])) - }) + test.isTrue(await Roles.userIsInRoleAsync(user, ["editor", "admin"])); + } +); - it('can\'t add non-existent user to role', async function () { - await Roles.createRoleAsync('admin') +Tinytest.addAsync( + "roles -can't add non-existent user to role", + async function (test) { + await clearData(); + await Roles.createRoleAsync("admin"); - await Roles.addUsersToRolesAsync(['1'], ['admin']) - assert.equal(await Meteor.users.findOneAsync({ _id: '1' }), undefined) - }) + await Roles.addUsersToRolesAsync(["1"], ["admin"]); + test.equal(await Meteor.users.findOneAsync({ _id: "1" }), undefined); + } +); - it('can\'t add user to non-existent role', async function () { - await assert.isRejected(Roles.addUsersToRolesAsync(users.eve, ['admin']), /Role 'admin' does not exist/) - await Roles.addUsersToRolesAsync(users.eve, ['admin'], { ifExists: true }) - }) +Tinytest.addAsync( + "roles -can't add user to non-existent role", + async function (test) { + await clearData(); + try { + await Roles.addUsersToRolesAsync(users.eve, ["admin"]); + test.fail("Role shouldn't exist"); + } catch (e) { + test.matches(e.message, /Role 'admin' does not exist/); + } + await Roles.addUsersToRolesAsync(users.eve, ["admin"], { ifExists: true }); + } +); - it('can\'t set non-existent user to role', async function () { - await Roles.createRoleAsync('admin') +Tinytest.addAsync( + "roles -can't set non-existent user to role", + async function (test) { + await clearData(); + await Roles.createRoleAsync("admin"); - await Roles.setUserRolesAsync(['1'], ['admin']) - assert.equal(await Meteor.users.findOneAsync({ _id: '1' }), undefined) - }) + await Roles.setUserRolesAsync(["1"], ["admin"]); + test.equal(await Meteor.users.findOneAsync({ _id: "1" }), undefined); + } +); - it('can\'t set user to non-existent role', async function () { - await assert.isRejected(Roles.setUserRolesAsync(users.eve, ['admin']), /Role 'admin' does not exist/) - await Roles.setUserRolesAsync(users.eve, ['admin'], { ifExists: true }) - }) +Tinytest.addAsync( + "roles -can't set user to non-existent role", + async function (test) { + await clearData(); + try { + await Roles.addUsersToRolesAsync(users.eve, ["admin"]); + test.fail("Role shouldn't exist"); + } catch (e) { + test.matches(e.message, /Role 'admin' does not exist/); + } + await Roles.setUserRolesAsync(users.eve, ["admin"], { ifExists: true }); + } +); - it('can add individual users to roles', async function () { - await Roles.createRoleAsync('admin') - await Roles.createRoleAsync('user') - await Roles.createRoleAsync('editor') +Tinytest.addAsync( + "roles -can add individual users to roles", + async function (test) { + await clearData(); + await Roles.createRoleAsync("admin"); + await Roles.createRoleAsync("user"); + await Roles.createRoleAsync("editor"); - await Roles.addUsersToRolesAsync(users.eve, ['admin', 'user']) + await Roles.addUsersToRolesAsync(users.eve, ["admin", "user"]); - await testUser('eve', ['admin', 'user']) - await testUser('bob', []) - await testUser('joe', []) + await testUser(test, "eve", ["admin", "user"]); + await testUser(test, "bob", []); + await testUser(test, "joe", []); - await Roles.addUsersToRolesAsync(users.joe, ['editor', 'user']) + await Roles.addUsersToRolesAsync(users.joe, ["editor", "user"]); - await testUser('eve', ['admin', 'user']) - await testUser('bob', []) - await testUser('joe', ['editor', 'user']) - }) + await testUser(test, "eve", ["admin", "user"]); + await testUser(test, "bob", []); + await testUser(test, "joe", ["editor", "user"]); + } +); - it('can add individual users to roles by scope', async function () { - await Roles.createRoleAsync('admin') - await Roles.createRoleAsync('user') - await Roles.createRoleAsync('editor') +Tinytest.addAsync( + "roles -can add individual users to roles by scope", + async function (test) { + await clearData(); + await Roles.createRoleAsync("admin"); + await Roles.createRoleAsync("user"); + await Roles.createRoleAsync("editor"); - await Roles.addUsersToRolesAsync(users.eve, ['admin', 'user'], 'scope1') + await Roles.addUsersToRolesAsync(users.eve, ["admin", "user"], "scope1"); - await testUser('eve', ['admin', 'user'], 'scope1') - await testUser('bob', [], 'scope1') - await testUser('joe', [], 'scope1') + await testUser(test, "eve", ["admin", "user"], "scope1"); + await testUser(test, "bob", [], "scope1"); + await testUser(test, "joe", [], "scope1"); - await testUser('eve', [], 'scope2') - await testUser('bob', [], 'scope2') - await testUser('joe', [], 'scope2') + await testUser(test, "eve", [], "scope2"); + await testUser(test, "bob", [], "scope2"); + await testUser(test, "joe", [], "scope2"); - await Roles.addUsersToRolesAsync(users.joe, ['editor', 'user'], 'scope1') - await Roles.addUsersToRolesAsync(users.bob, ['editor', 'user'], 'scope2') + await Roles.addUsersToRolesAsync(users.joe, ["editor", "user"], "scope1"); + await Roles.addUsersToRolesAsync(users.bob, ["editor", "user"], "scope2"); - await testUser('eve', ['admin', 'user'], 'scope1') - await testUser('bob', [], 'scope1') - await testUser('joe', ['editor', 'user'], 'scope1') + await testUser(test, "eve", ["admin", "user"], "scope1"); + await testUser(test, "bob", [], "scope1"); + await testUser(test, "joe", ["editor", "user"], "scope1"); - await testUser('eve', [], 'scope2') - await testUser('bob', ['editor', 'user'], 'scope2') - await testUser('joe', [], 'scope2') - }) + await testUser(test, "eve", [], "scope2"); + await testUser(test, "bob", ["editor", "user"], "scope2"); + await testUser(test, "joe", [], "scope2"); + } +); - it('can add user to roles via user object', async function () { - await Roles.createRoleAsync('admin') - await Roles.createRoleAsync('user') - await Roles.createRoleAsync('editor') +Tinytest.addAsync( + "roles -can add user to roles via user object", + async function (test) { + await clearData(); + await Roles.createRoleAsync("admin"); + await Roles.createRoleAsync("user"); + await Roles.createRoleAsync("editor"); - const eve = await Meteor.users.findOneAsync({ _id: users.eve }) - const bob = await Meteor.users.findOneAsync({ _id: users.bob }) + const eve = await Meteor.users.findOneAsync({ _id: users.eve }); + const bob = await Meteor.users.findOneAsync({ _id: users.bob }); - await Roles.addUsersToRolesAsync(eve, ['admin', 'user']) + await Roles.addUsersToRolesAsync(eve, ["admin", "user"]); - await testUser('eve', ['admin', 'user']) - await testUser('bob', []) - await testUser('joe', []) + await testUser(test, "eve", ["admin", "user"]); + await testUser(test, "bob", []); + await testUser(test, "joe", []); - await Roles.addUsersToRolesAsync(bob, ['editor']) + await Roles.addUsersToRolesAsync(bob, ["editor"]); - await testUser('eve', ['admin', 'user']) - await testUser('bob', ['editor']) - await testUser('joe', []) - }) + await testUser(test, "eve", ["admin", "user"]); + await testUser(test, "bob", ["editor"]); + await testUser(test, "joe", []); + } +); - it('can add user to roles multiple times', async function () { - await Roles.createRoleAsync('admin') - await Roles.createRoleAsync('user') - await Roles.createRoleAsync('editor') +Tinytest.addAsync( + "roles -can add user to roles multiple times", + async function (test) { + await clearData(); + await Roles.createRoleAsync("admin"); + await Roles.createRoleAsync("user"); + await Roles.createRoleAsync("editor"); - await Roles.addUsersToRolesAsync(users.eve, ['admin', 'user']) - await Roles.addUsersToRolesAsync(users.eve, ['admin', 'user']) + await Roles.addUsersToRolesAsync(users.eve, ["admin", "user"]); + await Roles.addUsersToRolesAsync(users.eve, ["admin", "user"]); - await testUser('eve', ['admin', 'user']) - await testUser('bob', []) - await testUser('joe', []) + await testUser(test, "eve", ["admin", "user"]); + await testUser(test, "bob", []); + await testUser(test, "joe", []); - await Roles.addUsersToRolesAsync(users.bob, ['admin']) - await Roles.addUsersToRolesAsync(users.bob, ['editor']) + await Roles.addUsersToRolesAsync(users.bob, ["admin"]); + await Roles.addUsersToRolesAsync(users.bob, ["editor"]); - await testUser('eve', ['admin', 'user']) - await testUser('bob', ['admin', 'editor']) - await testUser('joe', []) - }) + await testUser(test, "eve", ["admin", "user"]); + await testUser(test, "bob", ["admin", "editor"]); + await testUser(test, "joe", []); + } +); - it('can add user to roles multiple times by scope', async function () { - await Roles.createRoleAsync('admin') - await Roles.createRoleAsync('user') - await Roles.createRoleAsync('editor') +Tinytest.addAsync( + "roles -can add user to roles multiple times by scope", + async function (test) { + await clearData(); + await Roles.createRoleAsync("admin"); + await Roles.createRoleAsync("user"); + await Roles.createRoleAsync("editor"); - await Roles.addUsersToRolesAsync(users.eve, ['admin', 'user'], 'scope1') - await Roles.addUsersToRolesAsync(users.eve, ['admin', 'user'], 'scope1') + await Roles.addUsersToRolesAsync(users.eve, ["admin", "user"], "scope1"); + await Roles.addUsersToRolesAsync(users.eve, ["admin", "user"], "scope1"); - await testUser('eve', ['admin', 'user'], 'scope1') - await testUser('bob', [], 'scope1') - await testUser('joe', [], 'scope1') + await testUser(test, "eve", ["admin", "user"], "scope1"); + await testUser(test, "bob", [], "scope1"); + await testUser(test, "joe", [], "scope1"); - await Roles.addUsersToRolesAsync(users.bob, ['admin'], 'scope1') - await Roles.addUsersToRolesAsync(users.bob, ['editor'], 'scope1') + await Roles.addUsersToRolesAsync(users.bob, ["admin"], "scope1"); + await Roles.addUsersToRolesAsync(users.bob, ["editor"], "scope1"); - await testUser('eve', ['admin', 'user'], 'scope1') - await testUser('bob', ['admin', 'editor'], 'scope1') - await testUser('joe', [], 'scope1') - }) + await testUser(test, "eve", ["admin", "user"], "scope1"); + await testUser(test, "bob", ["admin", "editor"], "scope1"); + await testUser(test, "joe", [], "scope1"); + } +); - it('can add multiple users to roles', async function () { - await Roles.createRoleAsync('admin') - await Roles.createRoleAsync('user') - await Roles.createRoleAsync('editor') +Tinytest.addAsync( + "roles -can add multiple users to roles", + async function (test) { + await clearData(); + await Roles.createRoleAsync("admin"); + await Roles.createRoleAsync("user"); + await Roles.createRoleAsync("editor"); - await Roles.addUsersToRolesAsync([users.eve, users.bob], ['admin', 'user']) + await Roles.addUsersToRolesAsync([users.eve, users.bob], ["admin", "user"]); - await testUser('eve', ['admin', 'user']) - await testUser('bob', ['admin', 'user']) - await testUser('joe', []) + await testUser(test, "eve", ["admin", "user"]); + await testUser(test, "bob", ["admin", "user"]); + await testUser(test, "joe", []); - await Roles.addUsersToRolesAsync([users.bob, users.joe], ['editor', 'user']) + await Roles.addUsersToRolesAsync( + [users.bob, users.joe], + ["editor", "user"] + ); - await testUser('eve', ['admin', 'user']) - await testUser('bob', ['admin', 'editor', 'user']) - await testUser('joe', ['editor', 'user']) - }) + await testUser(test, "eve", ["admin", "user"]); + await testUser(test, "bob", ["admin", "editor", "user"]); + await testUser(test, "joe", ["editor", "user"]); + } +); - it('can add multiple users to roles by scope', async function () { - await Roles.createRoleAsync('admin') - await Roles.createRoleAsync('user') - await Roles.createRoleAsync('editor') +Tinytest.addAsync( + "roles -can add multiple users to roles by scope", + async function (test) { + await clearData(); + await Roles.createRoleAsync("admin"); + await Roles.createRoleAsync("user"); + await Roles.createRoleAsync("editor"); - await Roles.addUsersToRolesAsync([users.eve, users.bob], ['admin', 'user'], 'scope1') + await Roles.addUsersToRolesAsync( + [users.eve, users.bob], + ["admin", "user"], + "scope1" + ); - await testUser('eve', ['admin', 'user'], 'scope1') - await testUser('bob', ['admin', 'user'], 'scope1') - await testUser('joe', [], 'scope1') + await testUser(test, "eve", ["admin", "user"], "scope1"); + await testUser(test, "bob", ["admin", "user"], "scope1"); + await testUser(test, "joe", [], "scope1"); - await testUser('eve', [], 'scope2') - await testUser('bob', [], 'scope2') - await testUser('joe', [], 'scope2') + await testUser(test, "eve", [], "scope2"); + await testUser(test, "bob", [], "scope2"); + await testUser(test, "joe", [], "scope2"); - await Roles.addUsersToRolesAsync([users.bob, users.joe], ['editor', 'user'], 'scope1') - await Roles.addUsersToRolesAsync([users.bob, users.joe], ['editor', 'user'], 'scope2') + await Roles.addUsersToRolesAsync( + [users.bob, users.joe], + ["editor", "user"], + "scope1" + ); + await Roles.addUsersToRolesAsync( + [users.bob, users.joe], + ["editor", "user"], + "scope2" + ); - await testUser('eve', ['admin', 'user'], 'scope1') - await testUser('bob', ['admin', 'editor', 'user'], 'scope1') - await testUser('joe', ['editor', 'user'], 'scope1') + await testUser(test, "eve", ["admin", "user"], "scope1"); + await testUser(test, "bob", ["admin", "editor", "user"], "scope1"); + await testUser(test, "joe", ["editor", "user"], "scope1"); - await testUser('eve', [], 'scope2') - await testUser('bob', ['editor', 'user'], 'scope2') - await testUser('joe', ['editor', 'user'], 'scope2') - }) + await testUser(test, "eve", [], "scope2"); + await testUser(test, "bob", ["editor", "user"], "scope2"); + await testUser(test, "joe", ["editor", "user"], "scope2"); + } +); - it('can remove individual users from roles', async function () { - await Roles.createRoleAsync('user') - await Roles.createRoleAsync('editor') +Tinytest.addAsync( + "roles -can remove individual users from roles", + async function (test) { + await clearData(); + await Roles.createRoleAsync("user"); + await Roles.createRoleAsync("editor"); // remove user role - one user - await Roles.addUsersToRolesAsync([users.eve, users.bob], ['editor', 'user']) - await testUser('eve', ['editor', 'user']) - await testUser('bob', ['editor', 'user']) - await Roles.removeUsersFromRolesAsync(users.eve, ['user']) - await testUser('eve', ['editor']) - await testUser('bob', ['editor', 'user']) - }) + await Roles.addUsersToRolesAsync( + [users.eve, users.bob], + ["editor", "user"] + ); + await testUser(test, "eve", ["editor", "user"]); + await testUser(test, "bob", ["editor", "user"]); + await Roles.removeUsersFromRolesAsync(users.eve, ["user"]); + await testUser(test, "eve", ["editor"]); + await testUser(test, "bob", ["editor", "user"]); + } +); - it('can remove user from roles multiple times', async function () { - await Roles.createRoleAsync('user') - await Roles.createRoleAsync('editor') +Tinytest.addAsync( + "roles -can remove user from roles multiple times", + async function (test) { + await clearData(); + await Roles.createRoleAsync("user"); + await Roles.createRoleAsync("editor"); // remove user role - one user - await Roles.addUsersToRolesAsync([users.eve, users.bob], ['editor', 'user']) - await testUser('eve', ['editor', 'user']) - await testUser('bob', ['editor', 'user']) - await Roles.removeUsersFromRolesAsync(users.eve, ['user']) - await testUser('eve', ['editor']) - await testUser('bob', ['editor', 'user']) + await Roles.addUsersToRolesAsync( + [users.eve, users.bob], + ["editor", "user"] + ); + await testUser(test, "eve", ["editor", "user"]); + await testUser(test, "bob", ["editor", "user"]); + await Roles.removeUsersFromRolesAsync(users.eve, ["user"]); + await testUser(test, "eve", ["editor"]); + await testUser(test, "bob", ["editor", "user"]); // try remove again - await Roles.removeUsersFromRolesAsync(users.eve, ['user']) - await testUser('eve', ['editor']) - }) + await Roles.removeUsersFromRolesAsync(users.eve, ["user"]); + await testUser(test, "eve", ["editor"]); + } +); - it('can remove users from roles via user object', async function () { - await Roles.createRoleAsync('user') - await Roles.createRoleAsync('editor') +Tinytest.addAsync( + "roles -can remove users from roles via user object", + async function (test) { + await clearData(); + await Roles.createRoleAsync("user"); + await Roles.createRoleAsync("editor"); - const eve = await Meteor.users.findOneAsync({ _id: users.eve }) - const bob = await Meteor.users.findOneAsync({ _id: users.bob }) + const eve = await Meteor.users.findOneAsync({ _id: users.eve }); + const bob = await Meteor.users.findOneAsync({ _id: users.bob }); // remove user role - one user - await Roles.addUsersToRolesAsync([eve, bob], ['editor', 'user']) - await testUser('eve', ['editor', 'user']) - await testUser('bob', ['editor', 'user']) - await Roles.removeUsersFromRolesAsync(eve, ['user']) - await testUser('eve', ['editor']) - await testUser('bob', ['editor', 'user']) - }) + await Roles.addUsersToRolesAsync([eve, bob], ["editor", "user"]); + await testUser(test, "eve", ["editor", "user"]); + await testUser(test, "bob", ["editor", "user"]); + await Roles.removeUsersFromRolesAsync(eve, ["user"]); + await testUser(test, "eve", ["editor"]); + await testUser(test, "bob", ["editor", "user"]); + } +); - it('can remove individual users from roles by scope', async function () { - await Roles.createRoleAsync('admin') - await Roles.createRoleAsync('user') - await Roles.createRoleAsync('editor') +Tinytest.addAsync( + "roles -can remove individual users from roles by scope", + async function (test) { + await clearData(); + await Roles.createRoleAsync("admin"); + await Roles.createRoleAsync("user"); + await Roles.createRoleAsync("editor"); // remove user role - one user - await Roles.addUsersToRolesAsync([users.eve, users.bob], ['editor', 'user'], 'scope1') - await Roles.addUsersToRolesAsync([users.joe, users.bob], ['admin'], 'scope2') - await testUser('eve', ['editor', 'user'], 'scope1') - await testUser('bob', ['editor', 'user'], 'scope1') - await testUser('joe', [], 'scope1') - await testUser('eve', [], 'scope2') - await testUser('bob', ['admin'], 'scope2') - await testUser('joe', ['admin'], 'scope2') + await Roles.addUsersToRolesAsync( + [users.eve, users.bob], + ["editor", "user"], + "scope1" + ); + await Roles.addUsersToRolesAsync( + [users.joe, users.bob], + ["admin"], + "scope2" + ); + await testUser(test, "eve", ["editor", "user"], "scope1"); + await testUser(test, "bob", ["editor", "user"], "scope1"); + await testUser(test, "joe", [], "scope1"); + await testUser(test, "eve", [], "scope2"); + await testUser(test, "bob", ["admin"], "scope2"); + await testUser(test, "joe", ["admin"], "scope2"); - await Roles.removeUsersFromRolesAsync(users.eve, ['user'], 'scope1') - await testUser('eve', ['editor'], 'scope1') - await testUser('bob', ['editor', 'user'], 'scope1') - await testUser('joe', [], 'scope1') - await testUser('eve', [], 'scope2') - await testUser('bob', ['admin'], 'scope2') - await testUser('joe', ['admin'], 'scope2') - }) + await Roles.removeUsersFromRolesAsync(users.eve, ["user"], "scope1"); + await testUser(test, "eve", ["editor"], "scope1"); + await testUser(test, "bob", ["editor", "user"], "scope1"); + await testUser(test, "joe", [], "scope1"); + await testUser(test, "eve", [], "scope2"); + await testUser(test, "bob", ["admin"], "scope2"); + await testUser(test, "joe", ["admin"], "scope2"); + } +); - it('can remove individual users from roles by scope through options', async function () { - await Roles.createRoleAsync('admin') - await Roles.createRoleAsync('user') - await Roles.createRoleAsync('editor') +Tinytest.addAsync( + "roles -can remove individual users from roles by scope through options", + async function (test) { + await clearData(); + await Roles.createRoleAsync("admin"); + await Roles.createRoleAsync("user"); + await Roles.createRoleAsync("editor"); // remove user role - one user - await Roles.addUsersToRolesAsync([users.eve, users.bob], ['editor', 'user'], { scope: 'scope1' }) - await Roles.addUsersToRolesAsync([users.joe, users.bob], ['admin'], { scope: 'scope2' }) - await testUser('eve', ['editor', 'user'], 'scope1') - await testUser('bob', ['editor', 'user'], 'scope1') - await testUser('joe', [], 'scope1') - await testUser('eve', [], 'scope2') - await testUser('bob', ['admin'], 'scope2') - await testUser('joe', ['admin'], 'scope2') + await Roles.addUsersToRolesAsync( + [users.eve, users.bob], + ["editor", "user"], + { scope: "scope1" } + ); + await Roles.addUsersToRolesAsync([users.joe, users.bob], ["admin"], { + scope: "scope2", + }); + await testUser(test, "eve", ["editor", "user"], "scope1"); + await testUser(test, "bob", ["editor", "user"], "scope1"); + await testUser(test, "joe", [], "scope1"); + await testUser(test, "eve", [], "scope2"); + await testUser(test, "bob", ["admin"], "scope2"); + await testUser(test, "joe", ["admin"], "scope2"); - await Roles.removeUsersFromRolesAsync(users.eve, ['user'], { scope: 'scope1' }) - await testUser('eve', ['editor'], 'scope1') - await testUser('bob', ['editor', 'user'], 'scope1') - await testUser('joe', [], 'scope1') - await testUser('eve', [], 'scope2') - await testUser('bob', ['admin'], 'scope2') - await testUser('joe', ['admin'], 'scope2') - }) + await Roles.removeUsersFromRolesAsync(users.eve, ["user"], { + scope: "scope1", + }); + await testUser(test, "eve", ["editor"], "scope1"); + await testUser(test, "bob", ["editor", "user"], "scope1"); + await testUser(test, "joe", [], "scope1"); + await testUser(test, "eve", [], "scope2"); + await testUser(test, "bob", ["admin"], "scope2"); + await testUser(test, "joe", ["admin"], "scope2"); + } +); - it('can remove multiple users from roles', async function () { - await Roles.createRoleAsync('admin') - await Roles.createRoleAsync('user') - await Roles.createRoleAsync('editor') +Tinytest.addAsync( + "roles -can remove multiple users from roles", + async function (test) { + await clearData(); + await Roles.createRoleAsync("admin"); + await Roles.createRoleAsync("user"); + await Roles.createRoleAsync("editor"); // remove user role - two users - await Roles.addUsersToRolesAsync([users.eve, users.bob], ['editor', 'user']) - await testUser('eve', ['editor', 'user']) - await testUser('bob', ['editor', 'user']) + await Roles.addUsersToRolesAsync( + [users.eve, users.bob], + ["editor", "user"] + ); + await testUser(test, "eve", ["editor", "user"]); + await testUser(test, "bob", ["editor", "user"]); - assert.isFalse(await Roles.userIsInRoleAsync(users.joe, 'admin')) - await Roles.addUsersToRolesAsync([users.bob, users.joe], ['admin', 'user']) - await testUser('bob', ['admin', 'user', 'editor']) - await testUser('joe', ['admin', 'user']) - await Roles.removeUsersFromRolesAsync([users.bob, users.joe], ['admin']) - await testUser('bob', ['user', 'editor']) - await testUser('joe', ['user']) - }) + test.isFalse(await Roles.userIsInRoleAsync(users.joe, "admin")); + await Roles.addUsersToRolesAsync([users.bob, users.joe], ["admin", "user"]); + await testUser(test, "bob", ["admin", "user", "editor"]); + await testUser(test, "joe", ["admin", "user"]); + await Roles.removeUsersFromRolesAsync([users.bob, users.joe], ["admin"]); + await testUser(test, "bob", ["user", "editor"]); + await testUser(test, "joe", ["user"]); + } +); - it('can remove multiple users from roles by scope', async function () { - await Roles.createRoleAsync('admin') - await Roles.createRoleAsync('user') - await Roles.createRoleAsync('editor') +Tinytest.addAsync( + "roles -can remove multiple users from roles by scope", + async function (test) { + await clearData(); + await Roles.createRoleAsync("admin"); + await Roles.createRoleAsync("user"); + await Roles.createRoleAsync("editor"); // remove user role - one user - await Roles.addUsersToRolesAsync([users.eve, users.bob], ['editor', 'user'], 'scope1') - await Roles.addUsersToRolesAsync([users.joe, users.bob], ['admin'], 'scope2') - await testUser('eve', ['editor', 'user'], 'scope1') - await testUser('bob', ['editor', 'user'], 'scope1') - await testUser('joe', [], 'scope1') - await testUser('eve', [], 'scope2') - await testUser('bob', ['admin'], 'scope2') - await testUser('joe', ['admin'], 'scope2') + await Roles.addUsersToRolesAsync( + [users.eve, users.bob], + ["editor", "user"], + "scope1" + ); + await Roles.addUsersToRolesAsync( + [users.joe, users.bob], + ["admin"], + "scope2" + ); + await testUser(test, "eve", ["editor", "user"], "scope1"); + await testUser(test, "bob", ["editor", "user"], "scope1"); + await testUser(test, "joe", [], "scope1"); + await testUser(test, "eve", [], "scope2"); + await testUser(test, "bob", ["admin"], "scope2"); + await testUser(test, "joe", ["admin"], "scope2"); - await Roles.removeUsersFromRolesAsync([users.eve, users.bob], ['user'], 'scope1') - await testUser('eve', ['editor'], 'scope1') - await testUser('bob', ['editor'], 'scope1') - await testUser('joe', [], 'scope1') - await testUser('eve', [], 'scope2') - await testUser('bob', ['admin'], 'scope2') - await testUser('joe', ['admin'], 'scope2') + await Roles.removeUsersFromRolesAsync( + [users.eve, users.bob], + ["user"], + "scope1" + ); + await testUser(test, "eve", ["editor"], "scope1"); + await testUser(test, "bob", ["editor"], "scope1"); + await testUser(test, "joe", [], "scope1"); + await testUser(test, "eve", [], "scope2"); + await testUser(test, "bob", ["admin"], "scope2"); + await testUser(test, "joe", ["admin"], "scope2"); - await Roles.removeUsersFromRolesAsync([users.joe, users.bob], ['admin'], 'scope2') - await testUser('eve', [], 'scope2') - await testUser('bob', [], 'scope2') - await testUser('joe', [], 'scope2') - }) + await Roles.removeUsersFromRolesAsync( + [users.joe, users.bob], + ["admin"], + "scope2" + ); + await testUser(test, "eve", [], "scope2"); + await testUser(test, "bob", [], "scope2"); + await testUser(test, "joe", [], "scope2"); + } +); - it('can remove multiple users from roles of any scope', async function () { - await Roles.createRoleAsync('admin') - await Roles.createRoleAsync('user') - await Roles.createRoleAsync('editor') +Tinytest.addAsync( + "roles -can remove multiple users from roles of any scope", + async function (test) { + await clearData(); + await Roles.createRoleAsync("admin"); + await Roles.createRoleAsync("user"); + await Roles.createRoleAsync("editor"); // remove user role - one user - await Roles.addUsersToRolesAsync([users.eve, users.bob], ['editor', 'user'], 'scope1') - await Roles.addUsersToRolesAsync([users.joe, users.bob], ['user'], 'scope2') - await testUser('eve', ['editor', 'user'], 'scope1') - await testUser('bob', ['editor', 'user'], 'scope1') - await testUser('joe', [], 'scope1') - await testUser('eve', [], 'scope2') - await testUser('bob', ['user'], 'scope2') - await testUser('joe', ['user'], 'scope2') + await Roles.addUsersToRolesAsync( + [users.eve, users.bob], + ["editor", "user"], + "scope1" + ); + await Roles.addUsersToRolesAsync( + [users.joe, users.bob], + ["user"], + "scope2" + ); + await testUser(test, "eve", ["editor", "user"], "scope1"); + await testUser(test, "bob", ["editor", "user"], "scope1"); + await testUser(test, "joe", [], "scope1"); + await testUser(test, "eve", [], "scope2"); + await testUser(test, "bob", ["user"], "scope2"); + await testUser(test, "joe", ["user"], "scope2"); - await Roles.removeUsersFromRolesAsync([users.eve, users.bob], ['user'], { anyScope: true }) - await testUser('eve', ['editor'], 'scope1') - await testUser('bob', ['editor'], 'scope1') - await testUser('joe', [], 'scope1') - await testUser('eve', [], 'scope2') - await testUser('bob', [], 'scope2') - await testUser('joe', ['user'], 'scope2') - }) + await Roles.removeUsersFromRolesAsync([users.eve, users.bob], ["user"], { + anyScope: true, + }); + await testUser(test, "eve", ["editor"], "scope1"); + await testUser(test, "bob", ["editor"], "scope1"); + await testUser(test, "joe", [], "scope1"); + await testUser(test, "eve", [], "scope2"); + await testUser(test, "bob", [], "scope2"); + await testUser(test, "joe", ["user"], "scope2"); + } +); - it('can set user roles', async function () { - await Roles.createRoleAsync('admin') - await Roles.createRoleAsync('user') - await Roles.createRoleAsync('editor') +Tinytest.addAsync("roles -can set user roles", async function (test) { + await clearData(); + await Roles.createRoleAsync("admin"); + await Roles.createRoleAsync("user"); + await Roles.createRoleAsync("editor"); - const eve = await Meteor.users.findOneAsync({ _id: users.eve }) - const bob = await Meteor.users.findOneAsync({ _id: users.bob }) + const eve = await Meteor.users.findOneAsync({ _id: users.eve }); + const bob = await Meteor.users.findOneAsync({ _id: users.bob }); - await Roles.setUserRolesAsync([users.eve, bob], ['editor', 'user']) - await testUser('eve', ['editor', 'user']) - await testUser('bob', ['editor', 'user']) - await testUser('joe', []) + await Roles.setUserRolesAsync([users.eve, bob], ["editor", "user"]); + await testUser(test, "eve", ["editor", "user"]); + await testUser(test, "bob", ["editor", "user"]); + await testUser(test, "joe", []); - // use addUsersToRoles add some roles - await Roles.addUsersToRolesAsync([bob, users.joe], ['admin']) - await testUser('eve', ['editor', 'user']) - await testUser('bob', ['admin', 'editor', 'user']) - await testUser('joe', ['admin']) + // use addUsersToRoles add some roles + await Roles.addUsersToRolesAsync([bob, users.joe], ["admin"]); + await testUser(test, "eve", ["editor", "user"]); + await testUser(test, "bob", ["admin", "editor", "user"]); + await testUser(test, "joe", ["admin"]); - await Roles.setUserRolesAsync([eve, bob], ['user']) - await testUser('eve', ['user']) - await testUser('bob', ['user']) - await testUser('joe', ['admin']) + await Roles.setUserRolesAsync([eve, bob], ["user"]); + await testUser(test, "eve", ["user"]); + await testUser(test, "bob", ["user"]); + await testUser(test, "joe", ["admin"]); - await Roles.setUserRolesAsync(bob, 'editor') - await testUser('eve', ['user']) - await testUser('bob', ['editor']) - await testUser('joe', ['admin']) + await Roles.setUserRolesAsync(bob, "editor"); + await testUser(test, "eve", ["user"]); + await testUser(test, "bob", ["editor"]); + await testUser(test, "joe", ["admin"]); - await Roles.setUserRolesAsync([users.joe, users.bob], []) - await testUser('eve', ['user']) - await testUser('bob', []) - await testUser('joe', []) - }) + await Roles.setUserRolesAsync([users.joe, users.bob], []); + await testUser(test, "eve", ["user"]); + await testUser(test, "bob", []); + await testUser(test, "joe", []); +}); - it('can set user roles by scope', async function () { - await Roles.createRoleAsync('admin') - await Roles.createRoleAsync('user') - await Roles.createRoleAsync('editor') +Tinytest.addAsync("roles -can set user roles by scope", async function (test) { + await clearData(); + await Roles.createRoleAsync("admin"); + await Roles.createRoleAsync("user"); + await Roles.createRoleAsync("editor"); - const eve = await Meteor.users.findOneAsync({ _id: users.eve }) - const bob = await Meteor.users.findOneAsync({ _id: users.bob }) - const joe = await Meteor.users.findOneAsync({ _id: users.joe }) + const eve = await Meteor.users.findOneAsync({ _id: users.eve }); + const bob = await Meteor.users.findOneAsync({ _id: users.bob }); + const joe = await Meteor.users.findOneAsync({ _id: users.joe }); - await Roles.setUserRolesAsync([users.eve, users.bob], ['editor', 'user'], 'scope1') - await Roles.setUserRolesAsync([users.bob, users.joe], ['admin'], 'scope2') - await testUser('eve', ['editor', 'user'], 'scope1') - await testUser('bob', ['editor', 'user'], 'scope1') - await testUser('joe', [], 'scope1') - await testUser('eve', [], 'scope2') - await testUser('bob', ['admin'], 'scope2') - await testUser('joe', ['admin'], 'scope2') + await Roles.setUserRolesAsync( + [users.eve, users.bob], + ["editor", "user"], + "scope1" + ); + await Roles.setUserRolesAsync([users.bob, users.joe], ["admin"], "scope2"); + await testUser(test, "eve", ["editor", "user"], "scope1"); + await testUser(test, "bob", ["editor", "user"], "scope1"); + await testUser(test, "joe", [], "scope1"); + await testUser(test, "eve", [], "scope2"); + await testUser(test, "bob", ["admin"], "scope2"); + await testUser(test, "joe", ["admin"], "scope2"); - // use addUsersToRoles add some roles - await Roles.addUsersToRolesAsync([users.eve, users.bob], ['admin'], 'scope1') - await Roles.addUsersToRolesAsync([users.bob, users.joe], ['editor'], 'scope2') - await testUser('eve', ['admin', 'editor', 'user'], 'scope1') - await testUser('bob', ['admin', 'editor', 'user'], 'scope1') - await testUser('joe', [], 'scope1') - await testUser('eve', [], 'scope2') - await testUser('bob', ['admin', 'editor'], 'scope2') - await testUser('joe', ['admin', 'editor'], 'scope2') + // use addUsersToRoles add some roles + await Roles.addUsersToRolesAsync([users.eve, users.bob], ["admin"], "scope1"); + await Roles.addUsersToRolesAsync( + [users.bob, users.joe], + ["editor"], + "scope2" + ); + await testUser(test, "eve", ["admin", "editor", "user"], "scope1"); + await testUser(test, "bob", ["admin", "editor", "user"], "scope1"); + await testUser(test, "joe", [], "scope1"); + await testUser(test, "eve", [], "scope2"); + await testUser(test, "bob", ["admin", "editor"], "scope2"); + await testUser(test, "joe", ["admin", "editor"], "scope2"); - await Roles.setUserRolesAsync([eve, bob], ['user'], 'scope1') - await Roles.setUserRolesAsync([eve, joe], ['editor'], 'scope2') - await testUser('eve', ['user'], 'scope1') - await testUser('bob', ['user'], 'scope1') - await testUser('joe', [], 'scope1') - await testUser('eve', ['editor'], 'scope2') - await testUser('bob', ['admin', 'editor'], 'scope2') - await testUser('joe', ['editor'], 'scope2') + await Roles.setUserRolesAsync([eve, bob], ["user"], "scope1"); + await Roles.setUserRolesAsync([eve, joe], ["editor"], "scope2"); + await testUser(test, "eve", ["user"], "scope1"); + await testUser(test, "bob", ["user"], "scope1"); + await testUser(test, "joe", [], "scope1"); + await testUser(test, "eve", ["editor"], "scope2"); + await testUser(test, "bob", ["admin", "editor"], "scope2"); + await testUser(test, "joe", ["editor"], "scope2"); - await Roles.setUserRolesAsync(bob, 'editor', 'scope1') - await testUser('eve', ['user'], 'scope1') - await testUser('bob', ['editor'], 'scope1') - await testUser('joe', [], 'scope1') - await testUser('eve', ['editor'], 'scope2') - await testUser('bob', ['admin', 'editor'], 'scope2') - await testUser('joe', ['editor'], 'scope2') + await Roles.setUserRolesAsync(bob, "editor", "scope1"); + await testUser(test, "eve", ["user"], "scope1"); + await testUser(test, "bob", ["editor"], "scope1"); + await testUser(test, "joe", [], "scope1"); + await testUser(test, "eve", ["editor"], "scope2"); + await testUser(test, "bob", ["admin", "editor"], "scope2"); + await testUser(test, "joe", ["editor"], "scope2"); - const bobRoles1 = await Roles.getRolesForUserAsync(users.bob, { anyScope: true, fullObjects: true }) - const joeRoles1 = await Roles.getRolesForUserAsync(users.joe, { anyScope: true, fullObjects: true }) - assert.isTrue(bobRoles1.map(r => r.scope).includes('scope1')) - assert.isFalse(joeRoles1.map(r => r.scope).includes('scope1')) + const bobRoles1 = await Roles.getRolesForUserAsync(users.bob, { + anyScope: true, + fullObjects: true, + }); + const joeRoles1 = await Roles.getRolesForUserAsync(users.joe, { + anyScope: true, + fullObjects: true, + }); + test.isTrue(bobRoles1.map((r) => r.scope).includes("scope1")); + test.isFalse(joeRoles1.map((r) => r.scope).includes("scope1")); - await Roles.setUserRolesAsync([bob, users.joe], [], 'scope1') - await testUser('eve', ['user'], 'scope1') - await testUser('bob', [], 'scope1') - await testUser('joe', [], 'scope1') - await testUser('eve', ['editor'], 'scope2') - await testUser('bob', ['admin', 'editor'], 'scope2') - await testUser('joe', ['editor'], 'scope2') + await Roles.setUserRolesAsync([bob, users.joe], [], "scope1"); + await testUser(test, "eve", ["user"], "scope1"); + await testUser(test, "bob", [], "scope1"); + await testUser(test, "joe", [], "scope1"); + await testUser(test, "eve", ["editor"], "scope2"); + await testUser(test, "bob", ["admin", "editor"], "scope2"); + await testUser(test, "joe", ["editor"], "scope2"); - // When roles in a given scope are removed, we do not want any dangling database content for that scope. - const bobRoles2 = await Roles.getRolesForUserAsync(users.bob, { anyScope: true, fullObjects: true }) - const joeRoles2 = await Roles.getRolesForUserAsync(users.joe, { anyScope: true, fullObjects: true }) - assert.isFalse(bobRoles2.map(r => r.scope).includes('scope1')) - assert.isFalse(joeRoles2.map(r => r.scope).includes('scope1')) - }) + // When roles in a given scope are removed, we do not want any dangling database content for that scope. + const bobRoles2 = await Roles.getRolesForUserAsync(users.bob, { + anyScope: true, + fullObjects: true, + }); + const joeRoles2 = await Roles.getRolesForUserAsync(users.joe, { + anyScope: true, + fullObjects: true, + }); + test.isFalse(bobRoles2.map((r) => r.scope).includes("scope1")); + test.isFalse(joeRoles2.map((r) => r.scope).includes("scope1")); +}); - it('can set user roles by scope including GLOBAL_SCOPE', async function () { - await Roles.createRoleAsync('admin') - await Roles.createRoleAsync('editor') +Tinytest.addAsync( + "roles -can set user roles by scope including GLOBAL_SCOPE", + async function (test) { + await clearData(); + await Roles.createRoleAsync("admin"); + await Roles.createRoleAsync("editor"); - const eve = await Meteor.users.findOneAsync({ _id: users.eve }) + const eve = await Meteor.users.findOneAsync({ _id: users.eve }); - await Roles.addUsersToRolesAsync(eve, 'admin', Roles.GLOBAL_SCOPE) - await testUser('eve', ['admin'], 'scope1') - await testUser('eve', ['admin']) + await Roles.addUsersToRolesAsync(eve, "admin", Roles.GLOBAL_SCOPE); + await testUser(test, "eve", ["admin"], "scope1"); + await testUser(test, "eve", ["admin"]); - await Roles.setUserRolesAsync(eve, 'editor', Roles.GLOBAL_SCOPE) - await testUser('eve', ['editor'], 'scope2') - await testUser('eve', ['editor']) - }) + await Roles.setUserRolesAsync(eve, "editor", Roles.GLOBAL_SCOPE); + await testUser(test, "eve", ["editor"], "scope2"); + await testUser(test, "eve", ["editor"]); + } +); - it('can set user roles by scope and anyScope', async function () { - await Roles.createRoleAsync('admin') - await Roles.createRoleAsync('editor') +Tinytest.addAsync( + "roles -can set user roles by scope and anyScope", + async function (test) { + await clearData(); + await Roles.createRoleAsync("admin"); + await Roles.createRoleAsync("editor"); - const eve = await Meteor.users.findOneAsync({ _id: users.eve }) + const eve = await Meteor.users.findOneAsync({ _id: users.eve }); - const eveRoles = await Roles.getRolesForUserAsync(users.eve, { anyScope: true, fullObjects: true }) - assert.sameDeepMembers(eveRoles.map(obj => { delete obj._id; return obj }), []) + const eveRoles = await Roles.getRolesForUserAsync(users.eve, { + anyScope: true, + fullObjects: true, + }); + sameDeepMembers( + test, + eveRoles.map((obj) => { + delete obj._id; + return obj; + }), + [] + ); - await Roles.addUsersToRolesAsync(eve, 'admin') + await Roles.addUsersToRolesAsync(eve, "admin"); - const eveRoles2 = await Roles.getRolesForUserAsync(users.eve, { anyScope: true, fullObjects: true }) - assert.sameDeepMembers(eveRoles2.map(obj => { delete obj._id; return obj }), [{ - role: { _id: 'admin' }, - scope: null, - user: { _id: users.eve }, - inheritedRoles: [{ _id: 'admin' }] - }]) + const eveRoles2 = await Roles.getRolesForUserAsync(users.eve, { + anyScope: true, + fullObjects: true, + }); + sameDeepMembers( + test, + eveRoles2.map((obj) => { + delete obj._id; + return obj; + }), + [ + { + role: { _id: "admin" }, + scope: null, + user: { _id: users.eve }, + inheritedRoles: [{ _id: "admin" }], + }, + ] + ); - await Roles.setUserRolesAsync(eve, 'editor', { anyScope: true, scope: 'scope2' }) + await Roles.setUserRolesAsync(eve, "editor", { + anyScope: true, + scope: "scope2", + }); - const eveRoles3 = await Roles.getRolesForUserAsync(users.eve, { anyScope: true, fullObjects: true }) - assert.sameDeepMembers(eveRoles3.map(obj => { delete obj._id; return obj }), [{ - role: { _id: 'editor' }, - scope: 'scope2', - user: { _id: users.eve }, - inheritedRoles: [{ _id: 'editor' }] - }]) - }) + const eveRoles3 = await Roles.getRolesForUserAsync(users.eve, { + anyScope: true, + fullObjects: true, + }); + sameDeepMembers( + test, + eveRoles3.map((obj) => { + delete obj._id; + return obj; + }), + [ + { + role: { _id: "editor" }, + scope: "scope2", + user: { _id: users.eve }, + inheritedRoles: [{ _id: "editor" }], + }, + ] + ); + } +); - it('can get all roles', async function () { - for (const role of roles) { - await Roles.createRoleAsync(role) - } +Tinytest.addAsync("roles -can get all roles", async function (test) { + await clearData(); + for (const role of roles) { + await Roles.createRoleAsync(role); + } - // compare roles, sorted alphabetically - const expected = roles - const fetchAll = await Roles.getAllRoles().fetchAsync() - const actual = fetchAll.map(r => r._id) + // compare roles, sorted alphabetically + const expected = roles; + const fetchAll = await Roles.getAllRoles().fetchAsync(); + const actual = fetchAll.map((r) => r._id); - assert.sameMembers(actual, expected) + sameMembers(test, actual, expected); - const fetchSorted = await Roles.getAllRoles({ sort: { _id: -1 } }).fetchAsync() - assert.sameMembers(fetchSorted.map(r => r._id), expected.reverse()) - }) + const fetchSorted = await Roles.getAllRoles({ + sort: { _id: -1 }, + }).fetchAsync(); + sameMembers( + test, + fetchSorted.map((r) => r._id), + expected.reverse() + ); +}); - it('get an empty list of roles for an empty user', async function () { - assert.sameMembers(await Roles.getRolesForUserAsync(undefined), []) - assert.sameMembers(await Roles.getRolesForUserAsync(null), []) - assert.sameMembers(await Roles.getRolesForUserAsync({}), []) - }) +Tinytest.addAsync( + "roles -get an empty list of roles for an empty user", + async function (test) { + await clearData(); + sameMembers(test, await Roles.getRolesForUserAsync(undefined), []); + sameMembers(test, await Roles.getRolesForUserAsync(null), []); + sameMembers(test, await Roles.getRolesForUserAsync({}), []); + } +); - it('get an empty list of roles for non-existant user', async function () { - assert.sameMembers(await Roles.getRolesForUserAsync('1'), []) - assert.sameMembers(await Roles.getRolesForUserAsync('1', 'scope1'), []) - }) +Tinytest.addAsync( + "roles -get an empty list of roles for non-existant user", + async function (test) { + await clearData(); + sameMembers(test, await Roles.getRolesForUserAsync("1"), []); + sameMembers(test, await Roles.getRolesForUserAsync("1", "scope1"), []); + } +); - it('can get all roles for user', async function () { - await Roles.createRoleAsync('admin') - await Roles.createRoleAsync('user') +Tinytest.addAsync("roles -can get all roles for user", async function (test) { + await clearData(); + await Roles.createRoleAsync("admin"); + await Roles.createRoleAsync("user"); - const userId = users.eve - let userObj + const userId = users.eve; + let userObj; + + // by userId + sameMembers(test, await Roles.getRolesForUserAsync(userId), []); + + // by user object + userObj = await Meteor.users.findOneAsync({ _id: userId }); + sameMembers(test, await Roles.getRolesForUserAsync(userObj), []); + + await Roles.addUsersToRolesAsync(userId, ["admin", "user"]); + + // by userId + sameMembers(test, await Roles.getRolesForUserAsync(userId), [ + "admin", + "user", + ]); + + // by user object + userObj = await Meteor.users.findOneAsync({ _id: userId }); + sameMembers(test, await Roles.getRolesForUserAsync(userObj), [ + "admin", + "user", + ]); + + const userRoles = await Roles.getRolesForUserAsync(userId, { + fullObjects: true, + }); + sameDeepMembers( + test, + userRoles.map((obj) => { + delete obj._id; + return obj; + }), + [ + { + role: { _id: "admin" }, + scope: null, + user: { _id: userId }, + inheritedRoles: [{ _id: "admin" }], + }, + { + role: { _id: "user" }, + scope: null, + user: { _id: userId }, + inheritedRoles: [{ _id: "user" }], + }, + ] + ); +}); + +Tinytest.addAsync( + "roles -can get all roles for user by scope", + async function (test) { + await clearData(); + await Roles.createRoleAsync("admin"); + await Roles.createRoleAsync("user"); + await Roles.createRoleAsync("editor"); + + const userId = users.eve; + + await Roles.addUsersToRolesAsync([users.eve], ["editor"], "scope1"); + await Roles.addUsersToRolesAsync([users.eve], ["editor", "user"], "scope2"); // by userId - assert.sameMembers(await Roles.getRolesForUserAsync(userId), []) + sameMembers(test, await Roles.getScopesForUserAsync(userId, "user"), [ + "scope2", + ]); + sameMembers(test, await Roles.getScopesForUserAsync(userId, "editor"), [ + "scope1", + "scope2", + ]); + sameMembers(test, await Roles.getScopesForUserAsync(userId, "admin"), []); // by user object - userObj = await Meteor.users.findOneAsync({ _id: userId }) - assert.sameMembers(await Roles.getRolesForUserAsync(userObj), []) + const userObj = await Meteor.users.findOneAsync({ _id: userId }); + sameMembers(test, await Roles.getScopesForUserAsync(userObj, "user"), [ + "scope2", + ]); + sameMembers(test, await Roles.getScopesForUserAsync(userObj, "editor"), [ + "scope1", + "scope2", + ]); + sameMembers(test, await Roles.getScopesForUserAsync(userObj, "admin"), []); + } +); - await Roles.addUsersToRolesAsync(userId, ['admin', 'user']) +Tinytest.addAsync( + "roles -getScopesForUser returns [] when not using scopes", + async function (test) { + await clearData(); + await Roles.createRoleAsync("user"); + await Roles.createRoleAsync("editor"); + + const userId = users.eve; + + await Roles.addUsersToRolesAsync([users.eve], ["editor", "user"]); // by userId - assert.sameMembers(await Roles.getRolesForUserAsync(userId), ['admin', 'user']) + sameMembers(test, await Roles.getScopesForUserAsync(userId), []); + sameMembers(test, await Roles.getScopesForUserAsync(userId, "editor"), []); + sameMembers( + test, + await Roles.getScopesForUserAsync(userId, ["editor"]), + [] + ); + sameMembers( + test, + await Roles.getScopesForUserAsync(userId, ["editor", "user"]), + [] + ); // by user object - userObj = await Meteor.users.findOneAsync({ _id: userId }) - assert.sameMembers(await Roles.getRolesForUserAsync(userObj), ['admin', 'user']) + const userObj = await Meteor.users.findOneAsync({ _id: userId }); + sameMembers(test, await Roles.getScopesForUserAsync(userObj), []); + sameMembers(test, await Roles.getScopesForUserAsync(userObj, "editor"), []); + sameMembers( + test, + await Roles.getScopesForUserAsync(userObj, ["editor"]), + [] + ); + sameMembers( + test, + await Roles.getScopesForUserAsync(userObj, ["editor", "user"]), + [] + ); + } +); - const userRoles = await Roles.getRolesForUserAsync(userId, { fullObjects: true }) - assert.sameDeepMembers(userRoles.map(obj => { delete obj._id; return obj }), [{ - role: { _id: 'admin' }, - scope: null, - user: { _id: userId }, - inheritedRoles: [{ _id: 'admin' }] - }, { - role: { _id: 'user' }, - scope: null, - user: { _id: userId }, - inheritedRoles: [{ _id: 'user' }] - }]) - }) +Tinytest.addAsync( + "roles -can get all groups for user by role array", + async function (test) { + await clearData(); + const userId = users.eve; - it('can get all roles for user by scope', async function () { - await Roles.createRoleAsync('admin') - await Roles.createRoleAsync('user') + await Roles.createRoleAsync("user"); + await Roles.createRoleAsync("editor"); + await Roles.createRoleAsync("moderator"); + await Roles.createRoleAsync("admin"); - const userId = users.eve - let userObj - - // by userId - assert.sameMembers(await Roles.getRolesForUserAsync(userId, 'scope1'), []) - - // by user object - userObj = await Meteor.users.findOneAsync({ _id: userId }) - assert.sameMembers(await Roles.getRolesForUserAsync(userObj, 'scope1'), []) - - // add roles - await Roles.addUsersToRolesAsync(userId, ['admin', 'user'], 'scope1') - await Roles.addUsersToRolesAsync(userId, ['admin'], 'scope2') - - // by userId - assert.sameMembers(await Roles.getRolesForUserAsync(userId, 'scope1'), ['admin', 'user']) - assert.sameMembers(await Roles.getRolesForUserAsync(userId, 'scope2'), ['admin']) - assert.sameMembers(await Roles.getRolesForUserAsync(userId), []) - - // by user object - userObj = await Meteor.users.findOneAsync({ _id: userId }) - assert.sameMembers(await Roles.getRolesForUserAsync(userObj, 'scope1'), ['admin', 'user']) - assert.sameMembers(await Roles.getRolesForUserAsync(userObj, 'scope2'), ['admin']) - assert.sameMembers(await Roles.getRolesForUserAsync(userObj), []) - - const userRoles = await Roles.getRolesForUserAsync(userId, { fullObjects: true, scope: 'scope1' }) - assert.sameDeepMembers(userRoles.map(obj => { delete obj._id; return obj }), [{ - role: { _id: 'admin' }, - scope: 'scope1', - user: { _id: userId }, - inheritedRoles: [{ _id: 'admin' }] - }, { - role: { _id: 'user' }, - scope: 'scope1', - user: { _id: userId }, - inheritedRoles: [{ _id: 'user' }] - }]) - const userRoles2 = await Roles.getRolesForUserAsync(userId, { fullObjects: true, scope: 'scope2' }) - assert.sameDeepMembers(userRoles2.map(obj => { delete obj._id; return obj }), [{ - role: { _id: 'admin' }, - scope: 'scope2', - user: { _id: userId }, - inheritedRoles: [{ _id: 'admin' }] - }]) - - const userRoles3 = await Roles.getRolesForUserAsync(userId, { fullObjects: true, anyScope: true }) - assert.sameDeepMembers(userRoles3.map(obj => { delete obj._id; return obj }), [{ - role: { _id: 'admin' }, - scope: 'scope1', - user: { _id: userId }, - inheritedRoles: [{ _id: 'admin' }] - }, { - role: { _id: 'user' }, - scope: 'scope1', - user: { _id: userId }, - inheritedRoles: [{ _id: 'user' }] - }, { - role: { _id: 'admin' }, - scope: 'scope2', - user: { _id: userId }, - inheritedRoles: [{ _id: 'admin' }] - }]) - - await Roles.createRoleAsync('PERMISSION') - await Roles.addRolesToParentAsync('PERMISSION', 'user') - - const userRoles4 = await Roles.getRolesForUserAsync(userId, { fullObjects: true, scope: 'scope1' }) - assert.sameDeepMembers(userRoles4.map(obj => { delete obj._id; return obj }), [{ - role: { _id: 'admin' }, - scope: 'scope1', - user: { _id: userId }, - inheritedRoles: [{ _id: 'admin' }] - }, { - role: { _id: 'user' }, - scope: 'scope1', - user: { _id: userId }, - inheritedRoles: [{ _id: 'user' }, { _id: 'PERMISSION' }] - }]) - const userRoles5 = await Roles.getRolesForUserAsync(userId, { fullObjects: true, scope: 'scope2' }) - assert.sameDeepMembers(userRoles5.map(obj => { delete obj._id; return obj }), [{ - role: { _id: 'admin' }, - scope: 'scope2', - user: { _id: userId }, - inheritedRoles: [{ _id: 'admin' }] - }]) - assert.sameMembers(await Roles.getRolesForUserAsync(userId, { scope: 'scope1' }), ['admin', 'user', 'PERMISSION']) - assert.sameMembers(await Roles.getRolesForUserAsync(userId, { scope: 'scope2' }), ['admin']) - - const userRoles6 = await Roles.getRolesForUserAsync(userId, { fullObjects: true, anyScope: true }) - assert.sameDeepMembers(userRoles6.map(obj => { delete obj._id; return obj }), [{ - role: { _id: 'admin' }, - scope: 'scope1', - user: { _id: userId }, - inheritedRoles: [{ _id: 'admin' }] - }, { - role: { _id: 'user' }, - scope: 'scope1', - user: { _id: userId }, - inheritedRoles: [{ _id: 'user' }, { _id: 'PERMISSION' }] - }, { - role: { _id: 'admin' }, - scope: 'scope2', - user: { _id: userId }, - inheritedRoles: [{ _id: 'admin' }] - }]) - assert.sameMembers(await Roles.getRolesForUserAsync(userId, { anyScope: true }), ['admin', 'user', 'PERMISSION']) - - const userRoles7 = await Roles.getRolesForUserAsync(userId, { fullObjects: true, scope: 'scope1', onlyAssigned: true }) - assert.sameDeepMembers(userRoles7.map(obj => { delete obj._id; return obj }), [{ - role: { _id: 'admin' }, - scope: 'scope1', - user: { _id: userId }, - inheritedRoles: [{ _id: 'admin' }] - }, { - role: { _id: 'user' }, - scope: 'scope1', - user: { _id: userId }, - inheritedRoles: [{ _id: 'user' }, { _id: 'PERMISSION' }] - }]) - const userRoles8 = await Roles.getRolesForUserAsync(userId, { fullObjects: true, scope: 'scope2', onlyAssigned: true }) - assert.sameDeepMembers(userRoles8.map(obj => { delete obj._id; return obj }), [{ - role: { _id: 'admin' }, - scope: 'scope2', - user: { _id: userId }, - inheritedRoles: [{ _id: 'admin' }] - }]) - assert.sameMembers(await Roles.getRolesForUserAsync(userId, { scope: 'scope1', onlyAssigned: true }), ['admin', 'user']) - assert.sameMembers(await Roles.getRolesForUserAsync(userId, { scope: 'scope2', onlyAssigned: true }), ['admin']) - - const userRoles9 = await Roles.getRolesForUserAsync(userId, { fullObjects: true, anyScope: true, onlyAssigned: true }) - assert.sameDeepMembers(userRoles9.map(obj => { delete obj._id; return obj }), [{ - role: { _id: 'admin' }, - scope: 'scope1', - user: { _id: userId }, - inheritedRoles: [{ _id: 'admin' }] - }, { - role: { _id: 'user' }, - scope: 'scope1', - user: { _id: userId }, - inheritedRoles: [{ _id: 'user' }, { _id: 'PERMISSION' }] - }, { - role: { _id: 'admin' }, - scope: 'scope2', - user: { _id: userId }, - inheritedRoles: [{ _id: 'admin' }] - }]) - assert.sameMembers(await Roles.getRolesForUserAsync(userId, { anyScope: true, onlyAssigned: true }), ['admin', 'user']) - }) - - it('can get only scoped roles for user', async function () { - await Roles.createRoleAsync('admin') - await Roles.createRoleAsync('user') - - const userId = users.eve - - // add roles - await Roles.addUsersToRolesAsync(userId, ['user'], 'scope1') - await Roles.addUsersToRolesAsync(userId, ['admin']) - - await Roles.createRoleAsync('PERMISSION') - await Roles.addRolesToParentAsync('PERMISSION', 'user') - - assert.sameMembers(await Roles.getRolesForUserAsync(userId, { onlyScoped: true, scope: 'scope1' }), ['user', 'PERMISSION']) - assert.sameMembers(await Roles.getRolesForUserAsync(userId, { onlyScoped: true, onlyAssigned: true, scope: 'scope1' }), ['user']) - const userRoles = await Roles.getRolesForUserAsync(userId, { onlyScoped: true, fullObjects: true, scope: 'scope1' }) - assert.sameDeepMembers(userRoles.map(obj => { delete obj._id; return obj }), [{ - role: { _id: 'user' }, - scope: 'scope1', - user: { _id: userId }, - inheritedRoles: [{ _id: 'user' }, { _id: 'PERMISSION' }] - }]) - }) - - it('can get all roles for user by scope with periods in name', async function () { - await Roles.createRoleAsync('admin') - - await Roles.addUsersToRolesAsync(users.joe, ['admin'], 'example.k12.va.us') - - assert.sameMembers(await Roles.getRolesForUserAsync(users.joe, 'example.k12.va.us'), ['admin']) - }) - - it('can get all roles for user by scope including Roles.GLOBAL_SCOPE', async function () { - await Roles.createRoleAsync('admin') - await Roles.createRoleAsync('user') - await Roles.createRoleAsync('editor') - - const userId = users.eve - - await Roles.addUsersToRolesAsync([users.eve], ['editor'], Roles.GLOBAL_SCOPE) - await Roles.addUsersToRolesAsync([users.eve], ['admin', 'user'], 'scope1') - - // by userId - assert.sameMembers(await Roles.getRolesForUserAsync(userId, 'scope1'), ['editor', 'admin', 'user']) - assert.sameMembers(await Roles.getRolesForUserAsync(userId), ['editor']) - - // by user object - const userObj = await Meteor.users.findOneAsync({ _id: userId }) - assert.sameMembers(await Roles.getRolesForUserAsync(userObj, 'scope1'), ['editor', 'admin', 'user']) - assert.sameMembers(await Roles.getRolesForUserAsync(userObj), ['editor']) - }) - - describe('getRolesForUser', function () { - it('should not return null entries if user has no roles for scope', async function () { - await Roles.createRoleAsync('editor') - - const userId = users.eve - let userObj - - // by userId - assert.sameMembers(await Roles.getRolesForUserAsync(userId, 'scope1'), []) - assert.sameMembers(await Roles.getRolesForUserAsync(userId), []) - - // by user object - userObj = await Meteor.users.findOneAsync({ _id: userId }) - assert.sameMembers(await Roles.getRolesForUserAsync(userObj, 'scope1'), []) - assert.sameMembers(await Roles.getRolesForUserAsync(userObj), []) - - await Roles.addUsersToRolesAsync([users.eve], ['editor'], Roles.GLOBAL_SCOPE) - - // by userId - assert.sameMembers(await Roles.getRolesForUserAsync(userId, 'scope1'), ['editor']) - assert.sameMembers(await Roles.getRolesForUserAsync(userId), ['editor']) - - // by user object - userObj = await Meteor.users.findOneAsync({ _id: userId }) - assert.sameMembers(await Roles.getRolesForUserAsync(userObj, 'scope1'), ['editor']) - assert.sameMembers(await Roles.getRolesForUserAsync(userObj), ['editor']) - }) - - it('should not fail during a call of addUsersToRoles', async function () { - await Roles.createRoleAsync('editor') - - const userId = users.eve - const promises = [] - const interval = setInterval(() => { - promises.push(Promise.resolve().then(async () => { - await Roles.getRolesForUserAsync(userId) - })) - }, 0) - - await Roles.addUsersToRolesAsync([users.eve], ['editor'], Roles.GLOBAL_SCOPE) - clearInterval(interval) - - return Promise.all(promises) - }) - }) - - it('returns an empty list of scopes for null as user-id', async function () { - assert.sameMembers(await Roles.getScopesForUserAsync(undefined), []) - assert.sameMembers(await Roles.getScopesForUserAsync(null), []) - assert.sameMembers(await Roles.getScopesForUserAsync('foo'), []) - assert.sameMembers(await Roles.getScopesForUserAsync({}), []) - assert.sameMembers(await Roles.getScopesForUserAsync({ _id: 'foo' }), []) - }) - - it('can get all scopes for user', async function () { - await Roles.createRoleAsync('admin') - await Roles.createRoleAsync('user') - await Roles.createRoleAsync('editor') - - const userId = users.eve - - await Roles.addUsersToRolesAsync([users.eve], ['editor'], 'scope1') - await Roles.addUsersToRolesAsync([users.eve], ['admin', 'user'], 'scope2') - - // by userId - assert.sameMembers(await Roles.getScopesForUserAsync(userId), ['scope1', 'scope2']) - - // by user object - const userObj = await Meteor.users.findOneAsync({ _id: userId }) - assert.sameMembers(await Roles.getScopesForUserAsync(userObj), ['scope1', 'scope2']) - }) - - it('can get all scopes for user by role', async function () { - await Roles.createRoleAsync('admin') - await Roles.createRoleAsync('user') - await Roles.createRoleAsync('editor') - - const userId = users.eve - - await Roles.addUsersToRolesAsync([users.eve], ['editor'], 'scope1') - await Roles.addUsersToRolesAsync([users.eve], ['editor', 'user'], 'scope2') - - // by userId - assert.sameMembers(await Roles.getScopesForUserAsync(userId, 'user'), ['scope2']) - assert.sameMembers(await Roles.getScopesForUserAsync(userId, 'editor'), ['scope1', 'scope2']) - assert.sameMembers(await Roles.getScopesForUserAsync(userId, 'admin'), []) - - // by user object - const userObj = await Meteor.users.findOneAsync({ _id: userId }) - assert.sameMembers(await Roles.getScopesForUserAsync(userObj, 'user'), ['scope2']) - assert.sameMembers(await Roles.getScopesForUserAsync(userObj, 'editor'), ['scope1', 'scope2']) - assert.sameMembers(await Roles.getScopesForUserAsync(userObj, 'admin'), []) - }) - - it('getScopesForUser returns [] when not using scopes', async function () { - await Roles.createRoleAsync('user') - await Roles.createRoleAsync('editor') - - const userId = users.eve - - await Roles.addUsersToRolesAsync([users.eve], ['editor', 'user']) - - // by userId - assert.sameMembers(await Roles.getScopesForUserAsync(userId), []) - assert.sameMembers(await Roles.getScopesForUserAsync(userId, 'editor'), []) - assert.sameMembers(await Roles.getScopesForUserAsync(userId, ['editor']), []) - assert.sameMembers(await Roles.getScopesForUserAsync(userId, ['editor', 'user']), []) - - // by user object - const userObj = await Meteor.users.findOneAsync({ _id: userId }) - assert.sameMembers(await Roles.getScopesForUserAsync(userObj), []) - assert.sameMembers(await Roles.getScopesForUserAsync(userObj, 'editor'), []) - assert.sameMembers(await Roles.getScopesForUserAsync(userObj, ['editor']), []) - assert.sameMembers(await Roles.getScopesForUserAsync(userObj, ['editor', 'user']), []) - }) - - it('can get all groups for user by role array', async function () { - const userId = users.eve - - await Roles.createRoleAsync('user') - await Roles.createRoleAsync('editor') - await Roles.createRoleAsync('moderator') - await Roles.createRoleAsync('admin') - - await Roles.addUsersToRolesAsync([users.eve], ['editor'], 'group1') - await Roles.addUsersToRolesAsync([users.eve], ['editor', 'user'], 'group2') - await Roles.addUsersToRolesAsync([users.eve], ['moderator'], 'group3') + await Roles.addUsersToRolesAsync([users.eve], ["editor"], "group1"); + await Roles.addUsersToRolesAsync([users.eve], ["editor", "user"], "group2"); + await Roles.addUsersToRolesAsync([users.eve], ["moderator"], "group3"); // by userId, one role - assert.sameMembers(await Roles.getScopesForUserAsync(userId, ['user']), ['group2']) - assert.sameMembers(await Roles.getScopesForUserAsync(userId, ['editor']), ['group1', 'group2']) - assert.sameMembers(await Roles.getScopesForUserAsync(userId, ['admin']), []) + sameMembers(test, await Roles.getScopesForUserAsync(userId, ["user"]), [ + "group2", + ]); + sameMembers(test, await Roles.getScopesForUserAsync(userId, ["editor"]), [ + "group1", + "group2", + ]); + sameMembers(test, await Roles.getScopesForUserAsync(userId, ["admin"]), []); // by userId, multiple roles - assert.sameMembers(await Roles.getScopesForUserAsync(userId, ['editor', 'user']), ['group1', 'group2']) - assert.sameMembers(await Roles.getScopesForUserAsync(userId, ['editor', 'moderator']), ['group1', 'group2', 'group3']) - assert.sameMembers(await Roles.getScopesForUserAsync(userId, ['user', 'moderator']), ['group2', 'group3']) + sameMembers( + test, + await Roles.getScopesForUserAsync(userId, ["editor", "user"]), + ["group1", "group2"] + ); + sameMembers( + test, + await Roles.getScopesForUserAsync(userId, ["editor", "moderator"]), + ["group1", "group2", "group3"] + ); + sameMembers( + test, + await Roles.getScopesForUserAsync(userId, ["user", "moderator"]), + ["group2", "group3"] + ); // by user object, one role - const userObj = await Meteor.users.findOneAsync({ _id: userId }) - assert.sameMembers(await Roles.getScopesForUserAsync(userObj, ['user']), ['group2']) - assert.sameMembers(await Roles.getScopesForUserAsync(userObj, ['editor']), ['group1', 'group2']) - assert.sameMembers(await Roles.getScopesForUserAsync(userObj, ['admin']), []) + const userObj = await Meteor.users.findOneAsync({ _id: userId }); + sameMembers(test, await Roles.getScopesForUserAsync(userObj, ["user"]), [ + "group2", + ]); + sameMembers(test, await Roles.getScopesForUserAsync(userObj, ["editor"]), [ + "group1", + "group2", + ]); + sameMembers( + test, + await Roles.getScopesForUserAsync(userObj, ["admin"]), + [] + ); // by user object, multiple roles - assert.sameMembers(await Roles.getScopesForUserAsync(userObj, ['editor', 'user']), ['group1', 'group2']) - assert.sameMembers(await Roles.getScopesForUserAsync(userObj, ['editor', 'moderator']), ['group1', 'group2', 'group3']) - assert.sameMembers(await Roles.getScopesForUserAsync(userObj, ['user', 'moderator']), ['group2', 'group3']) - }) + sameMembers( + test, + await Roles.getScopesForUserAsync(userObj, ["editor", "user"]), + ["group1", "group2"] + ); + sameMembers( + test, + await Roles.getScopesForUserAsync(userObj, ["editor", "moderator"]), + ["group1", "group2", "group3"] + ); + sameMembers( + test, + await Roles.getScopesForUserAsync(userObj, ["user", "moderator"]), + ["group2", "group3"] + ); + } +); - it('getting all scopes for user does not include GLOBAL_SCOPE', async function () { - await Roles.createRoleAsync('admin') - await Roles.createRoleAsync('user') - await Roles.createRoleAsync('editor') +Tinytest.addAsync( + "roles -getting all scopes for user does not include GLOBAL_SCOPE", + async function (test) { + await clearData(); + await Roles.createRoleAsync("admin"); + await Roles.createRoleAsync("user"); + await Roles.createRoleAsync("editor"); - const userId = users.eve + const userId = users.eve; - await Roles.addUsersToRolesAsync([users.eve], ['editor'], 'scope1') - await Roles.addUsersToRolesAsync([users.eve], ['editor', 'user'], 'scope2') - await Roles.addUsersToRolesAsync([users.eve], ['editor', 'user', 'admin'], Roles.GLOBAL_SCOPE) + await Roles.addUsersToRolesAsync([users.eve], ["editor"], "scope1"); + await Roles.addUsersToRolesAsync([users.eve], ["editor", "user"], "scope2"); + await Roles.addUsersToRolesAsync( + [users.eve], + ["editor", "user", "admin"], + Roles.GLOBAL_SCOPE + ); // by userId - assert.sameMembers(await Roles.getScopesForUserAsync(userId, 'user'), ['scope2']) - assert.sameMembers(await Roles.getScopesForUserAsync(userId, 'editor'), ['scope1', 'scope2']) - assert.sameMembers(await Roles.getScopesForUserAsync(userId, 'admin'), []) - assert.sameMembers(await Roles.getScopesForUserAsync(userId, ['user']), ['scope2']) - assert.sameMembers(await Roles.getScopesForUserAsync(userId, ['editor']), ['scope1', 'scope2']) - assert.sameMembers(await Roles.getScopesForUserAsync(userId, ['admin']), []) - assert.sameMembers(await Roles.getScopesForUserAsync(userId, ['user', 'editor', 'admin']), ['scope1', 'scope2']) + sameMembers(test, await Roles.getScopesForUserAsync(userId, "user"), [ + "scope2", + ]); + sameMembers(test, await Roles.getScopesForUserAsync(userId, "editor"), [ + "scope1", + "scope2", + ]); + sameMembers(test, await Roles.getScopesForUserAsync(userId, "admin"), []); + sameMembers(test, await Roles.getScopesForUserAsync(userId, ["user"]), [ + "scope2", + ]); + sameMembers(test, await Roles.getScopesForUserAsync(userId, ["editor"]), [ + "scope1", + "scope2", + ]); + sameMembers(test, await Roles.getScopesForUserAsync(userId, ["admin"]), []); + sameMembers( + test, + await Roles.getScopesForUserAsync(userId, ["user", "editor", "admin"]), + ["scope1", "scope2"] + ); // by user object - const userObj = await Meteor.users.findOneAsync({ _id: userId }) - assert.sameMembers(await Roles.getScopesForUserAsync(userObj, 'user'), ['scope2']) - assert.sameMembers(await Roles.getScopesForUserAsync(userObj, 'editor'), ['scope1', 'scope2']) - assert.sameMembers(await Roles.getScopesForUserAsync(userObj, 'admin'), []) - assert.sameMembers(await Roles.getScopesForUserAsync(userObj, ['user']), ['scope2']) - assert.sameMembers(await Roles.getScopesForUserAsync(userObj, ['editor']), ['scope1', 'scope2']) - assert.sameMembers(await Roles.getScopesForUserAsync(userObj, ['admin']), []) - assert.sameMembers(await Roles.getScopesForUserAsync(userObj, ['user', 'editor', 'admin']), ['scope1', 'scope2']) - }) + const userObj = await Meteor.users.findOneAsync({ _id: userId }); + sameMembers(test, await Roles.getScopesForUserAsync(userObj, "user"), [ + "scope2", + ]); + sameMembers(test, await Roles.getScopesForUserAsync(userObj, "editor"), [ + "scope1", + "scope2", + ]); + sameMembers(test, await Roles.getScopesForUserAsync(userObj, "admin"), []); + sameMembers(test, await Roles.getScopesForUserAsync(userObj, ["user"]), [ + "scope2", + ]); + sameMembers(test, await Roles.getScopesForUserAsync(userObj, ["editor"]), [ + "scope1", + "scope2", + ]); + sameMembers( + test, + await Roles.getScopesForUserAsync(userObj, ["admin"]), + [] + ); + sameMembers( + test, + await Roles.getScopesForUserAsync(userObj, ["user", "editor", "admin"]), + ["scope1", "scope2"] + ); + } +); - it('can get all users in role', async function () { - await Roles.createRoleAsync('admin') - await Roles.createRoleAsync('user') - await Roles.createRoleAsync('editor') +Tinytest.addAsync("roles -can get all users in role", async function (test) { + await clearData(); + await Roles.createRoleAsync("admin"); + await Roles.createRoleAsync("user"); + await Roles.createRoleAsync("editor"); - await Roles.addUsersToRolesAsync([users.eve, users.joe], ['admin', 'user']) - await Roles.addUsersToRolesAsync([users.bob, users.joe], ['editor']) + await Roles.addUsersToRolesAsync([users.eve, users.joe], ["admin", "user"]); + await Roles.addUsersToRolesAsync([users.bob, users.joe], ["editor"]); - const expected = [users.eve, users.joe] - const cursor = await Roles.getUsersInRoleAsync('admin') - const fetched = await cursor.fetchAsync() - const actual = fetched.map(r => r._id) + const expected = [users.eve, users.joe]; + const cursor = await Roles.getUsersInRoleAsync("admin"); + const fetched = await cursor.fetchAsync(); + const actual = fetched.map((r) => r._id); - assert.sameMembers(actual, expected) - }) + sameMembers(test, actual, expected); +}); - it('can get all users in role by scope', async function () { - await Roles.createRoleAsync('admin') - await Roles.createRoleAsync('user') +Tinytest.addAsync( + "roles -can get all users in role by scope", + async function (test) { + await clearData(); + await Roles.createRoleAsync("admin"); + await Roles.createRoleAsync("user"); - await Roles.addUsersToRolesAsync([users.eve, users.joe], ['admin', 'user'], 'scope1') - await Roles.addUsersToRolesAsync([users.bob, users.joe], ['admin'], 'scope2') + await Roles.addUsersToRolesAsync( + [users.eve, users.joe], + ["admin", "user"], + "scope1" + ); + await Roles.addUsersToRolesAsync( + [users.bob, users.joe], + ["admin"], + "scope2" + ); - let expected = [users.eve, users.joe] - const cursor1 = await Roles.getUsersInRoleAsync('admin', 'scope1') - const fetched1 = await cursor1.fetchAsync() - let actual = fetched1.map(r => r._id) + let expected = [users.eve, users.joe]; + const cursor1 = await Roles.getUsersInRoleAsync("admin", "scope1"); + const fetched1 = await cursor1.fetchAsync(); + let actual = fetched1.map((r) => r._id); - assert.sameMembers(actual, expected) + sameMembers(test, actual, expected); - expected = [users.eve, users.joe] - const cursor2 = await Roles.getUsersInRoleAsync('admin', { scope: 'scope1' }) - const fetched2 = await cursor2.fetchAsync() - actual = fetched2.map(r => r._id) - assert.sameMembers(actual, expected) + expected = [users.eve, users.joe]; + const cursor2 = await Roles.getUsersInRoleAsync("admin", { + scope: "scope1", + }); + const fetched2 = await cursor2.fetchAsync(); + actual = fetched2.map((r) => r._id); + sameMembers(test, actual, expected); - expected = [users.eve, users.bob, users.joe] - const cursor3 = await Roles.getUsersInRoleAsync('admin', { anyScope: true }) - const fetched3 = await cursor3.fetchAsync() - actual = fetched3.map(r => r._id) - assert.sameMembers(actual, expected) + expected = [users.eve, users.bob, users.joe]; + const cursor3 = await Roles.getUsersInRoleAsync("admin", { + anyScope: true, + }); + const fetched3 = await cursor3.fetchAsync(); + actual = fetched3.map((r) => r._id); + sameMembers(test, actual, expected); - const cursor4 = await Roles.getUsersInRoleAsync('admin') - const fetched4 = await cursor4.fetchAsync() - actual = fetched4.map(r => r._id) - assert.sameMembers(actual, []) - }) + const cursor4 = await Roles.getUsersInRoleAsync("admin"); + const fetched4 = await cursor4.fetchAsync(); + actual = fetched4.map((r) => r._id); + sameMembers(test, actual, []); + } +); - // it('can get all users in role by scope including Roles.GLOBAL_SCOPE', function () { - // Roles.createRoleAsync('admin') - // Roles.createRoleAsync('user') - // - // Roles.addUsersToRolesAsync([users.eve], ['admin', 'user'], Roles.GLOBAL_SCOPE) - // Roles.addUsersToRolesAsync([users.bob, users.joe], ['admin'], 'scope2') - // - // let expected = [users.eve] - // let actual = await Roles.getUsersInRoleAsync('admin', 'scope1').fetch().map(r => r._id) - // - // assert.sameMembers(actual, expected) - // - // expected = [users.eve, users.bob, users.joe] - // actual = await Roles.getUsersInRoleAsync('admin', 'scope2').fetch().map(r => r._id) - // - // assert.sameMembers(actual, expected) - // - // expected = [users.eve] - // actual = await Roles.getUsersInRoleAsync('admin').fetch().map(r => r._id) - // - // assert.sameMembers(actual, expected) - // - // expected = [users.eve, users.bob, users.joe] - // actual = await Roles.getUsersInRoleAsync('admin', { anyScope: true }).fetch().map(r => r._id) - // - // assert.sameMembers(actual, expected) - // }) - // - // it('can get all users in role by scope excluding Roles.GLOBAL_SCOPE', function () { - // Roles.createRoleAsync('admin') - // - // Roles.addUsersToRolesAsync([users.eve], ['admin'], Roles.GLOBAL_SCOPE) - // Roles.addUsersToRolesAsync([users.bob], ['admin'], 'scope1') - // - // let expected = [users.eve] - // let actual = await Roles.getUsersInRoleAsync('admin').fetch().map(r => r._id) - // assert.sameMembers(actual, expected) - // - // expected = [users.eve, users.bob] - // actual = await Roles.getUsersInRoleAsync('admin', { scope: 'scope1' }).fetch().map(r => r._id) - // assert.sameMembers(actual, expected) - // - // expected = [users.bob] - // actual = await Roles.getUsersInRoleAsync('admin', { scope: 'scope1', onlyScoped: true }).fetch().map(r => r._id) - // assert.sameMembers(actual, expected) - // }) +Tinytest.addAsync( + "roles -can get all users in role by scope and passes through mongo query arguments", + async function (test) { + await clearData(); + await Roles.createRoleAsync("admin"); + await Roles.createRoleAsync("user"); - it('can get all users in role by scope and passes through mongo query arguments', async function () { - await Roles.createRoleAsync('admin') - await Roles.createRoleAsync('user') + await Roles.addUsersToRolesAsync( + [users.eve, users.joe], + ["admin", "user"], + "scope1" + ); + await Roles.addUsersToRolesAsync( + [users.bob, users.joe], + ["admin"], + "scope2" + ); - await Roles.addUsersToRolesAsync([users.eve, users.joe], ['admin', 'user'], 'scope1') - await Roles.addUsersToRolesAsync([users.bob, users.joe], ['admin'], 'scope2') + const cursor = await Roles.getUsersInRoleAsync("admin", "scope1", { + fields: { username: 0 }, + limit: 1, + }); + const results = await cursor.fetchAsync(); - const cursor = await Roles.getUsersInRoleAsync('admin', 'scope1', { fields: { username: 0 }, limit: 1 }) - const results = await cursor.fetchAsync() + test.equal(1, results.length); + test.isTrue(hasProp(results[0], "_id")); + test.isFalse(hasProp(results[0], "username")); + } +); - assert.equal(1, results.length) - assert.isTrue(hasProp(results[0], '_id')) - assert.isFalse(hasProp(results[0], 'username')) - }) +Tinytest.addAsync( + "roles -can use Roles.GLOBAL_SCOPE to assign blanket roles", + async function (test) { + await clearData(); + await Roles.createRoleAsync("admin"); - it('can use Roles.GLOBAL_SCOPE to assign blanket roles', async function () { - await Roles.createRoleAsync('admin') + await Roles.addUsersToRolesAsync( + [users.joe, users.bob], + ["admin"], + Roles.GLOBAL_SCOPE + ); - await Roles.addUsersToRolesAsync([users.joe, users.bob], ['admin'], Roles.GLOBAL_SCOPE) + await testUser(test, "eve", [], "scope1"); + await testUser(test, "joe", ["admin"], "scope2"); + await testUser(test, "joe", ["admin"], "scope1"); + await testUser(test, "bob", ["admin"], "scope2"); + await testUser(test, "bob", ["admin"], "scope1"); - await testUser('eve', [], 'scope1') - await testUser('joe', ['admin'], 'scope2') - await testUser('joe', ['admin'], 'scope1') - await testUser('bob', ['admin'], 'scope2') - await testUser('bob', ['admin'], 'scope1') + await Roles.removeUsersFromRolesAsync( + users.joe, + ["admin"], + Roles.GLOBAL_SCOPE + ); - await Roles.removeUsersFromRolesAsync(users.joe, ['admin'], Roles.GLOBAL_SCOPE) + await testUser(test, "eve", [], "scope1"); + await testUser(test, "joe", [], "scope2"); + await testUser(test, "joe", [], "scope1"); + await testUser(test, "bob", ["admin"], "scope2"); + await testUser(test, "bob", ["admin"], "scope1"); + } +); - await testUser('eve', [], 'scope1') - await testUser('joe', [], 'scope2') - await testUser('joe', [], 'scope1') - await testUser('bob', ['admin'], 'scope2') - await testUser('bob', ['admin'], 'scope1') - }) +Tinytest.addAsync( + "roles -Roles.GLOBAL_SCOPE is independent of other scopes", + async function (test) { + await clearData(); + await Roles.createRoleAsync("admin"); - it('Roles.GLOBAL_SCOPE is independent of other scopes', async function () { - await Roles.createRoleAsync('admin') + await Roles.addUsersToRolesAsync( + [users.joe, users.bob], + ["admin"], + "scope5" + ); + await Roles.addUsersToRolesAsync( + [users.joe, users.bob], + ["admin"], + Roles.GLOBAL_SCOPE + ); - await Roles.addUsersToRolesAsync([users.joe, users.bob], ['admin'], 'scope5') - await Roles.addUsersToRolesAsync([users.joe, users.bob], ['admin'], Roles.GLOBAL_SCOPE) + await testUser(test, "eve", [], "scope1"); + await testUser(test, "joe", ["admin"], "scope5"); + await testUser(test, "joe", ["admin"], "scope2"); + await testUser(test, "joe", ["admin"], "scope1"); + await testUser(test, "bob", ["admin"], "scope5"); + await testUser(test, "bob", ["admin"], "scope2"); + await testUser(test, "bob", ["admin"], "scope1"); - await testUser('eve', [], 'scope1') - await testUser('joe', ['admin'], 'scope5') - await testUser('joe', ['admin'], 'scope2') - await testUser('joe', ['admin'], 'scope1') - await testUser('bob', ['admin'], 'scope5') - await testUser('bob', ['admin'], 'scope2') - await testUser('bob', ['admin'], 'scope1') + await Roles.removeUsersFromRolesAsync( + users.joe, + ["admin"], + Roles.GLOBAL_SCOPE + ); - await Roles.removeUsersFromRolesAsync(users.joe, ['admin'], Roles.GLOBAL_SCOPE) + await testUser(test, "eve", [], "scope1"); + await testUser(test, "joe", ["admin"], "scope5"); + await testUser(test, "joe", [], "scope2"); + await testUser(test, "joe", [], "scope1"); + await testUser(test, "bob", ["admin"], "scope5"); + await testUser(test, "bob", ["admin"], "scope2"); + await testUser(test, "bob", ["admin"], "scope1"); + } +); - await testUser('eve', [], 'scope1') - await testUser('joe', ['admin'], 'scope5') - await testUser('joe', [], 'scope2') - await testUser('joe', [], 'scope1') - await testUser('bob', ['admin'], 'scope5') - await testUser('bob', ['admin'], 'scope2') - await testUser('bob', ['admin'], 'scope1') - }) +Tinytest.addAsync( + "roles -Roles.GLOBAL_SCOPE also checked when scope not specified", + async function (test) { + await clearData(); + await Roles.createRoleAsync("admin"); - it('Roles.GLOBAL_SCOPE also checked when scope not specified', async function () { - await Roles.createRoleAsync('admin') + await Roles.addUsersToRolesAsync(users.joe, "admin", Roles.GLOBAL_SCOPE); - await Roles.addUsersToRolesAsync(users.joe, 'admin', Roles.GLOBAL_SCOPE) + await testUser(test, "joe", ["admin"]); - await testUser('joe', ['admin']) + await Roles.removeUsersFromRolesAsync( + users.joe, + "admin", + Roles.GLOBAL_SCOPE + ); - await Roles.removeUsersFromRolesAsync(users.joe, 'admin', Roles.GLOBAL_SCOPE) + await testUser(test, "joe", []); + } +); - await testUser('joe', []) - }) +Tinytest.addAsync("roles -can use '.' in scope name", async function (test) { + await clearData(); + await Roles.createRoleAsync("admin"); - it('can use \'.\' in scope name', async function () { - await Roles.createRoleAsync('admin') + await Roles.addUsersToRolesAsync(users.joe, ["admin"], "example.com"); + await testUser(test, "joe", ["admin"], "example.com"); +}); - await Roles.addUsersToRolesAsync(users.joe, ['admin'], 'example.com') - await testUser('joe', ['admin'], 'example.com') - }) +Tinytest.addAsync( + "roles -can use multiple periods in scope name", + async function (test) { + await clearData(); + await Roles.createRoleAsync("admin"); - it('can use multiple periods in scope name', async function () { - await Roles.createRoleAsync('admin') + await Roles.addUsersToRolesAsync(users.joe, ["admin"], "example.k12.va.us"); + await testUser(test, "joe", ["admin"], "example.k12.va.us"); + } +); - await Roles.addUsersToRolesAsync(users.joe, ['admin'], 'example.k12.va.us') - await testUser('joe', ['admin'], 'example.k12.va.us') - }) +Tinytest.addAsync("roles -renaming of roles", async function (test) { + await clearData(); + await Roles.createRoleAsync("admin"); + await Roles.createRoleAsync("user"); + await Roles.createRoleAsync("editor"); - it('renaming of roles', async function () { - await Roles.createRoleAsync('admin') - await Roles.createRoleAsync('user') - await Roles.createRoleAsync('editor') + await Roles.setUserRolesAsync( + [users.eve, users.bob], + ["editor", "user"], + "scope1" + ); + await Roles.setUserRolesAsync( + [users.bob, users.joe], + ["user", "admin"], + "scope2" + ); - await Roles.setUserRolesAsync([users.eve, users.bob], ['editor', 'user'], 'scope1') - await Roles.setUserRolesAsync([users.bob, users.joe], ['user', 'admin'], 'scope2') + test.isTrue(await Roles.userIsInRoleAsync(users.eve, "editor", "scope1")); + test.isFalse(await Roles.userIsInRoleAsync(users.eve, "editor", "scope2")); - assert.isTrue(await Roles.userIsInRoleAsync(users.eve, 'editor', 'scope1')) - assert.isFalse(await Roles.userIsInRoleAsync(users.eve, 'editor', 'scope2')) + test.isFalse(await Roles.userIsInRoleAsync(users.joe, "admin", "scope1")); + test.isTrue(await Roles.userIsInRoleAsync(users.joe, "admin", "scope2")); - assert.isFalse(await Roles.userIsInRoleAsync(users.joe, 'admin', 'scope1')) - assert.isTrue(await Roles.userIsInRoleAsync(users.joe, 'admin', 'scope2')) + test.isTrue(await Roles.userIsInRoleAsync(users.eve, "user", "scope1")); + test.isTrue(await Roles.userIsInRoleAsync(users.bob, "user", "scope1")); + test.isFalse(await Roles.userIsInRoleAsync(users.joe, "user", "scope1")); - assert.isTrue(await Roles.userIsInRoleAsync(users.eve, 'user', 'scope1')) - assert.isTrue(await Roles.userIsInRoleAsync(users.bob, 'user', 'scope1')) - assert.isFalse(await Roles.userIsInRoleAsync(users.joe, 'user', 'scope1')) + test.isFalse(await Roles.userIsInRoleAsync(users.eve, "user", "scope2")); + test.isTrue(await Roles.userIsInRoleAsync(users.bob, "user", "scope2")); + test.isTrue(await Roles.userIsInRoleAsync(users.joe, "user", "scope2")); - assert.isFalse(await Roles.userIsInRoleAsync(users.eve, 'user', 'scope2')) - assert.isTrue(await Roles.userIsInRoleAsync(users.bob, 'user', 'scope2')) - assert.isTrue(await Roles.userIsInRoleAsync(users.joe, 'user', 'scope2')) + test.isFalse(await Roles.userIsInRoleAsync(users.eve, "user2", "scope1")); + test.isFalse(await Roles.userIsInRoleAsync(users.eve, "user2", "scope2")); - assert.isFalse(await Roles.userIsInRoleAsync(users.eve, 'user2', 'scope1')) - assert.isFalse(await Roles.userIsInRoleAsync(users.eve, 'user2', 'scope2')) + await Roles.renameRoleAsync("user", "user2"); - await Roles.renameRoleAsync('user', 'user2') + test.isTrue(await Roles.userIsInRoleAsync(users.eve, "editor", "scope1")); + test.isFalse(await Roles.userIsInRoleAsync(users.eve, "editor", "scope2")); - assert.isTrue(await Roles.userIsInRoleAsync(users.eve, 'editor', 'scope1')) - assert.isFalse(await Roles.userIsInRoleAsync(users.eve, 'editor', 'scope2')) + test.isFalse(await Roles.userIsInRoleAsync(users.joe, "admin", "scope1")); + test.isTrue(await Roles.userIsInRoleAsync(users.joe, "admin", "scope2")); - assert.isFalse(await Roles.userIsInRoleAsync(users.joe, 'admin', 'scope1')) - assert.isTrue(await Roles.userIsInRoleAsync(users.joe, 'admin', 'scope2')) + test.isTrue(await Roles.userIsInRoleAsync(users.eve, "user2", "scope1")); + test.isTrue(await Roles.userIsInRoleAsync(users.bob, "user2", "scope1")); + test.isFalse(await Roles.userIsInRoleAsync(users.joe, "user2", "scope1")); - assert.isTrue(await Roles.userIsInRoleAsync(users.eve, 'user2', 'scope1')) - assert.isTrue(await Roles.userIsInRoleAsync(users.bob, 'user2', 'scope1')) - assert.isFalse(await Roles.userIsInRoleAsync(users.joe, 'user2', 'scope1')) + test.isFalse(await Roles.userIsInRoleAsync(users.eve, "user2", "scope2")); + test.isTrue(await Roles.userIsInRoleAsync(users.bob, "user2", "scope2")); + test.isTrue(await Roles.userIsInRoleAsync(users.joe, "user2", "scope2")); - assert.isFalse(await Roles.userIsInRoleAsync(users.eve, 'user2', 'scope2')) - assert.isTrue(await Roles.userIsInRoleAsync(users.bob, 'user2', 'scope2')) - assert.isTrue(await Roles.userIsInRoleAsync(users.joe, 'user2', 'scope2')) + test.isFalse(await Roles.userIsInRoleAsync(users.eve, "user", "scope1")); + test.isFalse(await Roles.userIsInRoleAsync(users.eve, "user", "scope2")); +}); - assert.isFalse(await Roles.userIsInRoleAsync(users.eve, 'user', 'scope1')) - assert.isFalse(await Roles.userIsInRoleAsync(users.eve, 'user', 'scope2')) - }) +Tinytest.addAsync("roles -_addUserToRole", async function (test) { + await clearData(); + await Roles.createRoleAsync("admin"); - it('_addUserToRole', async function () { - await Roles.createRoleAsync('admin') + const userRoles = await Roles.getRolesForUserAsync(users.eve, { + anyScope: true, + fullObjects: true, + }); + sameDeepMembers( + test, + userRoles.map((obj) => { + delete obj._id; + return obj; + }), + [] + ); - const userRoles = await Roles.getRolesForUserAsync(users.eve, { anyScope: true, fullObjects: true }) - assert.sameDeepMembers(userRoles.map(obj => { delete obj._id; return obj }), []) + const roles = await Roles._addUserToRoleAsync(users.eve, "admin", { + scope: null, + ifExists: false, + }); + hasAnyKeys(test, roles, "insertedId"); - const roles = await Roles._addUserToRoleAsync(users.eve, 'admin', { scope: null, ifExists: false }) - assert.hasAnyKeys(roles, 'insertedId') + const userRoles2 = await Roles.getRolesForUserAsync(users.eve, { + anyScope: true, + fullObjects: true, + }); + sameDeepMembers( + test, + userRoles2.map((obj) => { + delete obj._id; + return obj; + }), + [ + { + role: { _id: "admin" }, + scope: null, + user: { _id: users.eve }, + inheritedRoles: [{ _id: "admin" }], + }, + ] + ); - const userRoles2 = await Roles.getRolesForUserAsync(users.eve, { anyScope: true, fullObjects: true }) - assert.sameDeepMembers(userRoles2.map(obj => { delete obj._id; return obj }), [{ - role: { _id: 'admin' }, - scope: null, - user: { _id: users.eve }, - inheritedRoles: [{ _id: 'admin' }] - }]) + const roles2 = await Roles._addUserToRoleAsync(users.eve, "admin", { + scope: null, + ifExists: false, + }); + hasAnyKeys(test, roles2, "insertedId"); - const roles2 = await Roles._addUserToRoleAsync(users.eve, 'admin', { scope: null, ifExists: false }) - assert.hasAnyKeys(roles2, 'insertedId') + const roles3 = await Roles.getRolesForUserAsync(users.eve, { + anyScope: true, + fullObjects: true, + }); + sameDeepMembers( + test, + roles3.map((obj) => { + delete obj._id; + return obj; + }), + [ + { + role: { _id: "admin" }, + scope: null, + user: { _id: users.eve }, + inheritedRoles: [{ _id: "admin" }], + }, + ] + ); +}); - const roles3 = await Roles.getRolesForUserAsync(users.eve, { anyScope: true, fullObjects: true }) - assert.sameDeepMembers(roles3.map(obj => { delete obj._id; return obj }), [{ - role: { _id: 'admin' }, - scope: null, - user: { _id: users.eve }, - inheritedRoles: [{ _id: 'admin' }] - }]) - }) +Tinytest.addAsync("roles -_removeUserFromRole", async function (test) { + await clearData(); + await Roles.createRoleAsync("admin"); - it('_removeUserFromRole', async function () { - await Roles.createRoleAsync('admin') + await Roles.addUsersToRolesAsync(users.eve, "admin"); - await Roles.addUsersToRolesAsync(users.eve, 'admin') + const rolesForUser = await Roles.getRolesForUserAsync(users.eve, { + anyScope: true, + fullObjects: true, + }); + sameDeepMembers( + test, + rolesForUser.map((obj) => { + delete obj._id; + return obj; + }), + [ + { + role: { _id: "admin" }, + scope: null, + user: { _id: users.eve }, + inheritedRoles: [{ _id: "admin" }], + }, + ] + ); - const rolesForUser = await Roles.getRolesForUserAsync(users.eve, { anyScope: true, fullObjects: true }) - assert.sameDeepMembers(rolesForUser.map(obj => { delete obj._id; return obj }), [{ - role: { _id: 'admin' }, - scope: null, - user: { _id: users.eve }, - inheritedRoles: [{ _id: 'admin' }] - }]) + await Roles._removeUserFromRoleAsync(users.eve, "admin", { scope: null }); - await Roles._removeUserFromRoleAsync(users.eve, 'admin', { scope: null }) + const rolesForUser2 = await Roles.getRolesForUserAsync(users.eve, { + anyScope: true, + fullObjects: true, + }); + sameDeepMembers( + test, + rolesForUser2.map((obj) => { + delete obj._id; + return obj; + }), + [] + ); +}); - const rolesForUser2 = await Roles.getRolesForUserAsync(users.eve, { anyScope: true, fullObjects: true }) - assert.sameDeepMembers(rolesForUser2.map(obj => { delete obj._id; return obj }), []) - }) +Tinytest.addAsync("roles -keep assigned roles", async function (test) { + await clearData(); + await Roles.createRoleAsync("admin"); + await Roles.createRoleAsync("user"); + await Roles.createRoleAsync("ALL_PERMISSIONS"); + await Roles.createRoleAsync("VIEW_PERMISSION"); + await Roles.createRoleAsync("EDIT_PERMISSION"); + await Roles.createRoleAsync("DELETE_PERMISSION"); + await Roles.addRolesToParentAsync("ALL_PERMISSIONS", "user"); + await Roles.addRolesToParentAsync("EDIT_PERMISSION", "ALL_PERMISSIONS"); + await Roles.addRolesToParentAsync("VIEW_PERMISSION", "ALL_PERMISSIONS"); + await Roles.addRolesToParentAsync("DELETE_PERMISSION", "admin"); - it('keep assigned roles', async function () { - await Roles.createRoleAsync('admin') - await Roles.createRoleAsync('user') - await Roles.createRoleAsync('ALL_PERMISSIONS') - await Roles.createRoleAsync('VIEW_PERMISSION') - await Roles.createRoleAsync('EDIT_PERMISSION') - await Roles.createRoleAsync('DELETE_PERMISSION') - await Roles.addRolesToParentAsync('ALL_PERMISSIONS', 'user') - await Roles.addRolesToParentAsync('EDIT_PERMISSION', 'ALL_PERMISSIONS') - await Roles.addRolesToParentAsync('VIEW_PERMISSION', 'ALL_PERMISSIONS') - await Roles.addRolesToParentAsync('DELETE_PERMISSION', 'admin') + await Roles.addUsersToRolesAsync(users.eve, ["user"]); - await Roles.addUsersToRolesAsync(users.eve, ['user']) + test.isTrue(await Roles.userIsInRoleAsync(users.eve, "VIEW_PERMISSION")); - assert.isTrue(await Roles.userIsInRoleAsync(users.eve, 'VIEW_PERMISSION')) + const rolesForUser = await Roles.getRolesForUserAsync(users.eve, { + anyScope: true, + fullObjects: true, + }); + sameDeepMembers( + test, + rolesForUser.map((obj) => { + delete obj._id; + return obj; + }), + [ + { + role: { _id: "user" }, + scope: null, + user: { _id: users.eve }, + inheritedRoles: [ + { _id: "user" }, + { _id: "ALL_PERMISSIONS" }, + { _id: "EDIT_PERMISSION" }, + { _id: "VIEW_PERMISSION" }, + ], + }, + ] + ); - const rolesForUser = await Roles.getRolesForUserAsync(users.eve, { anyScope: true, fullObjects: true }) - assert.sameDeepMembers(rolesForUser.map(obj => { delete obj._id; return obj }), [{ - role: { _id: 'user' }, - scope: null, - user: { _id: users.eve }, - inheritedRoles: [ - { _id: 'user' }, - { _id: 'ALL_PERMISSIONS' }, - { _id: 'EDIT_PERMISSION' }, - { _id: 'VIEW_PERMISSION' } + await Roles.addUsersToRolesAsync(users.eve, "VIEW_PERMISSION"); + + test.isTrue(await Roles.userIsInRoleAsync(users.eve, "VIEW_PERMISSION")); + + const rolesForUser2 = await Roles.getRolesForUserAsync(users.eve, { + anyScope: true, + fullObjects: true, + }); + sameDeepMembers( + test, + rolesForUser2.map((obj) => { + delete obj._id; + return obj; + }), + [ + { + role: { _id: "user" }, + scope: null, + user: { _id: users.eve }, + inheritedRoles: [ + { _id: "user" }, + { _id: "ALL_PERMISSIONS" }, + { _id: "EDIT_PERMISSION" }, + { _id: "VIEW_PERMISSION" }, + ], + }, + { + role: { _id: "VIEW_PERMISSION" }, + scope: null, + user: { _id: users.eve }, + inheritedRoles: [{ _id: "VIEW_PERMISSION" }], + }, + ] + ); + + await Roles.removeUsersFromRolesAsync(users.eve, "user"); + + test.isTrue(await Roles.userIsInRoleAsync(users.eve, "VIEW_PERMISSION")); + + const rolesForUser3 = await Roles.getRolesForUserAsync(users.eve, { + anyScope: true, + fullObjects: true, + }); + sameDeepMembers( + test, + rolesForUser3.map((obj) => { + delete obj._id; + return obj; + }), + [ + { + role: { _id: "VIEW_PERMISSION" }, + scope: null, + user: { _id: users.eve }, + inheritedRoles: [{ _id: "VIEW_PERMISSION" }], + }, + ] + ); + + await Roles.removeUsersFromRolesAsync(users.eve, "VIEW_PERMISSION"); + + test.isFalse(await Roles.userIsInRoleAsync(users.eve, "VIEW_PERMISSION")); + + const rolesForUser4 = await Roles.getRolesForUserAsync(users.eve, { + anyScope: true, + fullObjects: true, + }); + sameDeepMembers( + test, + rolesForUser4.map((obj) => { + delete obj._id; + return obj; + }), + [] + ); +}); + +Tinytest.addAsync( + "roles -adds children of the added role to the assignments", + async function (test) { + await clearData(); + await Roles.createRoleAsync("admin"); + await Roles.createRoleAsync("ALBUM.ADMIN"); + await Roles.createRoleAsync("ALBUM.VIEW"); + await Roles.createRoleAsync("TRACK.ADMIN"); + await Roles.createRoleAsync("TRACK.VIEW"); + + await Roles.addRolesToParentAsync("ALBUM.VIEW", "ALBUM.ADMIN"); + await Roles.addRolesToParentAsync("TRACK.VIEW", "TRACK.ADMIN"); + + await Roles.addRolesToParentAsync("ALBUM.ADMIN", "admin"); + + await Roles.addUsersToRolesAsync(users.eve, ["admin"]); + + test.isFalse(await Roles.userIsInRoleAsync(users.eve, "TRACK.VIEW")); + + await Roles.addRolesToParentAsync("TRACK.ADMIN", "admin"); + + test.isTrue(await Roles.userIsInRoleAsync(users.eve, "TRACK.VIEW")); + } +); + +Tinytest.addAsync( + "roles -removes children of the removed role from the assignments", + async function (test) { + await clearData(); + await Roles.createRoleAsync("admin"); + await Roles.createRoleAsync("ALBUM.ADMIN"); + await Roles.createRoleAsync("ALBUM.VIEW"); + await Roles.createRoleAsync("TRACK.ADMIN"); + await Roles.createRoleAsync("TRACK.VIEW"); + + await Roles.addRolesToParentAsync("ALBUM.VIEW", "ALBUM.ADMIN"); + await Roles.addRolesToParentAsync("TRACK.VIEW", "TRACK.ADMIN"); + + await Roles.addRolesToParentAsync("ALBUM.ADMIN", "admin"); + await Roles.addRolesToParentAsync("TRACK.ADMIN", "admin"); + + await Roles.addUsersToRolesAsync(users.eve, ["admin"]); + + test.isTrue(await Roles.userIsInRoleAsync(users.eve, "TRACK.VIEW")); + + await Roles.removeRolesFromParentAsync("TRACK.ADMIN", "admin"); + + test.isFalse(await Roles.userIsInRoleAsync(users.eve, "TRACK.VIEW")); + } +); + +Tinytest.addAsync( + "roles -modify assigned hierarchical roles", + async function (test) { + await clearData(); + await Roles.createRoleAsync("admin"); + await Roles.createRoleAsync("user"); + await Roles.createRoleAsync("ALL_PERMISSIONS"); + await Roles.createRoleAsync("VIEW_PERMISSION"); + await Roles.createRoleAsync("EDIT_PERMISSION"); + await Roles.createRoleAsync("DELETE_PERMISSION"); + await Roles.addRolesToParentAsync("ALL_PERMISSIONS", "user"); + await Roles.addRolesToParentAsync("EDIT_PERMISSION", "ALL_PERMISSIONS"); + await Roles.addRolesToParentAsync("VIEW_PERMISSION", "ALL_PERMISSIONS"); + await Roles.addRolesToParentAsync("DELETE_PERMISSION", "admin"); + + await Roles.addUsersToRolesAsync(users.eve, ["user"]); + await Roles.addUsersToRolesAsync(users.eve, ["ALL_PERMISSIONS"], "scope"); + + test.isFalse( + await Roles.userIsInRoleAsync(users.eve, "MODERATE_PERMISSION") + ); + test.isFalse( + await Roles.userIsInRoleAsync(users.eve, "MODERATE_PERMISSION", "scope") + ); + + const usersRoles = await Roles.getRolesForUserAsync(users.eve, { + anyScope: true, + fullObjects: true, + }); + sameDeepMembers( + test, + usersRoles.map((obj) => { + delete obj._id; + return obj; + }), + [ + { + role: { _id: "user" }, + scope: null, + user: { _id: users.eve }, + inheritedRoles: [ + { _id: "user" }, + { _id: "ALL_PERMISSIONS" }, + { _id: "EDIT_PERMISSION" }, + { _id: "VIEW_PERMISSION" }, + ], + }, + { + role: { _id: "ALL_PERMISSIONS" }, + scope: "scope", + user: { _id: users.eve }, + inheritedRoles: [ + { _id: "ALL_PERMISSIONS" }, + { _id: "EDIT_PERMISSION" }, + { _id: "VIEW_PERMISSION" }, + ], + }, ] - }]) + ); - await Roles.addUsersToRolesAsync(users.eve, 'VIEW_PERMISSION') + await Roles.createRoleAsync("MODERATE_PERMISSION"); - assert.eventually.isTrue(Roles.userIsInRoleAsync(users.eve, 'VIEW_PERMISSION')) + await Roles.addRolesToParentAsync("MODERATE_PERMISSION", "ALL_PERMISSIONS"); - const rolesForUser2 = await Roles.getRolesForUserAsync(users.eve, { anyScope: true, fullObjects: true }) - assert.sameDeepMembers(rolesForUser2.map(obj => { delete obj._id; return obj }), [{ - role: { _id: 'user' }, - scope: null, - user: { _id: users.eve }, - inheritedRoles: [ - { _id: 'user' }, - { _id: 'ALL_PERMISSIONS' }, - { _id: 'EDIT_PERMISSION' }, - { _id: 'VIEW_PERMISSION' } + test.isTrue( + await Roles.userIsInRoleAsync(users.eve, "MODERATE_PERMISSION") + ); + test.isTrue( + await Roles.userIsInRoleAsync(users.eve, "MODERATE_PERMISSION", "scope") + ); + + const usersRoles2 = await Roles.getRolesForUserAsync(users.eve, { + anyScope: true, + fullObjects: true, + }); + sameDeepMembers( + test, + usersRoles2.map((obj) => { + delete obj._id; + return obj; + }), + [ + { + role: { _id: "user" }, + scope: null, + user: { _id: users.eve }, + inheritedRoles: [ + { _id: "user" }, + { _id: "ALL_PERMISSIONS" }, + { _id: "EDIT_PERMISSION" }, + { _id: "VIEW_PERMISSION" }, + { _id: "MODERATE_PERMISSION" }, + ], + }, + { + role: { _id: "ALL_PERMISSIONS" }, + scope: "scope", + user: { _id: users.eve }, + inheritedRoles: [ + { _id: "ALL_PERMISSIONS" }, + { _id: "EDIT_PERMISSION" }, + { _id: "VIEW_PERMISSION" }, + { _id: "MODERATE_PERMISSION" }, + ], + }, ] - }, { - role: { _id: 'VIEW_PERMISSION' }, - scope: null, - user: { _id: users.eve }, - inheritedRoles: [ - { _id: 'VIEW_PERMISSION' } + ); + + await Roles.addUsersToRolesAsync(users.eve, ["admin"]); + + test.isTrue(await Roles.userIsInRoleAsync(users.eve, "DELETE_PERMISSION")); + test.isTrue( + await Roles.userIsInRoleAsync(users.eve, "DELETE_PERMISSION", "scope") + ); + + const usersRoles3 = await Roles.getRolesForUserAsync(users.eve, { + anyScope: true, + fullObjects: true, + }); + sameDeepMembers( + test, + usersRoles3.map((obj) => { + delete obj._id; + return obj; + }), + [ + { + role: { _id: "user" }, + scope: null, + user: { _id: users.eve }, + inheritedRoles: [ + { _id: "user" }, + { _id: "ALL_PERMISSIONS" }, + { _id: "EDIT_PERMISSION" }, + { _id: "VIEW_PERMISSION" }, + { _id: "MODERATE_PERMISSION" }, + ], + }, + { + role: { _id: "ALL_PERMISSIONS" }, + scope: "scope", + user: { _id: users.eve }, + inheritedRoles: [ + { _id: "ALL_PERMISSIONS" }, + { _id: "EDIT_PERMISSION" }, + { _id: "VIEW_PERMISSION" }, + { _id: "MODERATE_PERMISSION" }, + ], + }, + { + role: { _id: "admin" }, + scope: null, + user: { _id: users.eve }, + inheritedRoles: [{ _id: "admin" }, { _id: "DELETE_PERMISSION" }], + }, ] - }]) + ); - await Roles.removeUsersFromRolesAsync(users.eve, 'user') + await Roles.addRolesToParentAsync("DELETE_PERMISSION", "ALL_PERMISSIONS"); - assert.isTrue(await Roles.userIsInRoleAsync(users.eve, 'VIEW_PERMISSION')) + test.isTrue(await Roles.userIsInRoleAsync(users.eve, "DELETE_PERMISSION")); + test.isTrue( + await Roles.userIsInRoleAsync(users.eve, "DELETE_PERMISSION", "scope") + ); - const rolesForUser3 = await Roles.getRolesForUserAsync(users.eve, { anyScope: true, fullObjects: true }) - assert.sameDeepMembers(rolesForUser3.map(obj => { delete obj._id; return obj }), [{ - role: { _id: 'VIEW_PERMISSION' }, - scope: null, - user: { _id: users.eve }, - inheritedRoles: [ - { _id: 'VIEW_PERMISSION' } + const usersRoles4 = await Roles.getRolesForUserAsync(users.eve, { + anyScope: true, + fullObjects: true, + }); + sameDeepMembers( + test, + usersRoles4.map((obj) => { + delete obj._id; + return obj; + }), + [ + { + role: { _id: "user" }, + scope: null, + user: { _id: users.eve }, + inheritedRoles: [ + { _id: "user" }, + { _id: "ALL_PERMISSIONS" }, + { _id: "EDIT_PERMISSION" }, + { _id: "VIEW_PERMISSION" }, + { _id: "MODERATE_PERMISSION" }, + { _id: "DELETE_PERMISSION" }, + ], + }, + { + role: { _id: "ALL_PERMISSIONS" }, + scope: "scope", + user: { _id: users.eve }, + inheritedRoles: [ + { _id: "ALL_PERMISSIONS" }, + { _id: "EDIT_PERMISSION" }, + { _id: "VIEW_PERMISSION" }, + { _id: "MODERATE_PERMISSION" }, + { _id: "DELETE_PERMISSION" }, + ], + }, + { + role: { _id: "admin" }, + scope: null, + user: { _id: users.eve }, + inheritedRoles: [{ _id: "admin" }, { _id: "DELETE_PERMISSION" }], + }, ] - }]) + ); - await Roles.removeUsersFromRolesAsync(users.eve, 'VIEW_PERMISSION') + await Roles.removeUsersFromRolesAsync(users.eve, ["admin"]); - assert.isFalse(await Roles.userIsInRoleAsync(users.eve, 'VIEW_PERMISSION')) + test.isTrue(await Roles.userIsInRoleAsync(users.eve, "DELETE_PERMISSION")); + test.isTrue( + await Roles.userIsInRoleAsync(users.eve, "DELETE_PERMISSION", "scope") + ); - const rolesForUser4 = await Roles.getRolesForUserAsync(users.eve, { anyScope: true, fullObjects: true }) - assert.sameDeepMembers(rolesForUser4.map(obj => { delete obj._id; return obj }), []) - }) - - it('adds children of the added role to the assignments', async function () { - await Roles.createRoleAsync('admin') - await Roles.createRoleAsync('ALBUM.ADMIN') - await Roles.createRoleAsync('ALBUM.VIEW') - await Roles.createRoleAsync('TRACK.ADMIN') - await Roles.createRoleAsync('TRACK.VIEW') - - await Roles.addRolesToParentAsync('ALBUM.VIEW', 'ALBUM.ADMIN') - await Roles.addRolesToParentAsync('TRACK.VIEW', 'TRACK.ADMIN') - - await Roles.addRolesToParentAsync('ALBUM.ADMIN', 'admin') - - await Roles.addUsersToRolesAsync(users.eve, ['admin']) - - assert.isFalse(await Roles.userIsInRoleAsync(users.eve, 'TRACK.VIEW')) - - await Roles.addRolesToParentAsync('TRACK.ADMIN', 'admin') - - assert.isTrue(await Roles.userIsInRoleAsync(users.eve, 'TRACK.VIEW')) - }) - - it('removes children of the removed role from the assignments', async function () { - await Roles.createRoleAsync('admin') - await Roles.createRoleAsync('ALBUM.ADMIN') - await Roles.createRoleAsync('ALBUM.VIEW') - await Roles.createRoleAsync('TRACK.ADMIN') - await Roles.createRoleAsync('TRACK.VIEW') - - await Roles.addRolesToParentAsync('ALBUM.VIEW', 'ALBUM.ADMIN') - await Roles.addRolesToParentAsync('TRACK.VIEW', 'TRACK.ADMIN') - - await Roles.addRolesToParentAsync('ALBUM.ADMIN', 'admin') - await Roles.addRolesToParentAsync('TRACK.ADMIN', 'admin') - - await Roles.addUsersToRolesAsync(users.eve, ['admin']) - - assert.isTrue(await Roles.userIsInRoleAsync(users.eve, 'TRACK.VIEW')) - - await Roles.removeRolesFromParentAsync('TRACK.ADMIN', 'admin') - - assert.isFalse(await Roles.userIsInRoleAsync(users.eve, 'TRACK.VIEW')) - }) - - it('modify assigned hierarchical roles', async function () { - await Roles.createRoleAsync('admin') - await Roles.createRoleAsync('user') - await Roles.createRoleAsync('ALL_PERMISSIONS') - await Roles.createRoleAsync('VIEW_PERMISSION') - await Roles.createRoleAsync('EDIT_PERMISSION') - await Roles.createRoleAsync('DELETE_PERMISSION') - await Roles.addRolesToParentAsync('ALL_PERMISSIONS', 'user') - await Roles.addRolesToParentAsync('EDIT_PERMISSION', 'ALL_PERMISSIONS') - await Roles.addRolesToParentAsync('VIEW_PERMISSION', 'ALL_PERMISSIONS') - await Roles.addRolesToParentAsync('DELETE_PERMISSION', 'admin') - - await Roles.addUsersToRolesAsync(users.eve, ['user']) - await Roles.addUsersToRolesAsync(users.eve, ['ALL_PERMISSIONS'], 'scope') - - assert.isFalse(await Roles.userIsInRoleAsync(users.eve, 'MODERATE_PERMISSION')) - assert.isFalse(await Roles.userIsInRoleAsync(users.eve, 'MODERATE_PERMISSION', 'scope')) - - const usersRoles = await Roles.getRolesForUserAsync(users.eve, { anyScope: true, fullObjects: true }) - assert.sameDeepMembers(usersRoles.map(obj => { delete obj._id; return obj }), [{ - role: { _id: 'user' }, - scope: null, - user: { _id: users.eve }, - inheritedRoles: [ - { _id: 'user' }, - { _id: 'ALL_PERMISSIONS' }, - { _id: 'EDIT_PERMISSION' }, - { _id: 'VIEW_PERMISSION' } + const usersRoles5 = await Roles.getRolesForUserAsync(users.eve, { + anyScope: true, + fullObjects: true, + }); + sameDeepMembers( + test, + usersRoles5.map((obj) => { + delete obj._id; + return obj; + }), + [ + { + role: { _id: "user" }, + scope: null, + user: { _id: users.eve }, + inheritedRoles: [ + { _id: "user" }, + { _id: "ALL_PERMISSIONS" }, + { _id: "EDIT_PERMISSION" }, + { _id: "VIEW_PERMISSION" }, + { _id: "MODERATE_PERMISSION" }, + { _id: "DELETE_PERMISSION" }, + ], + }, + { + role: { _id: "ALL_PERMISSIONS" }, + scope: "scope", + user: { _id: users.eve }, + inheritedRoles: [ + { _id: "ALL_PERMISSIONS" }, + { _id: "EDIT_PERMISSION" }, + { _id: "VIEW_PERMISSION" }, + { _id: "MODERATE_PERMISSION" }, + { _id: "DELETE_PERMISSION" }, + ], + }, ] - }, { - role: { _id: 'ALL_PERMISSIONS' }, - scope: 'scope', - user: { _id: users.eve }, - inheritedRoles: [ - { _id: 'ALL_PERMISSIONS' }, - { _id: 'EDIT_PERMISSION' }, - { _id: 'VIEW_PERMISSION' } + ); + + await await Roles.deleteRoleAsync("ALL_PERMISSIONS"); + + test.isFalse(await Roles.userIsInRoleAsync(users.eve, "DELETE_PERMISSION")); + test.isFalse( + await Roles.userIsInRoleAsync(users.eve, "DELETE_PERMISSION", "scope") + ); + + test.isFalse( + await Roles.userIsInRoleAsync(users.eve, "MODERATE_PERMISSION") + ); + test.isFalse( + await Roles.userIsInRoleAsync(users.eve, "MODERATE_PERMISSION", "scope") + ); + + const usersRoles6 = await Roles.getRolesForUserAsync(users.eve, { + anyScope: true, + fullObjects: true, + }); + sameDeepMembers( + test, + usersRoles6.map((obj) => { + delete obj._id; + return obj; + }), + [ + { + role: { _id: "user" }, + scope: null, + user: { _id: users.eve }, + inheritedRoles: [{ _id: "user" }], + }, ] - }]) + ); + } +); - await Roles.createRoleAsync('MODERATE_PERMISSION') +Tinytest.addAsync( + "roles -delete role with overlapping hierarchical roles", + async function (test) { + await clearData(); + await Roles.createRoleAsync("role1"); + await Roles.createRoleAsync("role2"); + await Roles.createRoleAsync("COMMON_PERMISSION_1"); + await Roles.createRoleAsync("COMMON_PERMISSION_2"); + await Roles.createRoleAsync("COMMON_PERMISSION_3"); + await Roles.createRoleAsync("EXTRA_PERMISSION_ROLE_1"); + await Roles.createRoleAsync("EXTRA_PERMISSION_ROLE_2"); - await Roles.addRolesToParentAsync('MODERATE_PERMISSION', 'ALL_PERMISSIONS') + await Roles.addRolesToParentAsync("COMMON_PERMISSION_1", "role1"); + await Roles.addRolesToParentAsync("COMMON_PERMISSION_2", "role1"); + await Roles.addRolesToParentAsync("COMMON_PERMISSION_3", "role1"); + await Roles.addRolesToParentAsync("EXTRA_PERMISSION_ROLE_1", "role1"); - assert.isTrue(await Roles.userIsInRoleAsync(users.eve, 'MODERATE_PERMISSION')) - assert.isTrue(await Roles.userIsInRoleAsync(users.eve, 'MODERATE_PERMISSION', 'scope')) + await Roles.addRolesToParentAsync("COMMON_PERMISSION_1", "role2"); + await Roles.addRolesToParentAsync("COMMON_PERMISSION_2", "role2"); + await Roles.addRolesToParentAsync("COMMON_PERMISSION_3", "role2"); + await Roles.addRolesToParentAsync("EXTRA_PERMISSION_ROLE_2", "role2"); - const usersRoles2 = await Roles.getRolesForUserAsync(users.eve, { anyScope: true, fullObjects: true }) - assert.sameDeepMembers(usersRoles2.map(obj => { delete obj._id; return obj }), [{ - role: { _id: 'user' }, - scope: null, - user: { _id: users.eve }, - inheritedRoles: [ - { _id: 'user' }, - { _id: 'ALL_PERMISSIONS' }, - { _id: 'EDIT_PERMISSION' }, - { _id: 'VIEW_PERMISSION' }, - { _id: 'MODERATE_PERMISSION' } + await Roles.addUsersToRolesAsync(users.eve, "role1"); + await Roles.addUsersToRolesAsync(users.eve, "role2"); + + test.isTrue( + await Roles.userIsInRoleAsync(users.eve, "COMMON_PERMISSION_1") + ); + test.isTrue( + await Roles.userIsInRoleAsync(users.eve, "EXTRA_PERMISSION_ROLE_1") + ); + test.isTrue( + await Roles.userIsInRoleAsync(users.eve, "EXTRA_PERMISSION_ROLE_2") + ); + + const usersRoles = await Roles.getRolesForUserAsync(users.eve, { + anyScope: true, + fullObjects: true, + }); + sameDeepMembers( + test, + usersRoles.map((obj) => { + delete obj._id; + return obj; + }), + [ + { + role: { _id: "role1" }, + scope: null, + user: { _id: users.eve }, + inheritedRoles: [ + { _id: "role1" }, + { _id: "COMMON_PERMISSION_1" }, + { _id: "COMMON_PERMISSION_2" }, + { _id: "COMMON_PERMISSION_3" }, + { _id: "EXTRA_PERMISSION_ROLE_1" }, + ], + }, + { + role: { _id: "role2" }, + scope: null, + user: { _id: users.eve }, + inheritedRoles: [ + { _id: "role2" }, + { _id: "COMMON_PERMISSION_1" }, + { _id: "COMMON_PERMISSION_2" }, + { _id: "COMMON_PERMISSION_3" }, + { _id: "EXTRA_PERMISSION_ROLE_2" }, + ], + }, ] - }, { - role: { _id: 'ALL_PERMISSIONS' }, - scope: 'scope', - user: { _id: users.eve }, - inheritedRoles: [ - { _id: 'ALL_PERMISSIONS' }, - { _id: 'EDIT_PERMISSION' }, - { _id: 'VIEW_PERMISSION' }, - { _id: 'MODERATE_PERMISSION' } + ); + + await Roles.removeUsersFromRolesAsync(users.eve, "role2"); + + test.isTrue( + await Roles.userIsInRoleAsync(users.eve, "COMMON_PERMISSION_1") + ); + test.isTrue( + await Roles.userIsInRoleAsync(users.eve, "EXTRA_PERMISSION_ROLE_1") + ); + test.isFalse( + await Roles.userIsInRoleAsync(users.eve, "EXTRA_PERMISSION_ROLE_2") + ); + + const usersRoles2 = await Roles.getRolesForUserAsync(users.eve, { + anyScope: true, + fullObjects: true, + }); + sameDeepMembers( + test, + usersRoles2.map((obj) => { + delete obj._id; + return obj; + }), + [ + { + role: { _id: "role1" }, + scope: null, + user: { _id: users.eve }, + inheritedRoles: [ + { _id: "role1" }, + { _id: "COMMON_PERMISSION_1" }, + { _id: "COMMON_PERMISSION_2" }, + { _id: "COMMON_PERMISSION_3" }, + { _id: "EXTRA_PERMISSION_ROLE_1" }, + ], + }, ] - }]) + ); - await Roles.addUsersToRolesAsync(users.eve, ['admin']) + await Roles.addUsersToRolesAsync(users.eve, "role2"); - assert.isTrue(await Roles.userIsInRoleAsync(users.eve, 'DELETE_PERMISSION')) - assert.isTrue(await Roles.userIsInRoleAsync(users.eve, 'DELETE_PERMISSION', 'scope')) + test.isTrue( + await Roles.userIsInRoleAsync(users.eve, "COMMON_PERMISSION_1") + ); + test.isTrue( + await Roles.userIsInRoleAsync(users.eve, "EXTRA_PERMISSION_ROLE_1") + ); + test.isTrue( + await Roles.userIsInRoleAsync(users.eve, "EXTRA_PERMISSION_ROLE_2") + ); - const usersRoles3 = await Roles.getRolesForUserAsync(users.eve, { anyScope: true, fullObjects: true }) - assert.sameDeepMembers(usersRoles3.map(obj => { delete obj._id; return obj }), [{ - role: { _id: 'user' }, - scope: null, - user: { _id: users.eve }, - inheritedRoles: [ - { _id: 'user' }, - { _id: 'ALL_PERMISSIONS' }, - { _id: 'EDIT_PERMISSION' }, - { _id: 'VIEW_PERMISSION' }, - { _id: 'MODERATE_PERMISSION' } + const usersRoles3 = await Roles.getRolesForUserAsync(users.eve, { + anyScope: true, + fullObjects: true, + }); + sameDeepMembers( + test, + usersRoles3.map((obj) => { + delete obj._id; + return obj; + }), + [ + { + role: { _id: "role1" }, + scope: null, + user: { _id: users.eve }, + inheritedRoles: [ + { _id: "role1" }, + { _id: "COMMON_PERMISSION_1" }, + { _id: "COMMON_PERMISSION_2" }, + { _id: "COMMON_PERMISSION_3" }, + { _id: "EXTRA_PERMISSION_ROLE_1" }, + ], + }, + { + role: { _id: "role2" }, + scope: null, + user: { _id: users.eve }, + inheritedRoles: [ + { _id: "role2" }, + { _id: "COMMON_PERMISSION_1" }, + { _id: "COMMON_PERMISSION_2" }, + { _id: "COMMON_PERMISSION_3" }, + { _id: "EXTRA_PERMISSION_ROLE_2" }, + ], + }, ] - }, { - role: { _id: 'ALL_PERMISSIONS' }, - scope: 'scope', - user: { _id: users.eve }, - inheritedRoles: [ - { _id: 'ALL_PERMISSIONS' }, - { _id: 'EDIT_PERMISSION' }, - { _id: 'VIEW_PERMISSION' }, - { _id: 'MODERATE_PERMISSION' } + ); + + await Roles.deleteRoleAsync("role2"); + + test.isTrue( + await Roles.userIsInRoleAsync(users.eve, "COMMON_PERMISSION_1") + ); + test.isTrue( + await Roles.userIsInRoleAsync(users.eve, "EXTRA_PERMISSION_ROLE_1") + ); + test.isFalse( + await Roles.userIsInRoleAsync(users.eve, "EXTRA_PERMISSION_ROLE_2") + ); + + const usersRoles4 = await Roles.getRolesForUserAsync(users.eve, { + anyScope: true, + fullObjects: true, + }); + sameDeepMembers( + test, + usersRoles4.map((obj) => { + delete obj._id; + return obj; + }), + [ + { + role: { _id: "role1" }, + scope: null, + user: { _id: users.eve }, + inheritedRoles: [ + { _id: "role1" }, + { _id: "COMMON_PERMISSION_1" }, + { _id: "COMMON_PERMISSION_2" }, + { _id: "COMMON_PERMISSION_3" }, + { _id: "EXTRA_PERMISSION_ROLE_1" }, + ], + }, ] - }, { - role: { _id: 'admin' }, - scope: null, - user: { _id: users.eve }, - inheritedRoles: [ - { _id: 'admin' }, - { _id: 'DELETE_PERMISSION' } + ); + } +); + +Tinytest.addAsync("roles -set parent on assigned role", async function (test) { + await clearData(); + await Roles.createRoleAsync("admin"); + await Roles.createRoleAsync("EDIT_PERMISSION"); + + await Roles.addUsersToRolesAsync(users.eve, "EDIT_PERMISSION"); + + test.isTrue(await Roles.userIsInRoleAsync(users.eve, "EDIT_PERMISSION")); + test.isFalse(await Roles.userIsInRoleAsync(users.eve, "admin")); + + const usersRoles = await Roles.getRolesForUserAsync(users.eve, { + anyScope: true, + fullObjects: true, + }); + sameDeepMembers( + test, + usersRoles.map((obj) => { + delete obj._id; + return obj; + }), + [ + { + role: { _id: "EDIT_PERMISSION" }, + scope: null, + user: { _id: users.eve }, + inheritedRoles: [{ _id: "EDIT_PERMISSION" }], + }, + ] + ); + + await Roles.addRolesToParentAsync("EDIT_PERMISSION", "admin"); + + test.isTrue(await Roles.userIsInRoleAsync(users.eve, "EDIT_PERMISSION")); + test.isFalse(await Roles.userIsInRoleAsync(users.eve, "admin")); + + const usersRoles2 = await Roles.getRolesForUserAsync(users.eve, { + anyScope: true, + fullObjects: true, + }); + sameDeepMembers( + test, + usersRoles2.map((obj) => { + delete obj._id; + return obj; + }), + [ + { + role: { _id: "EDIT_PERMISSION" }, + scope: null, + user: { _id: users.eve }, + inheritedRoles: [{ _id: "EDIT_PERMISSION" }], + }, + ] + ); +}); + +Tinytest.addAsync( + "roles -remove parent on assigned role", + async function (test) { + await clearData(); + await Roles.createRoleAsync("admin"); + await Roles.createRoleAsync("EDIT_PERMISSION"); + + await Roles.addRolesToParentAsync("EDIT_PERMISSION", "admin"); + + await Roles.addUsersToRolesAsync(users.eve, "EDIT_PERMISSION"); + + test.isTrue(await Roles.userIsInRoleAsync(users.eve, "EDIT_PERMISSION")); + test.isFalse(await Roles.userIsInRoleAsync(users.eve, "admin")); + + const usersRoles = await Roles.getRolesForUserAsync(users.eve, { + anyScope: true, + fullObjects: true, + }); + sameDeepMembers( + test, + usersRoles.map((obj) => { + delete obj._id; + return obj; + }), + [ + { + role: { _id: "EDIT_PERMISSION" }, + scope: null, + user: { _id: users.eve }, + inheritedRoles: [{ _id: "EDIT_PERMISSION" }], + }, ] - }]) + ); - await Roles.addRolesToParentAsync('DELETE_PERMISSION', 'ALL_PERMISSIONS') + await Roles.removeRolesFromParentAsync("EDIT_PERMISSION", "admin"); - assert.isTrue(await Roles.userIsInRoleAsync(users.eve, 'DELETE_PERMISSION')) - assert.isTrue(await Roles.userIsInRoleAsync(users.eve, 'DELETE_PERMISSION', 'scope')) + test.isTrue(await Roles.userIsInRoleAsync(users.eve, "EDIT_PERMISSION")); + test.isFalse(await Roles.userIsInRoleAsync(users.eve, "admin")); - const usersRoles4 = await Roles.getRolesForUserAsync(users.eve, { anyScope: true, fullObjects: true }) - assert.sameDeepMembers(usersRoles4.map(obj => { delete obj._id; return obj }), [{ - role: { _id: 'user' }, - scope: null, - user: { _id: users.eve }, - inheritedRoles: [ - { _id: 'user' }, - { _id: 'ALL_PERMISSIONS' }, - { _id: 'EDIT_PERMISSION' }, - { _id: 'VIEW_PERMISSION' }, - { _id: 'MODERATE_PERMISSION' }, - { _id: 'DELETE_PERMISSION' } + const usersRoles2 = await Roles.getRolesForUserAsync(users.eve, { + anyScope: true, + fullObjects: true, + }); + sameDeepMembers( + test, + usersRoles2.map((obj) => { + delete obj._id; + return obj; + }), + [ + { + role: { _id: "EDIT_PERMISSION" }, + scope: null, + user: { _id: users.eve }, + inheritedRoles: [{ _id: "EDIT_PERMISSION" }], + }, ] - }, { - role: { _id: 'ALL_PERMISSIONS' }, - scope: 'scope', - user: { _id: users.eve }, - inheritedRoles: [ - { _id: 'ALL_PERMISSIONS' }, - { _id: 'EDIT_PERMISSION' }, - { _id: 'VIEW_PERMISSION' }, - { _id: 'MODERATE_PERMISSION' }, - { _id: 'DELETE_PERMISSION' } + ); + } +); + +Tinytest.addAsync( + "roles -adding and removing extra role parents", + async function (test) { + await clearData(); + await Roles.createRoleAsync("admin"); + await Roles.createRoleAsync("user"); + await Roles.createRoleAsync("EDIT_PERMISSION"); + + await Roles.addRolesToParentAsync("EDIT_PERMISSION", "admin"); + + await Roles.addUsersToRolesAsync(users.eve, "EDIT_PERMISSION"); + + test.isTrue(await Roles.userIsInRoleAsync(users.eve, "EDIT_PERMISSION")); + test.isFalse(await Roles.userIsInRoleAsync(users.eve, "admin")); + + const usersRoles = await Roles.getRolesForUserAsync(users.eve, { + anyScope: true, + fullObjects: true, + }); + sameDeepMembers( + test, + usersRoles.map((obj) => { + delete obj._id; + return obj; + }), + [ + { + role: { _id: "EDIT_PERMISSION" }, + scope: null, + user: { _id: users.eve }, + inheritedRoles: [{ _id: "EDIT_PERMISSION" }], + }, ] - }, { - role: { _id: 'admin' }, - scope: null, - user: { _id: users.eve }, - inheritedRoles: [ - { _id: 'admin' }, - { _id: 'DELETE_PERMISSION' } + ); + + await Roles.addRolesToParentAsync("EDIT_PERMISSION", "user"); + + test.isTrue(await Roles.userIsInRoleAsync(users.eve, "EDIT_PERMISSION")); + test.isFalse(await Roles.userIsInRoleAsync(users.eve, "admin")); + + const usersRoles2 = await Roles.getRolesForUserAsync(users.eve, { + anyScope: true, + fullObjects: true, + }); + sameDeepMembers( + test, + usersRoles2.map((obj) => { + delete obj._id; + return obj; + }), + [ + { + role: { _id: "EDIT_PERMISSION" }, + scope: null, + user: { _id: users.eve }, + inheritedRoles: [{ _id: "EDIT_PERMISSION" }], + }, ] - }]) + ); - await Roles.removeUsersFromRolesAsync(users.eve, ['admin']) + await Roles.removeRolesFromParentAsync("EDIT_PERMISSION", "user"); - assert.isTrue(await Roles.userIsInRoleAsync(users.eve, 'DELETE_PERMISSION')) - assert.isTrue(await Roles.userIsInRoleAsync(users.eve, 'DELETE_PERMISSION', 'scope')) + test.isTrue(await Roles.userIsInRoleAsync(users.eve, "EDIT_PERMISSION")); + test.isFalse(await Roles.userIsInRoleAsync(users.eve, "admin")); - const usersRoles5 = await Roles.getRolesForUserAsync(users.eve, { anyScope: true, fullObjects: true }) - assert.sameDeepMembers(usersRoles5.map(obj => { delete obj._id; return obj }), [{ - role: { _id: 'user' }, - scope: null, - user: { _id: users.eve }, - inheritedRoles: [ - { _id: 'user' }, - { _id: 'ALL_PERMISSIONS' }, - { _id: 'EDIT_PERMISSION' }, - { _id: 'VIEW_PERMISSION' }, - { _id: 'MODERATE_PERMISSION' }, - { _id: 'DELETE_PERMISSION' } + const usersRoles3 = await Roles.getRolesForUserAsync(users.eve, { + anyScope: true, + fullObjects: true, + }); + sameDeepMembers( + test, + usersRoles3.map((obj) => { + delete obj._id; + return obj; + }), + [ + { + role: { _id: "EDIT_PERMISSION" }, + scope: null, + user: { _id: users.eve }, + inheritedRoles: [{ _id: "EDIT_PERMISSION" }], + }, ] - }, { - role: { _id: 'ALL_PERMISSIONS' }, - scope: 'scope', - user: { _id: users.eve }, - inheritedRoles: [ - { _id: 'ALL_PERMISSIONS' }, - { _id: 'EDIT_PERMISSION' }, - { _id: 'VIEW_PERMISSION' }, - { _id: 'MODERATE_PERMISSION' }, - { _id: 'DELETE_PERMISSION' } - ] - }]) + ); + } +); - await await Roles.deleteRoleAsync('ALL_PERMISSIONS') +Tinytest.addAsync("roles -cyclic roles", async function (test) { + await clearData(); + await Roles.createRoleAsync("admin"); + await Roles.createRoleAsync("editor"); + await Roles.createRoleAsync("user"); - assert.isFalse(await Roles.userIsInRoleAsync(users.eve, 'DELETE_PERMISSION')) - assert.isFalse(await Roles.userIsInRoleAsync(users.eve, 'DELETE_PERMISSION', 'scope')) + await Roles.addRolesToParentAsync("editor", "admin"); + await Roles.addRolesToParentAsync("user", "editor"); - assert.isFalse(await Roles.userIsInRoleAsync(users.eve, 'MODERATE_PERMISSION')) - assert.isFalse(await Roles.userIsInRoleAsync(users.eve, 'MODERATE_PERMISSION', 'scope')) + try { + await Roles.addRolesToParentAsync("admin", "user"); + test.fail("Should throw cycle error"); + } catch (e) { + test.matches(e.message, /form a cycle/); + } +}); - const usersRoles6 = await Roles.getRolesForUserAsync(users.eve, { anyScope: true, fullObjects: true }) - assert.sameDeepMembers(usersRoles6.map(obj => { delete obj._id; return obj }), [{ - role: { _id: 'user' }, - scope: null, - user: { _id: users.eve }, - inheritedRoles: [ - { _id: 'user' } - ] - }]) - }) +Tinytest.addAsync( + "roles -userIsInRole returns false for unknown roles", + async function (test) { + await clearData(); + await Roles.createRoleAsync("admin"); + await Roles.createRoleAsync("user"); + await Roles.createRoleAsync("editor"); + await Roles.addUsersToRolesAsync(users.eve, ["admin", "user"]); + await Roles.addUsersToRolesAsync(users.eve, ["editor"]); - it('delete role with overlapping hierarchical roles', async function () { - await Roles.createRoleAsync('role1') - await Roles.createRoleAsync('role2') - await Roles.createRoleAsync('COMMON_PERMISSION_1') - await Roles.createRoleAsync('COMMON_PERMISSION_2') - await Roles.createRoleAsync('COMMON_PERMISSION_3') - await Roles.createRoleAsync('EXTRA_PERMISSION_ROLE_1') - await Roles.createRoleAsync('EXTRA_PERMISSION_ROLE_2') + test.isFalse(await Roles.userIsInRoleAsync(users.eve, "unknown")); + test.isFalse(await Roles.userIsInRoleAsync(users.eve, [])); + test.isFalse(await Roles.userIsInRoleAsync(users.eve, null)); + test.isFalse(await Roles.userIsInRoleAsync(users.eve, undefined)); - await Roles.addRolesToParentAsync('COMMON_PERMISSION_1', 'role1') - await Roles.addRolesToParentAsync('COMMON_PERMISSION_2', 'role1') - await Roles.addRolesToParentAsync('COMMON_PERMISSION_3', 'role1') - await Roles.addRolesToParentAsync('EXTRA_PERMISSION_ROLE_1', 'role1') + test.isFalse( + await Roles.userIsInRoleAsync(users.eve, "unknown", { anyScope: true }) + ); + test.isFalse( + await Roles.userIsInRoleAsync(users.eve, [], { anyScope: true }) + ); + test.isFalse( + await Roles.userIsInRoleAsync(users.eve, null, { anyScope: true }) + ); + test.isFalse( + await Roles.userIsInRoleAsync(users.eve, undefined, { anyScope: true }) + ); - await Roles.addRolesToParentAsync('COMMON_PERMISSION_1', 'role2') - await Roles.addRolesToParentAsync('COMMON_PERMISSION_2', 'role2') - await Roles.addRolesToParentAsync('COMMON_PERMISSION_3', 'role2') - await Roles.addRolesToParentAsync('EXTRA_PERMISSION_ROLE_2', 'role2') + test.isFalse( + await Roles.userIsInRoleAsync( + users.eve, + ["Role1", "Role2", undefined], + "GroupName" + ) + ); + } +); - await Roles.addUsersToRolesAsync(users.eve, 'role1') - await Roles.addUsersToRolesAsync(users.eve, 'role2') +Tinytest.addAsync( + "roles -userIsInRole returns false if user is a function", + async function (test) { + await clearData(); + await Roles.createRoleAsync("admin"); + await Roles.addUsersToRolesAsync(users.eve, ["admin"]); - assert.isTrue(await Roles.userIsInRoleAsync(users.eve, 'COMMON_PERMISSION_1')) - assert.isTrue(await Roles.userIsInRoleAsync(users.eve, 'EXTRA_PERMISSION_ROLE_1')) - assert.isTrue(await Roles.userIsInRoleAsync(users.eve, 'EXTRA_PERMISSION_ROLE_2')) + test.isFalse(await Roles.userIsInRoleAsync(() => {}, "admin")); + } +); - const usersRoles = await Roles.getRolesForUserAsync(users.eve, { anyScope: true, fullObjects: true }) - assert.sameDeepMembers(usersRoles.map(obj => { delete obj._id; return obj }), [{ - role: { _id: 'role1' }, - scope: null, - user: { _id: users.eve }, - inheritedRoles: [ - { _id: 'role1' }, - { _id: 'COMMON_PERMISSION_1' }, - { _id: 'COMMON_PERMISSION_2' }, - { _id: 'COMMON_PERMISSION_3' }, - { _id: 'EXTRA_PERMISSION_ROLE_1' } - ] - }, { - role: { _id: 'role2' }, - scope: null, - user: { _id: users.eve }, - inheritedRoles: [ - { _id: 'role2' }, - { _id: 'COMMON_PERMISSION_1' }, - { _id: 'COMMON_PERMISSION_2' }, - { _id: 'COMMON_PERMISSION_3' }, - { _id: 'EXTRA_PERMISSION_ROLE_2' } - ] - }]) +Tinytest.addAsync( + "roles -returns false for unknown roles", + async function (test) { + await clearData(); + await Roles.createRoleAsync("admin"); - await Roles.removeUsersFromRolesAsync(users.eve, 'role2') + test.isFalse(await Roles.isParentOfAsync("admin", "unknown")); + test.isFalse(await Roles.isParentOfAsync("admin", null)); + test.isFalse(await Roles.isParentOfAsync("admin", undefined)); - assert.isTrue(await Roles.userIsInRoleAsync(users.eve, 'COMMON_PERMISSION_1')) - assert.isTrue(await Roles.userIsInRoleAsync(users.eve, 'EXTRA_PERMISSION_ROLE_1')) - assert.isFalse(await Roles.userIsInRoleAsync(users.eve, 'EXTRA_PERMISSION_ROLE_2')) + test.isFalse(await Roles.isParentOfAsync("unknown", "admin")); + test.isFalse(await Roles.isParentOfAsync(null, "admin")); + test.isFalse(await Roles.isParentOfAsync(undefined, "admin")); + } +); - const usersRoles2 = await Roles.getRolesForUserAsync(users.eve, { anyScope: true, fullObjects: true }) - assert.sameDeepMembers(usersRoles2.map(obj => { delete obj._id; return obj }), [{ - role: { _id: 'role1' }, - scope: null, - user: { _id: users.eve }, - inheritedRoles: [ - { _id: 'role1' }, - { _id: 'COMMON_PERMISSION_1' }, - { _id: 'COMMON_PERMISSION_2' }, - { _id: 'COMMON_PERMISSION_3' }, - { _id: 'EXTRA_PERMISSION_ROLE_1' } - ] - }]) +Tinytest.addAsync( + "roles -returns false if role is not parent of", + async function (test) { + await clearData(); + await Roles.createRoleAsync("admin"); + await Roles.createRoleAsync("editor"); + await Roles.createRoleAsync("user"); + await Roles.addRolesToParentAsync(["editor"], "admin"); + await Roles.addRolesToParentAsync(["user"], "editor"); - await Roles.addUsersToRolesAsync(users.eve, 'role2') + test.isFalse(await Roles.isParentOfAsync("user", "admin")); + test.isFalse(await Roles.isParentOfAsync("editor", "admin")); + } +); - assert.isTrue(await Roles.userIsInRoleAsync(users.eve, 'COMMON_PERMISSION_1')) - assert.isTrue(await Roles.userIsInRoleAsync(users.eve, 'EXTRA_PERMISSION_ROLE_1')) - assert.isTrue(await Roles.userIsInRoleAsync(users.eve, 'EXTRA_PERMISSION_ROLE_2')) +Tinytest.addAsync( + "roles -returns true if role is parent of the demanded role", + async function (test) { + await clearData(); + await Roles.createRoleAsync("admin"); + await Roles.createRoleAsync("editor"); + await Roles.createRoleAsync("user"); + await Roles.addRolesToParentAsync(["editor"], "admin"); + await Roles.addRolesToParentAsync(["user"], "editor"); - const usersRoles3 = await Roles.getRolesForUserAsync(users.eve, { anyScope: true, fullObjects: true }) - assert.sameDeepMembers(usersRoles3.map(obj => { delete obj._id; return obj }), [{ - role: { _id: 'role1' }, - scope: null, - user: { _id: users.eve }, - inheritedRoles: [ - { _id: 'role1' }, - { _id: 'COMMON_PERMISSION_1' }, - { _id: 'COMMON_PERMISSION_2' }, - { _id: 'COMMON_PERMISSION_3' }, - { _id: 'EXTRA_PERMISSION_ROLE_1' } - ] - }, { - role: { _id: 'role2' }, - scope: null, - user: { _id: users.eve }, - inheritedRoles: [ - { _id: 'role2' }, - { _id: 'COMMON_PERMISSION_1' }, - { _id: 'COMMON_PERMISSION_2' }, - { _id: 'COMMON_PERMISSION_3' }, - { _id: 'EXTRA_PERMISSION_ROLE_2' } - ] - }]) + test.isTrue(await Roles.isParentOfAsync("admin", "user")); + test.isTrue(await Roles.isParentOfAsync("editor", "user")); + test.isTrue(await Roles.isParentOfAsync("admin", "editor")); - await Roles.deleteRoleAsync('role2') + test.isTrue(await Roles.isParentOfAsync("admin", "admin")); + test.isTrue(await Roles.isParentOfAsync("editor", "editor")); + test.isTrue(await Roles.isParentOfAsync("user", "user")); + } +); - assert.isTrue(await Roles.userIsInRoleAsync(users.eve, 'COMMON_PERMISSION_1')) - assert.isTrue(await Roles.userIsInRoleAsync(users.eve, 'EXTRA_PERMISSION_ROLE_1')) - assert.isFalse(await Roles.userIsInRoleAsync(users.eve, 'EXTRA_PERMISSION_ROLE_2')) +// here - const usersRoles4 = await Roles.getRolesForUserAsync(users.eve, { anyScope: true, fullObjects: true }) - assert.sameDeepMembers(usersRoles4.map(obj => { delete obj._id; return obj }), [{ - role: { _id: 'role1' }, - scope: null, - user: { _id: users.eve }, - inheritedRoles: [ - { _id: 'role1' }, - { _id: 'COMMON_PERMISSION_1' }, - { _id: 'COMMON_PERMISSION_2' }, - { _id: 'COMMON_PERMISSION_3' }, - { _id: 'EXTRA_PERMISSION_ROLE_1' } - ] - }]) - }) +Tinytest.addAsync( + "should not return null entries if user has no roles for scope", + async function (test) { + await clearData(); + await Roles.createRoleAsync("editor"); - it('set parent on assigned role', async function () { - await Roles.createRoleAsync('admin') - await Roles.createRoleAsync('EDIT_PERMISSION') + const userId = users.eve; + let userObj; - await Roles.addUsersToRolesAsync(users.eve, 'EDIT_PERMISSION') + // by userId + sameMembers(test,await Roles.getRolesForUserAsync(userId, "scope1"), []); + sameMembers(test,await Roles.getRolesForUserAsync(userId), []); - assert.isTrue(await Roles.userIsInRoleAsync(users.eve, 'EDIT_PERMISSION')) - assert.isFalse(await Roles.userIsInRoleAsync(users.eve, 'admin')) + // by user object + userObj = await Meteor.users.findOneAsync({ _id: userId }); + sameMembers(test,await Roles.getRolesForUserAsync(userObj, "scope1"), []); + sameMembers(test,await Roles.getRolesForUserAsync(userObj), []); - const usersRoles = await Roles.getRolesForUserAsync(users.eve, { anyScope: true, fullObjects: true }) - assert.sameDeepMembers(usersRoles.map(obj => { delete obj._id; return obj }), [{ - role: { _id: 'EDIT_PERMISSION' }, - scope: null, - user: { _id: users.eve }, - inheritedRoles: [{ _id: 'EDIT_PERMISSION' }] - }]) + await Roles.addUsersToRolesAsync( + [users.eve], + ["editor"], + Roles.GLOBAL_SCOPE + ); - await Roles.addRolesToParentAsync('EDIT_PERMISSION', 'admin') + // by userId + sameMembers(test,await Roles.getRolesForUserAsync(userId, "scope1"), [ + "editor", + ]); + sameMembers(test,await Roles.getRolesForUserAsync(userId), ["editor"]); - assert.isTrue(await Roles.userIsInRoleAsync(users.eve, 'EDIT_PERMISSION')) - assert.isFalse(await Roles.userIsInRoleAsync(users.eve, 'admin')) + // by user object + userObj = await Meteor.users.findOneAsync({ _id: userId }); + sameMembers(test,await Roles.getRolesForUserAsync(userObj, "scope1"), [ + "editor", + ]); + sameMembers(test,await Roles.getRolesForUserAsync(userObj), ["editor"]); + } +); - const usersRoles2 = await Roles.getRolesForUserAsync(users.eve, { anyScope: true, fullObjects: true }) - assert.sameDeepMembers(usersRoles2.map(obj => { delete obj._id; return obj }), [{ - role: { _id: 'EDIT_PERMISSION' }, - scope: null, - user: { _id: users.eve }, - inheritedRoles: [{ _id: 'EDIT_PERMISSION' }] - }]) - }) +Tinytest.addAsync( + "should not fail during a call of addUsersToRoles", + async function (test) { + await clearData(); + await Roles.createRoleAsync("editor"); - it('remove parent on assigned role', async function () { - await Roles.createRoleAsync('admin') - await Roles.createRoleAsync('EDIT_PERMISSION') + const userId = users.eve; + const promises = []; + const interval = setInterval(() => { + promises.push( + Promise.resolve().then(async () => { + await Roles.getRolesForUserAsync(userId); + }) + ); + }, 0); - await Roles.addRolesToParentAsync('EDIT_PERMISSION', 'admin') + await Roles.addUsersToRolesAsync( + [users.eve], + ["editor"], + Roles.GLOBAL_SCOPE + ); + clearInterval(interval); - await Roles.addUsersToRolesAsync(users.eve, 'EDIT_PERMISSION') + return Promise.all(promises); + } +); - assert.isTrue(await Roles.userIsInRoleAsync(users.eve, 'EDIT_PERMISSION')) - assert.isFalse(await Roles.userIsInRoleAsync(users.eve, 'admin')) +Tinytest.addAsync( + "returns an empty list of scopes for null as user-id", + async function (test) { + await clearData(); + sameMembers(test,await Roles.getScopesForUserAsync(undefined), []); + sameMembers(test,await Roles.getScopesForUserAsync(null), []); + sameMembers(test,await Roles.getScopesForUserAsync("foo"), []); + sameMembers(test,await Roles.getScopesForUserAsync({}), []); + sameMembers(test,await Roles.getScopesForUserAsync({ _id: "foo" }), []); + } +); - const usersRoles = await Roles.getRolesForUserAsync(users.eve, { anyScope: true, fullObjects: true }) - assert.sameDeepMembers(usersRoles.map(obj => { delete obj._id; return obj }), [{ - role: { _id: 'EDIT_PERMISSION' }, - scope: null, - user: { _id: users.eve }, - inheritedRoles: [{ _id: 'EDIT_PERMISSION' }] - }]) +Tinytest.addAsync("can get all scopes for user", async function (test) { + await clearData(); + await Roles.createRoleAsync("admin"); + await Roles.createRoleAsync("user"); + await Roles.createRoleAsync("editor"); - await Roles.removeRolesFromParentAsync('EDIT_PERMISSION', 'admin') + const userId = users.eve; - assert.isTrue(await Roles.userIsInRoleAsync(users.eve, 'EDIT_PERMISSION')) - assert.isFalse(await Roles.userIsInRoleAsync(users.eve, 'admin')) + await Roles.addUsersToRolesAsync([users.eve], ["editor"], "scope1"); + await Roles.addUsersToRolesAsync([users.eve], ["admin", "user"], "scope2"); - const usersRoles2 = await Roles.getRolesForUserAsync(users.eve, { anyScope: true, fullObjects: true }) - assert.sameDeepMembers(usersRoles2.map(obj => { delete obj._id; return obj }), [{ - role: { _id: 'EDIT_PERMISSION' }, - scope: null, - user: { _id: users.eve }, - inheritedRoles: [{ _id: 'EDIT_PERMISSION' }] - }]) - }) + // by userId + sameMembers(test,await Roles.getScopesForUserAsync(userId), [ + "scope1", + "scope2", + ]); - it('adding and removing extra role parents', async function () { - await Roles.createRoleAsync('admin') - await Roles.createRoleAsync('user') - await Roles.createRoleAsync('EDIT_PERMISSION') + // by user object + const userObj = await Meteor.users.findOneAsync({ _id: userId }); + sameMembers(test,await Roles.getScopesForUserAsync(userObj), [ + "scope1", + "scope2", + ]); +}); - await Roles.addRolesToParentAsync('EDIT_PERMISSION', 'admin') +Tinytest.addAsync("can get all scopes for user by role", async function (test) { + await clearData(); + await Roles.createRoleAsync("admin"); + await Roles.createRoleAsync("user"); + await Roles.createRoleAsync("editor"); - await Roles.addUsersToRolesAsync(users.eve, 'EDIT_PERMISSION') + const userId = users.eve; - assert.isTrue(await Roles.userIsInRoleAsync(users.eve, 'EDIT_PERMISSION')) - assert.isFalse(await Roles.userIsInRoleAsync(users.eve, 'admin')) + await Roles.addUsersToRolesAsync([users.eve], ["editor"], "scope1"); + await Roles.addUsersToRolesAsync([users.eve], ["editor", "user"], "scope2"); - const usersRoles = await Roles.getRolesForUserAsync(users.eve, { anyScope: true, fullObjects: true }) - assert.sameDeepMembers(usersRoles.map(obj => { delete obj._id; return obj }), [{ - role: { _id: 'EDIT_PERMISSION' }, - scope: null, - user: { _id: users.eve }, - inheritedRoles: [{ _id: 'EDIT_PERMISSION' }] - }]) + // by userId + sameMembers(test,await Roles.getScopesForUserAsync(userId, "user"), [ + "scope2", + ]); + sameMembers(test,await Roles.getScopesForUserAsync(userId, "editor"), [ + "scope1", + "scope2", + ]); + sameMembers(test,await Roles.getScopesForUserAsync(userId, "admin"), []); - await Roles.addRolesToParentAsync('EDIT_PERMISSION', 'user') + // by user object + const userObj = await Meteor.users.findOneAsync({ _id: userId }); + sameMembers(test,await Roles.getScopesForUserAsync(userObj, "user"), [ + "scope2", + ]); + sameMembers(test,await Roles.getScopesForUserAsync(userObj, "editor"), [ + "scope1", + "scope2", + ]); + sameMembers(test,await Roles.getScopesForUserAsync(userObj, "admin"), []); +}); - assert.isTrue(await Roles.userIsInRoleAsync(users.eve, 'EDIT_PERMISSION')) - assert.isFalse(await Roles.userIsInRoleAsync(users.eve, 'admin')) +Tinytest.addAsync( + "getScopesForUser returns [] when not using scopes", + async function (test) { + await clearData(); + await Roles.createRoleAsync("user"); + await Roles.createRoleAsync("editor"); - const usersRoles2 = await Roles.getRolesForUserAsync(users.eve, { anyScope: true, fullObjects: true }) - assert.sameDeepMembers(usersRoles2.map(obj => { delete obj._id; return obj }), [{ - role: { _id: 'EDIT_PERMISSION' }, - scope: null, - user: { _id: users.eve }, - inheritedRoles: [{ _id: 'EDIT_PERMISSION' }] - }]) + const userId = users.eve; - await Roles.removeRolesFromParentAsync('EDIT_PERMISSION', 'user') + await Roles.addUsersToRolesAsync([users.eve], ["editor", "user"]); - assert.isTrue(await Roles.userIsInRoleAsync(users.eve, 'EDIT_PERMISSION')) - assert.isFalse(await Roles.userIsInRoleAsync(users.eve, 'admin')) + // by userId + sameMembers(test,await Roles.getScopesForUserAsync(userId), []); + sameMembers(test,await Roles.getScopesForUserAsync(userId, "editor"), []); + sameMembers(test, + await Roles.getScopesForUserAsync(userId, ["editor"]), + [] + ); + sameMembers(test, + await Roles.getScopesForUserAsync(userId, ["editor", "user"]), + [] + ); - const usersRoles3 = await Roles.getRolesForUserAsync(users.eve, { anyScope: true, fullObjects: true }) - assert.sameDeepMembers(usersRoles3.map(obj => { delete obj._id; return obj }), [{ - role: { _id: 'EDIT_PERMISSION' }, - scope: null, - user: { _id: users.eve }, - inheritedRoles: [{ _id: 'EDIT_PERMISSION' }] - }]) - }) - - it('cyclic roles', async function () { - await Roles.createRoleAsync('admin') - await Roles.createRoleAsync('editor') - await Roles.createRoleAsync('user') - - await Roles.addRolesToParentAsync('editor', 'admin') - await Roles.addRolesToParentAsync('user', 'editor') - - await assert.isRejected(Roles.addRolesToParentAsync('admin', 'user'), /form a cycle/) - }) - - describe('userIsInRole', function () { - it('userIsInRole returns false for unknown roles', async function () { - await Roles.createRoleAsync('admin') - await Roles.createRoleAsync('user') - await Roles.createRoleAsync('editor') - await Roles.addUsersToRolesAsync(users.eve, ['admin', 'user']) - await Roles.addUsersToRolesAsync(users.eve, ['editor']) - - assert.isFalse(await Roles.userIsInRoleAsync(users.eve, 'unknown')) - assert.isFalse(await Roles.userIsInRoleAsync(users.eve, [])) - assert.isFalse(await Roles.userIsInRoleAsync(users.eve, null)) - assert.isFalse(await Roles.userIsInRoleAsync(users.eve, undefined)) - - assert.isFalse(await Roles.userIsInRoleAsync(users.eve, 'unknown', { anyScope: true })) - assert.isFalse(await Roles.userIsInRoleAsync(users.eve, [], { anyScope: true })) - assert.isFalse(await Roles.userIsInRoleAsync(users.eve, null, { anyScope: true })) - assert.isFalse(await Roles.userIsInRoleAsync(users.eve, undefined, { anyScope: true })) - - assert.isFalse(await Roles.userIsInRoleAsync(users.eve, ['Role1', 'Role2', undefined], 'GroupName')) - }) - - it('userIsInRole returns false if user is a function', async function () { - await Roles.createRoleAsync('admin') - await Roles.addUsersToRolesAsync(users.eve, ['admin']) - - assert.isFalse(await Roles.userIsInRoleAsync(() => {}, 'admin')) - }) - }) - - describe('isParentOf', function () { - it('returns false for unknown roles', async function () { - await Roles.createRoleAsync('admin') - - assert.isFalse(await Roles.isParentOfAsync('admin', 'unknown')) - assert.isFalse(await Roles.isParentOfAsync('admin', null)) - assert.isFalse(await Roles.isParentOfAsync('admin', undefined)) - - assert.isFalse(await Roles.isParentOfAsync('unknown', 'admin')) - assert.isFalse(await Roles.isParentOfAsync(null, 'admin')) - assert.isFalse(await Roles.isParentOfAsync(undefined, 'admin')) - }) - - it('returns false if role is not parent of', async function () { - await Roles.createRoleAsync('admin') - await Roles.createRoleAsync('editor') - await Roles.createRoleAsync('user') - await Roles.addRolesToParentAsync(['editor'], 'admin') - await Roles.addRolesToParentAsync(['user'], 'editor') - - assert.isFalse(await Roles.isParentOfAsync('user', 'admin')) - assert.isFalse(await Roles.isParentOfAsync('editor', 'admin')) - }) - - it('returns true if role is parent of the demanded role', async function () { - await Roles.createRoleAsync('admin') - await Roles.createRoleAsync('editor') - await Roles.createRoleAsync('user') - await Roles.addRolesToParentAsync(['editor'], 'admin') - await Roles.addRolesToParentAsync(['user'], 'editor') - - assert.isTrue(await Roles.isParentOfAsync('admin', 'user')) - assert.isTrue(await Roles.isParentOfAsync('editor', 'user')) - assert.isTrue(await Roles.isParentOfAsync('admin', 'editor')) - - assert.isTrue(await Roles.isParentOfAsync('admin', 'admin')) - assert.isTrue(await Roles.isParentOfAsync('editor', 'editor')) - assert.isTrue(await Roles.isParentOfAsync('user', 'user')) - }) - }) -}) + // by user object + const userObj = await Meteor.users.findOneAsync({ _id: userId }); + sameMembers(test,await Roles.getScopesForUserAsync(userObj), []); + sameMembers(test, + await Roles.getScopesForUserAsync(userObj, "editor"), + [] + ); + sameMembers(test, + await Roles.getScopesForUserAsync(userObj, ["editor"]), + [] + ); + sameMembers(test, + await Roles.getScopesForUserAsync(userObj, ["editor", "user"]), + [] + ); + } +); From d8c8c3db77c2b951d19611196499d1a08c118ef8 Mon Sep 17 00:00:00 2001 From: denihs Date: Mon, 11 Nov 2024 12:35:30 -0400 Subject: [PATCH 2/3] - update node version on travis - use the latest version on puppeteer --- .travis.yml | 2 +- packages/test-in-console/run.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 6d58476294..95a5100c76 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,7 +4,7 @@ dist: jammy sudo: required services: xvfb node_js: - - "20.15.1" + - "22.11.0" cache: directories: - ".meteor" diff --git a/packages/test-in-console/run.sh b/packages/test-in-console/run.sh index 9a6231d209..5a88e9065d 100755 --- a/packages/test-in-console/run.sh +++ b/packages/test-in-console/run.sh @@ -9,7 +9,7 @@ cd $(dirname $0)/../.. export METEOR_HOME=`pwd` # Installs into dev_bundle/lib/node_modules/puppeteer. -./meteor npm install -g puppeteer@20.4.0 +./meteor npm install -g puppeteer@23.6.0 export PATH=$METEOR_HOME:$PATH From bd5d58a3a890bc0900ebb6724f638b8670e671e1 Mon Sep 17 00:00:00 2001 From: denihs Date: Mon, 11 Nov 2024 13:58:45 -0400 Subject: [PATCH 3/3] - add text condition so puppeteer works with Travis --- packages/test-in-console/puppeteer_runner.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/test-in-console/puppeteer_runner.js b/packages/test-in-console/puppeteer_runner.js index 0ad644d070..991bbd4631 100644 --- a/packages/test-in-console/puppeteer_runner.js +++ b/packages/test-in-console/puppeteer_runner.js @@ -12,6 +12,10 @@ async function runNextUrl(browser) { page.on('console', async msg => { // this is a way to make sure the travis does not timeout // if the test is running for too long without any output to the console (10 minutes) + const text = msg.text(); + if (text.includes('Permissions policy violation')) { + return; + } if (msg._text !== undefined) console.log(msg._text); else { testNumber++;