role_spec.rb 8.4 KB

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