<commit_before>var LogicalPermissions = require('../lib/LogicalPermissions.js');
var assert = require('assert');
describe('LogicalPermissions', function() {

  describe('creation', function () {
    it('should create a LogicalPermissions instance', function () {
      var lp = new LogicalPermissions();
      assert(lp instanceof LogicalPermissions);
    });
  });

  /*-----------LogicalPermissions::addType()-------------*/

  describe('testAddTypeParamNameMissing', function() {
    it('should call LogicalPermissions::addType() with no "name" parameter and catch a MissingArgumentException exception', function() {
      var lp = new LogicalPermissions();
      assert.throws(function() {
        lp.addType();
      }, function(err) {return err.name === 'MissingArgumentException';});
    });
  });
  describe('testAddTypeParamNameWrongType', function() {
    it('should call LogicalPermissions::addType() with the wrong data type for the "name" parameter and catch an InvalidArgumentTypeException exception', function() {
      var lp = new LogicalPermissions();
      assert.throws(function() {
        lp.addType(0, function(){});
      }, function(err) {return err.name === 'InvalidArgumentTypeException';});
    });
  });
  describe('testAddTypeParamNameEmpty', function() {
    it('should call LogicalPermissions::addType() with an empty string for "name" parameter and catch an InvalidArgumentValueException exception', function() {
      var lp = new LogicalPermissions();
      assert.throws(function() {
        lp.addType('', function(){});
      }, function(err) {return err.name === 'InvalidArgumentValueException';});
    });
  });
  describe('testAddTypeParamNameIsCoreKey', function() {
    it('should call LogicalPermissions::addType() with an illegal "name" parameter and catch an InvalidArgumentValueException exception', function() {
      var lp = new LogicalPermissions();
      assert.throws(function() {
        lp.addType('AND', function(){});
      }, function(err) {return err.name === 'InvalidArgumentValueException';});
    });
  });
  describe('testAddTypeParamNameExists', function() {
    it('should call LogicalPermissions::addType() with a "name" parameter that already exists and catch a PermissionTypeAlreadyExistsException exception', function() {
      var lp = new LogicalPermissions();
      assert.throws(function() {
        lp.addType('test', function(){});
        lp.addType('test', function(){});
      }, function(err) {return err.name === 'PermissionTypeAlreadyExistsException';});
    });
  });
  describe('testAddTypeParamCallbackMissing', function() {
    it('should call LogicalPermissions::addType() with no "callback" parameter and catch a MissingArgumentException exception', function() {
      var lp = new LogicalPermissions();
      assert.throws(function() {
        lp.addType('test');
      }, function(err) {return err.name === 'MissingArgumentException';});
    });
  });
  describe('testAddTypeParamCallbackWrongType', function() {
    it('should call LogicalPermissions::addType() with the wrong data type for the "callback" parameter and catch an InvalidArgumentTypeException exception', function() {
      var lp = new LogicalPermissions();
      assert.throws(function() {
        lp.addType('test', 0);
      }, function(err) {return err.name === 'InvalidArgumentTypeException';});
    });
  });
  describe('testAddType', function() {
    it('should call LogicalPermissions::addType() and assert that the type was indeed added', function() {
      var lp = new LogicalPermissions();
      lp.addType('test', function(){});
      assert(lp.typeExists('test'));
    });
  });

  /*-------------LogicalPermissions::removeType()--------------*/

  describe('testRemoveTypeParamNameMissing', function() {
    it('should call LogicalPermissions::removeType() with no "name" parameter and catch a MissingArgumentException exception', function() {
      var lp = new LogicalPermissions();
      assert.throws(function() {
        lp.removeType();
      }, function(err) {return err.name === 'MissingArgumentException';});
    });
  });
  describe('testRemoveTypeParamNameWrongType', function() {
    it('should call LogicalPermissions::removeType() with the wrong data type for the "name" parameter and catch an InvalidArgumentTypeException exception', function() {
      var lp = new LogicalPermissions();
      assert.throws(function() {
        lp.removeType(0);
      }, function(err) {return err.name === 'InvalidArgumentTypeException';});
    });
  });
  describe('testRemoveTypeParamNameEmpty', function() {
    it('should call LogicalPermissions::removeType() with an empty string for "name" parameter and catch an InvalidArgumentValueException exception', function() {
      var lp = new LogicalPermissions();
      assert.throws(function() {
        lp.removeType('');
      }, function(err) {return err.name === 'InvalidArgumentValueException';});
    });
  });
  describe('testRemoveTypeParamNameDoesntExist', function() {
    it('should call LogicalPermissions::removeType() with a "name" parameter that is not registered and catch a PermissionTypeNotRegisteredException exception', function() {
      var lp = new LogicalPermissions();
      assert.throws(function() {
        lp.removeType('test');
      }, function(err) {return err.name === 'PermissionTypeNotRegisteredException';});
    });
  });
  describe('testRemoveType', function() {
    it('should call LogicalPermissions::removeType() and successfully remove a registered permission type', function() {
      var lp = new LogicalPermissions();
      lp.addType('test', function(){});
      lp.removeType('test');
      assert(!lp.typeExists('test'));
    });
  });

  /*-------------LogicalPermissions::typeExists()--------------*/

  describe('testTypeExistsParamNameMissing', function() {
    it('should call LogicalPermissions::typeExists() with no "name" parameter and catch a MissingArgumentException exception', function() {
      var lp = new LogicalPermissions();
      assert.throws(function() {
        lp.typeExists();
      }, function(err) {return err.name === 'MissingArgumentException';});
    });
  });
  describe('testTypeExistsParamNameWrongType', function() {
    it('should call LogicalPermissions::typeExists() with the wrong data type for the "name" parameter and catch an InvalidArgumentTypeException exception', function() {
      var lp = new LogicalPermissions();
      assert.throws(function() {
        lp.typeExists(0);
      }, function(err) {return err.name === 'InvalidArgumentTypeException';});
    });
  });
  describe('testTypeExistsParamNameEmpty', function() {
    it('should call LogicalPermissions::typeExists() with an empty string for "name" parameter and catch an InvalidArgumentValueException exception', function() {
      var lp = new LogicalPermissions();
      assert.throws(function() {
        lp.typeExists('');
      }, function(err) {return err.name === 'InvalidArgumentValueException';});
    });
  });
  describe('testTypeExists', function() {
    it('should call LogicalPermissions::typeExists() and assert that a created type exists', function() {
      var lp = new LogicalPermissions();
      assert(!lp.typeExists('test'));
      lp.addType('test', function(){});
      assert(lp.typeExists('test'));
    });
  });

  /*-------------LogicalPermissions::getTypeCallback()--------------*/

  describe('testGetTypeCallbackParamNameMissing', function() {
    it('should call LogicalPermissions::getTypeCallback() with no "name" parameter and catch a MissingArgumentException exception', function() {
      var lp = new LogicalPermissions();
      assert.throws(function() {
        lp.getTypeCallback();
      }, function(err) {return err.name === 'MissingArgumentException';});
    });
  });
  describe('testGetTypeCallbackParamNameWrongType', function() {
    it('should call LogicalPermissions::getTypeCallback() with the wrong data type for the "name" parameter and catch an InvalidArgumentTypeException exception', function() {
      var lp = new LogicalPermissions();
      assert.throws(function() {
        lp.getTypeCallback(0);
      }, function(err) {return err.name === 'InvalidArgumentTypeException';});
    });
  });
  describe('testGetTypeCallbackParamNameEmpty', function() {
    it('should call LogicalPermissions::getTypeCallback() with an empty string for "name" parameter and catch an InvalidArgumentValueException exception', function() {
      var lp = new LogicalPermissions();
      assert.throws(function() {
        lp.getTypeCallback('');
      }, function(err) {return err.name === 'InvalidArgumentValueException';});
    });
  });
  describe('testGetTypeCallbackParamNameDoesntExist', function() {
    it('should call LogicalPermissions::getTypeCallback() with a "name" parameter that is not registered and catch a PermissionTypeNotRegisteredException exception', function() {
      var lp = new LogicalPermissions();
      assert.throws(function() {
        lp.getTypeCallback('test');
      }, function(err) {return err.name === 'PermissionTypeNotRegisteredException';});
    });
  });
  describe('testGetTypeCallback', function() {
    it('should call LogicalPermissions::getTypeCallback() and successfully get a registered permission type callback', function() {
      var lp = new LogicalPermissions();
      var callback = function(){};
      lp.addType('test', callback);
      assert.strictEqual(lp.getTypeCallback('test'), callback);
    });
  });

  /*-------------LogicalPermissions::setTypeCallback()--------------*/

  describe('testSetTypeCallbackParamNameMissing', function() {
    it('should call LogicalPermissions::setTypeCallback() with no "name" parameter and catch a MissingArgumentException exception', function() {
      var lp = new LogicalPermissions();
      assert.throws(function() {
        lp.setTypeCallback();
      }, function(err) {return err.name === 'MissingArgumentException';});
    });
  });
  describe('testSetTypeCallbackParamNameWrongType', function() {
    it('should call LogicalPermissions::setTypeCallback() with the wrong data type for the "name" parameter and catch an InvalidArgumentTypeException exception', function() {
      var lp = new LogicalPermissions();
      assert.throws(function() {
        lp.setTypeCallback(0);
      }, function(err) {return err.name === 'InvalidArgumentTypeException';});
    });
  });
  describe('testSetTypeCallbackParamNameEmpty', function() {
    it('should call LogicalPermissions::setTypeCallback() with an empty string for "name" parameter and catch an InvalidArgumentValueException exception', function() {
      var lp = new LogicalPermissions();
      assert.throws(function() {
        lp.setTypeCallback('');
      }, function(err) {return err.name === 'InvalidArgumentValueException';});
    });
  });
  describe('testSetTypeCallbackParamNameDoesntExist', function() {
    it('should call LogicalPermissions::setTypeCallback() with a "name" parameter that is not registered and catch a PermissionTypeNotRegisteredException exception', function() {
      var lp = new LogicalPermissions();
      assert.throws(function() {
        lp.setTypeCallback('test');
      }, function(err) {return err.name === 'PermissionTypeNotRegisteredException';});
    });
  });
  describe('testSetTypeCallbackParamCallbackMissing', function() {
    it('should call LogicalPermissions::setTypeCallback() with no "callback" parameter and catch a MissingArgumentException exception', function() {
      var lp = new LogicalPermissions();
      lp.addType('test', function(){});
      assert.throws(function() {
        lp.setTypeCallback('test');
      }, function(err) {return err.name === 'MissingArgumentException';});
    });
  });
  describe('testSetTypeCallbackParamCallbackWrongType', function() {
    it('should call LogicalPermissions::setTypeCallback() with the wrong data type for the "callback" parameter and catch an InvalidArgumentTypeException exception', function() {
      var lp = new LogicalPermissions();
      lp.addType('test', function(){});
      assert.throws(function() {
        lp.setTypeCallback('test', 0);
      }, function(err) {return err.name === 'InvalidArgumentTypeException';});
    });
  });
  describe('testSetTypeCallback', function() {
    it('should call LogicalPermissions::setTypeCallback() and successfully set a permission type callback', function() {
      var lp = new LogicalPermissions();
      lp.addType('test', function(){});
      var callback = function(){};
      assert.notStrictEqual(lp.getTypeCallback('test'), callback);
      lp.setTypeCallback('test', callback);
      assert.strictEqual(lp.getTypeCallback('test'), callback);
    });
  });

  /*-------------LogicalPermissions::getTypes()--------------*/

  describe('testGetTypes', function() {
    it('should call LogicalPermissions::getTypes() and successfully get all registered types', function() {
      var lp = new LogicalPermissions();
      assert.deepEqual(lp.getTypes(), {});
      var callback = function(){};
      lp.addType('test', callback);
      var types = lp.getTypes();
      assert.deepEqual(types, {test: callback});
      assert.strictEqual(types.test, callback);
      types.test2 = function(){};
      assert(!lp.getTypes().hasOwnProperty('test2'));
    });
  });

  /*-------------LogicalPermissions::setTypes()--------------*/

  describe('testSetTypesParamTypesMissing', function() {
    it('should call LogicalPermissions::setTypes() with no "types" parameter and catch a MissingArgumentException exception', function() {
      var lp = new LogicalPermissions();
      assert.throws(function() {
        lp.setTypes();
      }, function(err) {return err.name === 'MissingArgumentException';});
    });
  });
  describe('testSetTypesParamTypesWrongType', function() {
    it('should call LogicalPermissions::setTypes() with the wrong data type for the "types" parameter and catch an InvalidArgumentTypeException exception', function() {
      var lp = new LogicalPermissions();
      assert.throws(function() {
        lp.setTypes(0);
      }, function(err) {return err.name === 'InvalidArgumentTypeException';});
    });
  });
  describe('testSetTypesParamTypesNameWrongType', function() {
    it('should call LogicalPermissions::setTypes() with the wrong data type for a type name key and catch an InvalidArgumentValueException exception', function() {
      var lp = new LogicalPermissions();
      assert.throws(function() {
        var types = {0: function(){}};
        lp.setTypes(types);
      }, function(err) {return err.name === 'InvalidArgumentValueException';});
    });
  });
  describe('testSetTypesParamTypesNameEmpty', function() {
    it('should call LogicalPermissions::setTypes() with an empty type name key and catch an InvalidArgumentValueException exception', function() {
      var lp = new LogicalPermissions();
      assert.throws(function() {
        var types = {'': function(){}};
        lp.setTypes(types);
      }, function(err) {return err.name === 'InvalidArgumentValueException';});
    });
  });
  describe('testSetTypesParamTypesNameIsCoreKey', function() {
    it('should call LogicalPermissions::setTypes() with an illegal name key and catch an InvalidArgumentValueException exception', function() {
      var lp = new LogicalPermissions();
      assert.throws(function() {
        var types = {'AND': function(){}};
        lp.setTypes(types);
      }, function(err) {return err.name === 'InvalidArgumentValueException';});
    });
  });
  describe('testSetTypesParamTypesCallbackWrongType', function() {
    it('should call LogicalPermissions::setTypes() with the wrong data type for a type callback and catch an InvalidArgumentValueException exception', function() {
      var lp = new LogicalPermissions();
      assert.throws(function() {
        var types = {'test': 'hej'};
        lp.setTypes(types);
      }, function(err) {return err.name === 'InvalidArgumentValueException';});
    });
  });
  describe('testSetTypes', function() {
    it('should call LogicalPermissions::setTypes() and successfully overwrite all types', function() {
      var lp = new LogicalPermissions();
      var callback = function(){};
      var types = {'test': callback};
      lp.setTypes(types);
      var existing_types = lp.getTypes();
      assert.deepEqual(existing_types, {test: callback});
      assert.strictEqual(existing_types.test, callback);
      types.test2 = function(){};
      assert(!lp.getTypes().hasOwnProperty('test2'));
    });
  });

  /*-------------LogicalPermissions::getBypassCallback()--------------*/

  describe('testGetBypassCallback', function() {
    it('should call LogicalPermissions::getBypassCallback() and check that the callback is null', function() {
      var lp = new LogicalPermissions();
      assert.equal(lp.getBypassCallback(), null);
    });
  });

  /*-------------LogicalPermissions::setBypassCallback()--------------*/

  describe('testSetBypassCallbackParamCallbackMissing', function() {
    it('should call LogicalPermissions::setBypassCallback() with no "callback" parameter and catch a MissingArgumentException exception', function() {
      var lp = new LogicalPermissions();
      assert.throws(function() {
        lp.setBypassCallback();
      }, function(err) {return err.name === 'MissingArgumentException';});
    });
  });
  describe('testSetBypassCallbackParamCallbackWrongType', function() {
    it('should call LogicalPermissions::setBypassCallback() with the wrong data type for the "callback" parameter and catch an InvalidArgumentTypeException exception', function() {
      var lp = new LogicalPermissions();
      assert.throws(function() {
        lp.setBypassCallback(0);
      }, function(err) {return err.name === 'InvalidArgumentTypeException';});
    });
  });
  describe('testSetBypassCallback', function() {
    it('should call LogicalPermissions::setBypassCallback() and successfully register a bypass callback', function() {
      var lp = new LogicalPermissions();
      var callback = function(){};
      lp.setBypassCallback(callback);
      assert.strictEqual(lp.getBypassCallback(), callback);
    });
  });

  /*------------LogicalPermissions::getValidPermissionKeys()---------------*/

  describe('testGetValidPermissionKeys', function() {
    var lp = new LogicalPermissions();
    assert.deepEqual(lp.getValidPermissionKeys(), ['no_bypass', 'AND', 'NAND', 'OR', 'NOR', 'XOR', 'NOT', 'TRUE', 'FALSE']);
    var types = {
      flag: function(flag, context) {
        var access = false;
        if(flag === 'testflag') {
          if(context.hasOwnProperty('user') && context.user.hasOwnProperty('testflag')) {
            access = !!context.user.testflag;
          }
        }
        return access;
      },
      role: function(role, context) {
        var access = false;
        if(context.hasOwnProperty('user') && context.user.hasOwnProperty('roles')) {
          access = context.user.roles.indexOf(role) > -1;
        }
        return access;
      },
      misc: function(item, context) {
        var access = false;
        if(context.hasOwnProperty('user') && context.user.hasOwnProperty(item)) {
          access = !!context.user[item];
        }
        return access;
      }
    };
    lp.setTypes(types);
    assert.deepEqual(lp.getValidPermissionKeys(), ['no_bypass', 'AND', 'NAND', 'OR', 'NOR', 'XOR', 'NOT', 'TRUE', 'FALSE', 'flag', 'role', 'misc']);
  });

  /*-------------LogicalPermissions::checkAccess()--------------*/

  describe('testCheckAccessParamPermissionsMissing', function() {
    it('should call LogicalPermissions::checkAccess() with no "permissions" parameter and catch a MissingArgumentException exception', function() {
      var lp = new LogicalPermissions();
      assert.throws(function() {
        lp.checkAccess();
      }, function(err) {return err.name === 'MissingArgumentException';});
    });
  });
  describe('testCheckAccessParamPermissionsWrongType', function() {
    it('should call LogicalPermissions::checkAccess() with the wrong data type for the "permissions" parameter and catch an InvalidArgumentTypeException exception', function() {
      var lp = new LogicalPermissions();
      assert.throws(function() {
        lp.checkAccess(50);
      }, function(err) {return err.name === 'InvalidArgumentTypeException';});
    });
  });
  describe('testCheckAccessParamPermissionsWrongPermissionType', function() {
    it('should call LogicalPermissions::checkAccess() with an invalid permission value and catch an InvalidArgumentTypeException exception', function() {
      var lp = new LogicalPermissions();
      var permissions = {
        flag: 50
      };
      assert.throws(function() {
        lp.checkAccess(permissions);
      }, function(err) {return err.name === 'InvalidArgumentTypeException';});
    });
  });
  describe('testCheckAccessParamPermissionsNestedTypes', function() {
    it('should call LogicalPermissions::checkAccess() with nested permission types and catch an InvalidArgumentValueException exception', function() {
      var lp = new LogicalPermissions();

      //Directly nested
      var permissions = {
        flag: {
          flag: 'testflag'
        }
      };
      assert.throws(function() {
        lp.checkAccess(permissions);
      }, function(err) {return err.name === 'InvalidArgumentValueException';});

      //Indirectly nested
      var permissions = {
        flag: {
          OR: {
            flag: 'testflag'
          }
        }
      };
      assert.throws(function() {
        lp.checkAccess(permissions);
      }, function(err) {return err.name === 'InvalidArgumentValueException';});
    });
  });
  describe('testCheckAccessParamPermissionsUnregisteredType', function() {
    it('should call LogicalPermissions::checkAccess() with an unregistered permission type and catch a PermissionTypeNotRegisteredException exception', function() {
      var lp = new LogicalPermissions();
      var permissions = {
        flag: 'testflag'
      };
      assert.throws(function() {
        lp.checkAccess(permissions);
      }, function(err) {return err.name === 'PermissionTypeNotRegisteredException';});
    });
  });
  describe('testCheckAccessParamContextWrongType', function() {
    it('should call LogicalPermissions::checkAccess() with the wrong data type for the "context" parameter and catch an InvalidArgumentTypeException exception', function() {
      var lp = new LogicalPermissions();
      assert.throws(function() {
        lp.checkAccess({}, []);
      }, function(err) {return err.name === 'InvalidArgumentTypeException';});
    });
  });
  describe('testCheckAccessParamAllowBypassWrongType', function() {
    it('should call LogicalPermissions::checkAccess() with the wrong data type for the "allow_bypass" parameter and catch an InvalidArgumentTypeException exception', function() {
      var lp = new LogicalPermissions();
      assert.throws(function() {
        lp.checkAccess({}, {}, 'test');
      }, function(err) {return err.name === 'InvalidArgumentTypeException';});
    });
  });
  describe('testCheckAccessBypassAccessCheckContextPassing', function() {
    it('should call LogicalPermissions::checkAccess() and check that the context parameter is passed to the bypass access callback', function() {
      var lp = new LogicalPermissions();
      var user = {<commit_msg>kristofer: Added test for checking behavior for a permissions tree containing only array values<commit_after>var LogicalPermissions = require('../lib/LogicalPermissions.js');
var assert = require('assert');
describe('LogicalPermissions', function() {

  describe('creation', function () {
    it('should create a LogicalPermissions instance', function () {
      var lp = new LogicalPermissions();
      assert(lp instanceof LogicalPermissions);
    });
  });

  /*-----------LogicalPermissions::addType()-------------*/

  describe('testAddTypeParamNameMissing', function() {
    it('should call LogicalPermissions::addType() with no "name" parameter and catch a MissingArgumentException exception', function() {
      var lp = new LogicalPermissions();
      assert.throws(function() {
        lp.addType();
      }, function(err) {return err.name === 'MissingArgumentException';});
    });
  });
  describe('testAddTypeParamNameWrongType', function() {
    it('should call LogicalPermissions::addType() with the wrong data type for the "name" parameter and catch an InvalidArgumentTypeException exception', function() {
      var lp = new LogicalPermissions();
      assert.throws(function() {
        lp.addType(0, function(){});
      }, function(err) {return err.name === 'InvalidArgumentTypeException';});
    });
  });
  describe('testAddTypeParamNameEmpty', function() {
    it('should call LogicalPermissions::addType() with an empty string for "name" parameter and catch an InvalidArgumentValueException exception', function() {
      var lp = new LogicalPermissions();
      assert.throws(function() {
        lp.addType('', function(){});
      }, function(err) {return err.name === 'InvalidArgumentValueException';});
    });
  });
  describe('testAddTypeParamNameIsCoreKey', function() {
    it('should call LogicalPermissions::addType() with an illegal "name" parameter and catch an InvalidArgumentValueException exception', function() {
      var lp = new LogicalPermissions();
      assert.throws(function() {
        lp.addType('AND', function(){});
      }, function(err) {return err.name === 'InvalidArgumentValueException';});
    });
  });
  describe('testAddTypeParamNameExists', function() {
    it('should call LogicalPermissions::addType() with a "name" parameter that already exists and catch a PermissionTypeAlreadyExistsException exception', function() {
      var lp = new LogicalPermissions();
      assert.throws(function() {
        lp.addType('test', function(){});
        lp.addType('test', function(){});
      }, function(err) {return err.name === 'PermissionTypeAlreadyExistsException';});
    });
  });
  describe('testAddTypeParamCallbackMissing', function() {
    it('should call LogicalPermissions::addType() with no "callback" parameter and catch a MissingArgumentException exception', function() {
      var lp = new LogicalPermissions();
      assert.throws(function() {
        lp.addType('test');
      }, function(err) {return err.name === 'MissingArgumentException';});
    });
  });
  describe('testAddTypeParamCallbackWrongType', function() {
    it('should call LogicalPermissions::addType() with the wrong data type for the "callback" parameter and catch an InvalidArgumentTypeException exception', function() {
      var lp = new LogicalPermissions();
      assert.throws(function() {
        lp.addType('test', 0);
      }, function(err) {return err.name === 'InvalidArgumentTypeException';});
    });
  });
  describe('testAddType', function() {
    it('should call LogicalPermissions::addType() and assert that the type was indeed added', function() {
      var lp = new LogicalPermissions();
      lp.addType('test', function(){});
      assert(lp.typeExists('test'));
    });
  });

  /*-------------LogicalPermissions::removeType()--------------*/

  describe('testRemoveTypeParamNameMissing', function() {
    it('should call LogicalPermissions::removeType() with no "name" parameter and catch a MissingArgumentException exception', function() {
      var lp = new LogicalPermissions();
      assert.throws(function() {
        lp.removeType();
      }, function(err) {return err.name === 'MissingArgumentException';});
    });
  });
  describe('testRemoveTypeParamNameWrongType', function() {
    it('should call LogicalPermissions::removeType() with the wrong data type for the "name" parameter and catch an InvalidArgumentTypeException exception', function() {
      var lp = new LogicalPermissions();
      assert.throws(function() {
        lp.removeType(0);
      }, function(err) {return err.name === 'InvalidArgumentTypeException';});
    });
  });
  describe('testRemoveTypeParamNameEmpty', function() {
    it('should call LogicalPermissions::removeType() with an empty string for "name" parameter and catch an InvalidArgumentValueException exception', function() {
      var lp = new LogicalPermissions();
      assert.throws(function() {
        lp.removeType('');
      }, function(err) {return err.name === 'InvalidArgumentValueException';});
    });
  });
  describe('testRemoveTypeParamNameDoesntExist', function() {
    it('should call LogicalPermissions::removeType() with a "name" parameter that is not registered and catch a PermissionTypeNotRegisteredException exception', function() {
      var lp = new LogicalPermissions();
      assert.throws(function() {
        lp.removeType('test');
      }, function(err) {return err.name === 'PermissionTypeNotRegisteredException';});
    });
  });
  describe('testRemoveType', function() {
    it('should call LogicalPermissions::removeType() and successfully remove a registered permission type', function() {
      var lp = new LogicalPermissions();
      lp.addType('test', function(){});
      lp.removeType('test');
      assert(!lp.typeExists('test'));
    });
  });

  /*-------------LogicalPermissions::typeExists()--------------*/

  describe('testTypeExistsParamNameMissing', function() {
    it('should call LogicalPermissions::typeExists() with no "name" parameter and catch a MissingArgumentException exception', function() {
      var lp = new LogicalPermissions();
      assert.throws(function() {
        lp.typeExists();
      }, function(err) {return err.name === 'MissingArgumentException';});
    });
  });
  describe('testTypeExistsParamNameWrongType', function() {
    it('should call LogicalPermissions::typeExists() with the wrong data type for the "name" parameter and catch an InvalidArgumentTypeException exception', function() {
      var lp = new LogicalPermissions();
      assert.throws(function() {
        lp.typeExists(0);
      }, function(err) {return err.name === 'InvalidArgumentTypeException';});
    });
  });
  describe('testTypeExistsParamNameEmpty', function() {
    it('should call LogicalPermissions::typeExists() with an empty string for "name" parameter and catch an InvalidArgumentValueException exception', function() {
      var lp = new LogicalPermissions();
      assert.throws(function() {
        lp.typeExists('');
      }, function(err) {return err.name === 'InvalidArgumentValueException';});
    });
  });
  describe('testTypeExists', function() {
    it('should call LogicalPermissions::typeExists() and assert that a created type exists', function() {
      var lp = new LogicalPermissions();
      assert(!lp.typeExists('test'));
      lp.addType('test', function(){});
      assert(lp.typeExists('test'));
    });
  });

  /*-------------LogicalPermissions::getTypeCallback()--------------*/

  describe('testGetTypeCallbackParamNameMissing', function() {
    it('should call LogicalPermissions::getTypeCallback() with no "name" parameter and catch a MissingArgumentException exception', function() {
      var lp = new LogicalPermissions();
      assert.throws(function() {
        lp.getTypeCallback();
      }, function(err) {return err.name === 'MissingArgumentException';});
    });
  });
  describe('testGetTypeCallbackParamNameWrongType', function() {
    it('should call LogicalPermissions::getTypeCallback() with the wrong data type for the "name" parameter and catch an InvalidArgumentTypeException exception', function() {
      var lp = new LogicalPermissions();
      assert.throws(function() {
        lp.getTypeCallback(0);
      }, function(err) {return err.name === 'InvalidArgumentTypeException';});
    });
  });
  describe('testGetTypeCallbackParamNameEmpty', function() {
    it('should call LogicalPermissions::getTypeCallback() with an empty string for "name" parameter and catch an InvalidArgumentValueException exception', function() {
      var lp = new LogicalPermissions();
      assert.throws(function() {
        lp.getTypeCallback('');
      }, function(err) {return err.name === 'InvalidArgumentValueException';});
    });
  });
  describe('testGetTypeCallbackParamNameDoesntExist', function() {
    it('should call LogicalPermissions::getTypeCallback() with a "name" parameter that is not registered and catch a PermissionTypeNotRegisteredException exception', function() {
      var lp = new LogicalPermissions();
      assert.throws(function() {
        lp.getTypeCallback('test');
      }, function(err) {return err.name === 'PermissionTypeNotRegisteredException';});
    });
  });
  describe('testGetTypeCallback', function() {
    it('should call LogicalPermissions::getTypeCallback() and successfully get a registered permission type callback', function() {
      var lp = new LogicalPermissions();
      var callback = function(){};
      lp.addType('test', callback);
      assert.strictEqual(lp.getTypeCallback('test'), callback);
    });
  });

  /*-------------LogicalPermissions::setTypeCallback()--------------*/

  describe('testSetTypeCallbackParamNameMissing', function() {
    it('should call LogicalPermissions::setTypeCallback() with no "name" parameter and catch a MissingArgumentException exception', function() {
      var lp = new LogicalPermissions();
      assert.throws(function() {
        lp.setTypeCallback();
      }, function(err) {return err.name === 'MissingArgumentException';});
    });
  });
  describe('testSetTypeCallbackParamNameWrongType', function() {
    it('should call LogicalPermissions::setTypeCallback() with the wrong data type for the "name" parameter and catch an InvalidArgumentTypeException exception', function() {
      var lp = new LogicalPermissions();
      assert.throws(function() {
        lp.setTypeCallback(0);
      }, function(err) {return err.name === 'InvalidArgumentTypeException';});
    });
  });
  describe('testSetTypeCallbackParamNameEmpty', function() {
    it('should call LogicalPermissions::setTypeCallback() with an empty string for "name" parameter and catch an InvalidArgumentValueException exception', function() {
      var lp = new LogicalPermissions();
      assert.throws(function() {
        lp.setTypeCallback('');
      }, function(err) {return err.name === 'InvalidArgumentValueException';});
    });
  });
  describe('testSetTypeCallbackParamNameDoesntExist', function() {
    it('should call LogicalPermissions::setTypeCallback() with a "name" parameter that is not registered and catch a PermissionTypeNotRegisteredException exception', function() {
      var lp = new LogicalPermissions();
      assert.throws(function() {
        lp.setTypeCallback('test');
      }, function(err) {return err.name === 'PermissionTypeNotRegisteredException';});
    });
  });
  describe('testSetTypeCallbackParamCallbackMissing', function() {
    it('should call LogicalPermissions::setTypeCallback() with no "callback" parameter and catch a MissingArgumentException exception', function() {
      var lp = new LogicalPermissions();
      lp.addType('test', function(){});
      assert.throws(function() {
        lp.setTypeCallback('test');
      }, function(err) {return err.name === 'MissingArgumentException';});
    });
  });
  describe('testSetTypeCallbackParamCallbackWrongType', function() {
    it('should call LogicalPermissions::setTypeCallback() with the wrong data type for the "callback" parameter and catch an InvalidArgumentTypeException exception', function() {
      var lp = new LogicalPermissions();
      lp.addType('test', function(){});
      assert.throws(function() {
        lp.setTypeCallback('test', 0);
      }, function(err) {return err.name === 'InvalidArgumentTypeException';});
    });
  });
  describe('testSetTypeCallback', function() {
    it('should call LogicalPermissions::setTypeCallback() and successfully set a permission type callback', function() {
      var lp = new LogicalPermissions();
      lp.addType('test', function(){});
      var callback = function(){};
      assert.notStrictEqual(lp.getTypeCallback('test'), callback);
      lp.setTypeCallback('test', callback);
      assert.strictEqual(lp.getTypeCallback('test'), callback);
    });
  });

  /*-------------LogicalPermissions::getTypes()--------------*/

  describe('testGetTypes', function() {
    it('should call LogicalPermissions::getTypes() and successfully get all registered types', function() {
      var lp = new LogicalPermissions();
      assert.deepEqual(lp.getTypes(), {});
      var callback = function(){};
      lp.addType('test', callback);
      var types = lp.getTypes();
      assert.deepEqual(types, {test: callback});
      assert.strictEqual(types.test, callback);
      types.test2 = function(){};
      assert(!lp.getTypes().hasOwnProperty('test2'));
    });
  });

  /*-------------LogicalPermissions::setTypes()--------------*/

  describe('testSetTypesParamTypesMissing', function() {
    it('should call LogicalPermissions::setTypes() with no "types" parameter and catch a MissingArgumentException exception', function() {
      var lp = new LogicalPermissions();
      assert.throws(function() {
        lp.setTypes();
      }, function(err) {return err.name === 'MissingArgumentException';});
    });
  });
  describe('testSetTypesParamTypesWrongType', function() {
    it('should call LogicalPermissions::setTypes() with the wrong data type for the "types" parameter and catch an InvalidArgumentTypeException exception', function() {
      var lp = new LogicalPermissions();
      assert.throws(function() {
        lp.setTypes(0);
      }, function(err) {return err.name === 'InvalidArgumentTypeException';});
    });
  });
  describe('testSetTypesParamTypesNameWrongType', function() {
    it('should call LogicalPermissions::setTypes() with the wrong data type for a type name key and catch an InvalidArgumentValueException exception', function() {
      var lp = new LogicalPermissions();
      assert.throws(function() {
        var types = {0: function(){}};
        lp.setTypes(types);
      }, function(err) {return err.name === 'InvalidArgumentValueException';});
    });
  });
  describe('testSetTypesParamTypesNameEmpty', function() {
    it('should call LogicalPermissions::setTypes() with an empty type name key and catch an InvalidArgumentValueException exception', function() {
      var lp = new LogicalPermissions();
      assert.throws(function() {
        var types = {'': function(){}};
        lp.setTypes(types);
      }, function(err) {return err.name === 'InvalidArgumentValueException';});
    });
  });
  describe('testSetTypesParamTypesNameIsCoreKey', function() {
    it('should call LogicalPermissions::setTypes() with an illegal name key and catch an InvalidArgumentValueException exception', function() {
      var lp = new LogicalPermissions();
      assert.throws(function() {
        var types = {'AND': function(){}};
        lp.setTypes(types);
      }, function(err) {return err.name === 'InvalidArgumentValueException';});
    });
  });
  describe('testSetTypesParamTypesCallbackWrongType', function() {
    it('should call LogicalPermissions::setTypes() with the wrong data type for a type callback and catch an InvalidArgumentValueException exception', function() {
      var lp = new LogicalPermissions();
      assert.throws(function() {
        var types = {'test': 'hej'};
        lp.setTypes(types);
      }, function(err) {return err.name === 'InvalidArgumentValueException';});
    });
  });
  describe('testSetTypes', function() {
    it('should call LogicalPermissions::setTypes() and successfully overwrite all types', function() {
      var lp = new LogicalPermissions();
      var callback = function(){};
      var types = {'test': callback};
      lp.setTypes(types);
      var existing_types = lp.getTypes();
      assert.deepEqual(existing_types, {test: callback});
      assert.strictEqual(existing_types.test, callback);
      types.test2 = function(){};
      assert(!lp.getTypes().hasOwnProperty('test2'));
    });
  });

  /*-------------LogicalPermissions::getBypassCallback()--------------*/

  describe('testGetBypassCallback', function() {
    it('should call LogicalPermissions::getBypassCallback() and check that the callback is null', function() {
      var lp = new LogicalPermissions();
      assert.equal(lp.getBypassCallback(), null);
    });
  });

  /*-------------LogicalPermissions::setBypassCallback()--------------*/

  describe('testSetBypassCallbackParamCallbackMissing', function() {
    it('should call LogicalPermissions::setBypassCallback() with no "callback" parameter and catch a MissingArgumentException exception', function() {
      var lp = new LogicalPermissions();
      assert.throws(function() {
        lp.setBypassCallback();
      }, function(err) {return err.name === 'MissingArgumentException';});
    });
  });
  describe('testSetBypassCallbackParamCallbackWrongType', function() {
    it('should call LogicalPermissions::setBypassCallback() with the wrong data type for the "callback" parameter and catch an InvalidArgumentTypeException exception', function() {
      var lp = new LogicalPermissions();
      assert.throws(function() {
        lp.setBypassCallback(0);
      }, function(err) {return err.name === 'InvalidArgumentTypeException';});
    });
  });
  describe('testSetBypassCallback', function() {
    it('should call LogicalPermissions::setBypassCallback() and successfully register a bypass callback', function() {
      var lp = new LogicalPermissions();
      var callback = function(){};
      lp.setBypassCallback(callback);
      assert.strictEqual(lp.getBypassCallback(), callback);
    });
  });

  /*------------LogicalPermissions::getValidPermissionKeys()---------------*/

  describe('testGetValidPermissionKeys', function() {
    var lp = new LogicalPermissions();
    assert.deepEqual(lp.getValidPermissionKeys(), ['no_bypass', 'AND', 'NAND', 'OR', 'NOR', 'XOR', 'NOT', 'TRUE', 'FALSE']);
    var types = {
      flag: function(flag, context) {
        var access = false;
        if(flag === 'testflag') {
          if(context.hasOwnProperty('user') && context.user.hasOwnProperty('testflag')) {
            access = !!context.user.testflag;
          }
        }
        return access;
      },
      role: function(role, context) {
        var access = false;
        if(context.hasOwnProperty('user') && context.user.hasOwnProperty('roles')) {
          access = context.user.roles.indexOf(role) > -1;
        }
        return access;
      },
      misc: function(item, context) {
        var access = false;
        if(context.hasOwnProperty('user') && context.user.hasOwnProperty(item)) {
          access = !!context.user[item];
        }
        return access;
      }
    };
    lp.setTypes(types);
    assert.deepEqual(lp.getValidPermissionKeys(), ['no_bypass', 'AND', 'NAND', 'OR', 'NOR', 'XOR', 'NOT', 'TRUE', 'FALSE', 'flag', 'role', 'misc']);
  });

  /*-------------LogicalPermissions::checkAccess()--------------*/

  describe('testCheckAccessParamPermissionsMissing', function() {
    it('should call LogicalPermissions::checkAccess() with no "permissions" parameter and catch a MissingArgumentException exception', function() {
      var lp = new LogicalPermissions();
      assert.throws(function() {
        lp.checkAccess();
      }, function(err) {return err.name === 'MissingArgumentException';});
    });
  });
  describe('testCheckAccessParamPermissionsWrongType', function() {
    it('should call LogicalPermissions::checkAccess() with the wrong data type for the "permissions" parameter and catch an InvalidArgumentTypeException exception', function() {
      var lp = new LogicalPermissions();
      assert.throws(function() {
        lp.checkAccess(50);
      }, function(err) {return err.name === 'InvalidArgumentTypeException';});
    });
  });
  describe('testCheckAccessParamPermissionsWrongPermissionType', function() {
    it('should call LogicalPermissions::checkAccess() with an invalid permission value and catch an InvalidArgumentTypeException exception', function() {
      var lp = new LogicalPermissions();
      var permissions = {
        flag: 50
      };
      assert.throws(function() {
        lp.checkAccess(permissions);
      }, function(err) {return err.name === 'InvalidArgumentTypeException';});
    });
  });
  describe('testCheckAccessParamPermissionsNestedTypes', function() {
    it('should call LogicalPermissions::checkAccess() with nested permission types and catch an InvalidArgumentValueException exception', function() {
      var lp = new LogicalPermissions();

      //Directly nested
      var permissions = {
        flag: {
          flag: 'testflag'
        }
      };
      assert.throws(function() {
        lp.checkAccess(permissions);
      }, function(err) {return err.name === 'InvalidArgumentValueException';});

      //Indirectly nested
      var permissions = {
        flag: {
          OR: {
            flag: 'testflag'
          }
        }
      };
      assert.throws(function() {
        lp.checkAccess(permissions);
      }, function(err) {return err.name === 'InvalidArgumentValueException';});
    });
  });
  describe('testCheckAccessParamPermissionsUnregisteredType', function() {
    it('should call LogicalPermissions::checkAccess() with an unregistered permission type and catch a PermissionTypeNotRegisteredException exception', function() {
      var lp = new LogicalPermissions();
      var permissions = {
        flag: 'testflag'
      };
      assert.throws(function() {
        lp.checkAccess(permissions);
      }, function(err) {return err.name === 'PermissionTypeNotRegisteredException';});
    });
  });
  describe('testCheckAccessParamPermissionsArrayValue', function() {
    it('should call LogicalPermissions::checkAccess() with an array containing only values and catch a MissingArgumentException exception', function() {
      var lp = new LogicalPermissions();
      var permissions = [
        'test1',
        'test2'
      ];
      assert.throws(function() {
        lp.checkAccess(permissions);
      }, function(err) {return err.name === 'MissingArgumentException';});
    });
  });
  describe('testCheckAccessParamContextWrongType', function() {
    it('should call LogicalPermissions::checkAccess() with the wrong data type for the "context" parameter and catch an InvalidArgumentTypeException exception', function() {
      var lp = new LogicalPermissions();
      assert.throws(function() {
        lp.checkAccess({}, []);
      }, function(err) {return err.name === 'InvalidArgumentTypeException';});
    });
  });
  describe('testCheckAccessParamAllowBypassWrongType', function() {
    it('should call LogicalPermissions::checkAccess() with the wrong data type for the "allow_bypass" parameter and catch an InvalidArgumentTypeException exception', function() {
      var lp = new LogicalPermissions();
      assert.throws(function() {
        lp.checkAccess({}, {}, 'test');
      }, function(err) {return err.name === 'InvalidArgumentTypeException';});
    });
  });
  describe('testCheckAccessBypassAccessCheckContextPassing', function() {
    it('should call LogicalPermissions::checkAccess() and check that the context parameter is passed to the bypass access callback', function() {
      var lp = new LogicalPermissions();
      var user = {
{'fraction_non_alphanumeric': 0.14915655519384433, 'fraction_numerical': 0.0008455587029129497, 'mean_word_length': 3.8386007977907335, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2622392', 'n_tokens_mistral': 11956, 'n_tokens_neox': 12080, 'n_words': 3030}