vkontakte_api 0.2.1 → 1.0.rc

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. data/.rspec +1 -0
  2. data/.travis.yml +1 -0
  3. data/.yardopts +1 -1
  4. data/CHANGELOG.md +23 -0
  5. data/README.md +136 -61
  6. data/lib/generators/vkontakte_api/install/USAGE +2 -0
  7. data/lib/generators/vkontakte_api/install/install_generator.rb +9 -0
  8. data/lib/generators/vkontakte_api/install/templates/initializer.rb +22 -0
  9. data/lib/vkontakte_api/api.rb +27 -39
  10. data/lib/vkontakte_api/authorization.rb +66 -0
  11. data/lib/vkontakte_api/client.rb +14 -12
  12. data/lib/vkontakte_api/configuration.rb +22 -4
  13. data/lib/vkontakte_api/error.rb +15 -7
  14. data/lib/vkontakte_api/logger.rb +35 -0
  15. data/lib/vkontakte_api/method.rb +40 -0
  16. data/lib/vkontakte_api/namespace.rb +7 -0
  17. data/lib/vkontakte_api/resolvable.rb +20 -0
  18. data/lib/vkontakte_api/resolver.rb +18 -103
  19. data/lib/vkontakte_api/result.rb +48 -0
  20. data/lib/vkontakte_api/uploading.rb +29 -0
  21. data/lib/vkontakte_api/utils.rb +28 -0
  22. data/lib/vkontakte_api/version.rb +2 -1
  23. data/lib/vkontakte_api.rb +14 -3
  24. data/spec/integration_spec.rb +84 -0
  25. data/spec/spec_helper.rb +18 -0
  26. data/spec/vkontakte_api/api_spec.rb +39 -58
  27. data/spec/vkontakte_api/authorization_spec.rb +111 -0
  28. data/spec/vkontakte_api/client_spec.rb +17 -24
  29. data/spec/vkontakte_api/configuration_spec.rb +5 -0
  30. data/spec/vkontakte_api/error_spec.rb +30 -10
  31. data/spec/vkontakte_api/logger_spec.rb +88 -0
  32. data/spec/vkontakte_api/method_spec.rb +59 -0
  33. data/spec/vkontakte_api/namespace_spec.rb +5 -0
  34. data/spec/vkontakte_api/resolvable_spec.rb +21 -0
  35. data/spec/vkontakte_api/resolver_spec.rb +58 -141
  36. data/spec/vkontakte_api/result_spec.rb +115 -0
  37. data/spec/vkontakte_api/uploading_spec.rb +46 -0
  38. data/spec/vkontakte_api/utils_spec.rb +47 -0
  39. data/spec/vkontakte_api_spec.rb +4 -0
  40. data/vkontakte_api.gemspec +6 -5
  41. metadata +119 -38
  42. data/README.ru.md +0 -115
