Commit 0165d36f authored by Sanad Liaquat's avatar Sanad Liaquat

Merge branch 'acunskis-iteration-migration' into 'master'

E2E: Validate iterations migration

See merge request gitlab-org/gitlab!70785
parents 89d2d950 8b325d3b
......@@ -20,9 +20,29 @@ module QA
end
end
# Get group iterations
#
# @return [Array<QA::EE::Resource::GroupIteration>]
def iterations
parse_body(api_get_from(api_iterations_path)).map do |iteration|
GroupIteration.init do |resource|
resource.group = self
resource.api_client = api_client
resource.id = iteration[:id]
resource.iid = iteration[:iid]
resource.title = iteration[:title]
resource.description = iteration[:description]
end
end
end
def api_epics_path
"#{api_get_path}/epics"
end
def api_iterations_path
"#{api_get_path}/iterations"
end
end
end
end
......
......@@ -6,19 +6,21 @@ module QA
class GroupIteration < QA::Resource::Base
include Support::Dates
attr_accessor :title
attribute :group do
QA::Resource::Group.fabricate_via_api! do |group|
group.path = "group-to-test-iterations-#{SecureRandom.hex(8)}"
end
end
attribute :id
attribute :start_date
attribute :due_date
attribute :description
attribute :title
attributes :id,
:iid,
:description,
:title,
:state,
:start_date,
:due_date,
:created_at,
:updated_at
def initialize
@start_date = current_date_yyyy_mm_dd
......@@ -34,23 +36,68 @@ module QA
QA::EE::Page::Group::Iteration::Index.perform(&:click_new_iteration_button)
QA::EE::Page::Group::Iteration::New.perform do |new|
new.fill_title(@title)
new.fill_description(@description)
new.fill_start_date(@start_date)
new.fill_due_date(@due_date)
new.click_create_iteration_button
QA::EE::Page::Group::Iteration::New.perform do |iteration_page|
iteration_page.fill_title(@title)
iteration_page.fill_description(@description)
iteration_page.fill_start_date(@start_date)
iteration_page.fill_due_date(@due_date)
iteration_page.click_create_iteration_button
end
end
# Iteration attributes
#
# @return [String]
def gql_attributes
@gql_attributes ||= <<~GQL
id
iid
description
title
state
startDate
dueDate
createdAt
updatedAt
webUrl
GQL
end
# Path for fetching iteration
#
# @return [String]
def api_get_path
"gid://gitlab/Iteration/#{id}"
"/graphql"
end
# Fetch iteration
#
# @return [Hash]
def api_get
process_api_response(
api_post_to(
api_get_path,
<<~GQL
query {
iteration(id: "gid://gitlab/Iteration/#{id}") {
#{gql_attributes}
}
}
GQL
)
)
end
# Path to create iteration
#
# @return [String]
def api_post_path
"/graphql"
end
# Graphql mutation for iteration creation
#
# @return [String]
def api_post_body
<<~GQL
mutation {
......@@ -62,18 +109,45 @@ module QA
dueDate: "#{@due_date}"
}) {
iteration {
id
title
description
startDate
dueDate
webUrl
#{gql_attributes}
}
errors
}
}
GQL
end
# Object comparison
#
# @param [QA::EE::Resource::GroupIteration] other
# @return [Boolean]
def ==(other)
other.is_a?(GroupIteration) && comparable_iteration == other.comparable_iteration
end
# Override inspect for a better rspec failure diff output
#
# @return [String]
def inspect
JSON.pretty_generate(comparable_iteration)
end
protected
# Return subset of fields for comparing iterations
#
# @return [Hash]
def comparable_iteration
reload! unless api_response
api_response.slice(
:title,
:description,
:state,
:due_date,
:start_date
)
end
end
end
end
......
......@@ -96,31 +96,35 @@ module QA
end
def api_post
if api_post_path == "/graphql"
graphql_response = post(
Runtime::API::Request.new(api_client, api_post_path).url,
query: api_post_body)
process_api_response(api_post_to(api_post_path, api_post_body))
end
def api_post_to(post_path, post_body)
if post_path == "/graphql"
graphql_response = post(Runtime::API::Request.new(api_client, post_path).url, query: post_body)
flattened_response = flatten_hash(parse_body(graphql_response))
body = 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}`."
unless graphql_response.code == HTTP_STATUS_OK && (body[:errors].nil? || body[:errors].empty?)
raise(ResourceFabricationFailedError, <<~MSG)
Fabrication of #{self.class.name} using the API failed (#{graphql_response.code}) with `#{graphql_response}`.
MSG
end
flattened_response[:web_url] = flattened_response.delete(:webUrl)
flattened_response[:id] = flattened_response.fetch(:id).split('/')[-1]
body[:id] = body.fetch(:id).split('/').last
process_api_response(flattened_response)
body.transform_keys { |key| key.to_s.underscore.to_sym }
else
response = post(
Runtime::API::Request.new(api_client, api_post_path).url,
api_post_body)
response = post(Runtime::API::Request.new(api_client, post_path).url, post_body)
unless response.code == HTTP_STATUS_CREATED
raise ResourceFabricationFailedError, "Fabrication of #{self.class.name} using the API failed (#{response.code}) with `#{response}`."
raise(
ResourceFabricationFailedError,
"Fabrication of #{self.class.name} using the API failed (#{response.code}) with `#{response}`."
)
end
process_api_response(parse_body(response))
parse_body(response)
end
end
......
......@@ -6,6 +6,7 @@ module QA
describe 'Bulk group import' do
let(:admin_api_client) { Runtime::API::Client.as_admin }
let(:api_client) { Runtime::API::Client.new(user: user) }
# validate different epic author is migrated correctly
let(:author_api_client) { Runtime::API::Client.new(user: author) }
let(:user) do
......@@ -46,6 +47,13 @@ module QA
let(:source_epics) { source_group.epics }
let(:imported_epics) { imported_group.epics }
let(:source_iteration) do
EE::Resource::GroupIteration.fabricate_via_api! do |iteration|
iteration.api_client = api_client
iteration.group = source_group
end
end
# Find epic by title
#
# @param [Array] epics
......@@ -76,6 +84,8 @@ module QA
child_epic.award_emoji('thumbsup')
child_epic.award_emoji('thumbsdown')
source_iteration
end
after do
......@@ -83,7 +93,10 @@ module QA
author.remove_via_api!
end
it 'imports group epics', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1921' do
it(
'imports group epics and iterations',
testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1921'
) do
expect { imported_group.import_status }.to(
eventually_eq('finished').within(max_duration: 300, sleep_interval: 2)
)
......@@ -91,11 +104,17 @@ module QA
source_parent_epic = find_epic(source_epics, 'Parent epic')
imported_parent_epic = find_epic(imported_epics, 'Parent epic')
imported_child_epic = find_epic(imported_epics, 'Child epic')
imported_iteration = imported_group.reload!.iterations.find { |ml| ml.title == source_iteration.title }
aggregate_failures 'epics imported incorrectly' do
aggregate_failures do
expect(imported_epics).to eq(source_epics)
expect(imported_child_epic.parent_id).to eq(imported_parent_epic.id)
expect(imported_parent_epic.author).to eq(source_parent_epic.author)
expect(imported_iteration).to eq(source_iteration)
expect(imported_iteration.iid).to eq(source_iteration.iid)
expect(imported_iteration.created_at).to eq(source_iteration.created_at)
expect(imported_iteration.updated_at).to eq(source_iteration.updated_at)
end
end
end
......
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