yammer-client 0.1.2 → 0.1.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (61) hide show
  1. data.tar.gz.sig +0 -0
  2. data/.travis.yml +1 -0
  3. data/CHANGELOG.md +22 -0
  4. data/Gemfile +1 -1
  5. data/Gemfile.lock +3 -4
  6. data/README.md +11 -10
  7. data/file.txt +1 -0
  8. data/lib/yammer.rb +7 -11
  9. data/lib/yammer/api.rb +2 -1
  10. data/lib/yammer/api/autocomplete.rb +1 -1
  11. data/lib/yammer/api/group.rb +5 -5
  12. data/lib/yammer/api/group_membership.rb +2 -2
  13. data/lib/yammer/api/message.rb +13 -13
  14. data/lib/yammer/api/network.rb +1 -1
  15. data/lib/yammer/api/notification.rb +1 -1
  16. data/lib/yammer/api/pending_attachment.rb +48 -0
  17. data/lib/yammer/api/search.rb +1 -1
  18. data/lib/yammer/api/topic.rb +1 -1
  19. data/lib/yammer/api/user.rb +17 -17
  20. data/lib/yammer/api_handler.rb +15 -0
  21. data/lib/yammer/{response.rb → api_response.rb} +6 -6
  22. data/lib/yammer/base.rb +19 -11
  23. data/lib/yammer/client.rb +27 -42
  24. data/lib/yammer/configurable.rb +14 -8
  25. data/lib/yammer/group.rb +1 -1
  26. data/lib/yammer/group_membership.rb +1 -1
  27. data/lib/yammer/http_adapter.rb +74 -0
  28. data/lib/yammer/message.rb +1 -1
  29. data/lib/yammer/thread.rb +1 -1
  30. data/lib/yammer/user.rb +6 -6
  31. data/lib/yammer/version.rb +1 -1
  32. data/spec/api/autocomplete_spec.rb +1 -2
  33. data/spec/api/group_membership_spec.rb +1 -2
  34. data/spec/api/group_spec.rb +1 -2
  35. data/spec/api/message_spec.rb +1 -2
  36. data/spec/api/network_spec.rb +1 -2
  37. data/spec/api/notification_spec.rb +3 -4
  38. data/spec/api/pending_attachment_spec.rb +37 -0
  39. data/spec/api/search_spec.rb +1 -2
  40. data/spec/api/thread_spec.rb +1 -2
  41. data/spec/api/topic_spec.rb +1 -2
  42. data/spec/api/user_spec.rb +15 -2
  43. data/spec/{response_spec.rb → api_response.rb} +9 -8
  44. data/spec/client_spec.rb +203 -66
  45. data/spec/fixtures/users_followed.json +1 -0
  46. data/spec/fixtures/users_following.json +1 -0
  47. data/spec/http_adapter_spec.rb +90 -0
  48. data/spec/mocks/attachment.txt +1 -0
  49. data/spec/model/base_spec.rb +26 -5
  50. data/spec/model/group_membership_spec.rb +11 -0
  51. data/spec/model/group_spec.rb +10 -0
  52. data/spec/model/message_spec.rb +10 -0
  53. data/spec/model/thread_spec.rb +6 -0
  54. data/spec/model/user_spec.rb +53 -0
  55. data/spec/spec_helper.rb +8 -0
  56. data/yammer.gemspec +3 -1
  57. metadata +35 -10
  58. metadata.gz.sig +0 -0
  59. data/lib/yammer/http_connection.rb +0 -184
  60. data/lib/yammer/model.rb +0 -6
  61. data/spec/connection_spec.rb +0 -306
@@ -7,7 +7,7 @@ module Yammer
7
7
  # @rate_limited Yes
8
8
  # @authentication Requires user context
9
9
  # @raise [Yammer::Error::Unauthorized] Error raised when supplied user credentials are not valid.
10
- # @return [Yammer::Response]
10
+ # @return [Yammer::ApiResponse]
11
11
  # @param [Hash] opts the options to fetch a thread with