@@ -0,0 +1,35 @@
1
+ module VkontakteApi
2
+ # Faraday middleware for logging requests and responses.
3
+ #
4
+ # It's behaviour depends on the logging options in the configuration.
5
+ class Logger < Faraday::Response::Middleware
6
+ # Creates a middleware instance.
7
+ # The logger is set from `:logger` configuration option.
8
+ def initialize(app)
9
+ super(app)
10
+ @logger = VkontakteApi.logger
11
+ end
12
+
13
+ # Logs the request if needed.
14
+ # @param [Hash] env Request data.
15
+ def call(env)
16
+ if VkontakteApi.log_requests?
17
+ @logger.debug "#{env[:method].to_s.upcase} #{env[:url].to_s}"
18
+ end
19
+
20
+ super
21
+ end
22
+
23
+ # Logs the response (successful or not) if needed.
24
+ # @param [Hash] env Response data.
25
+ def on_complete(env)
26
+ if env[:body].error?
27
+ @logger.warn env[:raw_body] if VkontakteApi.log_errors?
28
+ else
29
+ @logger.debug env[:raw_body] if VkontakteApi.log_responses?
30
+ end
31
+ end
32
+ end
33
+ end
34
+
35
+ Faraday.register_middleware :response, :vk_logger => VkontakteApi::Logger
@@ -0,0 +1,40 @@
1
+ module VkontakteApi
2
+ # An API method. It is responsible for generating it's full name and determining it's type.
3
+ class Method
4
+ include Resolvable
5
+
6
+ # A pattern for names of methods with a boolean result.
7
+ PREDICATE_NAMES = /^is.*\?$/
8
+
9
+ # Calling the API method.
10
+ # It delegates the network request to `API.call` and result processing to `Result.process`.
11
+ # @param [Hash] args Arguments for the API method.
12
+ def call(args = {}, &block)
13
+ response = API.call(full_name, args, token)
14
+ Result.process(response, type, block)
15
+ end
16
+
17
+ private
18
+ def full_name
19
+ parts = [@previous_resolver.name, @name].compact.map { |part| camelize(part) }
20
+ parts.join('.').gsub(/[^A-Za-z.]/, '')
21
+ end
22
+
23
+ def type
24
+ @name =~ PREDICATE_NAMES ? :boolean : :anything
25
+ end
26
+
27
+ # camelize('get_profiles')
28
+ # => 'getProfiles'
29
+ def camelize(name)
30
+ words = name.split('_')
31
+ first_word = words.shift
32
+
33
+ words.each do |word|
34
+ word.sub!(/^[a-z]/, &:upcase)
35
+ end
36
+
37
+ words.unshift(first_word).join
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,7 @@
1
+ module VkontakteApi
2
+ # An API method namespace (such as `users` or `friends`). It just includes `Resolvable` and `Resolver`.
3
+ class Namespace
4
+ include Resolvable
5
+ include Resolver
6
+ end
7
+ end
@@ -0,0 +1,20 @@
1
+ module VkontakteApi
2
+ # A mixin for classes that will be resolved via `#method_missing`.
3
+ module Resolvable
4
+ attr_reader :name
5
+
6
+ # Creates a resolvable object keeping it's name and the object that resolved it.
7
+ # @param [String] name The name of this resolvable.
8
+ # @option options [Hashie::Mash] :resolver A mash holding information about the previous resolver.
9
+ def initialize(name, options = {})
10
+ @name = name
11
+ @previous_resolver = options.delete(:resolver)
12
+ end
13
+
14
+ # Returns the token from the previous resolver.
15
+ # @return [String] A token.
16
+ def token
17
+ @previous_resolver.token
18
+ end
19
+ end
20
+ end
@@ -1,125 +1,40 @@
1
1
  module VkontakteApi
2
- # A class for resolving namespaced methods like `friends.get`.
3
- #
4
- # Methods are dispatched the following way:
5
- #
6
- # 1. API client gets an unknown method, creates a `VkontakteApi::Resolver` instance and sends it the method
7
- # 2. if the method is a namespace (like `friends`), it creates another `VkontakteApi::Resolver` instance, namespaced this time; else go to 3
8
- # 3. the `VkontakteApi::Resolver` instance gets the last method, inserts an access token into params and sends it to `VkontakteApi::API`
9
- # 4. the result is typecasted and/or yielded (mapped) to a block depending on it's type
10
- class Resolver
11
- # A pattern for names of methods with a boolean result.
12
- PREDICATE_NAMES = /^(is.*)\?$/
13
-
14
- # A namespace of the current instance (if present).
15
- attr_reader :namespace
16
-
17
- # A new resolver.
18
- # @option options [String] :namespace A namespace.
19
- # @option options [String] :access_token An access token.
20
- def initialize(options = {})
21
- @namespace = options.delete(:namespace)
22
- @access_token = options.delete(:access_token)
23
- end
24
-
2
+ # A mixin for classes that will resolve other classes' objects via `#method_missing`.
3
+ module Resolver
25
4
  # Main methods dispatch.
26
5
  #
27
- # If the called method is a namespace, it creates and returns a new `VkontakteApi::Resolver` instance.
28
- # Otherwise it determines the full method name and result type, and sends everything to `VkontakteApi::API`.
29
- #
30
- # If the result is enumerable, each element is yielded to the block (or returned as is if called without a block).
31
- # Non-enumerable results are typecasted (and yielded if the block is present).
32
- #
33
- # Called with a block, it returns the result of the block; called without a block it returns just the result.
34
- # @todo Break this crap into several small methods.
6
+ # If the called method is a namespace, it creates and returns a new `VkontakteApi::Namespace` instance.
7
+ # Otherwise it creates a `VkontakteApi::Method` instance and invokes it's `#call` method passing it the arguments and a block.
35
8
  def method_missing(method_name, *args, &block)
