1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145
|
# frozen_string_literal: true
RSpec.describe FaradayMiddleware::OAuth do
def auth_header(env)
env[:request_headers]['Authorization']
end
def auth_values(env)
auth = auth_header(env)
return unless auth
raise "invalid header: #{auth.inspect}" unless auth.sub!('OAuth ', '')
Hash[*auth.split(/, |=/)]
end
def perform(oauth_options = {}, headers = {}, params = {})
env = {
url: URI('http://example.com/'),
request_headers: Faraday::Utils::Headers.new.update(headers),
request: {},
body: params
}
env[:request][:oauth] = oauth_options unless oauth_options.is_a?(Hash) && oauth_options.empty?
app = make_app
app.call(faraday_env(env))
end
def make_app
described_class.new(->(env) { env }, *Array(options))
end
context 'invalid options' do
let(:options) { nil }
it 'errors out' do
expect { make_app }.to raise_error(ArgumentError)
end
end
context 'empty options' do
let(:options) { [{}] }
it 'signs request' do
auth = auth_values(perform)
expected_keys = %w[ oauth_nonce
oauth_signature oauth_signature_method
oauth_timestamp oauth_version ]
expect(auth.keys).to match_array expected_keys
end
end
context 'configured with consumer and token' do
let(:options) do
[{ consumer_key: 'CKEY', consumer_secret: 'CSECRET',
token: 'TOKEN', token_secret: 'TSECRET' }]
end
it 'adds auth info to the header' do
auth = auth_values(perform)
expected_keys = %w[ oauth_consumer_key oauth_nonce
oauth_signature oauth_signature_method
oauth_timestamp oauth_token oauth_version ]
expect(auth.keys).to match_array expected_keys
expect(auth['oauth_version']).to eq(%("1.0"))
expect(auth['oauth_signature_method']).to eq(%("HMAC-SHA1"))
expect(auth['oauth_consumer_key']).to eq(%("CKEY"))
expect(auth['oauth_token']).to eq(%("TOKEN"))
end
it "doesn't override existing header" do
request = perform({}, 'Authorization' => 'iz me!')
expect(auth_header(request)).to eq('iz me!')
end
it 'can override oauth options per-request' do
auth = auth_values(perform(consumer_key: 'CKEY2'))
expect(auth['oauth_consumer_key']).to eq(%("CKEY2"))
expect(auth['oauth_token']).to eq(%("TOKEN"))
end
it 'can turn off oauth signing per-request' do
expect(auth_header(perform(false))).to be_nil
end
end
context 'configured without token' do
let(:options) { [{ consumer_key: 'CKEY', consumer_secret: 'CSECRET' }] }
it 'adds auth info to the header' do
auth = auth_values(perform)
expect(auth).to include('oauth_consumer_key')
expect(auth).not_to include('oauth_token')
end
end
context 'handling body parameters' do
let(:options) do
[{ consumer_key: 'CKEY',
consumer_secret: 'CSECRET',
nonce: '547fed103e122eecf84c080843eedfe6',
timestamp: '1286830180' }]
end
let(:value) { { 'foo' => 'bar' } }
let(:type_json) { { 'Content-Type' => 'application/json' } }
let(:type_form) { { 'Content-Type' => 'application/x-www-form-urlencoded' } }
extend Forwardable
def_delegator :'Faraday::Utils', :build_nested_query
it 'does not include the body for JSON' do
auth_header_with = auth_header(perform({}, type_json, '{"foo":"bar"}'))
auth_header_without = auth_header(perform({}, type_json, {}))
expect(auth_header_with).to eq(auth_header_without)
end
it 'includes the body parameters with form Content-Type' do
auth_header_with = auth_header(perform({}, type_form, {}))
auth_header_without = auth_header(perform({}, type_form, value))
expect(auth_header_with).not_to eq(auth_header_without)
end
it 'includes the body parameters with an unspecified Content-Type' do
auth_header_with = auth_header(perform({}, {}, value))
auth_header_without = auth_header(perform({}, type_form, value))
expect(auth_header_with).to eq(auth_header_without)
end
it 'includes the body parameters for form type with string body' do
# simulates the behavior of Faraday::MiddleWare::UrlEncoded
value = { 'foo' => %w[bar baz wat] }
auth_header_hash = auth_header(perform({}, type_form, value))
auth_header_string = auth_header(perform({}, type_form, build_nested_query(value)))
expect(auth_header_string).to eq(auth_header_hash)
end
end
end
|