diff --git a/qa/qa.rb b/qa/qa.rb index 8b38011486b..9bf28d396ba 100644 --- a/qa/qa.rb +++ b/qa/qa.rb @@ -66,6 +66,7 @@ module QA autoload :Fork, 'qa/resource/fork' autoload :SSHKey, 'qa/resource/ssh_key' autoload :Snippet, 'qa/resource/snippet' + autoload :ProjectMember, 'qa/resource/project_member' module Events autoload :Base, 'qa/resource/events/base' diff --git a/qa/qa/git/repository.rb b/qa/qa/git/repository.rb index 84353e3d0c7..24b9fc67dd9 100644 --- a/qa/qa/git/repository.rb +++ b/qa/qa/git/repository.rb @@ -85,6 +85,8 @@ module QA end def add_file(name, contents) + FileUtils.mkdir_p(::File.dirname(name)) + ::File.write(name, contents) if use_lfs? diff --git a/qa/qa/page/main/login.rb b/qa/qa/page/main/login.rb index 94245bbfcba..65d83926f38 100644 --- a/qa/qa/page/main/login.rb +++ b/qa/qa/page/main/login.rb @@ -148,6 +148,12 @@ module QA click_element :saml_login_button end + def sign_out_and_sign_in_as(user:) + Menu.perform(&:sign_out) + has_sign_in_tab? + sign_in_using_credentials(user) + end + private def sign_in_using_gitlab_credentials(user) diff --git a/qa/qa/page/merge_request/show.rb b/qa/qa/page/merge_request/show.rb index 72f8e1c3ef0..6e550805f9f 100644 --- a/qa/qa/page/merge_request/show.rb +++ b/qa/qa/page/merge_request/show.rb @@ -119,7 +119,7 @@ module QA has_element?(:description, text: description) end - def merge! + def try_to_merge! # The merge button is disabled on load wait do has_element?(:merge_button) @@ -131,6 +131,10 @@ module QA end merge_immediately + end + + def merge! + try_to_merge! success = wait do has_text?('The changes were merged into') diff --git a/qa/qa/page/project/sub_menus/repository.rb b/qa/qa/page/project/sub_menus/repository.rb index c53d805c61d..65149e631f3 100644 --- a/qa/qa/page/project/sub_menus/repository.rb +++ b/qa/qa/page/project/sub_menus/repository.rb @@ -44,3 +44,5 @@ module QA end end end + +QA::Page::Project::SubMenus::Repository.prepend_if_ee('QA::EE::Page::Project::SubMenus::Repository') diff --git a/qa/qa/resource/api_fabricator.rb b/qa/qa/resource/api_fabricator.rb index d1d75b6179e..e4f708dc251 100644 --- a/qa/qa/resource/api_fabricator.rb +++ b/qa/qa/resource/api_fabricator.rb @@ -11,6 +11,7 @@ module QA ResourceNotFoundError = Class.new(RuntimeError) ResourceFabricationFailedError = Class.new(RuntimeError) ResourceURLMissingError = Class.new(RuntimeError) + ResourceNotDeletedError = Class.new(RuntimeError) attr_reader :api_resource, :api_response attr_writer :api_client @@ -30,6 +31,10 @@ module QA resource_web_url(api_post) end + def remove_via_api! + api_delete + end + def eager_load_api_client! return unless api_client.nil? @@ -79,6 +84,17 @@ module QA process_api_response(parse_body(response)) end + def api_delete + url = Runtime::API::Request.new(api_client, api_delete_path).url + response = delete(url) + + unless response.code == HTTP_STATUS_NO_CONTENT + raise ResourceNotDeletedError, "Resource at #{url} could not be deleted (#{response.code}): `#{response}`." + end + + response + end + def api_client @api_client ||= begin Runtime::API::Client.new(:gitlab, is_new_session: !current_url.start_with?('http'), user: user) diff --git a/qa/qa/resource/base.rb b/qa/qa/resource/base.rb index 283fc6cdbcb..88069df6ade 100644 --- a/qa/qa/resource/base.rb +++ b/qa/qa/resource/base.rb @@ -47,6 +47,18 @@ module QA end end + def self.remove_via_api!(*args, &prepare_block) + options = args.extract_options! + resource = options.fetch(:resource) { new } + parents = options.fetch(:parents) { [] } + + resource.eager_load_api_client! + + do_fabricate!(resource: resource, prepare_block: prepare_block, parents: parents) do + log_fabrication(:api, resource, parents, args) { resource.remove_via_api! } + end + end + def fabricate!(*_args) raise NotImplementedError end diff --git a/qa/qa/resource/branch.rb b/qa/qa/resource/branch.rb index a45dd030625..6dc47e36977 100644 --- a/qa/qa/resource/branch.rb +++ b/qa/qa/resource/branch.rb @@ -72,6 +72,18 @@ module QA end end end + + def self.unprotect_via_api!(&block) + self.remove_via_api!(&block) + end + + def api_get_path + "/projects/#{@project.api_resource[:id]}/protected_branches/#{@branch_name}" + end + + def api_delete_path + "/projects/#{@project.api_resource[:id]}/protected_branches/#{@branch_name}" + end end end end diff --git a/qa/qa/resource/merge_request.rb b/qa/qa/resource/merge_request.rb index 53126c67ba3..fe7eeeed37a 100644 --- a/qa/qa/resource/merge_request.rb +++ b/qa/qa/resource/merge_request.rb @@ -17,6 +17,7 @@ module QA :labels, :file_name, :file_content + attr_writer :no_preparation attribute :project do Project.fabricate! do |resource| @@ -58,6 +59,7 @@ module QA @file_name = "added_file.txt" @file_content = "File Added" @target_new_branch = true + @no_preparation = false end def fabricate! @@ -80,7 +82,7 @@ module QA end def fabricate_via_api! - populate(:target, :source) + populate(:target, :source) unless @no_preparation super end diff --git a/qa/qa/resource/project_member.rb b/qa/qa/resource/project_member.rb new file mode 100644 index 00000000000..dfaa157038c --- /dev/null +++ b/qa/qa/resource/project_member.rb @@ -0,0 +1,35 @@ +# frozen_string_literal: true + +module QA + module Resource + class ProjectMember < Base + attr_accessor :user, :project, :access_level + attr_reader :level + + def initialize + @level = { + guest: 10, + reporter: 20, + developer: 30, + maintainer: 40, + owner: 50 + } + end + + def api_get_path + "/projects/#{project.api_resource[:id]}/members/#{user.api_resource[:id]}" + end + + def api_post_path + "/projects/#{project.api_resource[:id]}/members" + end + + def api_post_body + { + user_id: user.api_resource[:id], + access_level: access_level + } + end + end + end +end diff --git a/qa/qa/support/api.rb b/qa/qa/support/api.rb index 203064b2665..d0ff1f8bc2c 100644 --- a/qa/qa/support/api.rb +++ b/qa/qa/support/api.rb @@ -5,6 +5,7 @@ module QA module Api HTTP_STATUS_OK = 200 HTTP_STATUS_CREATED = 201 + HTTP_STATUS_NO_CONTENT = 204 def post(url, payload) RestClient::Request.execute(