# frozen_string_literal: true

module Gitlab
  module QA
    describe Component::Selenoid do
      describe '#start' do
        subject(:selenoid) { described_class.new }
        let(:docker_engine) { spy('docker engine') }
        let(:docker_command) { spy('docker command') }
        let(:selenoid_browser_version) { '111.0' }
        let(:browser) { 'chrome' }
        let(:video_recorder_image) { 'custom-recorder-image' }
        let(:video_recorder_version) { 'recorder-version' }
        let(:selenoid_browser_image) { 'browser-image' }
        let(:mobile_layout) { false }
        let(:record_video) { true }
        let(:selenoid_dir) { 'selenoid/dir' }
        let(:fixtures_dir) { File.expand_path('../../../../lib/gitlab/qa/component', __dir__) }

        before do
          stub_const('Gitlab::QA::Docker::Engine', docker_engine)
          stub_const('Gitlab::QA::Docker::Command', docker_command)
          selenoid.network = Runtime::Env.docker_network
          allow(Gitlab::QA::Runtime::Env).to receive_messages(
            video_recorder_image: video_recorder_image,
            video_recorder_version: video_recorder_version,
            selenoid_browser_image: selenoid_browser_image,
            selenoid_browser_version: selenoid_browser_version,
            browser: browser, mobile_layout?: mobile_layout,
            record_video: record_video,
            selenoid_directory: selenoid_dir
          )
          allow(selenoid).to receive(:grid_healthy?).and_return(true)
          allow(docker_engine).to receive(:run).and_yield(docker_command)
        end

        it 'pulls selenoid video-recorder image' do
          selenoid.start

          expect(docker_engine).to have_received(:pull).with(image: video_recorder_image, tag: video_recorder_version)
        end

        it 'pulls selenoid browser image' do
          selenoid.start

          expect(docker_engine).to have_received(:pull).with(
            image: selenoid_browser_image, tag: selenoid_browser_version)
        end

        it 'runs selenoid container' do
          selenoid.start

          expect(docker_engine).to have_received(:run).with({ args:
            ["-video-recorder-image",
              video_recorder_image,
              "-container-network",
              selenoid.network,
              "-timeout",
              "10m0s"], image: "aerokube/selenoid", tag: "latest-release" })
        end

        it 'sets name' do
          selenoid.start

          expect(docker_command).to have_received(:<<).with("--name #{selenoid.name}")
        end

        it 'sets network' do
          selenoid.start

          expect(docker_command).to have_received(:<<).with("--net #{selenoid.network}")
        end

        it 'sets hostname' do
          selenoid.start

          expect(docker_command).to have_received(:<<).with("--hostname #{selenoid.hostname}")
        end

        it 'publishes port' do
          selenoid.start

          expect(docker_command).to have_received(:<<).with("--publish 4444:4444")
        end

        it 'overrides video directory' do
          selenoid.start

          expect(docker_command).to have_received(:<<)
            .with("-e OVERRIDE_VIDEO_OUTPUT_DIR=#{Runtime::Env.selenoid_directory}/video")
        end

        it 'sets volume' do
          selenoid.start

          expect(docker_command).to have_received(:volume).with('/var/run/docker.sock', '/var/run/docker.sock')
        end

        it 'sets browsers.json volume' do
          selenoid.start

          expect(docker_command).to have_received(:volume).with("#{fixtures_dir}/../../../../fixtures/selenoid",
            "/etc/selenoid")
        end

        it 'sets video volume' do
          selenoid.start

          expect(docker_command).to have_received(:volume).with("#{selenoid_dir}/video", '/opt/selenoid/video')
        end
      end
    end
  end
end
