diff --git a/.gitignore b/.gitignore index af948e388..9f1724a79 100644 --- a/.gitignore +++ b/.gitignore @@ -9,3 +9,4 @@ doc/* log/* measurement/* pkg/* +*.swp diff --git a/.travis.yml b/.travis.yml index 8fbe6af07..d9013558d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,7 +3,6 @@ cache: bundler language: ruby rvm: - - 2.0.0 - 2.1 - 2.2 - 2.3.3 diff --git a/Gemfile b/Gemfile index cb1f9afd5..b3a9d347b 100644 --- a/Gemfile +++ b/Gemfile @@ -4,7 +4,7 @@ gem 'jruby-openssl', platforms: :jruby gem 'rake' gem 'yard' -group :development do +group :development, :test do gem 'pry' end diff --git a/lib/twitter/rest/request.rb b/lib/twitter/rest/request.rb index db34abbe1..9a7b6beef 100644 --- a/lib/twitter/rest/request.rb +++ b/lib/twitter/rest/request.rb @@ -4,17 +4,18 @@ require 'json' require 'openssl' require 'twitter/error' -require 'twitter/headers' require 'twitter/rate_limit' require 'twitter/utils' +require 'twitter/rest/request_options' module Twitter module REST class Request include Twitter::Utils + include Twitter::REST::RequestOptions BASE_URL = 'https://api.twitter.com'.freeze attr_accessor :client, :headers, :options, :path, :rate_limit, - :request_method, :uri + :request_method, :uri, :options_key alias verb request_method # @param client [Twitter::Client] @@ -25,15 +26,14 @@ class Request def initialize(client, request_method, path, options = {}) @client = client @uri = Addressable::URI.parse(path.start_with?('http') ? path : BASE_URL + path) - set_multipart_options!(request_method, options) + create_request_options!(request_method, options) @path = uri.path @options = options end # @return [Array, Hash] def perform - options_key = @request_method == :get ? :params : :form - response = http_client.headers(@headers).public_send(@request_method, @uri.to_s, options_key => @options) + response = http_client.headers(@headers).public_send(@request_method, @uri.to_s, @options_key => @options) response_body = response.body.empty? ? '' : symbolize_keys!(response.parse) response_headers = response.headers fail_or_return_response_body(response.code, response_body, response_headers) @@ -41,41 +41,6 @@ def perform private - def merge_multipart_file!(options) - key = options.delete(:key) - file = options.delete(:file) - - options[key] = if file.is_a?(StringIO) - HTTP::FormData::File.new(file, mime_type: 'video/mp4') - else - HTTP::FormData::File.new(file, filename: File.basename(file), mime_type: mime_type(File.basename(file))) - end - end - - def set_multipart_options!(request_method, options) - if request_method == :multipart_post - merge_multipart_file!(options) - @request_method = :post - @headers = Twitter::Headers.new(@client, @request_method, @uri).request_headers - else - @request_method = request_method - @headers = Twitter::Headers.new(@client, @request_method, @uri, options).request_headers - end - end - - def mime_type(basename) - case basename - when /\.gif$/i - 'image/gif' - when /\.jpe?g/i - 'image/jpeg' - when /\.png$/i - 'image/png' - else - 'application/octet-stream' - end - end - def fail_or_return_response_body(code, body, headers) error = error(code, body, headers) raise(error) if error diff --git a/lib/twitter/rest/request_options.rb b/lib/twitter/rest/request_options.rb new file mode 100644 index 000000000..a82c7c088 --- /dev/null +++ b/lib/twitter/rest/request_options.rb @@ -0,0 +1,67 @@ +require 'twitter/headers' + +module Twitter + module REST + module RequestOptions + # Set the request method, content type, and headers on the client + # + # @param request_method [Symbol] Desired request method + # @param options [Hash] the content body + # @return [void] + def create_request_options!(request_method, options) + if request_method == :multipart_post + create_multipart_options!(options) + elsif request_method == :json_post + create_json_options! + else + create_standard_options!(request_method, options) + end + end + + private + + def merge_multipart_file!(options) + key = options.delete(:key) + file = options.delete(:file) + + options[key] = if file.is_a?(StringIO) + HTTP::FormData::File.new(file, mime_type: 'video/mp4') + else + HTTP::FormData::File.new(file, filename: File.basename(file), mime_type: mime_type(File.basename(file))) + end + end + + def create_multipart_options!(options) + merge_multipart_file!(options) + @request_method = :post + @options_key = :form + @headers = Twitter::Headers.new(@client, @request_method, @uri).request_headers + end + + def create_json_options! + @options_key = :json + @request_method = :post + @headers = Twitter::Headers.new(@client, @request_method, @uri).request_headers + end + + def create_standard_options!(request_method, options) + @request_method = request_method + @options_key = @request_method == :get ? :params : :form + @headers = Twitter::Headers.new(@client, @request_method, @uri, options).request_headers + end + + def mime_type(basename) + case basename + when /\.gif$/i + 'image/gif' + when /\.jpe?g/i + 'image/jpeg' + when /\.png$/i + 'image/png' + else + 'application/octet-stream' + end + end + end + end +end diff --git a/spec/helper.rb b/spec/helper.rb index f3279d3b4..5b4acc056 100644 --- a/spec/helper.rb +++ b/spec/helper.rb @@ -15,6 +15,7 @@ require 'tempfile' require 'timecop' require 'webmock/rspec' +require 'pry' require_relative 'support/media_object_examples' diff --git a/spec/twitter/rest/request_spec.rb b/spec/twitter/rest/request_spec.rb index d13dfec7b..ec9be033c 100644 --- a/spec/twitter/rest/request_spec.rb +++ b/spec/twitter/rest/request_spec.rb @@ -19,6 +19,22 @@ expect(a_post('/1.1/statuses/update.json').with(body: {status: 'Update', media_ids: '470030289822314497'})).to have_been_made end + context 'when posting JSON' do + it 'makes a proper json encoded request' do + stub_post('/1.1/json-post-endpoint.json') + .with( + body: {test_key: 'test value'}, + headers: {content_type: 'application/json; charset=UTF-8'} + ) + .to_return( + body: '{"success":true}', + headers: {content_type: 'application/json; charset=utf-8'} + ) + Twitter::REST::Request.new(@client, :json_post, '/1.1/json-post-endpoint.json', test_key: 'test value').perform + expect(a_post('/1.1/json-post-endpoint.json').with(body: {test_key: 'test value'})).to have_been_made + end + end + context 'when using a proxy' do before do @client = Twitter::REST::Client.new(consumer_key: 'CK', consumer_secret: 'CS', access_token: 'AT', access_token_secret: 'AS', proxy: {host: '127.0.0.1', port: 3328}) diff --git a/twitter.gemspec b/twitter.gemspec index b43d34f6f..7321f54bb 100644 --- a/twitter.gemspec +++ b/twitter.gemspec @@ -22,7 +22,7 @@ Gem::Specification.new do |spec| spec.licenses = %w[MIT] spec.name = 'twitter' spec.require_paths = %w[lib] - spec.required_ruby_version = '>= 1.9.3' + spec.required_ruby_version = '>= 2.1.0' spec.summary = spec.description spec.version = Twitter::Version end