36
9
  method_name = method_name.to_s
37
10
 
38
11
  if Resolver.namespaces.include?(method_name)
39
- # first level of method with a two-level name called
40
- Resolver.new(:namespace => method_name, :access_token => @access_token)
12
+ # called from Client
13
+ Namespace.new(method_name, :resolver => resolver)
41
14
  else
42
- # method with a one-level name called (or second level of a two-level method)
43
- name, type = Resolver.vk_method_name(method_name, @namespace)
44
-
45
- args = args.first || {}
46
- args[:access_token] = @access_token unless @access_token.nil?
47
-
48
- result = API.call(name, args, &block)
49
-
50
- if result.respond_to?(:each)
51
- # enumerable result receives :map with a block when called with a block
52
- # or is returned untouched otherwise
53
- block_given? ? result.map(&block) : result
54
- else
55
- # non-enumerable result is typecasted
56
- # (and yielded if block_given?)
57
- result = typecast(result, type)
58
- block_given? ? yield(result) : result
59
- end
15
+ # called from Namespace or one-level method
16
+ Method.new(method_name, :resolver => resolver).call(args.first || {}, &block)
60
17
  end
61
18
  end
62
19
 
63
- private
64
- def typecast(parameter, type)
65
- case type
66
- when :boolean
67
- # '1' becomes true, '0' becomes false
68
- !parameter.to_i.zero?
69
- else
70
- parameter
71
- end
20
+ # A `Hashie::Mash` structure holding the name and token of current instance.
21
+ # @return [Hashie::Mash]
22
+ def resolver
23
+ @resolver ||= Hashie::Mash.new(:name => @name, :token => token)
72
24
  end
73
25
 
74
26
  class << self
75
27
  # An array of method namespaces.
28
+ # Lazily loads the list from `namespaces.yml` and caches it.
76
29
  # @return [Array]
77
- attr_reader :namespaces
78
-
79
- # Loading namespaces array from `namespaces.yml`.
80
- # This method is called automatically at startup time.
81
- def load_namespaces
82
- filename = File.expand_path('../namespaces.yml', __FILE__)
83
- file = File.read(filename)
84
- @namespaces = YAML.load(file)
85
- end
86
-
87
- # A complete method name needed by VKontakte.
88
- #
89
- # Returns a full name and the result type (:boolean or :anything).
90
- # @example
91
- # vk_method_name('is_app_user?')
92
- # # => 'isAppUser'
93
- # vk_method_name('get_country_by_id', 'places')
94
- # # => 'places.getCountryById'
95
- # @return [Array] full method name and type
96
- def vk_method_name(method_name, namespace = nil)
97
- method_name = method_name.to_s
98
-
99
- if method_name =~ PREDICATE_NAMES
100
- # predicate methods should return true or false
101
- method_name.sub!(PREDICATE_NAMES, '\1')
102
- type = :boolean
103
- else
104
- # other methods can return anything they want
105
- type = :anything
30
+ def namespaces
31
+ if @namespaces.nil?
32
+ filename = File.expand_path('../namespaces.yml', __FILE__)
33
+ @namespaces = YAML.load_file(filename)
106
34
  end
107
35
 
108
- full_name = ''
109
- full_name << convert(namespace) + '.' unless namespace.nil?
110
- full_name << convert(method_name)
111
-
112
- [full_name, type]
113
- end
114
-
115
- private
116
- # convert('get_profiles')
117
- # => 'getProfiles'
118
- def convert(name)
119
- name.camelize(:lower)
36
+ @namespaces
120
37
  end
121
38
  end
122
39
  end
123
40
  end
