yammer-client 0.1.2 → 0.1.3

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 (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