require_relative "../support/spec_helper"

module Dalmatian
  RSpec.describe RdsTest do
    let(:helper) { class_double(Helper, change_to: true, run!: true, git_checkout: true) }
    let(:logger) { class_double(Logger, info: true) }

    let(:terraform) do
      class_double(
        Terraform,
        fmt: true,
        init: true,
        validate: true,
        ensure_presence_of_workspace: true
      )
    end

    let(:rds) do
      instance_double(
        Rds,
        identifier: "testservice",
        in_use_by: [
          "test-service"
        ],
        clusters_in_use: {
          "production" => [
            "test"
          ],
          "staging" => [
            "test"
          ]
        },
        instance_class: {
          "production" => "db.t2.small",
          "staging" => "db.t2.micro"
        },
        engine: "postgres",
        engine_version: "11.4",
        allocated_storage: 20,
        storage_encrypted: true,
        storage_type: "gp3",
        db_name: "testapp",
        port: 5432,
        maintenance_window: "mon:19:00-mon:19:30",
        backup_window: "09:00-10:00",
        backup_retention_period: 31,
        force_ssl: true,
        cluster_id: "new-dedicated-cluster-id",
        account_id: 123456789012,
        parameter_store_path_db_url_name: "DATABASE_URL",
        sql_backup_scheduled_task_environment_variables: [
          {
            "name" => "foo",
            "value" => "bar"
          }
        ],
        check_sql_backup_scheduled_task_environment_variables: [
          {
            "name" => "foo",
            "value" => "bar"
          }
        ],
        sync_sql_backup_to_azure: false,
        replication_bucket_destination_arn: "arn:aws:s3:::dest-bucket",
        replication_kms_key_id: "key-id",
        codebuild_access: [
          "service-name"
        ]
      )
    end

    let!(:rds_test) do
      RdsTest.new(
        rds: rds,
        env: {name: "staging", details: {"min_servers" => 2, "max_servers" => 4}},
        helper: helper,
        logger: logger,
        terraform: terraform
      )
    end

    describe "#call" do
      before do
        allow(Terraform).to receive(:init)
        allow(Terraform).to receive(:ensure_presence_of_workspace)
        allow(logger).to receive(:info)
      end

      let(:workspace_name) { "new-dedicated-cluster-id-testservice-rds-staging" }

      before { rds_test.call }

      it "changes to the ecs-services directory" do
        directory = File.join(
          Infrastructure::APP_ROOT,
          Infrastructure::PATH,
          "rds"
        )

        expect(helper).to have_received(:change_to).with(directory)
      end

      it "logs our intention to run Terraform init" do
        expect(logger).to have_received(:info).with(
          "Running terraform init for #{workspace_name}"
        )
      end

      it "runs Terraform init, with upgrade option" do
        expect(terraform).to have_received(:init).with(upgrade: true)
      end

      it "ensures presence of workspace" do
        expect(terraform).to have_received(:ensure_presence_of_workspace)
          .with(workspace_name)
      end

      it "logs our intention to run Terraform fmt" do
        expect(logger).to have_received(:info).with(
          "Running terraform fmt for #{workspace_name}"
        )
      end

      it "runs Terraform fmt with check and diff options" do
        expect(terraform).to have_received(:fmt).with("-check -diff")
      end

      it "logs our intention to run Terraform validate" do
        expect(logger).to have_received(:info).with(
          "Running terraform validate for #{workspace_name}"
        )
      end

      it "runs Terraform validate, with upgrade option" do
        env_config = {"min_servers" => 2,
                      "max_servers" => 4,
                      "rds" => {
                        "identifier" => "testservice",
                        "in_use_by" => [
                          "test-service"
                        ],
                        "clusters_in_use" => {
                          "production" => [
                            "test"
                          ],
                          "staging" => [
                            "test"
                          ]
                        },
                        "instance_class" => {
                          "production" => "db.t2.small",
                          "staging" => "db.t2.micro"
                        },
                        "engine" => "postgres",
                        "engine_version" => "11.4",
                        "allocated_storage" => 20,
                        "storage_encrypted" => true,
                        "storage_type" => "gp3",
                        "db_name" => "testapp",
                        "port" => 5432,
                        "replication_bucket_destination_arn" => "arn:aws:s3:::dest-bucket",
                        "replication_kms_key_id" => "key-id",
                        "maintenance_window" => "mon:19:00-mon:19:30",
                        "backup_window" => "09:00-10:00",
                        "backup_retention_period" => 31,
                        "force_ssl" => true,
                        "parameter_store_path_db_url_name" => "DATABASE_URL",
                        "sql_backup_scheduled_task_environment_variables" => [
                          {
                            "name" => "foo",
                            "value" => "bar"
                          }
                        ],
                        "check_sql_backup_scheduled_task_environment_variables" => [
                          {
                            "name" => "foo",
                            "value" => "bar"
                          }
                        ],
                        "codebuild_access" => [
                          "service-name"
                        ],
                        "sync_sql_backup_to_azure" => false
                      },
                      "account_id" => 123456789012,
                      "infrastructure_name" => "new-dedicated-cluster-id",
                      "environment" => "staging",
                      "dalmatian_role" => "dalmatian-read"}
        expect(terraform).to have_received(:validate).with(
          tfvars: env_config
        )
      end

      it "changes back to the app root directory" do
        expect(helper).to have_received(:change_to).with(Infrastructure::APP_ROOT)
      end
    end
  end
end
