scope-util.test.ts 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. import { SCOPE } from '@growi/core/dist/interfaces';
  2. import { describe, expect, it } from 'vitest';
  3. import { extractScopes, getDisabledScopes, parseScopes } from './scope-util';
  4. describe('scope-util', () => {
  5. const mockScopes = {
  6. READ: {
  7. USER: 'read:user',
  8. ADMIN: {
  9. SETTING: 'read:admin:setting',
  10. ALL: 'read:admin:all',
  11. },
  12. ALL: 'read:all',
  13. },
  14. WRITE: {
  15. USER: 'write:user',
  16. ADMIN: {
  17. SETTING: 'write:admin:setting',
  18. ALL: 'write:admin:all',
  19. },
  20. ALL: 'write:all',
  21. },
  22. };
  23. it('should parse scopes correctly for non-admin', () => {
  24. const result = parseScopes({ scopes: mockScopes, isAdmin: false });
  25. // Check that admin scopes are excluded
  26. expect(result.ADMIN).toBeUndefined();
  27. expect(result.ALL).toBeUndefined();
  28. // Check that user scopes are included
  29. expect(result.USER).toBeDefined();
  30. expect(result.USER['read:user']).toBe('read:user');
  31. expect(result.USER['write:user']).toBe('write:user');
  32. });
  33. it('should include admin scopes for admin users', () => {
  34. const result = parseScopes({ scopes: mockScopes, isAdmin: true });
  35. // Check that admin scopes are included
  36. expect(result.ADMIN).toBeDefined();
  37. expect(result.ALL).toBeDefined();
  38. // Check admin settings
  39. expect(result.ADMIN['admin:setting']['read:admin:setting']).toBe(
  40. 'read:admin:setting',
  41. );
  42. expect(result.ADMIN['admin:setting']['write:admin:setting']).toBe(
  43. 'write:admin:setting',
  44. );
  45. // Check ALL category
  46. expect(result.ALL['read:all']).toBe('read:all');
  47. expect(result.ALL['write:all']).toBe('write:all');
  48. });
  49. it('should return empty set when no scopes are selected', () => {
  50. const result = getDisabledScopes([], ['read:user', 'write:user']);
  51. expect(result.size).toBe(0);
  52. });
  53. it('should disable specific scopes when a wildcard is selected', () => {
  54. const selectedScopes = [SCOPE.READ.ALL];
  55. const availableScopes = [
  56. SCOPE.READ.FEATURES.PAGE,
  57. SCOPE.READ.FEATURES.ATTACHMENT,
  58. SCOPE.WRITE.FEATURES.PAGE,
  59. SCOPE.READ.ALL,
  60. ];
  61. const result = getDisabledScopes(selectedScopes, availableScopes);
  62. // Should disable all read: scopes except the wildcard itself
  63. expect(result.has(SCOPE.READ.FEATURES.PAGE)).toBe(true);
  64. expect(result.has(SCOPE.READ.FEATURES.ATTACHMENT)).toBe(true);
  65. expect(result.has(SCOPE.WRITE.FEATURES.PAGE)).toBe(false);
  66. expect(result.has(SCOPE.READ.ALL)).toBe(false);
  67. });
  68. it('should handle multiple wildcard selections', () => {
  69. const selectedScopes = [SCOPE.READ.ALL, SCOPE.WRITE.ALL];
  70. const availableScopes = [
  71. SCOPE.READ.FEATURES.PAGE,
  72. SCOPE.READ.FEATURES.ATTACHMENT,
  73. SCOPE.READ.ALL,
  74. SCOPE.WRITE.FEATURES.PAGE,
  75. SCOPE.WRITE.FEATURES.ATTACHMENT,
  76. SCOPE.WRITE.ALL,
  77. ];
  78. const result = getDisabledScopes(selectedScopes, availableScopes);
  79. // Should disable all specific scopes under both wildcards
  80. expect(result.has(SCOPE.READ.FEATURES.PAGE)).toBe(true);
  81. expect(result.has(SCOPE.READ.FEATURES.ATTACHMENT)).toBe(true);
  82. expect(result.has(SCOPE.WRITE.FEATURES.PAGE)).toBe(true);
  83. expect(result.has(SCOPE.WRITE.FEATURES.ATTACHMENT)).toBe(true);
  84. expect(result.has(SCOPE.READ.ALL)).toBe(false);
  85. expect(result.has(SCOPE.WRITE.ALL)).toBe(false);
  86. });
  87. it('should extract all scope strings from a nested object', () => {
  88. const scopeObj = {
  89. USER: {
  90. 'read:user': 'read:user',
  91. 'write:user': 'write:user',
  92. },
  93. ADMIN: {
  94. 'ADMIN:SETTING': {
  95. 'read:admin:setting': 'read:admin:setting',
  96. 'write:admin:setting': 'write:admin:setting',
  97. },
  98. },
  99. };
  100. const result = extractScopes(scopeObj);
  101. expect(result).toContain('read:user');
  102. expect(result).toContain('write:user');
  103. expect(result).toContain('read:admin:setting');
  104. expect(result).toContain('write:admin:setting');
  105. expect(result.length).toBe(4);
  106. });
  107. it('should return empty array for empty object', () => {
  108. const result = extractScopes({});
  109. expect(result).toEqual([]);
  110. });
  111. it('should handle objects with no string values', () => {
  112. const scopeObj = {
  113. level1: {
  114. level2: {
  115. level3: {},
  116. },
  117. },
  118. };
  119. const result = extractScopes(scopeObj);
  120. expect(result).toEqual([]);
  121. });
  122. });