scope-util.spec.ts 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. import { SCOPE } from '@growi/core/dist/interfaces';
  2. import { describe, it, expect } from 'vitest';
  3. import {
  4. isValidScope, hasAllScope, extractAllScope, extractScopes,
  5. } from './scope-utils';
  6. describe('scope-utils', () => {
  7. describe('isValidScope', () => {
  8. it('should return true for valid scopes', () => {
  9. expect(isValidScope(SCOPE.READ.USER_SETTINGS.API.API_TOKEN)).toBe(true);
  10. expect(isValidScope(SCOPE.WRITE.USER_SETTINGS.API.ACCESS_TOKEN)).toBe(true);
  11. expect(isValidScope(SCOPE.READ.ADMIN.APP)).toBe(true);
  12. });
  13. it('should return false for invalid scopes', () => {
  14. expect(isValidScope('invalid:scope' as any)).toBe(false);
  15. expect(isValidScope('read:invalid:path' as any)).toBe(false);
  16. expect(isValidScope('write:user:invalid' as any)).toBe(false);
  17. });
  18. });
  19. describe('hasAllScope', () => {
  20. it('should return true for scopes ending with *', () => {
  21. expect(hasAllScope(SCOPE.READ.USER_SETTINGS.API.ALL)).toBe(true);
  22. expect(hasAllScope(SCOPE.WRITE.ADMIN.ALL)).toBe(true);
  23. });
  24. it('should return false for specific scopes', () => {
  25. expect(hasAllScope(SCOPE.READ.USER_SETTINGS.API.API_TOKEN)).toBe(false);
  26. expect(hasAllScope(SCOPE.WRITE.USER_SETTINGS.API.ACCESS_TOKEN)).toBe(false);
  27. });
  28. });
  29. describe('extractAllScope', () => {
  30. it('should extract all specific scopes from ALL scope', () => {
  31. const extracted = extractAllScope(SCOPE.READ.USER_SETTINGS.API.ALL);
  32. expect(extracted).toContain(SCOPE.READ.USER_SETTINGS.API.API_TOKEN);
  33. expect(extracted).toContain(SCOPE.READ.USER_SETTINGS.API.ACCESS_TOKEN);
  34. expect(extracted).not.toContain(SCOPE.READ.USER_SETTINGS.API.ALL);
  35. });
  36. it('should return array with single scope for specific scope', () => {
  37. const scope = SCOPE.READ.USER_SETTINGS.API.API_TOKEN;
  38. const extracted = extractAllScope(scope);
  39. expect(extracted).toEqual([scope]);
  40. });
  41. });
  42. describe('extractScopes', () => {
  43. it('should return empty array for undefined input', () => {
  44. expect(extractScopes()).toEqual([]);
  45. });
  46. it('should extract all implied scopes including READ permission for WRITE scopes', () => {
  47. const scopes = [SCOPE.WRITE.USER_SETTINGS.API.ACCESS_TOKEN];
  48. const extracted = extractScopes(scopes);
  49. expect(extracted).toContain(SCOPE.WRITE.USER_SETTINGS.API.ACCESS_TOKEN);
  50. expect(extracted).toContain(SCOPE.READ.USER_SETTINGS.API.ACCESS_TOKEN);
  51. });
  52. it('should extract all specific scopes from ALL scope with implied permissions', () => {
  53. const scopes = [SCOPE.WRITE.USER_SETTINGS.API.ALL];
  54. const extracted = extractScopes(scopes);
  55. // Should include both WRITE and READ permissions for all specific scopes
  56. expect(extracted).toContain(SCOPE.WRITE.USER_SETTINGS.API.API_TOKEN);
  57. expect(extracted).toContain(SCOPE.WRITE.USER_SETTINGS.API.ACCESS_TOKEN);
  58. expect(extracted).toContain(SCOPE.READ.USER_SETTINGS.API.API_TOKEN);
  59. expect(extracted).toContain(SCOPE.READ.USER_SETTINGS.API.ACCESS_TOKEN);
  60. // Should not include ALL scopes
  61. expect(extracted).not.toContain(SCOPE.WRITE.USER_SETTINGS.API.ALL);
  62. expect(extracted).not.toContain(SCOPE.READ.USER_SETTINGS.API.ALL);
  63. });
  64. it('should remove duplicate scopes', () => {
  65. const scopes = [
  66. SCOPE.WRITE.USER_SETTINGS.API.ACCESS_TOKEN,
  67. SCOPE.READ.USER_SETTINGS.API.ACCESS_TOKEN, // This is implied by WRITE
  68. ];
  69. const extracted = extractScopes(scopes);
  70. const accessTokenScopes = extracted.filter(s => s.endsWith('access_token'));
  71. expect(accessTokenScopes).toHaveLength(2); // Only READ and WRITE, no duplicates
  72. });
  73. });
  74. });