diff --git a/qa/qa/specs/features/api/1_manage/import/import_github_repo_spec.rb b/qa/qa/specs/features/api/1_manage/import/import_github_repo_spec.rb index c59a4f468dfddf0f749ba163cea105319ebc8818..1abd75a743998d908ac86f2411b10c3eef6b7708 100644 --- a/qa/qa/specs/features/api/1_manage/import/import_github_repo_spec.rb +++ b/qa/qa/specs/features/api/1_manage/import/import_github_repo_spec.rb @@ -1,194 +1,227 @@ # frozen_string_literal: true module QA - # https://github.com/gitlab-qa-github/import-test <- project under test + # Spec uses real github.com, which means outage of github.com can actually block deployment + # Keep spec in reliable bucket but don't run in blocking pipelines # - RSpec.describe 'Manage', product_group: :import do - describe 'GitHub import', :reliable do - include_context 'with github import' - - context 'when imported via api' do - it 'imports project', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347670' do - imported_project.reload! # import the project - - expect { imported_project.project_import_status[:import_status] }.to eventually_eq('finished') - .within(max_duration: 240, sleep_interval: 1) - - aggregate_failures do - verify_status_data - verify_repository_import - verify_protected_branches_import - verify_commits_import - verify_labels_import - verify_issues_import - verify_milestones_import - verify_wikis_import - verify_merge_requests_import - verify_release_import - end + # https://github.com/gitlab-qa-github/import-test <- project under test + RSpec.describe 'Manage', :github, :reliable, :skip_live_env, :requires_admin, product_group: :import do + describe 'Project import', issue: 'https://gitlab.com/gitlab-org/gitlab/-/issues/353583' do + let!(:api_client) { Runtime::API::Client.as_admin } + let!(:group) { Resource::Group.fabricate_via_api! { |resource| resource.api_client = api_client } } + let!(:user) do + Resource::User.fabricate_via_api! do |resource| + resource.api_client = api_client + resource.hard_delete_on_api_removal = true end + end - def verify_status_data - stats = imported_project.project_import_status.dig(:stats, :imported) - expect(stats).to include( - issue: 1, - label: 9, - milestone: 1, - note: 3, - pull_request: 1, - pull_request_review: 1, - diff_note: 1, - release: 1 - ) + let!(:user_api_client) { Runtime::API::Client.new(user: user) } + + let(:imported_project) do + Resource::ProjectImportedFromGithub.fabricate_via_api! do |project| + project.name = 'imported-project' + project.group = group + project.github_personal_access_token = Runtime::Env.github_access_token + project.github_repository_path = 'gitlab-qa-github/import-test' + project.api_client = user_api_client + project.issue_events_import = true + project.full_notes_import = true end + end - def verify_repository_import - expect(imported_project.reload!.description).to eq('Project for github import test') - expect(imported_project.api_response[:import_error]).to be_nil - end + before do + group.add_member(user, Resource::Members::AccessLevel::MAINTAINER) + end - def verify_protected_branches_import - branches = imported_project.protected_branches.map do |branch| - branch.slice(:name, :allow_force_push, :code_owner_approval_required) - end - expect(branches.first).to include( - { - name: 'main' - # TODO: Add validation once https://gitlab.com/groups/gitlab-org/-/epics/8585 is closed - # At the moment both options are always set to false regardless of state in github - # allow_force_push: true, - # code_owner_approval_required: true - } - ) - end + after do + user.remove_via_api! + end - def verify_commits_import - expect(imported_project.commits.length).to eq(2) + it 'imports Github repo via api', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347670' do + imported_project.reload! # import the project + + expect { imported_project.project_import_status[:import_status] }.to eventually_eq('finished') + .within(max_duration: 240, sleep_interval: 1) + + aggregate_failures do + verify_status_data + verify_repository_import + verify_protected_branches_import + verify_commits_import + verify_labels_import + verify_issues_import + verify_milestones_import + verify_wikis_import + verify_merge_requests_import + verify_release_import end + end - def verify_labels_import - labels = imported_project.labels.map { |label| label.slice(:name, :color) } - - expect(labels).to include( - { name: 'bug', color: '#d73a4a' }, - { name: 'documentation', color: '#0075ca' }, - { name: 'duplicate', color: '#cfd3d7' }, - { name: 'enhancement', color: '#a2eeef' }, - { name: 'good first issue', color: '#7057ff' }, - { name: 'help wanted', color: '#008672' }, - { name: 'invalid', color: '#e4e669' }, - { name: 'question', color: '#d876e3' }, - { name: 'wontfix', color: '#ffffff' } - ) - end + def verify_status_data + stats = imported_project.project_import_status.dig(:stats, :imported) + expect(stats).to include( + issue: 1, + label: 9, + milestone: 1, + note: 3, + pull_request: 1, + pull_request_review: 1, + diff_note: 1, + release: 1 + ) + end - def verify_milestones_import - milestones = imported_project.milestones + def verify_repository_import + expect(imported_project.reload!.description).to eq('Project for github import test') + expect(imported_project.api_response[:import_error]).to be_nil + end - expect(milestones.length).to eq(1) - expect(milestones.first).to include(title: '0.0.1', description: nil, state: 'active') + def verify_protected_branches_import + branches = imported_project.protected_branches.map do |branch| + branch.slice(:name, :allow_force_push, :code_owner_approval_required) end + expect(branches.first).to include( + { + name: 'main' + # TODO: Add validation once https://gitlab.com/groups/gitlab-org/-/epics/8585 is closed + # At the moment both options are always set to false regardless of state in github + # allow_force_push: true, + # code_owner_approval_required: true + } + ) + + # GitHub branch protection rule "Require signed commits" is mapped to the + # "Reject unsigned commits" push rule + expect(imported_project.push_rules[:reject_unsigned_commits]).to be_truthy + end - def verify_wikis_import - wikis = imported_project.wikis + def verify_commits_import + expect(imported_project.commits.length).to eq(2) + end - expect(wikis.length).to eq(1) - expect(wikis.first).to include(title: 'Home', format: 'markdown') - end + def verify_labels_import + labels = imported_project.labels.map { |label| label.slice(:name, :color) } + + expect(labels).to include( + { name: 'bug', color: '#d73a4a' }, + { name: 'documentation', color: '#0075ca' }, + { name: 'duplicate', color: '#cfd3d7' }, + { name: 'enhancement', color: '#a2eeef' }, + { name: 'good first issue', color: '#7057ff' }, + { name: 'help wanted', color: '#008672' }, + { name: 'invalid', color: '#e4e669' }, + { name: 'question', color: '#d876e3' }, + { name: 'wontfix', color: '#ffffff' } + ) + end - def verify_issues_import - issues = imported_project.issues - issue = Resource::Issue.init do |resource| - resource.project = imported_project - resource.iid = issues.first[:iid] - resource.api_client = user_api_client - end.reload! - comments, events = fetch_events_and_comments(issue) - - expect(issues.length).to eq(1) - expect(issue.api_resource).to include( - title: 'Test issue', - description: "*Created by: gitlab-qa-github*\n\nTest issue description", - labels: ['good first issue', 'help wanted', 'question'] - ) - expect(comments).to match_array( - [ - "*Created by: gitlab-qa-github*\n\nSome test comment", - "*Created by: gitlab-qa-github*\n\nAnother test comment" - ] - ) - expect(events).to match_array( - [ - { name: "add_label", label: "question" }, - { name: "add_label", label: "good first issue" }, - { name: "add_label", label: "help wanted" }, - { name: "add_milestone", label: "0.0.1" }, - { name: "closed" }, - { name: "reopened" } - ] - ) - end + def verify_milestones_import + milestones = imported_project.milestones - def verify_merge_requests_import - merge_requests = imported_project.merge_requests - merge_request = Resource::MergeRequest.init do |mr| - mr.project = imported_project - mr.iid = merge_requests.first[:iid] - mr.api_client = user_api_client - end.reload! - comments, events = fetch_events_and_comments(merge_request) - - expect(merge_requests.length).to eq(1) - expect(merge_request.api_resource).to include( - title: 'Test pull request', - state: 'opened', - target_branch: 'main', - source_branch: 'gitlab-qa-github-patch-1', - labels: %w[documentation], - description: "*Created by: gitlab-qa-github*\n\nTest pull request body" - ) - expect(comments).to match_array( - [ - "*Created by: gitlab-qa-github*\n\n**Review:** Commented\n\nGood but needs some improvement", - "*Created by: gitlab-qa-github*\n\n```suggestion:-0+0\nProject for GitHub import test to GitLab\r\n```", - "*Created by: gitlab-qa-github*\n\nSome test PR comment" - ] - ) - expect(events).to match_array( - [ - { name: "add_label", label: "documentation" }, - { name: "add_milestone", label: "0.0.1" } - ] - ) - end + expect(milestones.length).to eq(1) + expect(milestones.first).to include(title: '0.0.1', description: nil, state: 'active') + end - def verify_release_import - releases = imported_project.releases - - expect(releases.length).to eq(1) - expect(releases.first).to include( - tag_name: "0.0.1", - name: "0.0.1", - description: "Initial release", - created_at: "2022-03-07T07:59:22.000Z", - released_at: "2022-03-07T08:02:09.000Z" - ) - end + def verify_wikis_import + wikis = imported_project.wikis - # Fetch events and comments from issue or mr - # - # @param [QA::Resource::Issuable] issuable - # @return [Array] - def fetch_events_and_comments(issuable) - comments = issuable.comments.map { |comment| comment[:body] } - events = [ - *issuable.label_events.map { |e| { name: "#{e[:action]}_label", label: e.dig(:label, :name) } }, - *issuable.state_events.map { |e| { name: e[:state] } }, - *issuable.milestone_events.map { |e| { name: "#{e[:action]}_milestone", label: e.dig(:milestone, :title) } } + expect(wikis.length).to eq(1) + expect(wikis.first).to include(title: 'Home', format: 'markdown') + end + + def verify_issues_import + issues = imported_project.issues + issue = Resource::Issue.init do |resource| + resource.project = imported_project + resource.iid = issues.first[:iid] + resource.api_client = user_api_client + end.reload! + comments, events = fetch_events_and_comments(issue) + + expect(issues.length).to eq(1) + expect(issue.api_resource).to include( + title: 'Test issue', + description: "*Created by: gitlab-qa-github*\n\nTest issue description", + labels: ['good first issue', 'help wanted', 'question'] + ) + expect(comments).to match_array( + [ + "*Created by: gitlab-qa-github*\n\nSome test comment", + "*Created by: gitlab-qa-github*\n\nAnother test comment" ] + ) + expect(events).to match_array( + [ + { name: "add_label", label: "question" }, + { name: "add_label", label: "good first issue" }, + { name: "add_label", label: "help wanted" }, + { name: "add_milestone", label: "0.0.1" }, + { name: "closed" }, + { name: "reopened" } + ] + ) + end - [comments, events] - end + def verify_merge_requests_import + merge_requests = imported_project.merge_requests + merge_request = Resource::MergeRequest.init do |mr| + mr.project = imported_project + mr.iid = merge_requests.first[:iid] + mr.api_client = user_api_client + end.reload! + comments, events = fetch_events_and_comments(merge_request) + + expect(merge_requests.length).to eq(1) + expect(merge_request.api_resource).to include( + title: 'Test pull request', + state: 'opened', + target_branch: 'main', + source_branch: 'gitlab-qa-github-patch-1', + labels: %w[documentation], + description: "*Created by: gitlab-qa-github*\n\nTest pull request body" + ) + expect(comments).to match_array( + [ + "*Created by: gitlab-qa-github*\n\n**Review:** Commented\n\nGood but needs some improvement", + "*Created by: gitlab-qa-github*\n\n```suggestion:-0+0\nProject for GitHub import test to GitLab\r\n```", + "*Created by: gitlab-qa-github*\n\nSome test PR comment" + ] + ) + expect(events).to match_array( + [ + { name: "add_label", label: "documentation" }, + { name: "add_milestone", label: "0.0.1" } + ] + ) + end + + def verify_release_import + releases = imported_project.releases + + expect(releases.length).to eq(1) + expect(releases.first).to include( + tag_name: "0.0.1", + name: "0.0.1", + description: "Initial release", + created_at: "2022-03-07T07:59:22.000Z", + released_at: "2022-03-07T08:02:09.000Z" + ) + end + + # Fetch events and comments from issue or mr + # + # @param [QA::Resource::Issuable] issuable + # @return [Array] + def fetch_events_and_comments(issuable) + comments = issuable.comments.map { |comment| comment[:body] } + events = [ + *issuable.label_events.map { |e| { name: "#{e[:action]}_label", label: e.dig(:label, :name) } }, + *issuable.state_events.map { |e| { name: e[:state] } }, + *issuable.milestone_events.map { |e| { name: "#{e[:action]}_milestone", label: e.dig(:milestone, :title) } } + ] + + [comments, events] end end end diff --git a/qa/qa/specs/features/browser_ui/1_manage/project/import_github_repo_spec.rb b/qa/qa/specs/features/browser_ui/1_manage/project/import_github_repo_spec.rb index 15563e3aa2aa012f11692e0819637f7d27403ab1..4f0f54c1a1586536806c8092e652539d847d388f 100644 --- a/qa/qa/specs/features/browser_ui/1_manage/project/import_github_repo_spec.rb +++ b/qa/qa/specs/features/browser_ui/1_manage/project/import_github_repo_spec.rb @@ -4,90 +4,88 @@ module QA # Spec uses real github.com, which means outage of github can actually block deployment # Keep spec in reliable bucket but don't run in blocking pipelines RSpec.describe 'Manage', :github, :reliable, :skip_live_env, :requires_admin, product_group: :import do - describe 'GitHub import' do - context 'when imported via UI' do - let(:github_repo) { 'gitlab-qa-github/import-test' } - let(:api_client) { Runtime::API::Client.as_admin } - let(:group) { Resource::Group.fabricate_via_api! { |resource| resource.api_client = api_client } } - let(:user) do - Resource::User.fabricate_via_api! do |resource| - resource.api_client = api_client - resource.hard_delete_on_api_removal = true - end + describe 'Project import' do + let(:github_repo) { 'gitlab-qa-github/import-test' } + let(:api_client) { Runtime::API::Client.as_admin } + let(:group) { Resource::Group.fabricate_via_api! { |resource| resource.api_client = api_client } } + let(:user) do + Resource::User.fabricate_via_api! do |resource| + resource.api_client = api_client + resource.hard_delete_on_api_removal = true end + end - let(:imported_project) do - Resource::ProjectImportedFromGithub.init do |project| - project.import = true - project.group = group - project.github_personal_access_token = Runtime::Env.github_access_token - project.github_repository_path = github_repo - project.api_client = api_client - end + let(:imported_project) do + Resource::ProjectImportedFromGithub.init do |project| + project.import = true + project.group = group + project.github_personal_access_token = Runtime::Env.github_access_token + project.github_repository_path = github_repo + project.api_client = api_client end + end - let(:imported_issue) do - Resource::Issue.init do |resource| - resource.project = imported_project - resource.iid = imported_project.issues.first[:iid] - resource.api_client = api_client - end.reload! - end + let(:imported_issue) do + Resource::Issue.init do |resource| + resource.project = imported_project + resource.iid = imported_project.issues.first[:iid] + resource.api_client = api_client + end.reload! + end - let(:imported_issue_events) do - imported_issue.label_events.map { |e| { name: "#{e[:action]}_label", label: e.dig(:label, :name) } } - end + let(:imported_issue_events) do + imported_issue.label_events.map { |e| { name: "#{e[:action]}_label", label: e.dig(:label, :name) } } + end - before do - group.add_member(user, Resource::Members::AccessLevel::MAINTAINER) + before do + group.add_member(user, Resource::Members::AccessLevel::MAINTAINER) - Flow::Login.sign_in(as: user) - Page::Main::Menu.perform(&:go_to_create_project) - Page::Project::New.perform do |project_page| - project_page.click_import_project - project_page.click_github_link - end + Flow::Login.sign_in(as: user) + Page::Main::Menu.perform(&:go_to_create_project) + Page::Project::New.perform do |project_page| + project_page.click_import_project + project_page.click_github_link end + end - after do - user.remove_via_api! - end + after do + user.remove_via_api! + end - it 'imports a project', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347877' do - Page::Project::Import::Github.perform do |import_page| - import_page.add_personal_access_token(Runtime::Env.github_access_token) + it 'imports a GitHub repo', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347877' do + Page::Project::Import::Github.perform do |import_page| + import_page.add_personal_access_token(Runtime::Env.github_access_token) - import_page.select_advanced_option(:single_endpoint_issue_events_import) - import_page.select_advanced_option(:single_endpoint_notes_import) - import_page.select_advanced_option(:attachments_import) + import_page.select_advanced_option(:single_endpoint_issue_events_import) + import_page.select_advanced_option(:single_endpoint_notes_import) + import_page.select_advanced_option(:attachments_import) - import_page.import!(github_repo, group.full_path, imported_project.name) + import_page.import!(github_repo, group.full_path, imported_project.name) - aggregate_failures do - expect(import_page).to have_imported_project(github_repo, wait: 240) - # validate button is present instead of navigating to avoid dealing with multiple tabs - # which makes the test more complicated - expect(import_page).to have_go_to_project_button(github_repo) - end + aggregate_failures do + expect(import_page).to have_imported_project(github_repo, wait: 240) + # validate button is present instead of navigating to avoid dealing with multiple tabs + # which makes the test more complicated + expect(import_page).to have_go_to_project_button(github_repo) end + end - imported_project.reload!.visit! - Page::Project::Show.perform do |project| - aggregate_failures do - expect(project).to have_content(imported_project.name) - expect(project).to have_content('Project for github import test') - end + imported_project.reload!.visit! + Page::Project::Show.perform do |project| + aggregate_failures do + expect(project).to have_content(imported_project.name) + expect(project).to have_content('Project for github import test') end - - # Validate :single_endpoint_issue_events_import option was triggered correctly and imported the events - expect(imported_issue_events).to match_array( - [ - { name: "add_label", label: "question" }, - { name: "add_label", label: "good first issue" }, - { name: "add_label", label: "help wanted" } - ] - ) end + + # Validate :single_endpoint_issue_events_import option was triggered correctly and imported the events + expect(imported_issue_events).to match_array( + [ + { name: "add_label", label: "question" }, + { name: "add_label", label: "good first issue" }, + { name: "add_label", label: "help wanted" } + ] + ) end end end diff --git a/qa/qa/specs/features/ee/api/1_manage/import/import_github_repo_spec.rb b/qa/qa/specs/features/ee/api/1_manage/import/import_github_repo_spec.rb deleted file mode 100644 index 91097c119e69c53b193fe26fd02166cb388fb977..0000000000000000000000000000000000000000 --- a/qa/qa/specs/features/ee/api/1_manage/import/import_github_repo_spec.rb +++ /dev/null @@ -1,23 +0,0 @@ -# frozen_string_literal: true - -module QA - # https://github.com/gitlab-qa-github/import-test <- project under test - # - RSpec.describe 'Manage', product_group: :import do - describe 'GitHub import' do - include_context 'with github import' - - context "when imported via api" do - it 'imports repo push rules', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/379494' do - imported_project.reload! # import the project - - expect { imported_project.project_import_status[:import_status] }.to eventually_eq('finished') - .within(max_duration: 240, sleep_interval: 1) - - # GitHub branch protection rule "Require signed commits" is mapped to the "Reject unsigned commits" push rule - expect(imported_project.push_rules[:reject_unsigned_commits]).to be_truthy - end - end - end - end -end diff --git a/qa/qa/specs/features/shared_contexts/github_import_shared_context.rb b/qa/qa/specs/features/shared_contexts/github_import_shared_context.rb deleted file mode 100644 index c32f5d8bf4b8dbc6b5e8717a7ccd9e40d1b15067..0000000000000000000000000000000000000000 --- a/qa/qa/specs/features/shared_contexts/github_import_shared_context.rb +++ /dev/null @@ -1,43 +0,0 @@ -# frozen_string_literal: true - -module QA - RSpec.shared_context "with github import", :github, :skip_live_env, :requires_admin do - let!(:api_client) { Runtime::API::Client.as_admin } - - let!(:group) do - Resource::Group.fabricate_via_api! do |resource| - resource.api_client = api_client - resource.path = "destination-group-for-import-#{SecureRandom.hex(4)}" - end - end - - let!(:user) do - Resource::User.fabricate_via_api! do |resource| - resource.api_client = api_client - resource.hard_delete_on_api_removal = true - end - end - - let!(:user_api_client) { Runtime::API::Client.new(user: user) } - - let(:imported_project) do - Resource::ProjectImportedFromGithub.fabricate_via_api! do |project| - project.name = 'imported-project' - project.group = group - project.github_personal_access_token = Runtime::Env.github_access_token - project.github_repository_path = 'gitlab-qa-github/import-test' - project.api_client = user_api_client - project.issue_events_import = true - project.full_notes_import = true - end - end - - before do - group.add_member(user, Resource::Members::AccessLevel::MAINTAINER) - end - - after do - user.remove_via_api! - end - end -end