12
12
  # @option opts [Integer] :num_per_page
13
13
  # @option opts [Integer] :page
@@ -7,7 +7,7 @@ module Yammer
7
7
  # @rate_limited Yes
8
8
  # @authentication Requires user context
9
9
  # @raise [Yammer::Error::Unauthorized] Error raised when supplied user credentials are not valid.
10
- # @return [Yammer::Response]
10
+ # @return [Yammer::ApiResponse]
11
11
  # @param id [Integer]
12
12
  # @param [Hash] opts the options to fetch a thread with
13
13
  # @option opts [Integer] :is_followed_by
@@ -6,7 +6,7 @@ module Yammer
6
6
  # @rate_limited Yes
7
7
  # @authentication Requires user context
8
8
  # @raise [Yammer::Error::Unauthorized] Error raised when supplied user credentials are not valid.
9
- # @return [Yammer::Response]
9
+ # @return [Yammer::ApiResponse]
10
10
  # @param opts [Hash] A customizable set of options.
11
11
  # @option opts [String] :email
12
12
  # @option opts [String] :full_name
@@ -39,7 +39,7 @@ module Yammer
39
39
  # @rate_limited Yes
40
40
  # @authentication Requires user context
41
41
  # @raise [Yammer::Error::Unauthorized] Error raised when supplied user credentials are not valid.
42
- # @return [Yammer::Response]
42
+ # @return [Yammer::ApiResponse]
43
43
  # @param opts [Hash] A customizable set of options.
44
44
  # @option opts [String] :email
45
45
  # @option opts [String] :full_name
@@ -72,7 +72,7 @@ module Yammer
72
72
  # @rate_limited Yes
73
73
  # @authentication Requires user context
74
74
  # @raise [Yammer::Error::Unauthorized] Error raised when supplied user credentials are not valid.
75
- # @return [Yammer::Response]
75
+ # @return [Yammer::ApiResponse]
76
76
  # @param id [Integer, String] A Yammer user ID
77
77
  # @example Delete user with ID 2
78
78
  # Yammer.delete_user(2)
@@ -84,7 +84,7 @@ module Yammer
84
84
  # @rate_limited Yes
85
85
  # @authentication Requires user context
86
86
  # @raise [Yammer::Error::Unauthorized] Error raised when supplied user credentials are not valid.
87
- # @return [Yammer::Response]
87
+ # @return [Yammer::ApiResponse]
88
88
  # @param id [Integer, String] A Yammer user ID
89
89
  # @example Fetch data user with ID 2
90
90
  # Yammer.get_user(2)
@@ -96,7 +96,7 @@ module Yammer
96
96
  # @rate_limited Yes
97
97
  # @authentication Requires user context
98
98
  # @raise [Yammer::Error::Unauthorized] Error raised when supplied user credentials are not valid.
99
- # @return [Yammer::Response]
99
+ # @return [Yammer::ApiResponse]
100
100
  # @param email [Integer, String] A Yammer user ID
101
101
  # @example Fetch data user with email `thekev@yammer.com`
102
102
  # Yammer.get_user_by_email('thekev@yammer.com')
@@ -108,7 +108,7 @@ module Yammer
108
108
  # @rate_limited Yes
109
109
  # @authentication Requires user context
110
110
  # @raise [Yammer::Error::Unauthorized] Error raised when supplied user credentials are not valid.
111
- # @return [Yammer::Response]
111
+ # @return [Yammer::ApiResponse]
112
112
  # @example Fetch data for the authenticated user
113
113
  # Yammer.current_user
114
114
  def current_user
@@ -119,10 +119,10 @@ module Yammer
119
119
  # @rate_limited Yes
120
120
  # @authentication Requires user context
121
121
  # @raise [Yammer::Error::Unauthorized] Error raised when supplied user credentials are not valid.
