# frozen_string_literal: true

# spec/lib/gitlab/qa/component/project_importer_spec.rb

require 'spec_helper'

module Gitlab
  module QA
    describe Component::ProjectImporter do
      let(:project_url) { 'https://example.com/project.git' }
      let(:project_name) { 'test-project' }
      let(:project_path) { 'custom-path' }
      let(:docker) { instance_double(Gitlab::QA::Docker::Engine) }
      let(:gitlab) do
        instance_double(
          Gitlab::QA::Component::Gitlab,
          address: "http://gitlab.example.com",
          class: Struct.new(:name).new("Gitlab::QA::Component::Gitlab")
        )
      end

      subject { described_class.new(project_url, project_name, project_path: project_path) }

      describe '#initialize' do
        it 'sets instance variables correctly' do
          importer = described_class.new(project_url, project_name)

          expect(importer.instance_variable_get(:@project_url)).to eq(project_url)
          expect(importer.instance_variable_get(:@project_name)).to eq(project_name)
          expect(importer.instance_variable_get(:@project_path)).to eq(project_name)
        end

        it 'allows custom project path' do
          importer = described_class.new(project_url, project_name, project_path: project_path)

          expect(importer.instance_variable_get(:@project_path)).to eq(project_path)
        end
      end

      describe '#import_project' do
        before do
          allow(gitlab).to receive_messages(docker: docker, name: 'gitlab-instance')
          allow(docker).to receive(:exec).and_return('Import successful')
        end

        it 'executes import command via docker' do
          expected_command = subject.send(:build_import_command,
            subject.send(:create_import_script),
            project_url, project_name, project_path)

          expect(docker).to receive(:exec).with('gitlab-instance', expected_command)

          subject.import_project(gitlab)
        end
      end

      describe '#build_import_command' do
        let(:script) { "puts 'test'" }
        let(:expected_url) { 'https://example.com/test.git' }
        let(:expected_name) { 'foo' }
        let(:expected_path) { 'bar' }

        it 'builds correct import command' do
          command = subject.send(:build_import_command, script, expected_url, expected_name, expected_path)

          expect(command).to include("PROJECT_URL='#{expected_url}'")
          expect(command).to include("PROJECT_NAME='#{expected_name}'")
          expect(command).to include("PROJECT_PATH='#{expected_path}'")
          expect(command).to include('gitlab-rails runner')
          expect(command).to include(script.gsub("'", "\\\\'"))
        end

        it 'properly escapes single quotes' do
          script_with_quotes = "puts 'test's test'"
          command = subject.send(:build_import_command, script_with_quotes, expected_url, expected_name, expected_path)

          expect(command).to include("\\'test\\'s test\\'")
        end
      end

      describe '#create_import_script' do
        it 'generates a valid Ruby script' do
          script = subject.send(:create_import_script)

          expect(script).to include('require \'timeout\'')
          expect(script).to include('Projects::CreateService')
          expect(script).to include('Timeout.timeout(300)')
        end

        it 'includes error handling' do
          script = subject.send(:create_import_script)

          expect(script).to include('rescue Timeout::Error')
        end
      end
    end
  end
end