124
-
125
- VkontakteApi::Resolver.load_namespaces
@@ -0,0 +1,48 @@
1
+ module VkontakteApi
2
+ # A module that handles method result processing.
3
+ #
4
+ # It implements method blocks support, result typecasting and raises `VkontakteApi::Error` in case of an error response.
5
+ module Result
6
+ class << self
7
+ # The main method result processing.
8
+ # @param [Hashie::Mash] response The server response in mash format.
9
+ # @param [Symbol] type The expected result type (`:boolean` or `:anything`).
10
+ # @param [Proc] block A block passed to the API method.
11
+ # @return [Array, Hashie::Mash] The processed result.
12
+ # @raise [VkontakteApi::Error] raised when VKontakte returns an error response.
13
+ def process(response, type, block)
14
+ result = extract_result(response)
15
+
16
+ if result.respond_to?(:each)
17
+ # enumerable result receives :map with a block when called with a block
18
+ # or is returned untouched otherwise
19
+ block.nil? ? result : result.map(&block)
20
+ else
21
+ # non-enumerable result is typecasted
22
+ # (and yielded if block_given?)
23
+ result = typecast(result, type)
24
+ block.nil? ? result : block.call(result)
25
+ end
26
+ end
27
+
28
+ private
29
+ def extract_result(response)
30
+ if response.error?
31
+ raise VkontakteApi::Error.new(response.error)
32
+ else
33
+ response.response
34
+ end
35
+ end
36
+
37
+ def typecast(parameter, type)
38
+ case type
39
+ when :boolean
40
+ # '1' becomes true, '0' becomes false
41
+ !parameter.to_i.zero?
42
+ else
43
+ parameter
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,29 @@
1
+ module VkontakteApi
2
+ # A module implementing files uploading functionality.
3
+ #
4
+ # @note `VkontakteApi::Uploading` extends `VkontakteApi` so these methods should be called from the latter.
5
+ module Uploading
6
+ # Files uploading. It uses the same faraday middleware stack as API method calls (by using `VkontakteApi::API.connection`).
7
+ # @param [Hash] params A list of files to upload (also includes the upload URL). See example for the hash format.
8
+ # @option params [String] :url URL for the request.
9
+ # @return [Hashie::Mash] The server response.
10
+ # @raise [ArgumentError] raised when a `:url` parameter is omitted.
11
+ # @example
12
+ # VkontakteApi.upload(
13
+ # url: 'http://example.com/upload',
14
+ # file1: ['/path/to/file1.jpg', 'image/jpeg'],
15
+ # file2: ['/path/to/file2.png', 'image/png']
16
+ # )
17
+ def upload(params = {})
18
+ url = params.delete(:url)
19
+ raise ArgumentError, 'You should pass :url parameter' unless url
20
+
21
+ files = {}
22
+ params.each do |param_name, (file_path, file_type)|
23
+ files[param_name] = Faraday::UploadIO.new(file_path, file_type)
24
+ end
25
+
26
+ API.connection.post(url, files).body
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,28 @@
1
+ module VkontakteApi
2
+ # An utility module able to flatten arguments (join arrays into comma-separated strings).
3
+ module Utils
4
+ class << self
5
+ # A multiple version of `#flatten_argument`. It transforms a hash flattening each value and keeping the keys untouched.
6
+ # @param [Hash] arguments The arguments to flatten.
7
+ # @return [Hash] Flattened arguments.
8
+ def flatten_arguments(arguments)
9
+ arguments.inject({}) do |flat_args, (arg_name, arg_value)|
10
+ flat_args[arg_name] = flatten_argument(arg_value)
11
+ flat_args
12
+ end
13
+ end
14
+
15
+ # If an argument is an array, it will be joined with a comma; otherwise it'll be returned untouched.
16
+ # @param [Object] argument The argument to flatten.
17
+ def flatten_argument(argument)
18
+ if argument.respond_to?(:join)
19
+ # if argument is an array, we join it with a comma
20
+ argument.join(',')
21
+ else
22
+ # otherwise leave it untouched
23
+ argument
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
@@ -1,3 +1,4 @@
1
1
  module VkontakteApi
2
- VERSION = '0.2.1'
2
+ # Library version.
3
+ VERSION = '1.0.rc'
3
4
  end
data/lib/vkontakte_api.rb CHANGED
@@ -1,19 +1,30 @@
1
1
  require 'faraday'
2
- require 'yajl'
2
+ require 'faraday_middleware'
3
+ require 'faraday_middleware/parse_oj'
4
+ require 'oauth2'
3
5
  require 'yaml'
4
- require 'active_support/core_ext/string/inflections'
5
- require 'active_support/core_ext/object/to_query'
6
+ require 'hashie'
6
7
 
7
8
  require 'vkontakte_api/version'
8
9
  require 'vkontakte_api/error'
