@memberjunction/ng-entity-permissions 5.42.0 → 5.44.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@memberjunction/ng-entity-permissions",
3
- "version": "5.42.0",
3
+ "version": "5.44.0",
4
4
  "description": "MemberJunction: Angular components for displaying/editing permissions for an entity, and related components.",
5
5
  "main": "./dist/public-api.js",
6
6
  "typings": "./dist/public-api.d.ts",
@@ -25,14 +25,14 @@
25
25
  "@angular/router": "21.1.3"
26
26
  },
27
27
  "dependencies": {
28
- "@memberjunction/core": "5.42.0",
29
- "@memberjunction/core-entities": "5.42.0",
30
- "@memberjunction/global": "5.42.0",
31
- "@memberjunction/ng-base-types": "5.42.0",
32
- "@memberjunction/ng-container-directives": "5.42.0",
33
- "@memberjunction/ng-shared": "5.42.0",
34
- "@memberjunction/ng-shared-generic": "5.42.0",
35
- "@memberjunction/ng-ui-components": "5.42.0",
28
+ "@memberjunction/core": "5.44.0",
29
+ "@memberjunction/core-entities": "5.44.0",
30
+ "@memberjunction/global": "5.44.0",
31
+ "@memberjunction/ng-base-types": "5.44.0",
32
+ "@memberjunction/ng-container-directives": "5.44.0",
33
+ "@memberjunction/ng-shared": "5.44.0",
34
+ "@memberjunction/ng-shared-generic": "5.44.0",
35
+ "@memberjunction/ng-ui-components": "5.44.0",
36
36
  "tslib": "^2.8.1"
37
37
  },
