PageRenderTime 55ms CodeModel.GetById 25ms RepoModel.GetById 0ms app.codeStats 0ms

/spec/requests/api/v3/members_spec.rb

https://gitlab.com/mehlah/gitlab-ce
Ruby | 340 lines | 274 code | 64 blank | 2 comment | 8 complexity | 110d27816347be0a2480030f60fb3716 MD5 | raw file
  1. require 'spec_helper'
  2. describe API::V3::Members do
  3. let(:master) { create(:user, username: 'master_user') }
  4. let(:developer) { create(:user) }
  5. let(:access_requester) { create(:user) }
  6. let(:stranger) { create(:user) }
  7. let(:project) do
  8. create(:project, :public, :access_requestable, creator_id: master.id, namespace: master.namespace) do |project|
  9. project.team << [developer, :developer]
  10. project.team << [master, :master]
  11. project.request_access(access_requester)
  12. end
  13. end
  14. let!(:group) do
  15. create(:group, :public, :access_requestable) do |group|
  16. group.add_developer(developer)
  17. group.add_owner(master)
  18. group.request_access(access_requester)
  19. end
  20. end
  21. shared_examples 'GET /:sources/:id/members' do |source_type|
  22. context "with :sources == #{source_type.pluralize}" do
  23. it_behaves_like 'a 404 response when source is private' do
  24. let(:route) { get v3_api("/#{source_type.pluralize}/#{source.id}/members", stranger) }
  25. end
  26. %i[master developer access_requester stranger].each do |type|
  27. context "when authenticated as a #{type}" do
  28. it 'returns 200' do
  29. user = public_send(type)
  30. get v3_api("/#{source_type.pluralize}/#{source.id}/members", user)
  31. expect(response).to have_gitlab_http_status(200)
  32. expect(json_response.size).to eq(2)
  33. expect(json_response.map { |u| u['id'] }).to match_array [master.id, developer.id]
  34. end
  35. end
  36. end
  37. it 'does not return invitees' do
  38. create(:"#{source_type}_member", invite_token: '123', invite_email: 'test@abc.com', source: source, user: nil)
  39. get v3_api("/#{source_type.pluralize}/#{source.id}/members", developer)
  40. expect(response).to have_gitlab_http_status(200)
  41. expect(json_response.size).to eq(2)
  42. expect(json_response.map { |u| u['id'] }).to match_array [master.id, developer.id]
  43. end
  44. it 'finds members with query string' do
  45. get v3_api("/#{source_type.pluralize}/#{source.id}/members", developer), query: master.username
  46. expect(response).to have_gitlab_http_status(200)
  47. expect(json_response.count).to eq(1)
  48. expect(json_response.first['username']).to eq(master.username)
  49. end
  50. end
  51. end
  52. shared_examples 'GET /:sources/:id/members/:user_id' do |source_type|
  53. context "with :sources == #{source_type.pluralize}" do
  54. it_behaves_like 'a 404 response when source is private' do
  55. let(:route) { get v3_api("/#{source_type.pluralize}/#{source.id}/members/#{developer.id}", stranger) }
  56. end
  57. context 'when authenticated as a non-member' do
  58. %i[access_requester stranger].each do |type|
  59. context "as a #{type}" do
  60. it 'returns 200' do
  61. user = public_send(type)
  62. get v3_api("/#{source_type.pluralize}/#{source.id}/members/#{developer.id}", user)
  63. expect(response).to have_gitlab_http_status(200)
  64. # User attributes
  65. expect(json_response['id']).to eq(developer.id)
  66. expect(json_response['name']).to eq(developer.name)
  67. expect(json_response['username']).to eq(developer.username)
  68. expect(json_response['state']).to eq(developer.state)
  69. expect(json_response['avatar_url']).to eq(developer.avatar_url)
  70. expect(json_response['web_url']).to eq(Gitlab::Routing.url_helpers.user_url(developer))
  71. # Member attributes
  72. expect(json_response['access_level']).to eq(Member::DEVELOPER)
  73. end
  74. end
  75. end
  76. end
  77. end
  78. end
  79. shared_examples 'POST /:sources/:id/members' do |source_type|
  80. context "with :sources == #{source_type.pluralize}" do
  81. it_behaves_like 'a 404 response when source is private' do
  82. let(:route) do
  83. post v3_api("/#{source_type.pluralize}/#{source.id}/members", stranger),
  84. user_id: access_requester.id, access_level: Member::MASTER
  85. end
  86. end
  87. context 'when authenticated as a non-member or member with insufficient rights' do
  88. %i[access_requester stranger developer].each do |type|
  89. context "as a #{type}" do
  90. it 'returns 403' do
  91. user = public_send(type)
  92. post v3_api("/#{source_type.pluralize}/#{source.id}/members", user),
  93. user_id: access_requester.id, access_level: Member::MASTER
  94. expect(response).to have_gitlab_http_status(403)
  95. end
  96. end
  97. end
  98. end
  99. context 'when authenticated as a master/owner' do
  100. context 'and new member is already a requester' do
  101. it 'transforms the requester into a proper member' do
  102. expect do
  103. post v3_api("/#{source_type.pluralize}/#{source.id}/members", master),
  104. user_id: access_requester.id, access_level: Member::MASTER
  105. expect(response).to have_gitlab_http_status(201)
  106. end.to change { source.members.count }.by(1)
  107. expect(source.requesters.count).to eq(0)
  108. expect(json_response['id']).to eq(access_requester.id)
  109. expect(json_response['access_level']).to eq(Member::MASTER)
  110. end
  111. end
  112. it 'creates a new member' do
  113. expect do
  114. post v3_api("/#{source_type.pluralize}/#{source.id}/members", master),
  115. user_id: stranger.id, access_level: Member::DEVELOPER, expires_at: '2016-08-05'
  116. expect(response).to have_gitlab_http_status(201)
  117. end.to change { source.members.count }.by(1)
  118. expect(json_response['id']).to eq(stranger.id)
  119. expect(json_response['access_level']).to eq(Member::DEVELOPER)
  120. expect(json_response['expires_at']).to eq('2016-08-05')
  121. end
  122. end
  123. it "returns #{source_type == 'project' ? 201 : 409} if member already exists" do
  124. post v3_api("/#{source_type.pluralize}/#{source.id}/members", master),
  125. user_id: master.id, access_level: Member::MASTER
  126. expect(response).to have_gitlab_http_status(source_type == 'project' ? 201 : 409)
  127. end
  128. it 'returns 400 when user_id is not given' do
  129. post v3_api("/#{source_type.pluralize}/#{source.id}/members", master),
  130. access_level: Member::MASTER
  131. expect(response).to have_gitlab_http_status(400)
  132. end
  133. it 'returns 400 when access_level is not given' do
  134. post v3_api("/#{source_type.pluralize}/#{source.id}/members", master),
  135. user_id: stranger.id
  136. expect(response).to have_gitlab_http_status(400)
  137. end
  138. it 'returns 422 when access_level is not valid' do
  139. post v3_api("/#{source_type.pluralize}/#{source.id}/members", master),
  140. user_id: stranger.id, access_level: 1234
  141. expect(response).to have_gitlab_http_status(422)
  142. end
  143. end
  144. end
  145. shared_examples 'PUT /:sources/:id/members/:user_id' do |source_type|
  146. context "with :sources == #{source_type.pluralize}" do
  147. it_behaves_like 'a 404 response when source is private' do
  148. let(:route) do
  149. put v3_api("/#{source_type.pluralize}/#{source.id}/members/#{developer.id}", stranger),
  150. access_level: Member::MASTER
  151. end
  152. end
  153. context 'when authenticated as a non-member or member with insufficient rights' do
  154. %i[access_requester stranger developer].each do |type|
  155. context "as a #{type}" do
  156. it 'returns 403' do
  157. user = public_send(type)
  158. put v3_api("/#{source_type.pluralize}/#{source.id}/members/#{developer.id}", user),
  159. access_level: Member::MASTER
  160. expect(response).to have_gitlab_http_status(403)
  161. end
  162. end
  163. end
  164. end
  165. context 'when authenticated as a master/owner' do
  166. it 'updates the member' do
  167. put v3_api("/#{source_type.pluralize}/#{source.id}/members/#{developer.id}", master),
  168. access_level: Member::MASTER, expires_at: '2016-08-05'
  169. expect(response).to have_gitlab_http_status(200)
  170. expect(json_response['id']).to eq(developer.id)
  171. expect(json_response['access_level']).to eq(Member::MASTER)
  172. expect(json_response['expires_at']).to eq('2016-08-05')
  173. end
  174. end
  175. it 'returns 409 if member does not exist' do
  176. put v3_api("/#{source_type.pluralize}/#{source.id}/members/123", master),
  177. access_level: Member::MASTER
  178. expect(response).to have_gitlab_http_status(404)
  179. end
  180. it 'returns 400 when access_level is not given' do
  181. put v3_api("/#{source_type.pluralize}/#{source.id}/members/#{developer.id}", master)
  182. expect(response).to have_gitlab_http_status(400)
  183. end
  184. it 'returns 422 when access level is not valid' do
  185. put v3_api("/#{source_type.pluralize}/#{source.id}/members/#{developer.id}", master),
  186. access_level: 1234
  187. expect(response).to have_gitlab_http_status(422)
  188. end
  189. end
  190. end
  191. shared_examples 'DELETE /:sources/:id/members/:user_id' do |source_type|
  192. context "with :sources == #{source_type.pluralize}" do
  193. it_behaves_like 'a 404 response when source is private' do
  194. let(:route) { delete v3_api("/#{source_type.pluralize}/#{source.id}/members/#{developer.id}", stranger) }
  195. end
  196. context 'when authenticated as a non-member or member with insufficient rights' do
  197. %i[access_requester stranger].each do |type|
  198. context "as a #{type}" do
  199. it 'returns 403' do
  200. user = public_send(type)
  201. delete v3_api("/#{source_type.pluralize}/#{source.id}/members/#{developer.id}", user)
  202. expect(response).to have_gitlab_http_status(403)
  203. end
  204. end
  205. end
  206. end
  207. context 'when authenticated as a member and deleting themself' do
  208. it 'deletes the member' do
  209. expect do
  210. delete v3_api("/#{source_type.pluralize}/#{source.id}/members/#{developer.id}", developer)
  211. expect(response).to have_gitlab_http_status(200)
  212. end.to change { source.members.count }.by(-1)
  213. end
  214. end
  215. context 'when authenticated as a master/owner' do
  216. context 'and member is a requester' do
  217. it "returns #{source_type == 'project' ? 200 : 404}" do
  218. expect do
  219. delete v3_api("/#{source_type.pluralize}/#{source.id}/members/#{access_requester.id}", master)
  220. expect(response).to have_gitlab_http_status(source_type == 'project' ? 200 : 404)
  221. end.not_to change { source.requesters.count }
  222. end
  223. end
  224. it 'deletes the member' do
  225. expect do
  226. delete v3_api("/#{source_type.pluralize}/#{source.id}/members/#{developer.id}", master)
  227. expect(response).to have_gitlab_http_status(200)
  228. end.to change { source.members.count }.by(-1)
  229. end
  230. end
  231. it "returns #{source_type == 'project' ? 200 : 404} if member does not exist" do
  232. delete v3_api("/#{source_type.pluralize}/#{source.id}/members/123", master)
  233. expect(response).to have_gitlab_http_status(source_type == 'project' ? 200 : 404)
  234. end
  235. end
  236. end
  237. it_behaves_like 'GET /:sources/:id/members', 'project' do
  238. let(:source) { project }
  239. end
  240. it_behaves_like 'GET /:sources/:id/members', 'group' do
  241. let(:source) { group }
  242. end
  243. it_behaves_like 'GET /:sources/:id/members/:user_id', 'project' do
  244. let(:source) { project }
  245. end
  246. it_behaves_like 'GET /:sources/:id/members/:user_id', 'group' do
  247. let(:source) { group }
  248. end
  249. it_behaves_like 'POST /:sources/:id/members', 'project' do
  250. let(:source) { project }
  251. end
  252. it_behaves_like 'POST /:sources/:id/members', 'group' do
  253. let(:source) { group }
  254. end
  255. it_behaves_like 'PUT /:sources/:id/members/:user_id', 'project' do
  256. let(:source) { project }
  257. end
  258. it_behaves_like 'PUT /:sources/:id/members/:user_id', 'group' do
  259. let(:source) { group }
  260. end
  261. it_behaves_like 'DELETE /:sources/:id/members/:user_id', 'project' do
  262. let(:source) { project }
  263. end
  264. it_behaves_like 'DELETE /:sources/:id/members/:user_id', 'group' do
  265. let(:source) { group }
  266. end
  267. context 'Adding owner to project' do
  268. it 'returns 403' do
  269. expect do
  270. post v3_api("/projects/#{project.id}/members", master),
  271. user_id: stranger.id, access_level: Member::OWNER
  272. expect(response).to have_gitlab_http_status(422)
  273. end.to change { project.members.count }.by(0)
  274. end
  275. end
  276. end