9
10
  require 'vkontakte_api/configuration'
11
+ require 'vkontakte_api/authorization'
12
+ require 'vkontakte_api/uploading'
13
+ require 'vkontakte_api/utils'
10
14
  require 'vkontakte_api/api'
11
15
  require 'vkontakte_api/resolver'
16
+ require 'vkontakte_api/resolvable'
12
17
  require 'vkontakte_api/client'
18
+ require 'vkontakte_api/namespace'
19
+ require 'vkontakte_api/method'
20
+ require 'vkontakte_api/result'
21
+ require 'vkontakte_api/logger'
13
22
 
14
23
  # Main module.
15
24
  module VkontakteApi
16
25
  extend VkontakteApi::Configuration
26
+ extend VkontakteApi::Authorization
27
+ extend VkontakteApi::Uploading
17
28
  end
18
29
 
19
30
  # short alias
@@ -0,0 +1,84 @@
1
+ # encoding: utf-8
2
+ require 'spec_helper'
3
+
4
+ describe "Integration" do
5
+ before(:all) do
6
+ # turn off all the logging
7
+ VkontakteApi.configure do |config|
8
+ config.log_requests = false
9
+ config.log_errors = false
10
+ config.log_responses = false
11
+ end
12
+ end
13
+
14
+ describe "unauthorized requests" do
15
+ before(:each) do
16
+ @vk = VkontakteApi::Client.new
17
+ end
18
+
19
+ it "get users" do
20
+ user = @vk.users.get(:uid => 1).first
21
+ user.uid.should == 1
22
+ user.last_name.should == 'Дуров'
23
+ user.first_name.should == 'Павел'
24
+ end
25
+ end
26
+
27
+ describe "authorized requests" do
28
+ before(:each) do
29
+ @vk = VkontakteApi::Client.new(ENV['TOKEN'])
30
+ end
31
+
32
+ it "get groups" do
33
+ groups = @vk.groups.get
34
+ groups.should include(1)
35
+ end
36
+ end if ENV['TOKEN']
37
+
38
+ describe "requests with camelCase and predicate methods" do
39
+ before(:each) do
40
+ @vk = VkontakteApi::Client.new(ENV['TOKEN'])
41
+ end
42
+
43
+ it "convert method names to vk.com format" do
44
+ @vk.is_app_user?.should be_true
45
+ end
46
+ end if ENV['TOKEN']
47
+
48
+ describe "requests with array arguments" do
49
+ before(:each) do
50
+ @vk = VkontakteApi::Client.new
51
+ end
52
+
53
+ it "join arrays with a comma" do
54
+ users = @vk.users.get(:uids => [1, 2, 3], :fields => %w[first_name last_name screen_name])
55
+ users.first.screen_name.should == 'durov'
56
+ end
57
+ end
58
+
59
+ describe "requests with blocks" do
60
+ before(:each) do
61
+ @vk = VK::Client.new
62
+ end
63
+
64
+ it "map the result with a block" do
65
+ users = @vk.users.get(:uid => 1) do |user|
66
+ "#{user.last_name} #{user.first_name}"
67
+ end
68
+
69
+ users.first.should == 'Дуров Павел'
70
+ end
71
+ end
72
+
73
+ describe "authorization" do
74
+ context "with a scope" do
75
+ it "returns a correct url" do
76
+ VkontakteApi.authorization_url(:scope => %w[friends groups]).should include('scope=friends%2Cgroups')
77
+ end
78
+ end
79
+ end
80
+
81
+ after(:all) do
82
+ VkontakteApi.reset
83
+ end
84
+ end
data/spec/spec_helper.rb CHANGED
@@ -1,2 +1,20 @@
1
1
  require 'vkontakte_api'
2
2
  require 'pry'