38
38
  "sideEffects": false,
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=entity-permissions.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"entity-permissions.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/entity-permissions.test.ts"],"names":[],"mappings":""}
@@ -1,23 +0,0 @@
1
- /**
2
- * Tests for entity-permissions package:
3
- * - Module export verification
4
- */
5
- import { describe, it, expect, vi } from 'vitest';
6
- vi.mock('@angular/core', () => ({
7
- Component: () => (target) => target,
8
- NgModule: () => (target) => target,
9
- Input: () => () => { },
10
- Output: () => () => { },
11
- EventEmitter: class {
12
- emit() { }
13
- },
14
- ChangeDetectorRef: class {
15
- },
16
- ChangeDetectionStrategy: { OnPush: 1 },
17
- }));
18
- describe('entity-permissions package', () => {
19
- it('should be a valid module', () => {
20
- expect(true).toBe(true);
21
- });
22
- });
23
- //# sourceMappingURL=entity-permissions.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"entity-permissions.test.js","sourceRoot":"","sources":["../../src/__tests__/entity-permissions.test.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAElD,EAAE,CAAC,IAAI,CAAC,eAAe,EAAE,GAAG,EAAE,CAAC,CAAC;IAC9B,SAAS,EAAE,GAAG,EAAE,CAAC,CAAC,MAAgB,EAAE,EAAE,CAAC,MAAM;IAC7C,QAAQ,EAAE,GAAG,EAAE,CAAC,CAAC,MAAgB,EAAE,EAAE,CAAC,MAAM;IAC5C,KAAK,EAAE,GAAG,EAAE,CAAC,GAAG,EAAE,GAAE,CAAC;IACrB,MAAM,EAAE,GAAG,EAAE,CAAC,GAAG,EAAE,GAAE,CAAC;IACtB,YAAY,EAAE;QAAQ,IAAI,KAAI,CAAC;KAAE;IACjC,iBAAiB,EAAE;KAAQ;IAC3B,uBAAuB,EAAE,EAAE,MAAM,EAAE,CAAC,EAAE;CACvC,CAAC,CAAC,CAAC;AAEJ,QAAQ,CAAC,4BAA4B,EAAE,GAAG,EAAE;IAC1C,EAAE,CAAC,0BAA0B,EAAE,GAAG,EAAE;QAClC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC1B,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC","sourcesContent":["/**\n * Tests for entity-permissions package:\n * - Module export verification\n */\nimport { describe, it, expect, vi } from 'vitest';\n\nvi.mock('@angular/core', () => ({\n Component: () => (target: Function) => target,\n NgModule: () => (target: Function) => target,\n Input: () => () => {},\n Output: () => () => {},\n EventEmitter: class { emit() {} },\n ChangeDetectorRef: class {},\n ChangeDetectionStrategy: { OnPush: 1 },\n}));\n\ndescribe('entity-permissions package', () => {\n it('should be a valid module', () => {\n expect(true).toBe(true);\n });\n});\n"]}
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=entity-permissions-grid.component.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"entity-permissions-grid.component.test.d.ts","sourceRoot":"","sources":["../../../../src/lib/grid/__tests__/entity-permissions-grid.component.test.ts"],"names":[],"mappings":""}
@@ -1,106 +0,0 @@
1
- import { describe, it, expect, beforeEach, vi } from 'vitest';
2
- /**
3
- * Recompute-trigger coverage for EntityPermissionsGridComponent's roleNameMap
4
- * precompute (PR #2841): the role-name lookup is built ONCE on data load
5
- * (`buildRoleNameMap`), keyed by NormalizeUUID(roleID), so the per-row template
6
- * binding `getRoleName` is an O(1) Map read instead of an O(roles) UUIDsEqual
7
- * scan over `md.Roles` every change-detection pass.
8
- *
9
- * These tests pin:
10
- * (1) getRoleName resolves a known role after the map is built,
11
- * (2) case variance (SQL upper vs Postgres lower) resolves via NormalizeUUID,
12
- * (3) empty / missing / unknown roleID returns '' (no throw),
13
- * (4) the map is REBUILT on each load — a role removed from the provider's
14
- * list no longer resolves.
15
- *
16
- * Uses the real NormalizeUUID (`@memberjunction/global`); the component is `new`'d
17
- * with a mocked provider exposing `Roles`.
18
- */
19
- vi.mock('@angular/core', () => ({
20
- Component: () => (t) => t,
21
- Input: () => () => { },
22
- Output: () => () => { },
23
- EventEmitter: class {
24
- emit() { }
25
- },
26
- ChangeDetectorRef: class {
27
- detectChanges() { }
28
- markForCheck() { }
29
- },
30
- OnInit: class {
31
- },
32
- OnChanges: class {
33
- },
34
- }));
35
- vi.mock('@memberjunction/ng-base-types', () => {
36
- class MockBaseAngularComponent {
37
- Provider = null;
38
- get ProviderToUse() {
39
- return this.Provider;
40
- }
41
- }
42
- return { BaseAngularComponent: MockBaseAngularComponent };
43
- });
44
- vi.mock('@memberjunction/core', () => ({
45
- Metadata: class {
46
- },
47
- RunView: class {
48
- },
49
- }));
50
- vi.mock('@memberjunction/core-entities', () => ({
51
- MJEntityPermissionEntity: class {
52
- },
53
- }));
54
- import { EntityPermissionsGridComponent } from '../entity-permissions-grid.component';
55
- function makeComponent(roles) {
56
- const component = new EntityPermissionsGridComponent();
57
- component.Provider = { Roles: roles };
58
- return component;
59
- }
60
- /** Call the private builder (the real component invokes it inside Refresh()). */
61
- function build(component) {
62
- component.buildRoleNameMap();
63
- }
64
- describe('EntityPermissionsGridComponent — roleNameMap precompute', () => {
65
- let component;
66
- const roles = [
67
- { ID: 'AAAAAAAA-1111-1111-1111-111111111111', Name: 'Administrator' },
68
- { ID: 'bbbbbbbb-2222-2222-2222-222222222222', Name: 'Integration' },
69
- ];
70
- beforeEach(() => {
71
- component = makeComponent(roles);
72
- build(component);
73
- });
74
- it('resolves a role name once the map is built', () => {
75
- expect(component.getRoleName('AAAAAAAA-1111-1111-1111-111111111111')).toBe('Administrator');
76
- expect(component.getRoleName('bbbbbbbb-2222-2222-2222-222222222222')).toBe('Integration');
77
- });
78
- it('resolves across UUID case variance (lookup upper vs stored lower, and vice versa)', () => {
79
- // stored uppercase, looked up lowercase
80
- expect(component.getRoleName('aaaaaaaa-1111-1111-1111-111111111111')).toBe('Administrator');
81
- // stored lowercase, looked up uppercase
82
- expect(component.getRoleName('BBBBBBBB-2222-2222-2222-222222222222')).toBe('Integration');
83
- });
84
- it('returns empty string for an empty roleID (no throw)', () => {
85
- expect(component.getRoleName('')).toBe('');
86
- });
87
- it('returns empty string for an unknown roleID', () => {
88
- expect(component.getRoleName('FFFFFFFF-9999-9999-9999-999999999999')).toBe('');
89
- });
90
- it('rebuilds the map on each load — a removed role no longer resolves', () => {
91
- expect(component.getRoleName('AAAAAAAA-1111-1111-1111-111111111111')).toBe('Administrator');
92
- // provider now exposes a DIFFERENT, smaller role set; rebuild
93
- component.Provider = {
94
- Roles: [{ ID: 'bbbbbbbb-2222-2222-2222-222222222222', Name: 'Integration' }],
95
- };
96
- build(component);
97
- expect(component.getRoleName('AAAAAAAA-1111-1111-1111-111111111111')).toBe('');
98
- expect(component.getRoleName('bbbbbbbb-2222-2222-2222-222222222222')).toBe('Integration');
99
- });
100
- it('handles an empty provider role list — every lookup returns ""', () => {
101
- const empty = makeComponent([]);
102
- build(empty);
103
- expect(empty.getRoleName('AAAAAAAA-1111-1111-1111-111111111111')).toBe('');
104
- });
105
- });
106
- //# sourceMappingURL=entity-permissions-grid.component.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"entity-permissions-grid.component.test.js","sourceRoot":"","sources":["../../../../src/lib/grid/__tests__/entity-permissions-grid.component.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { describe, it, expect, beforeEach, vi } from 'vitest';\n\n/**\n * Recompute-trigger coverage for EntityPermissionsGridComponent's roleNameMap\n * precompute (PR #2841): the role-name lookup is built ONCE on data load\n * (`buildRoleNameMap`), keyed by NormalizeUUID(roleID), so the per-row template\n * binding `getRoleName` is an O(1) Map read instead of an O(roles) UUIDsEqual\n * scan over `md.Roles` every change-detection pass.\n *\n * These tests pin:\n * (1) getRoleName resolves a known role after the map is built,\n * (2) case variance (SQL upper vs Postgres lower) resolves via NormalizeUUID,\n * (3) empty / missing / unknown roleID returns '' (no throw),\n * (4) the map is REBUILT on each load — a role removed from the provider's\n * list no longer resolves.\n *\n * Uses the real NormalizeUUID (`@memberjunction/global`); the component is `new`'d\n * with a mocked provider exposing `Roles`.\n */\n\nvi.mock('@angular/core', () => ({\n Component: () => (t: Function) => t,\n Input: () => () => {},\n Output: () => () => {},\n EventEmitter: class { emit() {} },\n ChangeDetectorRef: class { detectChanges() {} markForCheck() {} },\n OnInit: class {},\n OnChanges: class {},\n}));\n\nvi.mock('@memberjunction/ng-base-types', () => {\n class MockBaseAngularComponent {\n Provider: unknown = null;\n get ProviderToUse(): unknown {\n return this.Provider;\n }\n }\n return { BaseAngularComponent: MockBaseAngularComponent };\n});\n\nvi.mock('@memberjunction/core', () => ({\n Metadata: class {},\n RunView: class {},\n}));\n\nvi.mock('@memberjunction/core-entities', () => ({\n MJEntityPermissionEntity: class {},\n}));\n\nimport { EntityPermissionsGridComponent } from '../entity-permissions-grid.component';\n\ninterface MockRole {\n ID: string;\n Name: string;\n}\n\nfunction makeComponent(roles: MockRole[]): EntityPermissionsGridComponent {\n const component = new EntityPermissionsGridComponent();\n (component as unknown as { Provider: { Roles: MockRole[] } }).Provider = { Roles: roles };\n return component;\n}\n\n/** Call the private builder (the real component invokes it inside Refresh()). */\nfunction build(component: EntityPermissionsGridComponent): void {\n (component as unknown as { buildRoleNameMap: () => void }).buildRoleNameMap();\n}\n\ndescribe('EntityPermissionsGridComponent — roleNameMap precompute', () => {\n let component: EntityPermissionsGridComponent;\n const roles: MockRole[] = [\n { ID: 'AAAAAAAA-1111-1111-1111-111111111111', Name: 'Administrator' },\n { ID: 'bbbbbbbb-2222-2222-2222-222222222222', Name: 'Integration' },\n ];\n\n beforeEach(() => {\n component = makeComponent(roles);\n build(component);\n });\n\n it('resolves a role name once the map is built', () => {\n expect(component.getRoleName('AAAAAAAA-1111-1111-1111-111111111111')).toBe('Administrator');\n expect(component.getRoleName('bbbbbbbb-2222-2222-2222-222222222222')).toBe('Integration');\n });\n\n it('resolves across UUID case variance (lookup upper vs stored lower, and vice versa)', () => {\n // stored uppercase, looked up lowercase\n expect(component.getRoleName('aaaaaaaa-1111-1111-1111-111111111111')).toBe('Administrator');\n // stored lowercase, looked up uppercase\n expect(component.getRoleName('BBBBBBBB-2222-2222-2222-222222222222')).toBe('Integration');\n });\n\n it('returns empty string for an empty roleID (no throw)', () => {\n expect(component.getRoleName('')).toBe('');\n });\n\n it('returns empty string for an unknown roleID', () => {\n expect(component.getRoleName('FFFFFFFF-9999-9999-9999-999999999999')).toBe('');\n });\n\n it('rebuilds the map on each load — a removed role no longer resolves', () => {\n expect(component.getRoleName('AAAAAAAA-1111-1111-1111-111111111111')).toBe('Administrator');\n\n // provider now exposes a DIFFERENT, smaller role set; rebuild\n (component as unknown as { Provider: { Roles: MockRole[] } }).Provider = {\n Roles: [{ ID: 'bbbbbbbb-2222-2222-2222-222222222222', Name: 'Integration' }],\n };\n build(component);\n\n expect(component.getRoleName('AAAAAAAA-1111-1111-1111-111111111111')).toBe('');\n expect(component.getRoleName('bbbbbbbb-2222-2222-2222-222222222222')).toBe('Integration');\n });\n\n it('handles an empty provider role list — every lookup returns \"\"', () => {\n const empty = makeComponent([]);\n build(empty);\n expect(empty.getRoleName('AAAAAAAA-1111-1111-1111-111111111111')).toBe('');\n });\n});\n"]}