122
- # @return [Yammer::Response]
122
+ # @return [Yammer::ApiResponse]
123
123
  # @param opts [Hash] A customizable set of opts.
124
124
  # @option opts [Integer] :page
125
- # @example Fetch users from the autheticated user's network
125
+ # @example Fetch users from the authenticated user's network
126
126
  # Yammer.all_users
127
127
  def all_users(opts={})
128
128
  get("/api/v1/users", opts)
@@ -131,25 +131,25 @@ module Yammer
131
131
  # @rate_limited Yes
132
132
  # @authentication Requires user context
133
133
  # @raise [Yammer::Error::Unauthorized] Error raised when supplied user credentials are not valid.
134
- # @return [Yammer::Response]
134
+ # @return [Yammer::ApiResponse]
135
135
  # @param opts [Hash] A customizable set of opts.
136
136
  # @option opts [Boolean] :full
137
- # @example Fetch users from the autheticated user's network
137
+ # @example Fetch users from the authenticated user's network following user whose ID is provided
138
138
  # Yammer.users_following(1)
139
- def users_following(id, opts={})
140
- get("/api/v1/users/following/", opts)
139
+ def users_following(id)
140
+ get("/api/v1/users/following/#{id}")
141
141
  end
142
142
 
143
143
  # @rate_limited Yes
144
144
  # @authentication Requires user context
145
145
  # @raise [Yammer::Error::Unauthorized] Error raised when supplied user credentials are not valid.
146
- # @return [Yammer::Response]
146
+ # @return [Yammer::ApiResponse]
147
147
  # @param opts [Hash] A customizable set of opts.
148
148
  # @option opts [Boolean] :full
149
- # @example Fetch users from the autheticated user's network
150
- # Yammer.users_following(1)
151
- def users_followed(id, opts={})
152
- get("/api/v1/users/followed_by", opts)
149
+ # @example Fetch users from the authenticated user's network followed by the user whose ID is provided
150
+ # Yammer.users_followed(1)
151
+ def users_followed_by(id)
152
+ get("/api/v1/users/followed_by/#{id}")
153
153
  end
154
154
  end
155
155
  end
@@ -0,0 +1,15 @@
1
+ module Yammer
2
+ module ApiHandler
3
+ def api_handler
4
+ @api_handler ||= establish_api_handler
5
+ end
6
+
7
+ def establish_api_handler(opts={})
8
+ Yammer::Client.new(opts)
9
+ end
10
+
11
+ def reset_api_handler!
12
+ @api_handler = nil
13
+ end
14
+ end
15
+ end
@@ -1,12 +1,12 @@
1
1
  module Yammer
2
- class Response
2
+ class ApiResponse
3
3
 
4
- attr_reader :code, :body, :headers
4
+ attr_reader :code, :headers
5
5
 
6
- def initialize(response)
7
- @headers = response.header
8
- @body = response.body
9
- @code = response.code.to_i
6
+ def initialize(headers, body, code)
7
+ @headers = headers
8
+ @body = body
9
+ @code = code.to_i
10
10
  end
11
11
 
12
12
  def raw_body
data/lib/yammer/base.rb CHANGED
@@ -1,6 +1,7 @@
1
1
  module Yammer
2
2
  class Base
3
3
  class << self
4
+ include ApiHandler
4
5
 
5
6
  # Returns the non-qualified class name
6
7
  # @!scope class
@@ -32,7 +33,7 @@ module Yammer
32
33
  return unless identity_map
33
34
  attributes = identity_map.get("#{base_name}_#{id}")
34
35
  unless attributes
35
- result = Yammer.send("get_#{base_name}", id)
36
+ result = api_handler.send("get_#{base_name}", id)
36
37
  attributes = result.empty? ? nil : result.body
37
38
  unless attributes.empty?
38
39
  identity_map.put("#{base_name}_#{id}", attributes)
@@ -48,16 +49,16 @@ module Yammer
48
49
 
49
50
  # Returns a hash of all attributes that are meant to trigger an HTTP request
