PageRenderTime 42ms CodeModel.GetById 13ms RepoModel.GetById 0ms app.codeStats 0ms

/ee/spec/requests/api/merge_request_approval_rules_spec.rb

https://gitlab.com/markglenfletcher/gitlab-ee
Ruby | 370 lines | 291 code | 78 blank | 1 comment | 0 complexity | 17bcbbff65d92e6c4cb1e35e14380bc2 MD5 | raw file
  1. # frozen_string_literal: true
  2. require 'spec_helper'
  3. describe API::MergeRequestApprovalRules do
  4. set(:user) { create(:user) }
  5. set(:other_user) { create(:user) }
  6. set(:project) { create(:project, :public, :repository, creator: user, namespace: user.namespace) }
  7. let(:merge_request) { create(:merge_request, author: user, source_project: project, target_project: project) }
  8. shared_examples_for 'a protected API endpoint for merge request approval rule action' do
  9. context 'disable_overriding_approvers_per_merge_request is set to true' do
  10. before do
  11. project.update!(disable_overriding_approvers_per_merge_request: true)
  12. action
  13. end
  14. it 'responds with 403' do
  15. expect(response).to have_gitlab_http_status(403)
  16. end
  17. end
  18. context 'disable_overriding_approvers_per_merge_request is set to false' do
  19. before do
  20. project.update!(disable_overriding_approvers_per_merge_request: false)
  21. action
  22. end
  23. context 'user cannot update merge request' do
  24. let(:current_user) { other_user }
  25. it 'responds with 403' do
  26. expect(response).to have_gitlab_http_status(403)
  27. end
  28. end
  29. end
  30. end
  31. shared_examples_for 'a protected API endpoint that only allows action on regular merge request approval rule' do
  32. context 'approval rule is not a regular type' do
  33. let(:approval_rule) { create(:code_owner_rule, merge_request: merge_request) }
  34. it 'responds with 403' do
  35. expect(response).to have_gitlab_http_status(403)
  36. end
  37. end
  38. end
  39. describe 'GET /projects/:id/merge_requests/:merge_request_iid/approval_rules' do
  40. let(:current_user) { other_user }
  41. let(:url) { "/projects/#{project.id}/merge_requests/#{merge_request.iid}/approval_rules" }
  42. context 'user cannot read merge request' do
  43. before do
  44. project.project_feature.update!(merge_requests_access_level: ProjectFeature::PRIVATE)
  45. get api(url, other_user)
  46. end
  47. it 'responds with 403' do
  48. expect(response).to have_gitlab_http_status(403)
  49. end
  50. end
  51. context 'use can read merge request' do
  52. let(:approver) { create(:user) }
  53. let(:group) { create(:group) }
  54. let(:source_rule) { nil }
  55. let(:users) { [approver] }
  56. let(:groups) { [group] }
  57. let!(:mr_approval_rule) do
  58. create(
  59. :approval_merge_request_rule,
  60. merge_request: merge_request,
  61. approval_project_rule: source_rule,
  62. users: users,
  63. groups: groups
  64. )
  65. end
  66. before do
  67. group.add_developer(approver)
  68. merge_request.approvals.create(user: approver)
  69. get api(url, current_user)
  70. end
  71. it 'matches the response schema' do
  72. expect(response).to have_gitlab_http_status(200)
  73. expect(response).to match_response_schema('public_api/v4/merge_request_approval_rules', dir: 'ee')
  74. rules = json_response
  75. expect(rules.size).to eq(1)
  76. expect(rules.first['name']).to eq(mr_approval_rule.name)
  77. expect(rules.first['approvals_required']).to eq(mr_approval_rule.approvals_required)
  78. expect(rules.first['rule_type']).to eq(mr_approval_rule.rule_type)
  79. expect(rules.first['contains_hidden_groups']).to eq(false)
  80. expect(rules.first['source_rule']).to be_nil
  81. expect(rules.first['eligible_approvers']).to match([hash_including('id' => approver.id)])
  82. expect(rules.first['users']).to match([hash_including('id' => approver.id)])
  83. expect(rules.first['groups']).to match([hash_including('id' => group.id)])
  84. end
  85. context 'groups contain private groups' do
  86. let(:group) { create(:group, :private) }
  87. context 'current_user cannot see private group' do
  88. it 'hides private group' do
  89. rules = json_response
  90. expect(rules.first['contains_hidden_groups']).to eq(true)
  91. expect(rules.first['groups']).to be_empty
  92. end
  93. end
  94. context 'current_user can see private group' do
  95. let(:current_user) { approver }
  96. it 'shows private group' do
  97. rules = json_response
  98. expect(rules.first['contains_hidden_groups']).to eq(false)
  99. expect(rules.first['groups']).to match([hash_including('id' => group.id)])
  100. end
  101. end
  102. end
  103. context 'has existing merge request rule that overrides a project-level rule' do
  104. let(:source_rule) { create(:approval_project_rule, project: project) }
  105. it 'includes source_rule' do
  106. expect(json_response.first['source_rule']['approvals_required']).to eq(source_rule.approvals_required)
  107. end
  108. end
  109. end
  110. end
  111. describe 'POST /projects/:id/merge_requests/:merge_request_iid/approval_rules' do
  112. let(:current_user) { user }
  113. let(:url) { "/projects/#{project.id}/merge_requests/#{merge_request.iid}/approval_rules" }
  114. let(:approver) { create(:user) }
  115. let(:group) { create(:group) }
  116. let(:approval_project_rule_id) { nil }
  117. let(:user_ids) { [] }
  118. let(:group_ids) { [] }
  119. let(:params) do
  120. {
  121. name: 'Test',
  122. approvals_required: 1,
  123. approval_project_rule_id: approval_project_rule_id,
  124. user_ids: user_ids,
  125. group_ids: group_ids
  126. }
  127. end
  128. let(:action) { post api(url, current_user), params: params }
  129. it_behaves_like 'a protected API endpoint for merge request approval rule action'
  130. context 'when user can update merge request and approval rules can be overridden' do
  131. before do
  132. project.update!(disable_overriding_approvers_per_merge_request: false)
  133. project.add_developer(approver)
  134. group.add_developer(approver)
  135. action
  136. end
  137. it 'matches the response schema' do
  138. expect(response).to have_gitlab_http_status(201)
  139. expect(response).to match_response_schema('public_api/v4/merge_request_approval_rule', dir: 'ee')
  140. rule = json_response
  141. expect(rule['name']).to eq(params[:name])
  142. expect(rule['approvals_required']).to eq(params[:approvals_required])
  143. expect(rule['rule_type']).to eq('regular')
  144. expect(rule['contains_hidden_groups']).to eq(false)
  145. expect(rule['source_rule']).to be_nil
  146. expect(rule['eligible_approvers']).to be_empty
  147. expect(rule['users']).to be_empty
  148. expect(rule['groups']).to be_empty
  149. end
  150. context 'users are passed' do
  151. let(:user_ids) { [approver.id] }
  152. it 'includes users' do
  153. rule = json_response
  154. expect(rule['eligible_approvers']).to match([hash_including('id' => approver.id)])
  155. expect(rule['users']).to match([hash_including('id' => approver.id)])
  156. end
  157. end
  158. context 'groups are passed' do
  159. let(:group_ids) { [group.id] }
  160. it 'includes groups' do
  161. rule = json_response
  162. expect(rule['eligible_approvers']).to match([hash_including('id' => approver.id)])
  163. expect(rule['groups']).to match([hash_including('id' => group.id)])
  164. end
  165. end
  166. context 'approval_project_rule_id is passed' do
  167. let(:approval_project_rule) do
  168. create(
  169. :approval_project_rule,
  170. project: project,
  171. users: [approver],
  172. groups: [group]
  173. )
  174. end
  175. let(:approval_project_rule_id) { approval_project_rule.id }
  176. it 'copies the attributes from the project rule execpt approvals_required' do
  177. rule = json_response
  178. expect(rule['name']).to eq(approval_project_rule.name)
  179. expect(rule['approvals_required']).to eq(params[:approvals_required])
  180. expect(rule['source_rule']['approvals_required']).to eq(approval_project_rule.approvals_required)
  181. expect(rule['eligible_approvers']).to match([hash_including('id' => approver.id)])
  182. expect(rule['users']).to match([hash_including('id' => approver.id)])
  183. expect(rule['groups']).to match([hash_including('id' => group.id)])
  184. end
  185. end
  186. end
  187. end
  188. describe 'PUT /projects/:id/merge_requests/:merge_request_iid/approval_rules/:approval_rule_id' do
  189. let(:current_user) { user }
  190. let(:existing_approver) { create(:user) }
  191. let(:existing_group) { create(:group) }
  192. let(:approval_rule) do
  193. create(
  194. :approval_merge_request_rule,
  195. merge_request: merge_request,
  196. name: 'Old Name',
  197. approvals_required: 2,
  198. users: [existing_approver],
  199. groups: [existing_group]
  200. )
  201. end
  202. let(:url) { "/projects/#{project.id}/merge_requests/#{merge_request.iid}/approval_rules/#{approval_rule.id}" }
  203. let(:new_approver) { create(:user) }
  204. let(:new_group) { create(:group) }
  205. let(:user_ids) { [] }
  206. let(:group_ids) { [] }
  207. let(:remove_hidden_groups) { nil }
  208. let(:params) do
  209. {
  210. name: 'Test',
  211. approvals_required: 1,
  212. user_ids: user_ids,
  213. group_ids: group_ids,
  214. remove_hidden_groups: remove_hidden_groups
  215. }
  216. end
  217. let(:action) { put api(url, current_user), params: params }
  218. it_behaves_like 'a protected API endpoint for merge request approval rule action'
  219. context 'when user can update merge request and approval rules can be overridden' do
  220. before do
  221. project.update!(disable_overriding_approvers_per_merge_request: false)
  222. project.add_developer(existing_approver)
  223. project.add_developer(new_approver)
  224. existing_group.add_developer(existing_approver)
  225. new_group.add_developer(new_approver)
  226. action
  227. end
  228. it_behaves_like 'a protected API endpoint that only allows action on regular merge request approval rule'
  229. it 'matches the response schema' do
  230. expect(response).to have_gitlab_http_status(200)
  231. expect(response).to match_response_schema('public_api/v4/merge_request_approval_rule', dir: 'ee')
  232. rule = json_response
  233. expect(rule['name']).to eq(params[:name])
  234. expect(rule['approvals_required']).to eq(params[:approvals_required])
  235. expect(rule['rule_type']).to eq(approval_rule.rule_type)
  236. expect(rule['contains_hidden_groups']).to eq(false)
  237. expect(rule['source_rule']).to be_nil
  238. expect(rule['eligible_approvers']).to be_empty
  239. expect(rule['users']).to be_empty
  240. expect(rule['groups']).to be_empty
  241. end
  242. context 'users are passed' do
  243. let(:user_ids) { [new_approver.id] }
  244. it 'changes users' do
  245. rule = json_response
  246. expect(rule['eligible_approvers']).to match([hash_including('id' => new_approver.id)])
  247. expect(rule['users']).to match([hash_including('id' => new_approver.id)])
  248. end
  249. end
  250. context 'groups are passed' do
  251. let(:group_ids) { [new_group.id] }
  252. it 'changes groups' do
  253. rule = json_response
  254. expect(rule['eligible_approvers']).to match([hash_including('id' => new_approver.id)])
  255. expect(rule['groups']).to match([hash_including('id' => new_group.id)])
  256. end
  257. end
  258. context 'remove_hidden_groups is passed' do
  259. let(:existing_group) { create(:group, :private) }
  260. context 'when set to true' do
  261. let(:remove_hidden_groups) { true }
  262. it 'removes the existing private group' do
  263. expect(approval_rule.reload.groups).not_to include(existing_group)
  264. end
  265. end
  266. context 'when set to false' do
  267. let(:remove_hidden_groups) { false }
  268. it 'does not remove the existing private group' do
  269. expect(approval_rule.reload.groups).to include(existing_group)
  270. end
  271. end
  272. end
  273. end
  274. end
  275. describe 'DELETE /projects/:id/merge_requests/:merge_request_iid/approval_rules/:approval_rule_id' do
  276. let(:current_user) { user }
  277. let(:approval_rule) { create(:approval_merge_request_rule, merge_request: merge_request) }
  278. let(:url) { "/projects/#{project.id}/merge_requests/#{merge_request.iid}/approval_rules/#{approval_rule.id}" }
  279. let(:action) { delete api(url, current_user) }
  280. it_behaves_like 'a protected API endpoint for merge request approval rule action'
  281. context 'when user can update merge request and approval rules can be overridden' do
  282. before do
  283. project.update!(disable_overriding_approvers_per_merge_request: false)
  284. action
  285. end
  286. it_behaves_like 'a protected API endpoint that only allows action on regular merge request approval rule'
  287. it 'responds with 204' do
  288. expect(response).to have_gitlab_http_status(204)
  289. end
  290. end
  291. end
  292. end