Skip to content

Commit 3837a6d

Browse files
committed
Unit tests for AclRegistryService added
1 parent 49ce5b2 commit 3837a6d

File tree

4 files changed

+133
-48
lines changed

4 files changed

+133
-48
lines changed

dist/acl.js

Lines changed: 55 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ angular.module('stylet.acl').service('AclService', ["AclRegistryService", functi
7474
var _isAllowedRole = null;
7575

7676
/**
77-
* @returns {{AclRoleInterface|null}}
77+
* @returns {(AclRoleInterface|null)}
7878
*/
7979
this.getUserIdentity = function () {
8080
return _userIdentity;
@@ -108,8 +108,8 @@ angular.module('stylet.acl').service('AclService', ["AclRegistryService", functi
108108
};
109109

110110
/**
111-
* @param {(string|AclResourceInterface)} [resource=null] resource
112-
* @param {string} [privilege=null] privilege
111+
* @param {(string|AclResourceInterface)} [resource=null]
112+
* @param {string} [privilege=null]
113113
* @returns {boolean}
114114
*/
115115
this.can = function (resource, privilege) {
@@ -126,9 +126,9 @@ angular.module('stylet.acl').service('AclService', ["AclRegistryService", functi
126126
/**
127127
* Adds an "allow" rule to the ACL
128128
*
129-
* @param {(string|Array)} [roles=null] roles
130-
* @param {(string|Array)} [resources=null] resources
131-
* @param {(string|Array)} [privileges=null] privileges
129+
* @param {(string|Array)} [roles=null]
130+
* @param {(string|Array)} [resources=null]
131+
* @param {(string|Array)} [privileges=null]
132132
* @param {AclAssertion} assert
133133
* @return {AclService} Provides a fluent interface
134134
*/
@@ -144,9 +144,9 @@ angular.module('stylet.acl').service('AclService', ["AclRegistryService", functi
144144
/**
145145
* Adds a "deny" rule to the ACL
146146
*
147-
* @param {(string|Array)} [roles=null] roles
148-
* @param {(string|Array)} [resources=null] resources
149-
* @param {(string|Array)} [privileges=null] privileges
147+
* @param {(string|Array)} [roles=null]
148+
* @param {(string|Array)} [resources=null]
149+
* @param {(string|Array)} [privileges=null]
150150
* @param {AclAssertion} assert
151151
* @return {AclService} Provides a fluent interface
152152
*/
@@ -162,9 +162,9 @@ angular.module('stylet.acl').service('AclService', ["AclRegistryService", functi
162162
/**
163163
* Removes an "allow" rule from the ACL
164164
*
165-
* @param {(string|Array)} [roles=null] roles
166-
* @param {(string|Array)} [resources=null] resources
167-
* @param {(string|Array)} [privileges=null] privileges
165+
* @param {(string|Array)} [roles=null]
166+
* @param {(string|Array)} [resources=null]
167+
* @param {(string|Array)} [privileges=null]
168168
* @param {AclAssertion} assert
169169
* @return {AclService} Provides a fluent interface
170170
*/
@@ -180,9 +180,9 @@ angular.module('stylet.acl').service('AclService', ["AclRegistryService", functi
180180
/**
181181
* Removes an "deny" rule from the ACL
182182
*
183-
* @param {(string|Array)} [roles=null] roles
184-
* @param {(string|Array)} [resources=null] resources
185-
* @param {(string|Array)} [privileges=null] privileges
183+
* @param {(string|Array)} [roles=null]
184+
* @param {(string|Array)} [resources=null]
185+
* @param {(string|Array)} [privileges=null]
186186
* @param {AclAssertion} assert
187187
* @return {AclService} Provides a fluent interface
188188
*/
@@ -216,9 +216,9 @@ angular.module('stylet.acl').service('AclService', ["AclRegistryService", functi
216216
* and its respective parents are checked similarly before the lower-priority parents of
217217
* the Role are checked.
218218
*
219-
* @param {string} [role=null] role
220-
* @param {string|AclResourceInterface} [resource=null] resource
221-
* @param {string} [privilege=null] privilege
219+
* @param {string} [role=null]
220+
* @param {string|AclResourceInterface} [resource=null]
221+
* @param {string} [privilege=null]
222222
* @return {boolean}
223223
*/
224224
this.isAllowed = function (role, resource, privilege) {
@@ -297,7 +297,7 @@ angular.module('stylet.acl').service('AclService', ["AclRegistryService", functi
297297
* the existing Resource from which the newly added Resource will inherit.
298298
*
299299
* @param {string} resource
300-
* @param {string} [parent=null] parent
300+
* @param {string} [parent=null]
301301
* @return {AclService} Provides a fluent interface
302302
*/
303303
this.addResource = function (resource, parent) {
@@ -381,7 +381,7 @@ angular.module('stylet.acl').service('AclService', ["AclRegistryService", functi
381381
*
382382
* @param {(AclResourceInterface|string)} resource
383383
* @param {(AclResourceInterface|string)} inherit
384-
* @param {boolean} [onlyParent=false] onlyParent
384+
* @param {boolean} [onlyParent=false]
385385
* @return {boolean}
386386
*/
387387
this.inheritsResource = function (resource, inherit, onlyParent) {
@@ -486,7 +486,7 @@ angular.module('stylet.acl').service('AclService', ["AclRegistryService", functi
486486
* highest priority.
487487
*
488488
* @param {string} role
489-
* @param {(string|Array.<string>)} [parents=null] parents
489+
* @param {(string|Array.<string>)} [parents=null]
490490
* @return {AclService} Provides a fluent interface
491491
*/
492492
this.addRole = function (role, parents) {
@@ -543,7 +543,7 @@ angular.module('stylet.acl').service('AclService', ["AclRegistryService", functi
543543
*
544544
* @param {string} role
545545
* @param {string} inherit
546-
* @param {boolean} [onlyParents=false] onlyParents
546+
* @param {boolean} [onlyParents=false]
547547
* @return {boolean}
548548
*/
549549
this.inheritsRole = function (role, inherit, onlyParents) {
@@ -643,10 +643,10 @@ angular.module('stylet.acl').service('AclService', ["AclRegistryService", functi
643643
*
644644
* @param {string} operation
645645
* @param {string} type
646-
* @param {string|Array.<string>} [roles=null] roles
647-
* @param {string|Array.<string>} [resources=null] resources
648-
* @param {string|Array.<string>} [privileges=null] privileges
649-
* @param {function} [assert=null] assert
646+
* @param {string|Array.<string>} [roles=null]
647+
* @param {string|Array.<string>} [resources=null]
648+
* @param {string|Array.<string>} [privileges=null]
649+
* @param {function} [assert=null]
650650
* @return {AclService} Provides a fluent interface
651651
*/
652652
function setRule (
@@ -791,9 +791,9 @@ angular.module('stylet.acl').service('AclService', ["AclRegistryService", functi
791791
*
792792
* If the $create parameter is true, then a rule set is first created and then returned to the caller.
793793
*
794-
* @param {string} [resource=null] resource
795-
* @param {string} [role=null] role
796-
* @param {boolean} [create=false] create
794+
* @param {string} [resource=null]
795+
* @param {string} [role=null]
796+
* @param {boolean} [create=false]
797797
* @return {Object|null}
798798
*/
799799
function getRules (resource, role, create) {
@@ -849,8 +849,8 @@ angular.module('stylet.acl').service('AclService', ["AclRegistryService", functi
849849
* then this method returns false. If no applicable rule is found, then this method returns null.
850850
*
851851
* @param {string} role
852-
* @param {string} [resource=null] resource
853-
* @return bool|null
852+
* @param {string} [resource=null]
853+
* @return {(boolean|null)}
854854
*/
855855
function roleDFSAllPrivileges(role, resource){
856856
var dfs = {
@@ -884,9 +884,9 @@ angular.module('stylet.acl').service('AclService', ["AclRegistryService", functi
884884
* This method is used by the internal depth-first search algorithm and may modify the DFS data structure.
885885
*
886886
* @param {string} role
887-
* @param {string} [resource=null] resource
888-
* @param {Object} [dfs=null] dfs
889-
* @return {boolean|null}
887+
* @param {string} [resource=null]
888+
* @param {Object} [dfs=null]
889+
* @return {(boolean|null)}
890890
*/
891891
function roleDFSVisitAllPrivileges(role, resource, dfs) {
892892
resource = typeof resource === 'undefined' ? null : resource;
@@ -927,9 +927,9 @@ angular.module('stylet.acl').service('AclService', ["AclRegistryService", functi
927927
* then this method returns false. If no applicable rule is found, then this method returns null.
928928
*
929929
* @param {string} role
930-
* @param {string} [resource=null] resource
931-
* @param {string} [privilege=null] privilege
932-
* @return {boolean|null}
930+
* @param {string} [resource=null]
931+
* @param {string} [privilege=null]
932+
* @return {(boolean|null)}
933933
*/
934934
function roleDFSOnePrivilege(role, resource, privilege) {
935935
resource = typeof resource === 'undefined' ? null : resource;
@@ -971,10 +971,10 @@ angular.module('stylet.acl').service('AclService', ["AclRegistryService", functi
971971
* This method is used by the internal depth-first search algorithm and may modify the DFS data structure.
972972
*
973973
* @param {string} role
974-
* @param {string} [resource=null] resource
975-
* @param {string} [privilege=null] privilege
976-
* @param {Object} [dfs=null] dfs
977-
* @return bool|null
974+
* @param {string} [resource=null]
975+
* @param {string} [privilege=null]
976+
* @param {Object} [dfs=null]
977+
* @return {(boolean|null)}
978978
*/
979979
function roleDFSVisitOnePrivilege(role, resource, privilege, dfs) {
980980
resource = typeof resource === 'undefined' ? null : resource;
@@ -1020,10 +1020,10 @@ angular.module('stylet.acl').service('AclService', ["AclRegistryService", functi
10201020
* If all three parameters are null, then the default ACL rule type is returned,
10211021
* based on whether its assertion method passes.
10221022
*
1023-
* @param {null|string} [resource=null] resource
1024-
* @param {null|string} [role=null] role
1025-
* @param {null|string} [privilege=null] privilege
1026-
* @return {string|null}
1023+
* @param {null|string} [resource=null]
1024+
* @param {null|string} [role=null]
1025+
* @param {null|string} [privilege=null]
1026+
* @return {(string|null)}
10271027
*/
10281028
function getRuleType(resource, role, privilege) {
10291029
resource = typeof resource === 'undefined' ? null : resource;
@@ -1140,10 +1140,16 @@ angular.module('stylet.acl').service('AclService', ["AclRegistryService", functi
11401140
/**
11411141
* @ngdoc service
11421142
* @name AclRegistryService
1143+
* @description AclRegistryService factory
11431144
*/
11441145
angular.module('stylet.acl').factory('AclRegistryService', function () {
11451146
'use strict';
11461147

1148+
/**
1149+
* @ngdoc method
1150+
* @constructs AclRegistryService
1151+
* @description Initializes a new ACL role registry
1152+
*/
11471153
var AclRegistryService = function () {
11481154
var self = this;
11491155
var _storage = {};
@@ -1231,7 +1237,10 @@ angular.module('stylet.acl').factory('AclRegistryService', function () {
12311237
}
12321238

12331239
_storage[item].children.forEach(function (child) {
1234-
self.remove(child);
1240+
var index = _storage[child].parents.indexOf(item);
1241+
if (index !== -1) {
1242+
_storage[child].parents.splice(index, 1);
1243+
}
12351244
});
12361245
_storage[item].parents.forEach(function (parent) {
12371246
var index = _storage[parent].children.indexOf(item);

src/acl-registry-service.js

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,16 @@
11
/**
22
* @ngdoc service
33
* @name AclRegistryService
4+
* @description AclRegistryService factory
45
*/
56
angular.module('stylet.acl').factory('AclRegistryService', function () {
67
'use strict';
78

9+
/**
10+
* @ngdoc method
11+
* @constructs AclRegistryService
12+
* @description Initializes a new ACL role registry
13+
*/
814
var AclRegistryService = function () {
915
var self = this;
1016
var _storage = {};
@@ -92,7 +98,10 @@ angular.module('stylet.acl').factory('AclRegistryService', function () {
9298
}
9399

94100
_storage[item].children.forEach(function (child) {
95-
self.remove(child);
101+
var index = _storage[child].parents.indexOf(item);
102+
if (index !== -1) {
103+
_storage[child].parents.splice(index, 1);
104+
}
96105
});
97106
_storage[item].parents.forEach(function (parent) {
98107
var index = _storage[parent].children.indexOf(item);

test/acl-registry-service.js

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
'use strict';
2+
3+
describe('AclRegistryService', function () {
4+
/** @type {AclRegistryService} */
5+
var AclRegistryService;
6+
7+
beforeEach(module('stylet.acl'));
8+
9+
beforeEach(inject(function (_AclRegistryService_) {
10+
AclRegistryService = new _AclRegistryService_();
11+
}));
12+
13+
it('tests basic Role inheritance', function () {
14+
AclRegistryService
15+
.add('guest')
16+
.add('member', 'guest')
17+
.add('editor', 'member');
18+
19+
expect(AclRegistryService.getParents('guest')).toEqual([]);
20+
21+
var roleMemberParents = AclRegistryService.getParents('member');
22+
expect(roleMemberParents.length).toEqual(1);
23+
expect(roleMemberParents).toEqual(jasmine.arrayContaining(['guest']));
24+
25+
var roleEditorParents = AclRegistryService.getParents('editor');
26+
expect(roleEditorParents.length).toEqual(1);
27+
expect(roleEditorParents).toEqual(jasmine.arrayContaining(['member']));
28+
29+
expect(AclRegistryService.inherits('member', 'guest', true)).toBeTruthy();
30+
expect(AclRegistryService.inherits('editor', 'member', true)).toBeTruthy();
31+
expect(AclRegistryService.inherits('editor', 'guest')).toBeTruthy();
32+
33+
expect(AclRegistryService.inherits('guest', 'member')).toBeFalsy();
34+
expect(AclRegistryService.inherits('member', 'editor')).toBeFalsy();
35+
expect(AclRegistryService.inherits('guest', 'editor')).toBeFalsy();
36+
});
37+
38+
it('tests basic Role multiple inheritance with array', function () {
39+
AclRegistryService
40+
.add('parent1')
41+
.add('parent2')
42+
.add('child', ['parent1', 'parent2']);
43+
44+
var roleChildParents = AclRegistryService.getParents('child');
45+
expect(roleChildParents.length).toEqual(2);
46+
expect(roleChildParents).toEqual(jasmine.arrayContaining(['parent1', 'parent2']));
47+
48+
expect(AclRegistryService.inherits('child', 'parent1')).toBeTruthy();
49+
expect(AclRegistryService.inherits('child', 'parent2')).toBeTruthy();
50+
51+
AclRegistryService.remove('parent2');
52+
53+
roleChildParents = AclRegistryService.getParents('child');
54+
expect(roleChildParents.length).toEqual(1);
55+
expect(roleChildParents).toEqual(jasmine.arrayContaining(['parent1']));
56+
expect(AclRegistryService.inherits('child', 'parent1')).toBeTruthy();
57+
});
58+
59+
it('ensures that the same Role cannot be registered more than once to the registry', function () {
60+
AclRegistryService.add('tst');
61+
62+
expect(function() {
63+
AclRegistryService.add('tst');
64+
}).toThrowError();
65+
});
66+
67+
});

test/acl-service.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ describe('ncAclService', function () {
116116
AclService.removeRole('Manager');
117117

118118
expect(AclService.hasRole('Manager')).toBeFalsy();
119-
expect(AclService.hasRole('God')).toBeFalsy();
119+
expect(AclService.hasRole('God')).toBeTruthy();
120120
});
121121

122122
it('should throw Exception during removal of unexisted role', function () {

0 commit comments

Comments
 (0)