50
51
  # @!scope class
51
- def fetchable_attrs
52
- @fetchable_keys ||= {}
52
+ def model_attributes
53
+ @model_attributes ||= {}
53
54
  end
54
55
 
55
56
  protected
56
57
 
57
58
  def attr_accessor_deffered(*symbols)
58
59
  symbols.each do |key|
59
- # track attributes the trigger fetch
60
- fetchable_attrs[key] = false
60
+ # track attributes that should trigger a fetch
61
+ model_attributes[key] = false
61
62
 
62
63
  # getter
63
64
  define_method(key.to_s) do
@@ -82,16 +83,23 @@ module Yammer
82
83
  attr_reader :id, :attrs
83
84
 
84
85
  def initialize(props={})
86
+ @klass = self.class
85
87
  @modified_attributes = {}
86
88
  @new_record = true
87
89
  @loaded = false
88
90
  @attrs = props
89
91
  self.id = @attrs.delete(:id)
90
92
  self.update(@attrs)
93
+
94
+ yield self if block_given?
95
+ end
96
+
97
+ def api_handler
98
+ @klass.api_handler
91
99
  end
92
100
 
93
101
  def base_name
94
- self.class.base_name
102
+ @klass.base_name
95
103
  end
96
104
 
97
105
  def new_record?
@@ -115,7 +123,7 @@ module Yammer
115
123
  end
116
124
 
117
125
  def load!
118
- @attrs = self.class.fetch(@id)
126
+ @attrs = @klass.fetch(@id)
119
127
  @loaded = true
120
128
  update(@attrs)
121
129
  self
@@ -130,9 +138,9 @@ module Yammer
130
138
  return self if ((persisted? && @modified_attributes.empty?) || @attrs.empty?)
131
139
 
132
140
  result = if new_record?
133
- Yammer.send("create_#{base_name}", @attrs)
141
+ api_handler.send("create_#{base_name}", @attrs)
134
142
  else
135
- Yammer.send("update_#{base_name}", @id, @modified_attributes)
143
+ api_handler.send("update_#{base_name}", @id, @modified_attributes)
136
144
  end
137
145
  @modified_attributes = {}
138
146
  self
@@ -140,7 +148,7 @@ module Yammer
140
148
 
141
149
  def delete!
142
150
  return if new_record?
143
- result = Yammer.send("delete_#{base_name}", @id)
151
+ result = api_handler.send("delete_#{base_name}", @id)
144
152
  result.success?
145
153
  end
146
154
 
@@ -177,7 +185,7 @@ module Yammer
177
185
  send("#{key}=", value)
178
186
  end
179
187
  if persisted? && !loaded?
180
- @loaded = self.class.fetchable_attrs.keys.inject(true) do |result, key|
188
+ @loaded = @klass.model_attributes.keys.inject(true) do |result, key|
181
189
  result && @attrs.has_key?(key)
182
190
  end
183
191
  end
data/lib/yammer/client.rb CHANGED
@@ -1,7 +1,6 @@
1
- require 'multi_json'
2
- require 'yammer/configurable'
3
- require 'yammer/http_connection'
4
1
  require 'yammer/api'
2
+ require 'yammer/configurable'
3
+ require 'yammer/http_adapter'
5
4
 
6
5
  module Yammer
7
6
  class Client
@@ -16,28 +15,24 @@ module Yammer
16
15
  include Yammer::Api::Search
17
16
  include Yammer::Api::Notification
18
17
  include Yammer::Api::Autocomplete
18
+ include Yammer::Api::PendingAttachment
19
+
20
+ attr_reader :site_url, :headers, :connection_options
19
21
 
20
- attr_writer :connection_options
21
- attr_accessor :site_url, :http_adapter
22
+ attr_accessor :client_id, :client_secret, :access_token
22
23
 
23
24
  def initialize(opts={})
24
25
  Yammer::Configurable.keys.each do |key|