3
+
4
+ RSpec::Matchers.define :log_requests do
5
+ match do |logger|
6
+ logger.log_requests?
7
+ end
8
+ end
9
+
10
+ RSpec::Matchers.define :log_errors do
11
+ match do |logger|
12
+ logger.log_errors?
13
+ end
14
+ end
15
+
16
+ RSpec::Matchers.define :log_responses do
17
+ match do |logger|
18
+ logger.log_responses?
19
+ end
20
+ end
@@ -1,81 +1,62 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe VkontakteApi::API do
4
- before(:each) do
5
- @method_name = 'apiMethod'
6
- @args = {
7
- :field => 'value',
8
- :access_token => 'some_token'
9
- }
4
+ def create_connection
5
+ @result = {'response' => {'key' => 'value'}}
6
+
7
+ @connection = Faraday.new do |builder|
8
+ builder.response :mashify
9
+ builder.response :json, :preserve_raw => true
10
+ builder.adapter :test do |stub|
11
+ stub.get('/apiMethod') do
12
+ [200, {}, Oj.dump(@result)]
13
+ end
14
+ end
15
+ end
16
+ subject.stub(:connection).and_return(@connection)
10
17
  end
11
18
 
12
19
  describe ".call" do
13
20
  before(:each) do
14
- @url = stub("URL")
15
- VkontakteApi::API.stub(:url_for).and_return(@url)
16
-
17
- @connection = stub("Faraday connection")
18
- Faraday.stub(:new).and_return(@connection)
19
-
20
- body = stub("Response body")
21
- response = stub("Response", :body => body)
22
- @connection.stub(:get).and_return(response)
23
-
24
- @result = stub("Result")
25
- @result.stub(:has_key?) { |key| key == 'response' }
26
-
27
- @result_response = stub("Result[response]")
28
- @result_error = stub("Result[error]").as_null_object
29
-
30
- @result.stub(:[]) do |key|
31
- if key == :response
32
- @result_response
33
- else
34
- @result_error
35
- end
36
- end
37
-
38
- Yajl::Parser.stub(:parse).and_return(@result)
39
- end
40
-
41
- it "calls the url from .url_for" do
42
- @connection.should_receive(:get).with(@url)
43
- VkontakteApi::API.call('apiMethod')
21
+ create_connection
44
22
  end
45
23
 
46
- context "with a successful response" do
47
- it "returns the response body" do
48
- VkontakteApi::API.call('apiMethod').should == @result_response
24
+ context "called with a token parameter" do
25
+ it "sends it to .connection" do
26
+ subject.should_receive(:connection).with(:url => VkontakteApi::API::URL_PREFIX, :token => 'token')
27
+ subject.call('apiMethod', {:some => :params}, 'token')
49
28
  end
50
29
  end
51
30
 
52
- context "with an error response" do
53
- before(:each) do
54
- @result.stub(:has_key?) { |key| key != 'response' }
55
- end
56
-
57
- it "raises a VkontakteApi::Error" do
58
- expect {
59
- VkontakteApi::API.call('apiMethod')
60
- }.to raise_error(VkontakteApi::Error)
61
- end
31
+ it "returns the response body" do
32
+ subject.call('apiMethod').should == @result
62
33
  end
63
34
  end
64
35
 
65
- describe ".url_for" do
66
- it "constructs a valid VK API url" do
67
- url = VkontakteApi::API.send(:url_for, @method_name, @args)
68
- url.should == '/method/apiMethod?access_token=some_token&field=value'
36
+ describe ".connection" do
37
+ it "uses the :url parameter" do
38
+ url = stub("URL")
39
+ Faraday.should_receive(:new).with(url)
40
+ connection = subject.connection(:url => url)
41
+ end
42
+
43
+ context "without a token" do
44
+ it "creates a connection without an oauth2 middleware" do
45
+ connection = subject.connection
46
+ connection.builder.handlers.map(&:name).should_not include('FaradayMiddleware::OAuth2')
47
+ end
69
48
  end
70
49
 
71
- context "with an array argument" do
50
+ context "with a token" do
72
51
  before(:each) do
73
- @args_with_array = @args.merge(:array_arg => [1, 2, 3])
52
+ @token = stub("Token")
74
53
  end
75
54
 
76
- it "concats it with a comma" do
77
- url = VkontakteApi::API.send(:url_for, @method_name, @args_with_array)
78
- url.should == "/method/apiMethod?access_token=some_token&array_arg=#{CGI.escape('1,2,3')}&field=value"
55
+ it "creates a connection with an oauth2 middleware" do
56
+ connection = subject.connection(:token => @token)
57
+ handler = connection.builder.handlers.first
58
+ handler.name.should == 'FaradayMiddleware::OAuth2'
59
+ handler.instance_variable_get(:@args).should == [@token]
79
60
  end
80
61
  end
81
62
  end