Commit d4db3cf9 authored by Sanad Liaquat's avatar Sanad Liaquat

Merge branch 'acunskis-refactor-mr-api' into 'master'

E2E: Refactor merge request resource to api-only fabrication

See merge request gitlab-org/gitlab!77223
parents ccf33f48 015ab3aa
......@@ -6,11 +6,13 @@ module QA
attr_accessor :approval_rules,
:source_branch,
:target_new_branch,
:update_existing_file,
:assignee,
:milestone,
:labels,
:file_name,
:file_content
attr_writer :no_preparation,
:wait_for_merge,
:template
......@@ -25,6 +27,8 @@ module QA
attribute :project do
Project.fabricate_via_api! do |resource|
resource.name = 'project-with-merge-request'
resource.initialize_with_readme = true
resource.api_client = api_client
end
end
......@@ -33,22 +37,27 @@ module QA
end
attribute :target do
Repository::ProjectPush.fabricate! do |resource|
Repository::Commit.fabricate_via_api! do |resource|
resource.project = project
resource.branch_name = target_branch
resource.new_branch = target_new_branch
resource.remote_branch = target_branch
resource.api_client = api_client
resource.commit_message = 'This is a test commit'
resource.add_files([{ 'file_path': "file-#{SecureRandom.hex(8)}.txt", 'content': 'MR init' }])
resource.branch = target_branch
resource.start_branch = project.default_branch if target_branch != project.default_branch
end
end
attribute :source do
Repository::ProjectPush.fabricate! do |resource|
Repository::Commit.fabricate_via_api! do |resource|
resource.project = project
resource.branch_name = target_branch
resource.remote_branch = source_branch
resource.new_branch = false
resource.file_name = file_name
resource.file_content = file_content
resource.api_client = api_client
resource.commit_message = 'This is a test commit'
resource.branch = source_branch
resource.start_branch = target_branch
files = [{ 'file_path': file_name, 'content': file_content }]
update_existing_file ? resource.update_files(files) : resource.add_files(files)
end
end
......@@ -63,6 +72,7 @@ module QA
@file_name = "added_file-#{SecureRandom.hex(8)}.txt"
@file_content = "File Added"
@target_new_branch = true
@update_existing_file = false
@no_preparation = false
@wait_for_merge = true
end
......@@ -204,8 +214,24 @@ module QA
super(api_resource)
end
# Create source and target and commits if necessary
#
# @return [void]
def populate_target_and_source_if_required
populate(:target, :source) unless @no_preparation
return if @no_preparation
populate(:target) if create_target?
populate(:source)
end
# Check if target needs to be created
#
# Return false if project was already initialized and mr target is default branch
# Return false if target_new_branch is explicitly set to false
#
# @return [Boolean]
def create_target?
!(project.initialize_with_readme && target_branch == project.default_branch) && target_new_branch
end
end
end
......
......@@ -107,32 +107,6 @@ module QA
super
end
def has_file?(file_path)
response = repository_tree
raise ResourceNotFoundError, (response[:message]).to_s if response.is_a?(Hash) && response.has_key?(:message)
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(request_url("#{api_repository_branches_path}/#{branch}"))
response.code == HTTP_STATUS_OK
end
end
def has_tags?(tags)
tags.all? do |tag|
response = get(request_url("#{api_repository_tags_path}/#{tag}"))
response.code == HTTP_STATUS_OK
end
end
def api_get_path
"/projects/#{CGI.escape(path_with_namespace)}"
end
......@@ -237,6 +211,32 @@ module QA
post_body
end
def has_file?(file_path)
response = repository_tree
raise ResourceNotFoundError, (response[:message]).to_s if response.is_a?(Hash) && response.has_key?(:message)
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(request_url("#{api_repository_branches_path}/#{branch}"))
response.code == HTTP_STATUS_OK
end
end
def has_tags?(tags)
tags.all? do |tag|
response = get(request_url("#{api_repository_tags_path}/#{tag}"))
response.code == HTTP_STATUS_OK
end
end
def change_repository_storage(new_storage)
response = put(request_url(api_put_path), repository_storage: new_storage)
......
......@@ -22,42 +22,7 @@ module QA
def initialize
@commit_message = 'QA Test - Commit message'
end
def add_files(files)
validate_files!(files)
@add_files = files
end
def add_directory(dir)
raise "Must set directory as a Pathname" unless dir.is_a?(Pathname)
files_to_add = []
dir.each_child do |child|
case child.ftype?
when "file"
files_to_add.append({
file_path: child.to_s,
content: child.read
})
when "directory"
add_directory(child)
else
continue
end
end
validate_files!(files_to_add)
@add_files.merge(files_to_add)
end
def update_files(files)
validate_files!(files)
@update_files = files
@actions = []
end
# If `actions` are specified, it performs the actions to create,
......@@ -72,32 +37,74 @@ module QA
end
def api_get_path
api_post_path
"/projects/#{CGI.escape(project.path_with_namespace)}/repository/commits"
end
def api_post_path
"/projects/#{CGI.escape(project.path_with_namespace)}/repository/commits"
api_get_path
end
def api_post_body
{
branch: @branch || project.default_branch,
author_email: @author_email || Runtime::User.default_email,
author_name: @author_name || Runtime::User.username,
branch: branch || project.default_branch,
author_email: author_email || api_client.user&.email || Runtime::User.default_email,
author_name: author_name || api_client.user&.name || Runtime::User.username,
commit_message: commit_message,
actions: actions
}.merge(new_branch)
end
def actions
pending_actions = []
pending_actions << @add_files.map { |file| file.merge({ action: "create" }) } if @add_files
pending_actions << @update_files.map { |file| file.merge({ action: "update" }) } if @update_files
pending_actions.flatten
# Add files
# Pass in array of new files like, example:
# [{ "file_path": "foo/bar", "content": "some content" }]
#
# @param [Array<Hash>] files
# @return [void]
def add_files(files)
validate_files!(files)
actions.push(*files.map { |file| file.merge({ action: "create" }) })
end
# Update files
# Pass in array of files and it's contents, example:
# [{ "file_path": "foo/bar", "content": "some content" }]
#
# @param [Array<Hash>] files
# @return [void]
def update_files(files)
validate_files!(files)
actions.push(*files.map { |file| file.merge({ action: "update" }) })
end
# Add all files from directory
#
# @param [Pathname] dir
# @return [void]
def add_directory(dir)
raise "Must set directory as a Pathname" unless dir.is_a?(Pathname)
files_to_add = []
dir.each_child do |child|
case child.ftype
when "directory"
add_directory(child)
when "file"
files_to_add.push({ file_path: child.basename, content: child.read })
else
continue
end
end
add_files(files_to_add)
end
private
attr_reader :actions
def validate_files!(files)
if !files.is_a?(Array) ||
files.empty? ||
......
......@@ -198,6 +198,8 @@ module QA
end
context 'with merge request' do
let(:source_project_with_readme) { true }
let(:other_user) do
Resource::User.fabricate_via_api! do |usr|
usr.api_client = admin_api_client
......
......@@ -19,7 +19,7 @@ module QA
group = QA::Resource::Group.fabricate_via_api! do |group|
group.path = "group_for_follow_user_activity_#{SecureRandom.hex(8)}"
end
group.add_member(user)
group.add_member(user, Resource::Members::AccessLevel::MAINTAINER)
group
end
......
......@@ -13,7 +13,7 @@ module QA
Resource::Runner.fabricate_via_api! do |runner|
runner.project = project
runner.name = project.name
runner.tags = ["#{project.name}"]
runner.tags = [project.name]
end
end
......
......@@ -5,7 +5,7 @@ module QA
describe 'License merge request widget' do
let(:approved_license_name) { "MIT License" }
let(:denied_license_name) { "zlib License" }
let(:executor) {"qa-runner-#{Time.now.to_i}"}
let(:executor) { "qa-runner-#{Time.now.to_i}" }
after do
@runner.remove_via_api!
......@@ -25,12 +25,12 @@ module QA
runner.tags = ['secure_license']
end
Resource::Repository::ProjectPush.fabricate! do |project_push|
project_push.project = @project
project_push.directory = Pathname
Resource::Repository::Commit.fabricate_via_api! do |resource|
resource.project = @project
resource.commit_message = 'Create license file'
resource.add_directory(Pathname
.new(__dir__)
.join('../../../../../ee/fixtures/secure_license_files')
project_push.commit_message = 'Create license file'
.join('../../../../../ee/fixtures/secure_license_files'))
end
@project.visit!
......@@ -40,7 +40,6 @@ module QA
mr.project = @project
mr.source_branch = 'license-management-mr'
mr.target_branch = @project.default_branch
mr.target = @project.default_branch
mr.file_name = 'gl-license-scanning-report.json'
mr.file_content =
<<~FILE_UPDATE
......@@ -89,6 +88,7 @@ module QA
}
FILE_UPDATE
mr.target_new_branch = false
mr.update_existing_file = true
end
@project.visit!
......@@ -102,8 +102,7 @@ module QA
# Give time for the runner to complete pipeline
show.has_pipeline_status?('passed')
# TODO: Remove the reload_page: once https://gitlab.com/gitlab-org/gitlab/-/issues/335227 is fixed
Support::Retrier.retry_until(max_attempts: 5, sleep_interval: 5, reload_page: show) do
Support::Retrier.retry_until(max_attempts: 5, sleep_interval: 5) do
show.wait_for_license_compliance_report
end
......
......@@ -70,6 +70,7 @@ module QA
merge_request.project = @project
merge_request.description = Faker::Lorem.sentence
merge_request.target_new_branch = false
merge_request.update_existing_file = true
merge_request.file_name = @file_name
merge_request.file_content = Faker::Lorem.sentence
end
......@@ -115,7 +116,7 @@ module QA
Page::Dashboard::Todos.perform do |todos|
todos.wait_until(reload: true, sleep_interval: 1) { todos.has_todo_list? }
expect(todos).to have_latest_todo_item_with_content("Removed from Merge Train:", "#{mr_title}")
expect(todos).to have_latest_todo_item_with_content("Removed from Merge Train:", @mr_title)
end
end
end
......
......@@ -3,7 +3,13 @@
module QA
RSpec.describe 'Verify', :runner, :reliable do
describe 'Pipelines for merged results and merge trains' do
let(:executor) { "qa-runner-#{Faker::Alphanumeric.alphanumeric(8)}" }
let!(:project) do
Resource::Project.fabricate_via_api! do |project|
project.name = 'pipelines-for-merge-trains'
end
end
let!(:executor) { "qa-runner-#{Faker::Alphanumeric.alphanumeric(8)}" }
let!(:runner) do
Resource::Runner.fabricate_via_api! do |runner|
......@@ -13,12 +19,6 @@ module QA
end
end
let(:project) do
Resource::Project.fabricate_via_api! do |project|
project.name = 'pipelines-for-merge-trains'
end
end
let!(:ci_file) do
Resource::Repository::Commit.fabricate_via_api! do |commit|
commit.project = project
......@@ -60,7 +60,10 @@ module QA
runner.remove_via_api! if runner
end
it 'creates a pipeline with merged results', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/348034' do
it(
'creates a pipeline with merged results',
testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/348034'
) do
merge_request.visit!
Page::MergeRequest::Show.perform do |show|
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment