require 'spec_helper'

describe Sumo::Config do
  describe '.new' do
    subject { Sumo::Config }

    context 'when no argument is given' do
      it 'sets @config_file to its default value' do
        subject.new.config_file.should == Sumo::DEFAULT_CONFIG_FILE
      end
    end

    context 'when an argument is given' do
      context 'when it is not a String' do
        it 'raises an error' do
          expect { subject.new(nil) }.to raise_error(Sumo::Error::TypeError)
        end
      end

      context 'when it is a String' do
        let(:file) { '/dev/null' }

        it 'sets @config_file to the argument' do
          subject.new(file).config_file.should == file
        end
      end
    end
  end

  describe '#file_specified?' do
    context 'when @config_file is the default' do
      it 'returns false' do
        subject.file_specified?.should be_false
      end
    end

    context 'when @config_file is not the default' do
      subject { Sumo::Config.new('my-config-file') }

      it 'returns true' do
        subject.file_specified?.should be_true
      end
    end
  end

  describe '#env_creds' do
    before { ENV['SUMO_CREDS'] = creds }

    context 'when the environment variable is not set' do
      let(:creds) { nil }

      it 'returns nil' do
        subject.env_creds.should be_nil
      end
    end

    context 'when the environment variable is set' do
      let(:creds) { 'alpha' }

      it 'returns that variable' do
        subject.env_creds.should == creds
      end
    end
  end

  describe '#file_creds' do
    subject { Sumo::Config.new(file) }

    context 'when the @config_file does not exist' do
      let(:file) { 'not a file' }

      it 'returns nil' do
        subject.file_creds.should be_nil
      end
    end

    context 'when @config_file does exist' do
      let(:file) { 'spec/fixtures/sumo_creds' }

      it 'returns its contents' do
        subject.file_creds.should == 'fake_user@fake_site:fake_pass'
      end
    end
  end

  describe '#load_config' do
    before do
      subject.stub(:file_specified?).and_return(specified)
      subject.stub(:file_creds).and_return('alpha')
      subject.stub(:env_creds).and_return('beta')
    end

    context 'when an alternate file is specifed' do
      let(:specified) { true }

      it 'attempts to read the file first' do
        subject.load_config.should == 'alpha'
      end
    end

    context 'when an alternate file is not specified' do
      let(:specified) { false }

      it 'attempts to read the environment variable first' do
        subject.load_config.should == 'beta'
      end
    end
  end

  describe 'load_config!' do
    before { subject.stub(:load_config).and_return(config) }

    context 'when #load_config returns nil' do
      let(:config) { nil }

      it 'raises an error' do
        expect { subject.load_config! }
            .to raise_error(Sumo::Error::NoCredsFound)
      end
    end

    context 'when #load_config returns a value' do
      let(:config) { 'configuration' }

      it 'returns that value' do
        subject.load_config!.should == config
      end
    end
  end
end