role_spec.rb 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261
  1. require 'rails_helper'
  2. require 'models/application_model_examples'
  3. require 'models/concerns/can_be_imported_examples'
  4. require 'models/concerns/has_groups_examples'
  5. require 'models/concerns/has_collection_update_examples'
  6. require 'models/concerns/has_ticket_create_screen_impact_examples'
  7. RSpec.describe Role do
  8. it_behaves_like 'ApplicationModel'
  9. it_behaves_like 'CanBeImported'
  10. it_behaves_like 'HasGroups', group_access_factory: :role
  11. it_behaves_like 'HasCollectionUpdate', collection_factory: :role
  12. it_behaves_like 'HasTicketCreateScreenImpact', create_screen_factory: :role
  13. subject(:role) { create(:role) }
  14. describe 'Default state' do
  15. describe 'of whole table:' do
  16. it 'has three records ("Admin", "Agent", and "Customer")' do
  17. expect(described_class.pluck(:name)).to match_array(%w[Admin Agent Customer])
  18. end
  19. end
  20. describe 'of "Admin" role:' do
  21. it 'has default admin permissions' do
  22. expect(described_class.find_by(name: 'Admin').permissions.pluck(:name))
  23. .to match_array(%w[admin user_preferences report knowledge_base.editor])
  24. end
  25. end
  26. describe 'of "Agent" role:' do
  27. it 'has default agent permissions' do
  28. expect(described_class.find_by(name: 'Agent').permissions.pluck(:name))
  29. .to match_array(%w[ticket.agent chat.agent cti.agent user_preferences knowledge_base.reader])
  30. end
  31. end
  32. describe 'of "Customer" role:' do
  33. it 'has default customer permissions' do
  34. expect(described_class.find_by(name: 'Customer').permissions.pluck(:name))
  35. .to match_array(
  36. %w[
  37. user_preferences.password
  38. user_preferences.language
  39. user_preferences.linked_accounts
  40. user_preferences.avatar
  41. ticket.customer
  42. ]
  43. )
  44. end
  45. end
  46. end
  47. describe 'Callbacks -' do
  48. describe 'Permission validation:' do
  49. context 'with normal permission' do
  50. let(:permission) { create(:permission) }
  51. it 'can be created' do
  52. expect { create(:role, permissions: [permission]) }
  53. .to change(described_class, :count).by(1)
  54. end
  55. it 'can be added' do
  56. expect { role.permissions << permission }
  57. .to change { role.permissions.count }.by(1)
  58. end
  59. end
  60. context 'with disabled permission' do
  61. let(:permission) { create(:permission, preferences: { disabled: true }) }
  62. it 'cannot be created' do
  63. expect { create(:role, permissions: [permission]) }
  64. .to raise_error(/is disabled/)
  65. .and change(described_class, :count).by(0)
  66. end
  67. it 'cannot be added' do
  68. expect { role.permissions << permission }
  69. .to raise_error(/is disabled/)
  70. .and change { role.permissions.count }.by(0)
  71. end
  72. end
  73. context 'with multiple, explicitly incompatible permissions' do
  74. let(:permission) { create(:permission, preferences: { not: [Permission.first.name] }) }
  75. it 'cannot be created' do
  76. expect { create(:role, permissions: [Permission.first, permission]) }
  77. .to raise_error(/conflicts with/)
  78. .and change(described_class, :count).by(0)
  79. end
  80. it 'cannot be added' do
  81. role.permissions << Permission.first
  82. expect { role.permissions << permission }
  83. .to raise_error(/conflicts with/)
  84. .and change { role.permissions.count }.by(0)
  85. end
  86. end
  87. context 'with multiple, compatible permissions' do
  88. let(:permission) { create(:permission, preferences: { not: [Permission.pluck(:name).max.next] }) }
  89. it 'can be created' do
  90. expect { create(:role, permissions: [Permission.first, permission]) }
  91. .to change(described_class, :count).by(1)
  92. end
  93. it 'can be added' do
  94. role.permissions << Permission.first
  95. expect { role.permissions << permission }
  96. .to change { role.permissions.count }.by(1)
  97. end
  98. end
  99. end
  100. describe 'System-wide agent limit checks:' do
  101. let(:agents) { User.with_permissions('ticket.agent') }
  102. describe '#validate_agent_limit_by_attributes' do
  103. context 'when reactivating a role adds new agents' do
  104. subject(:role) { create(:agent_role, active: false) }
  105. before { create(:user, roles: [role]) }
  106. context 'exceeding the system limit' do
  107. before { Setting.set('system_agent_limit', agents.count) }
  108. it 'fails and raises an error' do
  109. expect { role.update!(active: true) }
  110. .to raise_error(Exceptions::UnprocessableEntity)
  111. .and change(agents, :count).by(0)
  112. end
  113. end
  114. end
  115. end
  116. end
  117. describe 'Restrictions on #default_at_signup:' do
  118. context 'for roles with "admin" permissions' do
  119. subject(:role) { build(:role, permissions: Permission.where(name: 'admin')) }
  120. it 'cannot be set to true on creation' do
  121. role.default_at_signup = true
  122. expect { role.save }
  123. .to raise_error(Exceptions::UnprocessableEntity, /Cannot set default at signup/)
  124. end
  125. it 'cannot be changed to true' do
  126. role.save
  127. expect { role.update(default_at_signup: true) }
  128. .to raise_error(Exceptions::UnprocessableEntity, /Cannot set default at signup/)
  129. end
  130. end
  131. context 'for roles with permissions that are children of "admin"' do
  132. subject(:role) { build(:role, permissions: [permission]) }
  133. let(:permission) { create(:permission, name: 'admin.foo') }
  134. it 'cannot be set to true on creation' do
  135. role.default_at_signup = true
  136. expect { role.save }
  137. .to raise_error(Exceptions::UnprocessableEntity, /Cannot set default at signup/)
  138. end
  139. it 'cannot be changed to true' do
  140. role.save
  141. expect { role.update(default_at_signup: true) }
  142. .to raise_error(Exceptions::UnprocessableEntity, /Cannot set default at signup/)
  143. end
  144. end
  145. context 'for roles with "ticket.agent" permissions' do
  146. subject(:role) { build(:role, permissions: Permission.where(name: 'ticket.agent')) }
  147. it 'cannot be set to true on creation' do
  148. role.default_at_signup = true
  149. expect { role.save }
  150. .to raise_error(Exceptions::UnprocessableEntity, /Cannot set default at signup/)
  151. end
  152. it 'cannot be changed to true' do
  153. role.save
  154. expect { role.update(default_at_signup: true) }
  155. .to raise_error(Exceptions::UnprocessableEntity, /Cannot set default at signup/)
  156. end
  157. end
  158. end
  159. end
  160. describe '.with_permissions' do
  161. context 'when given a name not matching any permissions' do
  162. let(:permission) { 'foo' }
  163. let(:result) { [] }
  164. it 'returns an empty array' do
  165. expect(described_class.with_permissions(permission)).to match_array(result)
  166. end
  167. end
  168. context 'when given the name of a top-level permission' do
  169. let(:permission) { 'user_preferences' }
  170. let(:result) { described_class.where(name: %w[Admin Agent]) }
  171. it 'returns an array of roles with that permission' do
  172. expect(described_class.with_permissions(permission)).to match_array(result)
  173. end
  174. end
  175. context 'when given the name of a child permission' do
  176. let(:permission) { 'user_preferences.language' }
  177. let(:result) { described_class.all }
  178. it 'returns an array of roles with either that permission or an ancestor' do
  179. expect(described_class.with_permissions(permission)).to match_array(result)
  180. end
  181. end
  182. context 'when given the names of multiple permissions' do
  183. let(:permissions) { %w[ticket.agent ticket.customer] }
  184. let(:result) { described_class.where(name: %w[Agent Customer]) }
  185. it 'returns an array of roles matching ANY given permission' do
  186. expect(described_class.with_permissions(permissions)).to match_array(result)
  187. end
  188. end
  189. end
  190. describe '#with_permission?' do
  191. subject(:role) { described_class.find_by(name: 'Admin') }
  192. context 'when given the name of a permission it has' do
  193. it 'returns true' do
  194. expect(role.with_permission?('admin')).to be(true)
  195. end
  196. end
  197. context 'when given the name of a permission it does NOT have' do
  198. it 'returns false' do
  199. expect(role.with_permission?('ticket.customer')).to be(false)
  200. end
  201. end
  202. context 'when given the name of multiple permissions' do
  203. it 'returns true as long as ANY match' do
  204. expect(role.with_permission?(['admin', 'ticket.customer'])).to be(true)
  205. end
  206. end
  207. end
  208. end