require "#{File.dirname(__FILE__)}/../spec_helper"
require 'ostruct'

require_relative '../../lib/services/chef_service.rb'
require_relative '../../lib/controllers/environments_api.rb'

describe 'main application' do
    include Rack::Test::Methods

    subject {
        @controller
    }

    def app
        subject
    end

    before(:each) do
        @service = ChefService.new
        @app = nil
        @controller = EnvironmentsApi.new @app, @service
        @controller
    end

    describe '/' do
        it 'Should respond ok' do
            data = [{:name => "Dev_One", :url => "/dev_one"}]
            expect(@service).to receive(:getAllEnvironments).and_return(data)

            get '/'

            json = data.to_json

            expect(last_response.ok?).to be true
            expect(last_response.body).to eq json
        end
    end

    describe '/:name/nodes' do
        it 'Should respond ok' do
            data = [{:node => "Sample"}]
            expect(@service).to receive(:getNodes).with("env_name")
            .and_return(data)

            get '/env_name/nodes'

            json = data.to_json

            expect(last_response.ok?).to eq true
            expect(last_response.body).to eq json
        end
    end

    describe '/:name/app_versions' do
        it 'should respond ok' do
            data = [{:app_version => "Sample"}]
            expect(@service).to receive(:getAppVersions).with("env_name")
            .and_return(data)

            get '/env_name/app_versions'

            json = data.to_json

            expect(last_response.ok?).to eq true
            expect(last_response.body).to eq json
        end

        it 'should only use windows app versions' do
          chef_environment = double("chef_environment")
          chef = double("chef")
          allow(@service).to receive(:chef).and_return(chef)
          allow(chef).to receive(:environment).and_return(chef_environment)

          data = [
                  OpenStruct.new({
                      :name => "same_thing",
                      :chef_attributes => OpenStruct.new({
                          :ppa_application_versions => {
                              :PPA_Verona => {
                                  :version => "1.0"
                              }
                          },
                          :run_list => [
                              "role[WINDOWS]"
                          ]
                      })
                  }),
                  OpenStruct.new({
                      :name => "same_thing",
                      :chef_attributes =>  OpenStruct.new({
                          :ppa_application_versions => {
                              :PPA_Verona => {
                                  :version => "5.0"
                              }
                          },
                          :run_list => [
                              "role[LINUX]"
                          ]
                      })
                  })
                ]

          environment = OpenStruct.new({:name => 'same_thing'})

          allow(chef_environment).to receive(:find).with("same_thing")
            .and_return(environment)
          allow(chef).to receive(:partial_search)
            .and_return(data)

          # Act
          app_versions = @service.getAppVersions("same_thing")

          # Assert
          target = app_versions.detect {|v| v[:name] == :PPA_Verona}
          expect(target).not_to be nil
          expect(target[:version][:version]).to eq "1.0"
      end

    end

    describe '/:name/cookbook_versions' do
        it 'should respond ok' do
            data = [{:name => "Sample", :version => "1.0.0"}]

            expect(@service).to receive(:getCookbookVersions).with("env_name")
            .and_return(data)

            get '/env_name/cookbook_versions'

            json = data.to_json

            expect(last_response.ok?).to eq true
            expect(last_response.body).to eq json
        end
    end


    describe '/:name' do
        it 'Should respond ok' do
            data = [{:enviro => "Sample"}]
            expect(@service).to receive(:getEnvironment).with("env_name")
            .and_return(data)

            get '/env_name'

            json = data.to_json

            expect(last_response.ok?).to eq true
            expect(last_response.body).to eq json
        end
    end
end
