lib/gitlab/qa/report/report_results.rb



# frozen_string_literal: true

module Gitlab
  module QA
    module Report
      # Uses the API to create or update GitLab test cases and issues with the results of tests from RSpec report files.
      class ReportResults < ReportAsIssue
        attr_accessor :testcase_project_reporter, :results_issue_project_reporter, :files, :test_case_project, :results_issue_project, :gitlab

        def initialize(token:, input_files:, test_case_project:, results_issue_project:, dry_run: false, **kwargs)
          @testcase_project_reporter = Gitlab::QA::Report::ResultsInTestCases.new(token: token, input_files: input_files, project: test_case_project, dry_run: dry_run, **kwargs)
          @results_issue_project_reporter = Gitlab::QA::Report::ResultsInIssues.new(token: token, input_files: input_files, project: results_issue_project, dry_run: dry_run, **kwargs)
          @test_case_project = test_case_project
          @results_issue_project = results_issue_project
          @files = Array(input_files)
          @gitlab = testcase_project_reporter.gitlab
        end

        def assert_project!
          return if test_case_project && results_issue_project

          abort "Please provide valid project IDs or paths with the `--results-issue-project` and `--test-case-project` options!"
        end

        def run!
          puts "Reporting test results in `#{files.join(',')}` as test cases in project `#{test_case_project}`"\
               " and issues in project `#{results_issue_project}` via the API at `#{Runtime::Env.gitlab_api_base}`."

          test_results_per_file do |test_results|
            puts "Reporting tests in #{test_results.path}"

            test_results.each do |test|
              puts "Reporting test: #{test.file} | #{test.name}\n"

              report_test(test) unless test.skipped
            end

            test_results.write
          end
        end

        private

        def report_test(test)
          testcase = testcase_project_reporter.find_or_create_testcase(test)
          # The API returns the test case with an issue URL since it is technically a type of issue.
          # This updates the URL to a valid test case link.
          test.testcase = testcase.web_url.sub('/issues/', '/quality/test_cases/')

          issue, is_new = results_issue_project_reporter.get_related_issue(testcase, test)

          testcase_project_reporter.add_issue_link_to_testcase(testcase, issue, test) if is_new

          testcase_project_reporter.update_testcase(testcase, test)
          results_issue_project_reporter.update_issue(issue, test)
        end
      end
    end
  end
end