25
- instance_variable_set(:"@#{key}", opts.fetch(key, Yammer.instance_variable_get(:"@#{key}")))
26
+ case key
27
+ when :headers, :connection_options
28
+ value = Yammer.instance_variable_get(:"@#{key}").merge(opts.fetch(key, {}))
29
+ else
30
+ value = opts.fetch(key, Yammer.instance_variable_get(:"@#{key}"))
31
+ end
32
+ instance_variable_set(:"@#{key}", value)
26
33
  end
27
34
  end
28
35
 
29
- # @return [Hash] the options used to setup the http connection
30
- def connection_options
31
- @connection_options ||= {}
32
- end
33
-
34
- # set the url to be used for creating an http connection
35
- # @param url [string]
36
- def site_url=(url)
37
- @connection = nil
38
- @site_url = url
39
- end
40
-
41
36
  # (see #request)
42
37
  # @note makes a GET request
43
38
  def get(path, params={})
@@ -64,38 +59,28 @@ module Yammer
64
59
 
65
60
  private
66
61
 
62
+ # returns an instance of the http adapter
63
+ # if none is specified, the default is Yammer::HttpConnection
64
+ # @!visibility private
65
+ def http_client
66
+ @http_client ||= @http_adapter.new(@site_url, @connection_options)
67
+ end
68
+
67
69
  # Makes an HTTP request using the provided parameters
68
70
  # @raise [Yammer::Error::Unauthorized]
69
71
  # @param method [string]
70
72
  # @param path [string]
71
73
  # @param params [Hash]
72
74
  # @param opts [Hash]
73
- # @return [Yammer::Response]
75
+ # @return [Yammer::ApiResponse]
74
76
  # @!visibility private
