/spec/requests/projects/google_cloud/service_accounts_controller_spec.rb

https://gitlab.com/abuhazim/gitlab-foss · Ruby · 248 lines · 195 code · 52 blank · 1 comment · 0 complexity · 9ddeb35ab928736721b0fbaf53017b64 MD5 · raw file

  1. # frozen_string_literal: true
  2. require 'spec_helper'
  3. RSpec.describe Projects::GoogleCloud::ServiceAccountsController do
  4. let_it_be(:project) { create(:project, :public) }
  5. describe 'GET index', :snowplow do
  6. let_it_be(:url) { "#{project_google_cloud_service_accounts_path(project)}" }
  7. let(:user_guest) { create(:user) }
  8. let(:user_developer) { create(:user) }
  9. let(:user_maintainer) { create(:user) }
  10. let(:user_creator) { project.creator }
  11. let(:unauthorized_members) { [user_guest, user_developer] }
  12. let(:authorized_members) { [user_maintainer, user_creator] }
  13. before do
  14. project.add_guest(user_guest)
  15. project.add_developer(user_developer)
  16. project.add_maintainer(user_maintainer)
  17. end
  18. context 'when a public request is made' do
  19. it 'returns not found on GET request' do
  20. get url
  21. expect(response).to have_gitlab_http_status(:not_found)
  22. expect_snowplow_event(
  23. category: 'Projects::GoogleCloud',
  24. action: 'admin_project_google_cloud!',
  25. label: 'access_denied',
  26. property: 'invalid_user',
  27. project: project,
  28. user: nil
  29. )
  30. end
  31. it 'returns not found on POST request' do
  32. post url
  33. expect(response).to have_gitlab_http_status(:not_found)
  34. end
  35. end
  36. context 'when unauthorized members make requests' do
  37. it 'returns not found on GET request' do
  38. unauthorized_members.each do |unauthorized_member|
  39. sign_in(unauthorized_member)
  40. get url
  41. expect_snowplow_event(
  42. category: 'Projects::GoogleCloud',
  43. action: 'admin_project_google_cloud!',
  44. label: 'access_denied',
  45. property: 'invalid_user',
  46. project: project,
  47. user: unauthorized_member
  48. )
  49. expect(response).to have_gitlab_http_status(:not_found)
  50. end
  51. end
  52. it 'returns not found on POST request' do
  53. unauthorized_members.each do |unauthorized_member|
  54. sign_in(unauthorized_member)
  55. post url
  56. expect_snowplow_event(
  57. category: 'Projects::GoogleCloud',
  58. action: 'admin_project_google_cloud!',
  59. label: 'access_denied',
  60. property: 'invalid_user',
  61. project: project,
  62. user: unauthorized_member
  63. )
  64. expect(response).to have_gitlab_http_status(:not_found)
  65. end
  66. end
  67. end
  68. context 'when authorized members make requests' do
  69. it 'redirects on GET request' do
  70. authorized_members.each do |authorized_member|
  71. sign_in(authorized_member)
  72. get url
  73. expect(response).to redirect_to(assigns(:authorize_url))
  74. end
  75. end
  76. it 'redirects on POST request' do
  77. authorized_members.each do |authorized_member|
  78. sign_in(authorized_member)
  79. post url
  80. expect(response).to redirect_to(assigns(:authorize_url))
  81. end
  82. end
  83. context 'and user has successfully completed the google oauth2 flow' do
  84. context 'but the user does not have gcp projects' do
  85. before do
  86. allow_next_instance_of(GoogleApi::CloudPlatform::Client) do |client|
  87. mock_service_account = Struct.new(:project_id, :unique_id, :email).new(123, 456, 'em@ai.l')
  88. allow(client).to receive(:list_projects).and_return([])
  89. allow(client).to receive(:validate_token).and_return(true)
  90. allow(client).to receive(:create_service_account).and_return(mock_service_account)
  91. allow(client).to receive(:create_service_account_key).and_return({})
  92. allow(client).to receive(:grant_service_account_roles)
  93. end
  94. end
  95. it 'renders no_gcp_projects' do
  96. authorized_members.each do |authorized_member|
  97. allow_next_instance_of(BranchesFinder) do |branches_finder|
  98. allow(branches_finder).to receive(:execute).and_return([])
  99. end
  100. allow_next_instance_of(TagsFinder) do |branches_finder|
  101. allow(branches_finder).to receive(:execute).and_return([])
  102. end
  103. sign_in(authorized_member)
  104. get url
  105. expect(response).to render_template('projects/google_cloud/errors/no_gcp_projects')
  106. end
  107. end
  108. end
  109. context 'user has three gcp_projects' do
  110. before do
  111. allow_next_instance_of(GoogleApi::CloudPlatform::Client) do |client|
  112. mock_service_account = Struct.new(:project_id, :unique_id, :email).new(123, 456, 'em@ai.l')
  113. allow(client).to receive(:list_projects).and_return([{}, {}, {}])
  114. allow(client).to receive(:validate_token).and_return(true)
  115. allow(client).to receive(:create_service_account).and_return(mock_service_account)
  116. allow(client).to receive(:create_service_account_key).and_return({})
  117. allow(client).to receive(:grant_service_account_roles)
  118. end
  119. end
  120. it 'returns success on GET' do
  121. authorized_members.each do |authorized_member|
  122. allow_next_instance_of(BranchesFinder) do |branches_finder|
  123. allow(branches_finder).to receive(:execute).and_return([])
  124. end
  125. allow_next_instance_of(TagsFinder) do |branches_finder|
  126. allow(branches_finder).to receive(:execute).and_return([])
  127. end
  128. sign_in(authorized_member)
  129. get url
  130. expect(response).to have_gitlab_http_status(:ok)
  131. end
  132. end
  133. it 'returns success on POST' do
  134. authorized_members.each do |authorized_member|
  135. sign_in(authorized_member)
  136. post url, params: { gcp_project: 'prj1', ref: 'env1' }
  137. expect(response).to redirect_to(project_google_cloud_index_path(project))
  138. end
  139. end
  140. end
  141. end
  142. context 'but google returns client error' do
  143. before do
  144. allow_next_instance_of(GoogleApi::CloudPlatform::Client) do |client|
  145. allow(client).to receive(:validate_token).and_return(true)
  146. allow(client).to receive(:list_projects).and_raise(Google::Apis::ClientError.new(''))
  147. allow(client).to receive(:create_service_account).and_raise(Google::Apis::ClientError.new(''))
  148. allow(client).to receive(:create_service_account_key).and_raise(Google::Apis::ClientError.new(''))
  149. end
  150. end
  151. it 'renders gcp_error template on GET' do
  152. authorized_members.each do |authorized_member|
  153. sign_in(authorized_member)
  154. get url
  155. expect(response).to render_template(:gcp_error)
  156. end
  157. end
  158. it 'renders gcp_error template on POST' do
  159. authorized_members.each do |authorized_member|
  160. sign_in(authorized_member)
  161. post url, params: { gcp_project: 'prj1', environment: 'env1' }
  162. expect(response).to render_template(:gcp_error)
  163. end
  164. end
  165. end
  166. context 'but gitlab instance is not configured for google oauth2' do
  167. before do
  168. unconfigured_google_oauth2 = Struct.new(:app_id, :app_secret)
  169. .new('', '')
  170. allow(Gitlab::Auth::OAuth::Provider).to receive(:config_for)
  171. .with('google_oauth2')
  172. .and_return(unconfigured_google_oauth2)
  173. end
  174. it 'returns forbidden' do
  175. authorized_members.each do |authorized_member|
  176. sign_in(authorized_member)
  177. get url
  178. expect(response).to have_gitlab_http_status(:forbidden)
  179. end
  180. end
  181. end
  182. context 'but feature flag is disabled' do
  183. before do
  184. stub_feature_flags(incubation_5mp_google_cloud: false)
  185. end
  186. it 'returns not found' do
  187. authorized_members.each do |authorized_member|
  188. sign_in(authorized_member)
  189. get url
  190. expect(response).to have_gitlab_http_status(:not_found)
  191. end
  192. end
  193. end
  194. end
  195. end
  196. end