diff options
Diffstat (limited to 'qa/qa/resource')
-rw-r--r-- | qa/qa/resource/api_fabricator.rb | 35 | ||||
-rw-r--r-- | qa/qa/resource/design.rb | 31 | ||||
-rw-r--r-- | qa/qa/resource/events/base.rb | 7 | ||||
-rw-r--r-- | qa/qa/resource/events/project.rb | 7 | ||||
-rw-r--r-- | qa/qa/resource/merge_request.rb | 46 | ||||
-rw-r--r-- | qa/qa/resource/project.rb | 16 | ||||
-rw-r--r-- | qa/qa/resource/repository/push.rb | 5 | ||||
-rw-r--r-- | qa/qa/resource/snippet.rb | 11 | ||||
-rw-r--r-- | qa/qa/resource/ssh_key.rb | 9 |
9 files changed, 156 insertions, 11 deletions
diff --git a/qa/qa/resource/api_fabricator.rb b/qa/qa/resource/api_fabricator.rb index d0cbab70983..034feb4e90f 100644 --- a/qa/qa/resource/api_fabricator.rb +++ b/qa/qa/resource/api_fabricator.rb @@ -96,15 +96,38 @@ module QA end def api_post - response = post( - Runtime::API::Request.new(api_client, api_post_path).url, - api_post_body) + if api_post_path == "/graphql" + graphql_response = post( + Runtime::API::Request.new(api_client, api_post_path).url, + query: api_post_body) - unless response.code == HTTP_STATUS_CREATED - raise ResourceFabricationFailedError, "Fabrication of #{self.class.name} using the API failed (#{response.code}) with `#{response}`." + flattened_response = flatten_hash(parse_body(graphql_response)) + + unless graphql_response.code == HTTP_STATUS_OK && flattened_response[:errors].empty? + raise ResourceFabricationFailedError, "Fabrication of #{self.class.name} using the API failed (#{graphql_response.code}) with `#{graphql_response}`." + end + + flattened_response[:web_url] = flattened_response.delete(:webUrl) + flattened_response[:id] = flattened_response.fetch(:id).split('/')[-1] + + process_api_response(flattened_response) + else + response = post( + Runtime::API::Request.new(api_client, api_post_path).url, + api_post_body) + + unless response.code == HTTP_STATUS_CREATED + raise ResourceFabricationFailedError, "Fabrication of #{self.class.name} using the API failed (#{response.code}) with `#{response}`." + end + + process_api_response(parse_body(response)) end + end - process_api_response(parse_body(response)) + def flatten_hash(param) + param.each_pair.reduce({}) do |a, (k, v)| + v.is_a?(Hash) ? a.merge(flatten_hash(v)) : a.merge(k.to_sym => v) + end end def api_delete diff --git a/qa/qa/resource/design.rb b/qa/qa/resource/design.rb new file mode 100644 index 00000000000..10d4f32d49d --- /dev/null +++ b/qa/qa/resource/design.rb @@ -0,0 +1,31 @@ +# frozen_string_literal: true + +module QA + module Resource + class Design < Base + attribute :issue do + Issue.fabricate_via_api! + end + + attribute :filepath do + ::File.absolute_path(::File.join('spec', 'fixtures', @filename)) + end + + attribute :id + attribute :filename + + def initialize + @filename = 'banana_sample.gif' + end + + # TODO This will be replaced as soon as file uploads over GraphQL are implemented + def fabricate! + issue.visit! + + Page::Project::Issue::Show.perform do |issue| + issue.add_design(filepath) + end + end + end + end +end diff --git a/qa/qa/resource/events/base.rb b/qa/qa/resource/events/base.rb index 91ec0e59e37..4c5f54825b3 100644 --- a/qa/qa/resource/events/base.rb +++ b/qa/qa/resource/events/base.rb @@ -9,9 +9,12 @@ module QA EventNotFoundError = Class.new(RuntimeError) module Base - def events(action: nil) + def events(action: nil, target_type: nil) + query = [] + query << "action=#{CGI.escape(action)}" if action + query << "target_type=#{CGI.escape(target_type)}" if target_type path = [api_get_events] - path << "?action=#{CGI.escape(action)}" if action + path << "?#{query.join("&")}" unless query.empty? parse_body(api_get_from("#{path.join}")) end diff --git a/qa/qa/resource/events/project.rb b/qa/qa/resource/events/project.rb index 99c78254f42..8c97f66c663 100644 --- a/qa/qa/resource/events/project.rb +++ b/qa/qa/resource/events/project.rb @@ -6,6 +6,13 @@ module QA module Project include Events::Base + def wait_for_merge(title) + QA::Runtime::Logger.debug(%Q[#{self.class.name} - wait_for_merge with title "#{title}"]) + wait_for_event do + events(action: 'accepted', target_type: 'merge_request').any? { |event| event[:target_title] == title } + end + end + def wait_for_push(commit_message) QA::Runtime::Logger.debug(%Q[#{self.class.name} - wait_for_push with commit message "#{commit_message}"]) wait_for_event do diff --git a/qa/qa/resource/merge_request.rb b/qa/qa/resource/merge_request.rb index 6c0f4621dd9..dca8fb6dc6b 100644 --- a/qa/qa/resource/merge_request.rb +++ b/qa/qa/resource/merge_request.rb @@ -1,6 +1,7 @@ # frozen_string_literal: true require 'securerandom' +require 'active_support/core_ext/object/blank' module QA module Resource @@ -17,7 +18,12 @@ module QA :labels, :file_name, :file_content - attr_writer :no_preparation + attr_writer :no_preparation, + :wait_for_merge + + attribute :merge_when_pipeline_succeeds + attribute :merge_status + attribute :state attribute :project do Project.fabricate! do |resource| @@ -58,6 +64,7 @@ module QA @file_content = "File Added" @target_new_branch = true @no_preparation = false + @wait_for_merge = true end def fabricate! @@ -80,10 +87,17 @@ module QA end def fabricate_via_api! + resource_web_url(api_get) + rescue ResourceNotFoundError populate(:target, :source) unless @no_preparation + super end + def api_merge_path + "/projects/#{project.id}/merge_requests/#{id}/merge" + end + def api_get_path "/projects/#{project.id}/merge_requests/#{id}" end @@ -100,6 +114,36 @@ module QA title: @title } end + + def merge_via_api! + Support::Waiter.wait_until(sleep_interval: 1) do + QA::Runtime::Logger.debug("Waiting until merge request with id '#{id}' can be merged") + + reload!.api_resource[:merge_status] == 'can_be_merged' + end + + Support::Retrier.retry_on_exception do + response = put(Runtime::API::Request.new(api_client, api_merge_path).url) + + unless response.code == HTTP_STATUS_OK + raise ResourceUpdateFailedError, "Could not merge. Request returned (#{response.code}): `#{response}`." + end + + result = parse_body(response) + + project.wait_for_merge(result[:title]) if @wait_for_merge + + result + end + end + + private + + def transform_api_resource(api_resource) + raise ResourceNotFoundError if api_resource.blank? + + super(api_resource) + end end end end diff --git a/qa/qa/resource/project.rb b/qa/qa/resource/project.rb index 0025ebb2fd5..163c0b40bb5 100644 --- a/qa/qa/resource/project.rb +++ b/qa/qa/resource/project.rb @@ -110,6 +110,10 @@ module QA response.any? { |file| file[:path] == file_path } end + def has_branch?(branch) + has_branches?(Array(branch)) + end + def has_branches?(branches) branches.all? do |branch| response = get(Runtime::API::Request.new(api_client, "#{api_repository_branches_path}/#{branch}").url) @@ -140,6 +144,10 @@ module QA "#{api_get_path}/members" end + def api_merge_requests_path + "#{api_get_path}/merge_requests" + end + def api_runners_path "#{api_get_path}/runners" end @@ -223,6 +231,14 @@ module QA result[:import_status] end + def merge_requests + parse_body(get(Runtime::API::Request.new(api_client, api_merge_requests_path).url)) + end + + def merge_request_with_title(title) + merge_requests.find { |mr| mr[:title] == title } + end + def runners(tag_list: nil) response = if tag_list get Runtime::API::Request.new(api_client, "#{api_runners_path}?tag_list=#{tag_list.compact.join(',')}").url diff --git a/qa/qa/resource/repository/push.rb b/qa/qa/resource/repository/push.rb index 1e5399fcc59..5266f8b9bea 100644 --- a/qa/qa/resource/repository/push.rb +++ b/qa/qa/resource/repository/push.rb @@ -11,7 +11,7 @@ module QA :branch_name, :new_branch, :output, :repository_http_uri, :repository_ssh_uri, :ssh_key, :user, :use_lfs, :tag_name - attr_writer :remote_branch, :gpg_key_id + attr_writer :remote_branch, :gpg_key_id, :merge_request_push_options def initialize @file_name = "file-#{SecureRandom.hex(8)}.txt" @@ -24,6 +24,7 @@ module QA @use_lfs = false @tag_name = nil @gpg_key_id = nil + @merge_request_push_options = nil end def remote_branch @@ -95,7 +96,7 @@ module QA end @output += commit_to repository - @output += repository.push_changes("#{branch_name}:#{remote_branch}") + @output += repository.push_changes("#{branch_name}:#{remote_branch}", push_options: @merge_request_push_options) end repository.delete_ssh_key diff --git a/qa/qa/resource/snippet.rb b/qa/qa/resource/snippet.rb index 39be5e5cb7d..c4ea6447209 100644 --- a/qa/qa/resource/snippet.rb +++ b/qa/qa/resource/snippet.rb @@ -11,6 +11,11 @@ module QA @visibility = 'Public' @file_content = 'The snippet content' @file_name = 'New snippet file name' + @files = [] + end + + def add_files + yield @files end def fabricate! @@ -22,6 +27,12 @@ module QA new_page.set_visibility(@visibility) new_page.fill_file_name(@file_name) new_page.fill_file_content(@file_content) + + @files.each.with_index(2) do |file, i| + new_page.click_add_file + new_page.fill_file_name(file[:name], i) + new_page.fill_file_content(file[:content], i) + end new_page.click_create_snippet_button end end diff --git a/qa/qa/resource/ssh_key.rb b/qa/qa/resource/ssh_key.rb index d4e394954ce..fcd0a479fec 100644 --- a/qa/qa/resource/ssh_key.rb +++ b/qa/qa/resource/ssh_key.rb @@ -76,6 +76,15 @@ module QA parse_body(response)[:title].include?(title) end end + + private + + def api_get + with_paginated_response_body(Runtime::API::Request.new(api_client, '/user/keys', per_page: '100').url) do |page| + key = page.find { |key| key[:title] == title } + break process_api_response(key) if key + end + end end end end |