General.utils.test.ts 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  1. import { describe, expect, it } from 'vitest'
  2. import { summarizeProjectAccess } from './General.utils'
  3. const roles = {
  4. org_scoped_roles: [
  5. {
  6. id: 1,
  7. name: 'Owner',
  8. description: null,
  9. base_role_id: 1,
  10. projects: [],
  11. },
  12. ],
  13. project_scoped_roles: [
  14. {
  15. id: 2,
  16. name: 'Developer',
  17. description: null,
  18. base_role_id: 3,
  19. projects: [{ name: 'Project A', ref: 'ref-a' }],
  20. },
  21. ],
  22. } as any
  23. describe('summarizeProjectAccess', () => {
  24. it('includes org-scoped members for every project', () => {
  25. const summary = summarizeProjectAccess({
  26. organizationMembers: [
  27. {
  28. gotrue_id: 'owner-id',
  29. username: 'Owner User',
  30. primary_email: 'owner@example.com',
  31. role_ids: [1],
  32. } as any,
  33. ],
  34. roles,
  35. projectRef: 'ref-a',
  36. hasLimitedVisibility: false,
  37. })
  38. expect(summary.projectMemberCount).toBe(1)
  39. expect(summary.projectMembers[0].email).toBe('owner@example.com')
  40. expect(summary.projectMembers[0].role).toBe('Owner')
  41. expect(summary.hasOrganizationWideAccess).toBe(true)
  42. })
  43. it('filters project-scoped members to the selected project', () => {
  44. const summary = summarizeProjectAccess({
  45. organizationMembers: [
  46. {
  47. gotrue_id: 'dev-visible',
  48. username: 'Dev Visible',
  49. primary_email: 'visible@example.com',
  50. role_ids: [2],
  51. } as any,
  52. {
  53. gotrue_id: 'dev-hidden',
  54. username: 'Dev Hidden',
  55. primary_email: 'hidden@example.com',
  56. role_ids: [3],
  57. } as any,
  58. ],
  59. roles: {
  60. ...roles,
  61. project_scoped_roles: [
  62. {
  63. ...roles.project_scoped_roles[0],
  64. projects: [{ name: 'Project A', ref: 'ref-a' }],
  65. },
  66. {
  67. ...roles.project_scoped_roles[0],
  68. id: 3,
  69. projects: [{ name: 'Project B', ref: 'ref-b' }],
  70. },
  71. ],
  72. } as any,
  73. projectRef: 'ref-a',
  74. hasLimitedVisibility: false,
  75. })
  76. expect(summary.projectMemberCount).toBe(1)
  77. expect(summary.projectMembers[0].email).toBe('visible@example.com')
  78. })
  79. it('excludes invited members', () => {
  80. const summary = summarizeProjectAccess({
  81. organizationMembers: [
  82. {
  83. gotrue_id: 'member-id',
  84. username: 'Member',
  85. primary_email: 'member@example.com',
  86. role_ids: [1],
  87. } as any,
  88. {
  89. gotrue_id: 'invite-id',
  90. username: 'invite',
  91. primary_email: 'invite@example.com',
  92. role_ids: [1],
  93. invited_id: 123,
  94. } as any,
  95. ],
  96. roles,
  97. projectRef: 'ref-a',
  98. hasLimitedVisibility: false,
  99. })
  100. expect(summary.organizationMemberCount).toBe(1)
  101. expect(summary.projectMemberCount).toBe(1)
  102. })
  103. it('does not show org comparison in limited-visibility mode', () => {
  104. const summary = summarizeProjectAccess({
  105. organizationMembers: [
  106. {
  107. gotrue_id: 'member-id',
  108. username: 'Member',
  109. primary_email: 'member@example.com',
  110. role_ids: [1],
  111. } as any,
  112. ],
  113. roles,
  114. projectRef: 'ref-a',
  115. hasLimitedVisibility: true,
  116. })
  117. expect(summary.shouldShowOrgComparison).toBe(false)
  118. expect(summary.hasOrganizationWideAccess).toBe(false)
  119. })
  120. it('caps visible members and tracks hidden count', () => {
  121. const summary = summarizeProjectAccess({
  122. organizationMembers: [
  123. {
  124. gotrue_id: '1',
  125. username: 'A',
  126. primary_email: 'a@example.com',
  127. role_ids: [1],
  128. } as any,
  129. {
  130. gotrue_id: '2',
  131. username: 'B',
  132. primary_email: 'b@example.com',
  133. role_ids: [1],
  134. } as any,
  135. ],
  136. roles,
  137. projectRef: 'ref-a',
  138. hasLimitedVisibility: false,
  139. maxVisibleMembers: 1,
  140. })
  141. expect(summary.projectMemberCount).toBe(2)
  142. expect(summary.visibleMembers).toHaveLength(1)
  143. expect(summary.hiddenMembersCount).toBe(1)
  144. })
  145. it('places current user at the top of project members', () => {
  146. const summary = summarizeProjectAccess({
  147. organizationMembers: [
  148. {
  149. gotrue_id: 'alpha-id',
  150. username: 'Alpha',
  151. primary_email: 'alpha@example.com',
  152. role_ids: [1],
  153. } as any,
  154. {
  155. gotrue_id: 'current-user-id',
  156. username: 'Current User',
  157. primary_email: 'zeta@example.com',
  158. role_ids: [1],
  159. } as any,
  160. {
  161. gotrue_id: 'beta-id',
  162. username: 'Beta',
  163. primary_email: 'beta@example.com',
  164. role_ids: [1],
  165. } as any,
  166. ],
  167. roles,
  168. projectRef: 'ref-a',
  169. hasLimitedVisibility: false,
  170. currentUserId: 'current-user-id',
  171. maxVisibleMembers: 2,
  172. })
  173. expect(summary.projectMembers.map((member) => member.id)).toEqual([
  174. 'current-user-id',
  175. 'alpha-id',
  176. 'beta-id',
  177. ])
  178. expect(summary.visibleMembers.map((member) => member.id)).toEqual([
  179. 'current-user-id',
  180. 'alpha-id',
  181. ])
  182. expect(summary.hiddenMembersCount).toBe(1)
  183. })
  184. })