require "spec_helper"

describe CpEnv::NamespaceDir do
  let(:namespace) { "mynamespace" }
  let(:dir) { "/namespaces/live1/#{namespace}" }
  let(:cluster) { "my-cluster" }

  let(:success) { double(success?: true) }
  let(:resp) { ["stdout", "stderr", success] }
  let(:executor) { double(CpEnv::Executor, execute: resp) }

  let(:terraform) { double(CpEnv::Terraform) }
  let(:kubectl_apply) { "kubectl -n #{namespace} apply -f #{dir}" }
  let(:yaml_files) { [] }
  let(:enable_skip_namespaces) { true }
  let(:block_secret_rotation) { true }

  let(:params) {
    {
      dir: dir,
      cluster: cluster,
      executor: executor,
      enable_skip_namespaces: enable_skip_namespaces,
      block_secret_rotation: block_secret_rotation
    }
  }

  subject(:namespace_dir) { described_class.new(params) }

  before do
    allow(CpEnv::Terraform).to receive(:new).and_return(terraform)
    allow(Dir).to receive(:glob).with("#{dir}/*.{yaml,yml,json}").and_return(yaml_files)
    allow($stdout).to receive(:puts)
  end

  context "when dir is not a directory path" do
    before do
      allow(FileTest).to receive(:directory?).with(dir).and_return(false)
    end

    it "does not update the working copy" do
      expect(executor).to_not receive(:execute).with("git pull")
      namespace_dir.apply
    end

    it "does not call terraform apply" do
      expect(terraform).to_not receive(:apply)
      namespace_dir.apply
    end
  end

  context "when given a directory" do
    before do
      allow(FileTest).to receive(:directory?).with(dir).and_return(true)
      allow(terraform).to receive(:apply)
    end

    it "updates the working copy" do
      expect(executor).to receive(:execute).with("git pull")
      namespace_dir.apply
    end

    it "calls terraform apply" do
      expect(terraform).to receive(:apply)
      namespace_dir.apply
    end

    context "with kubernetes files" do
      let(:yaml_files) { [1, 2, 3] } # just has to be a non-empty array that responds to 'any?'

      it "applies kubernetes files" do
        expect(executor).to receive(:execute).with(kubectl_apply)
        namespace_dir.apply
      end
    end

    context "with no kubernetes files" do
      let(:yaml_files) { [] } # just has to be a non-empty array that responds to 'any?'

      it "does not run kubectl apply" do
        expect(executor).to_not receive(:execute).with(kubectl_apply)
        namespace_dir.apply
      end
    end

    context "when enable_skip_namespaces is set" do
      let(:enable_skip_namespaces) { true }
      let(:block_secret_rotation) { false }

      context "and a skip file is present" do
        let(:yaml_files) { [1, 2, 3] } # just has to be a non-empty array that responds to 'any?'

        before do
          allow(FileTest).to receive(:exist?)
            .with("#{dir}/#{CpEnv::NamespaceDir::SKIP_FILE}")
            .and_return(true)
        end

        it "does not run kubectl apply" do
          expect(executor).to_not receive(:execute).with(kubectl_apply)
          namespace_dir.apply
        end

        it "does not run terraform apply" do
          expect(terraform).to_not receive(:apply)
          namespace_dir.apply
        end
      end
    end

    context "when enable_skip_namespaces is not set" do
      let(:enable_skip_namespaces) { false }
      let(:block_secret_rotation) { false }

      context "and a migrate skip file is present" do
        let(:yaml_files) { [1, 2, 3] } # just has to be a non-empty array that responds to 'any?'

        before do
          allow(FileTest).to receive(:exist?)
            .with("#{dir}/#{CpEnv::NamespaceDir::MIGRATE_SKIP_FILE}")
            .and_return(true)
        end

        it "does not run kubectl apply" do
          expect(executor).to_not receive(:execute).with(kubectl_apply)
          namespace_dir.apply
        end

        it "does not run terraform apply" do
          expect(terraform).to_not receive(:apply)
          namespace_dir.apply
        end
      end
    end

    context "when block_secret_rotation is set" do
      let(:enable_skip_namespaces) { false }
      let(:block_secret_rotation) { true }

      context "and a block file is present" do
        let(:yaml_files) { [1, 2, 3] } # just has to be a non-empty array that responds to 'any?'

        before do
          allow(FileTest).to receive(:exist?)
            .with("#{dir}/#{CpEnv::NamespaceDir::SECRET_ROTATE_FILE}")
            .and_return(true)
        end

        it "does not run kubectl apply" do
          expect(executor).to_not receive(:execute).with(kubectl_apply)
          namespace_dir.apply
        end

        it "does not run terraform apply" do
          expect(terraform).to_not receive(:apply)
          namespace_dir.apply
        end
      end
    end
  end
end