75
- def request(method, path, params={}, opts={})
76
- headers = opts.fetch(:headers, {}).merge({
77
- 'Authorization' => "Bearer #{@access_token}"
78
- })
79
- response = connection.send_request(method, path, {
80
- :params => params,
81
- :headers => headers
77
+ def request(method, path, params={})
78
+ @headers['Authorization'] ||= "Bearer #{@access_token}"
79
+ result = http_client.send_request(method, path, {
80
+ :params => params,
81
+ :headers => @headers
82
82
  })
83
- result = Yammer::Response.new(response)
84
- status = result.code
85
- case status
86
- when 200...400
87
- result
88
- else
89
- message = result.empty? ? '' : result.body[:response][:message]
90
- raise Yammer::Error.from_status(status).new(message)
91
- end
92
- end
93
-
94
- # returns an instance of the http adapter
95
- # if none is specified, the default is Yammer::HttpConnection
96
- # @!visibility private
97
- def connection
98
- @connection ||= @http_adapter.new(@site_url, connection_options)
83
+ result
99
84
  end
100
85
  end
101
86
  end
@@ -1,11 +1,13 @@
1
+ require 'yammer/http_adapter'
2
+
1
3
  module Yammer
2
4
  module Configurable
3
5
 
4
6
  ENDPOINT = 'https://www.yammer.com' unless defined? ENDPOINT
5
- HTTP_CONNECTION = Yammer::HttpConnection unless defined? HTTP_CONNECTION
7
+ HTTP_ADAPTER = Yammer::HttpAdapter unless defined? HTTP_CONNECTION
6
8
 
7
- attr_accessor :hostname, :client_id, :client_secret, :access_token, :site_url, :http_adapter,
8
- :connection_options
9
+ attr_accessor :client_id, :client_secret, :access_token, :site_url,
10
+ :connection_options, :headers, :http_adapter
9
11
 
10
12
  # Return a hash with the default options
11
13
  # @return [Hash]
@@ -15,14 +17,18 @@ module Yammer
15
17
  :client_id => ENV['YAMMER_CLIENT_ID'],
16
18
  :client_secret => ENV['YAMMER_CLIENT_SECRET'],
17
19
  :access_token => ENV['YAMMER_ACCESS_TOKEN'],
18
- :http_adapter => HTTP_CONNECTION,
19
- :connection_options => { :max_redirects => 5, :use_ssl => true }
20
+ :http_adapter => HTTP_ADAPTER,
21
+ :connection_options => { :max_redirects => 5, :verify_ssl => true },
22
+ :headers => {
23
+ 'Accept' => 'application/json',
24
+ 'User-Agent' => "Yammer Ruby Gem #{Yammer::Version}"
25
+ }
20
26
  }
21
27
  end
22
28
 
23
- # @return [Array<String>
29
+ # @return [Array<String>]
24
30
  def self.keys
25
- Yammer::Configurable.default_options.keys
31
+ self.default_options.keys
26
32
  end
27
33
 
28
34
  # @return [Hash]
@@ -39,7 +45,7 @@ module Yammer
39
45
 
40
46
  # Convenience method to allow configuration options to be set in a block
41
47
  def configure
42
- yield self
48
+ yield self if block_given?
43
49
  self
44
50
  end
45
51
  end
data/lib/yammer/group.rb CHANGED
@@ -7,7 +7,7 @@ module Yammer
7
7
 
8
8
  # @!scope class
9
9
  def self.create(params={})
10
- result = Yammer.create_group(params)
10
+ result = api_handler.create_group(params)
11
11
  end
12
12
  end
13
13
  end
@@ -5,7 +5,7 @@ module Yammer
5
5
 
6
6
  # @!scope class
7
7
  def self.create(id)
8
- Yammer.create_group_membership(id)
8
+ api_handler.create_group_membership(id)
9
9
  end
10
10
  end
11
11
  end
@@ -0,0 +1,74 @@
1
+ require 'restclient'
2
+ require 'multi_json'
3
+ require 'addressable/uri'
4
+
5
+ module Yammer
6
+ class HttpAdapter
7
+
8
+ attr_reader :site_url, :connection_options
9
+
10
+ def initialize(site_url, opts={})
11
+ unless site_url =~ /^https?/
12
+ raise ArgumentError, "site_url must include either http or https scheme"
13
+ end
14
+ @site_url = site_url
15
+ @connection_options = opts
16
+ end
17
+
18
+ # set the url to be used for creating an http connection
19
+ # @param url [string]
20
+ def site_url=(url)
21
+ @site_url = url
22
+ @host = nil
23
+ @scheme = nil
24
+ end
25
+
26
+ def host
27
+ @host ||= parsed_url.host
28
+ end
29
+
30
+ def scheme
31
+ @scheme ||= parsed_url.scheme
32
+ end
33
+
34
+ def absolute_url(path='')
35
+ "#{@site_url}#{path}"
36
+ end
37
+
38
+ def connection_options=(opts)
39
+ raise ArgumentError, 'expected Hash' unless opts.is_a?(Hash)
40
+ @connection_options = opts
41
+ end
42
+
43
+ def send_request(method, path, opts={})
44
+ params = opts.fetch(:params, {})
45
+
46
+ req_opts = self.connection_options.merge({
47
+ :method => method,
48
+ :headers => opts.fetch(:headers, {})
49
+ })
50
+
51
+ case method
52
+ when :get, :delete
53
+ query = Addressable::URI.form_encode(params)
54
+ normalized_path = query.empty? ? path : [path, query].join("?")
55
+ req_opts[:url] = absolute_url(normalized_path)
56
+ when :post, :put
57
+ req_opts[:payload] = params
58
+ req_opts[:url] = absolute_url(path)
59
+ else
60
+ raise "Unsupported HTTP method, #{method}"
61
+ end
62
+
63
+ resp = RestClient::Request.execute(req_opts)
64
+
65
+ result = Yammer::ApiResponse.new(resp.headers, resp.body, resp.code)
66
+ end
67
+
68
+ private
69
+ def parsed_url
70
+ Addressable::URI.parse(@site_url)
71
+ end
72
+
73
+ end
74
+ end