describe Frenetic::Configuration do let(:config) { { url:'http://example.org' } } let(:cache_cfg) do { metastore: 'foo', entitystore: 'bar' } end let(:instance) { described_class.new( config ) } subject { instance } it { should respond_to(:adapter) } it { should respond_to(:cache) } it { should respond_to(:url) } it { should respond_to(:username) } it { should respond_to(:password) } it { should respond_to(:headers) } it { should respond_to(:request) } it { should respond_to(:response) } it { should respond_to(:middleware) } describe '#attributes' do before { instance.use 'MyMiddleware' } subject { instance.attributes } it { should include(:adapter) } it { should include(:cache) } it { should include(:url) } it { should include(:username) } it { should include(:password) } it { should include(:headers) } it { should include(:request) } it { should include(:response) } it { should_not include(:middleware) } it 'should validate the configuration' do instance.should_receive :validate! subject end context 'with string keys' do let(:config) { {'url' => 'https://example.org'} } it 'should symbolize the keys' do subject[:url].should == 'https://example.org' end end end describe '#headers' do let(:attrs) { instance.headers } context 'Accepts' do subject { attrs[:accept] } it { should == 'application/hal+json' } context 'with other specific headers' do before { config.merge!(headers:{foo:123} )} it { should == 'application/hal+json' } end context 'with a custom Accepts header' do before { config.merge!(headers:{'accept' => 'application/vnd.yoursite-v1.hal+json'} )} it { should == 'application/vnd.yoursite-v1.hal+json' } end end context 'User-Agent' do subject { attrs[:user_agent] } it { should match %r{Frenetic v\d+\.\d+\.\d+; .+\Z} } context 'with a custom value' do before { config.merge!( headers:{user_agent:'MyApp'}) } it { should match %r{\AMyApp \(Frenetic v\d+\.\d+\.\d+; .+\)\Z} } end end end describe '#cache' do before { config.merge!(cache:cache_cfg) } subject { instance.cache } it { should include(metastore:'foo') } it { should include(entitystore:'bar') } it { should include(ignore_headers:%w[Set-Cookie X-Content-Digest]) } context 'with custom ignore headers' do before { cache_cfg.merge!(ignore_headers:%w{Set-Cookie X-My-Header}) } it { should include(ignore_headers:%w[Set-Cookie X-My-Header X-Content-Digest]) } end end describe '#username' do subject { instance.username } before { config.merge!(api_key:'api_key') } it { should == 'api_key' } context 'and an App ID' do before { config.merge!(app_id:'app_id') } it { should == 'app_id' } end end describe '#password' do subject { instance.password } before { config.merge!(api_key:'api_key') } it { should be_nil } context 'and an App ID' do before { config.merge!(app_id:'app_id') } it { should == 'api_key' } end end describe '#initialize' do subject { instance.attributes } it { should be_a Hash } it { should_not be_empty } end describe '#validate!' do subject { instance.validate! } shared_examples_for 'a misconfigured instance' do it 'by raising an error when empty' do expect{ subject }.to raise_error Frenetic::ConfigurationError end end context ':url' do before { config.delete :url } it_should_behave_like 'a misconfigured instance' end context ':cache' do context 'with a missing :metastore' do before { config.merge!(cache:{}) } it_should_behave_like 'a misconfigured instance' end context 'with a missing :entitystore' do before { config.merge!(cache:{metastore:'store'}) } it_should_behave_like 'a misconfigured instance' end context 'with no missing properties' do before { config.merge!(cache:{metastore:'mstore',entitystore:'estore'}) } it 'should not raise an error' do expect{ subject }.to_not raise_error end end end end describe '#use' do before do stub_const 'MyMiddleware', Class.new instance.use MyMiddleware, foo:123 end it 'should use the middleware' do subject.middleware.should include [ MyMiddleware, {foo:123} ] end end end