octocat_herder 0.0.2 → 0.1.0

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.
@@ -6,13 +6,27 @@ require 'octocat_herder/user'
6
6
  require 'octocat_herder/pull_request/repo'
7
7
 
8
8
  class OctocatHerder
9
- class PullRequest < Base
9
+ # Interface to the GitHub v3 API for interacting with pull requests.
10
+ #
11
+ # Currently, this only supports retrieval of information about the
12
+ # pull request itself, not the comments, or any updating/creation.
13
+ class PullRequest
14
+ include OctocatHerder::Base
15
+
16
+ # Query either the open or closed pull requests for a given
17
+ # repository.
18
+ #
19
+ # @since 0.0.1
20
+ # @param [String] owner_login The login name of the repository owner.
21
+ # @param [String] repository_name The name of the repository itself.
22
+ # @param ['open', 'closed'] status Defaults to querying open pull requests.
23
+ # @param [OctocatHerder::Connection] conn Defaults to unauthenticated requests.
24
+ # @return [Array<OctocatHerder::PullRequest>] An array of found pull requests.
10
25
  def self.find_for_repository(owner_login, repository_name, status = 'open', conn = OctocatHerder::Connection.new)
11
26
  raise ArgumentError.new("Unknown PullRequest status '#{status}'. Must be one of ['open', 'closed'].") unless
12
27
  ['open', 'closed'].include? status
13
28
 
14
- pull_requests = raw_get(
15
- conn,
29
+ pull_requests = conn.get(
16
30
  "/repos/#{CGI.escape(owner_login.to_s)}/#{CGI.escape(repository_name.to_s)}/pulls",
17
31
  :paginated => true,
18
32
  :params => { :state => status },
@@ -24,17 +38,38 @@ class OctocatHerder
24
38
  end
25
39
  end
26
40
 
41
+ # Query the open pull requests for a given repository.
42
+ #
43
+ # @since 0.0.1
44
+ # @param [String] owner_login The login name of the repository owner.
45
+ # @param [String] repository_name The name of the repository itself.
46
+ # @param [OctocatHerder::Connection] conn Defaults to unauthenticated requests.
47
+ # @return [Array<OctocatHerder::PullRequest>] An array of found pull requests.
27
48
  def self.find_open_for_repository(owner_login, repository_name, conn = OctocatHerder::Connection.new)
28
49
  OctocatHerder::PullRequest.find_for_repository(owner_login, repository_name, 'open', conn)
29
50
  end
30
51
 
52
+ # Query the closed pull requests for a given repository.
53
+ #
54
+ # @since 0.0.1
55
+ # @param [String] owner_login The login name of the repository owner.
56
+ # @param [String] repository_name The name of the repository itself.
57
+ # @param [OctocatHerder::Connection] conn Defaults to unauthenticated requests.
58
+ # @return [Array<OctocatHerder::PullRequest>] An array of found pull requests.
31
59
  def self.find_closed_for_repository(owner_login, repository_name, conn = OctocatHerder::Connection.new)
32
60
  OctocatHerder::PullRequest.find_for_repository(owner_login, repository_name, 'closed', conn)
33
61
  end
34
62
 
63
+ # Query information about a specific pull request.
64
+ #
65
+ # @since 0.0.1
66
+ # @param [String] owner_login The login name of the repository owner.
67
+ # @param [String] repository_name The name of the repository itself.
68
+ # @param [String, Integer] pull_request_number The pull request to retrieve.
69
+ # @param [OctocatHerder::Connection] conn Defaults to unauthenticated requests.
70
+ # @return [OctocatHerder::PullRequest]
35
71
  def self.fetch(owner_login, repository_name, pull_request_number, conn = OctocatHerder::Connection.new)
36
- request = raw_get(
37
- conn,
72
+ request = conn.get(
38
73
  "/repos/#{CGI.escape(owner_login.to_s)}/#{CGI.escape(repository_name.to_s)}/pulls/#{CGI.escape(pull_request_number.to_s)}",
39
74
  :headers => { 'Accept' => 'application/vnd.github-pull.full+json' }
40
75
  )
@@ -42,15 +77,29 @@ class OctocatHerder
42
77
  new(nil, request, conn)
43
78
  end
44
79
 
80
+ # @api private
81
+ # @since 0.0.1
82
+ # @param [Hash] raw_hash The 'overview' information retrieved from the pull request listing API.
83
+ # @param [Hash] raw_detail_hash The full information available by querying information about a specific pull request.
84
+ # @param [OctocatHerder::Connection] conn Defaults to unauthenticated requests.
45
85
  def initialize(raw_hash, raw_detail_hash = nil, conn = OctocatHerder::Connection.new)
46
86
  super raw_hash, conn
47
87
  @raw_detail_hash = raw_detail_hash
48
88
  end
49
89
 
90
+ # Get the full pull request details. When retrieved from
91
+ # .find_for_repository, .find_open_for_repository, or
92
+ # .find_closed_for_repository not all of the details of the pull
93
+ # request are available since GitHub doesn't return them in the
94
+ # listing. This will query information about the specific pull
95
+ # request, which will get us all of the available details.
96
+ #
97
+ # @since 0.0.1
98
+ # @return [self]
50
99
  def get_detail
51
100
  return if @raw_detail_hash
52
101
 
53
- @raw_detail_hash = raw_get(
102
+ @raw_detail_hash = connection.get(
54
103
  url,
55
104
  :headers => { 'Accept' => 'application/vnd.github-pull.full+json' }
56
105
  )
@@ -58,6 +107,12 @@ class OctocatHerder
58
107
  self
59
108
  end
60
109
 
110
+ # Check the "normal" place first for the information returned by
111
+ # the GitHub API, then check +@raw_detail_hash+ (populating it if
112
+ # needed).
113
+ #
114
+ # @since 0.0.1
115
+ # @return [String]
61
116
  def method_missing(id, *args)
62
117
  super
63
118
  rescue NoMethodError => e
@@ -67,105 +122,212 @@ class OctocatHerder
67
122
  raise e
68
123
  end
69
124
 
70
- # Nested data from the "overview" data.
125
+ # The URL to the avatar image of the person that opened the pull request.
126
+ #
127
+ # @note Since this is returned by the pull request API itself, this can be used without making an additional API request.
128
+ #
129
+ # @since 0.0.1
130
+ # @return [String] Avatar URL
71
131
  def user_avatar_url
72
132
  return @raw['user']['avatar_url'] if @raw
73
133
  @raw_detail_hash['user']['avatar_url']
74
134
  end
75
135
 
136
+ # The URL of the person that opened the pull request.
137
+ #
138
+ # @note Since this is returned by the pull request API itself, this can be used without making an additional API request.
139
+ #
140
+ # @since 0.0.1
141
+ # @return [String] User URL
76
142
  def user_url
77
143
  return @raw['user']['url'] if @raw
78
144
  @raw_detail_hash['user']['url']
79
145
  end
80
146
 
147
+ # The ID number of the person that opened the pull request.
148
+ #
149
+ # @note Since this is returned by the pull request API itself, this can be used without making an additional API request.
150
+ #
151
+ # @since 0.0.1
152
+ # @return [Integer] User ID
81
153
  def user_id
82
154
  return @raw['user']['id'] if @raw
83
155
  @raw_detail_hash['user']['id']
84
156
  end
85
157
 
158
+ # The login name of the person that opened the pull request.
159
+ #
160
+ # @note Since this is returned by the pull request API itself, this can be used without making an additional API request.
161
+ #
162
+ # @since 0.0.1
163
+ # @return [String] User login name
86
164
  def user_login
87
165
  return @raw['user']['login'] if @raw
88
166
  @raw_detail_hash['user']['login']
89
167
  end
90
168
 
91
- # Return a real user, instead of a hash with the nested data.
169
+ # The user that opened the pull request.
170
+ #
171
+ # @note This is cached locally to the individual pull request, but will make an additional API request to populate it initially.
172
+ #
173
+ # @since 0.0.1
174
+ # @return [OctocatHerder::User]
92
175
  def user
93
176
  @user ||= OctocatHerder::User.fetch(user_login, connection)
94
177
  end
95
178
 
96
- # Nested data from the "detail" data.
179
+ # The login name of the person that merged the pull request, or
180
+ # +nil+ if it has not been merged yet.
181
+ #
182
+ # @since 0.0.1
183
+ # @return [String, nil]
97
184
  def merged_by_login
98
- get_detail
185
+ return nil unless merged
99
186
 
187
+ get_detail
100
188
  @raw_detail_hash['merged_by']['login']
101
189
  end
102
190
 
191
+ # The ID number of the person that merged the pull request, or
192
+ # +nil+ if it has not been merged yet.
193
+ #
194
+ # @since 0.0.1
195
+ # @return [String, nil]
103
196
  def merged_by_id
104
- get_detail
197
+ return nil unless merged
105
198
 
199
+ get_detail
106
200
  @raw_detail_hash['merged_by']['id']
107
201
  end
108
202
 
203
+ # The URL to the avatar image of the person that merged the pull
204
+ # request, or +nil+ if it has not been merged yet.
205
+ #
206
+ # @since 0.0.1
207
+ # @return [String, nil]
109
208
  def merged_by_avatar_url
110
- get_detail
209
+ return nil unless merged
111
210
 
211
+ get_detail
112
212
  @raw_detail_hash['merged_by']['avatar_url']
113
213
  end
114
214
 
215
+ # The URL of the person that merged the pull request, or +nil+ if
216
+ # it has not been merged yet.
217
+ #
218
+ # @since 0.0.1
219
+ # @return [String, nil]
115
220
  def merged_by_url
116
- get_detail
221
+ return nil unless merged
117
222
 
223
+ get_detail
118
224
  @raw_detail_hash['merged_by']['url']
119
225
  end
120
226
 
121
- # Return a real user, instead of a hash with the nested data.
227
+ # The user that merged the pull request, or +nil+ if it has not
228
+ # been merged yet.
229
+ #
230
+ # @note This is cached locally to the individual pull request, but will make an additional API request to populate it initially.
231
+ #
232
+ # @since 0.0.1
233
+ # @return [OctocatHerder::User, nil]
122
234
  def merged_by
123
- get_detail
235
+ return nil unless merged
124
236
 
125
237
  @merged_by ||= OctocatHerder::User.fetch(merged_by_login, connection)
126
238
  end
127
239
 
128
- # Convert a few things to more Ruby friendly Objects
240
+ # When the pull request was first created.
241
+ #
242
+ # @since 0.0.1
243
+ # @return [Time]
129
244
  def created_at
130
245
  parse_date_time(@raw_detail_hash['created_at'])
131
246
  end
132
247
 
248
+ # When the pull request was last updated.
249
+ #
250
+ # @since 0.0.1
251
+ # @return [Time]
133
252
  def updated_at
134
253
  parse_date_time(@raw_detail_hash['updated_at'])
135
254
  end
136
255
 
256
+ # When the pull request was closed, or +nil+ if it is still open.
257
+ #
258
+ # @since 0.0.1
259
+ # @return [Time, nil]
137
260
  def closed_at
138
261
  parse_date_time(@raw_detail_hash['closed_at'])
139
262
  end
140
263
 
264
+ # When the pull request was merged, or +nil+ if it hasn't been merged.
265
+ #
266
+ # @since 0.0.1
267
+ # @return [Time, nil]
141
268
  def merged_at
142
269
  parse_date_time(@raw_detail_hash['merged_at'])
143
270
  end
144
271
 
272
+ # Information about what is being asked to be merged in the pull
273
+ # request.
274
+ #
275
+ # @since 0.0.1
276
+ # @return [OctocatHerder::PullRequest::Repo]
145
277
  def head
146
278
  get_detail
147
279
 
148
280
  @head_repo ||= OctocatHerder::PullRequest::Repo.new(@raw_detail_hash['head'], connection)
149
281
  end
150
282
 
283
+ # Information about what the pull request was based on in the pull
284
+ # request.
285
+ #
286
+ # @since 0.0.1
287
+ # @return [OctocatHerder::PullRequest::Repo]
151
288
  def base
152
289
  get_detail
153
290
 
154
291
  @base_repo ||= OctocatHerder::PullRequest::Repo.new(@raw_detail_hash['base'], connection)
155
292
  end
156
293
 
157
- def additional_attributes
158
- attrs = ['user_avatar_url', 'user_url', 'user_id', 'user_login']
159
-
160
- attrs += @raw_detail_hash.keys if @raw_detail_hash
161
- attrs += ['merged_by_login', 'merged_by_id', 'merged_by_avatar_url', 'merged_by_url']
162
- end
163
-
294
+ # A Hash representation of the pull request. Combines +@raw+, and
295
+ # +@raw_detail_hash+ into a single hash.
296
+ #
297
+ # @since 0.0.2
298
+ # @return [Hash]
164
299
  def to_hash
165
300
  raw = @raw || {}
166
301
  detail = @raw_detail_hash || {}
167
302
 
168
- raw.merge(detail)
303
+ ret = raw.merge(detail)
304
+ ret['patch_text'] = patch_text
305
+ ret['diff_text'] = diff_text
306
+
307
+ ret
308
+ end
309
+
310
+ def patch_text
311
+ @patch_text ||= connection.raw_get(patch_url).body
312
+ end
313
+
314
+ def diff_text
315
+ @diff_text ||= connection.raw_get(diff_url).body
316
+ end
317
+
318
+ private
319
+
320
+ # Give a full listing of the available information, since we
321
+ # define some of our own methods, and don't have everything in
322
+ # +@raw+.
323
+ #
324
+ # @api private
325
+ # @since 0.0.1
326
+ def additional_attributes
327
+ attrs = ['user_avatar_url', 'user_url', 'user_id', 'user_login', 'patch_text', 'diff_text']
328
+
329
+ attrs += @raw_detail_hash.keys if @raw_detail_hash
330
+ attrs += ['merged_by_login', 'merged_by_id', 'merged_by_avatar_url', 'merged_by_url']
169
331
  end
170
332
  end
171
333
  end
@@ -5,11 +5,42 @@ require 'octocat_herder/connection'
5
5
  require 'octocat_herder/user'
6
6
 
7
7
  class OctocatHerder
8
- class Repository < Base
8
+ # Interface to the GitHub v3 API for interacting with repositories.
9
+ #
10
+ # Currently, this only supports retrieval of information about the
11
+ # repository itself, not any updating/creation.
12
+ class Repository
13
+ include OctocatHerder::Base
14
+
15
+ # @overload list_all(login_name, account_type, conn = OctocatHerder::Connection.new)
16
+ # @overload list_private(login_name, account_type, conn)
17
+ # @overload list_public(login_name, account_type, conn = OctocatHerder::Connection.new)
18
+ # @overload list_member(login_name, account_type, conn = OctocatHerder::Connection.new)
19
+ #
20
+ # Fetch all, private, public, or member repositories for the specified user.
21
+ #
22
+ # @since 0.0.1
23
+ #
24
+ # @raise [ArgumentError] If no conn is not provided when listing
25
+ # private repositories.
26
+ #
27
+ # @param [String] login_name The login name of the user.
28
+ #
29
+ # @param ['User', 'Organization'] Whether login_name is for a user
30
+ # or organization.
31
+ #
32
+ # @param [OctocatHerder::Connection] conn Defaults to
33
+ # unauthenticated requests.
34
+ #
35
+ # @return [Array<OctocatHerder::Repository>]
9
36
  def self.method_missing(id, *args)
10
37
  if id.id2name =~ /list_(.+)/
11
38
  repository_type = Regexp.last_match(1)
12
39
  if ['all', 'private', 'public', 'member'].include? repository_type
40
+ if repository_type == 'private' and args[2].nil?
41
+ raise ArgumentError.new("Must specify a connection when listing private repositories.")
42
+ end
43
+
13
44
  arguments = [args[0], args[1], repository_type]
14
45
  arguments << args[2] unless args[2].nil?
15
46
 
@@ -20,42 +51,108 @@ class OctocatHerder
20
51
  raise NoMethodError.new("undefined method #{id.id2name} for #{self}:#{self.class}")
21
52
  end
22
53
 
54
+ # The login name of the owner of the repository.
55
+ #
56
+ # @since 0.0.1
57
+ # @return [String]
23
58
  def owner_login
24
59
  @raw['owner']['login']
25
60
  end
26
61
 
62
+ # The ID number of the owner of the repository.
63
+ #
64
+ # @since 0.0.1
65
+ # @return [Integer]
27
66
  def owner_id
28
67
  @raw['owner']['id']
29
68
  end
30
69
 
70
+ # The URL to the avatar image of the owner of the repository.
71
+ #
72
+ # @since 0.0.1
73
+ # @return [String]
31
74
  def owner_avatar_url
32
75
  @raw['owner']['avatar_url']
33
76
  end
34
77
 
78
+ # The URL of the owner of the repository.
79
+ #
80
+ # @since 0.0.1
81
+ # @return [String]
35
82
  def owner_url
36
83
  @raw['owner']['url']
37
84
  end
38
85
 
86
+ # The owner of the repository.
87
+ #
88
+ # @note This is cached locally to the instance of
89
+ # {OctocatHerder::Repository}, but will make an additional API
90
+ # request to populate it initially.
91
+ #
92
+ # @since 0.0.1
93
+ # @return [OctocatHerder::User]
39
94
  def owner
40
- OctocatHerder::User.fetch(owner_login, connection)
95
+ @owner ||= OctocatHerder::User.fetch(owner_login, connection)
41
96
  end
42
97
 
98
+ # The open pull requests for the repository.
99
+ #
100
+ # @note This is _not_ cached, and will make at least one API
101
+ # request every time it is called.
102
+ #
103
+ # @since 0.0.1
104
+ # @return [Array<OctocatHerder::PullRequest>]
43
105
  def open_pull_requests
44
- OctocatHerder::PullRequest.find_for_repository(owner_login, name, 'open')
106
+ OctocatHerder::PullRequest.find_open_for_repository(owner_login, name, connection)
45
107
  end
46
108
 
109
+ # The closed pull requests for the repository.
110
+ #
111
+ # @note This is _not_ cached, and will make at least one API
112
+ # request every time it is called.
113
+ #
114
+ # @since 0.0.1
115
+ # @return [Array<OctocatHerder::PullRequest>]
47
116
  def closed_pull_requests
48
- OctocatHerder::PullRequest.find_for_repository(owner_login, name, 'closed')
117
+ OctocatHerder::PullRequest.find_closed_for_repository(owner_login, name, connection)
49
118
  end
50
119
 
120
+ # The source repository that this one was forked from, or +nil+ if
121
+ # this repository is not a fork.
122
+ #
123
+ # @since 0.0.1
124
+ # @return [OctocatHerder::Repository, nil]
51
125
  def source
52
- return unless @raw['source']
126
+ return nil unless @raw['source']
53
127
 
54
128
  OctocatHerder::Repository.new(@raw['source'], connection)
55
129
  end
56
130
 
57
- private
58
-
131
+ # Fetch repositories of the specified type, owned by the given login
132
+ #
133
+ # @since 0.0.1
134
+ #
135
+ # @raise [ArgumentError] If provided an unauthenticated
136
+ # OctocatHerder::Connection and repository_type is 'private'.
137
+ #
138
+ # @raise [ArgumentError] If account_type is not one of the strings
139
+ # 'User', or 'Organization'.
140
+ #
141
+ # @raise [ArgumentError] If repository_type is not one of the
142
+ # strings 'all', 'private', 'public', or 'member'.
143
+ #
144
+ # @param [String] login Login name of the account.
145
+ #
146
+ # @param ['User', 'Organization'] account_type Type of the
147
+ # specified login.
148
+ #
149
+ # @param ['all', 'private', 'public', 'member'] repository_type
150
+ # Which set of repositories to list.
151
+ #
152
+ # @param [OctocatHerder::Connection] conn Default to
153
+ # unauthenticated requests.
154
+ #
155
+ # @return [Array<OctocatHerder::Repository>]
59
156
  def self.list(login, account_type, repository_type, conn = OctocatHerder::Connection.new)
60
157
  url_base = case account_type
61
158
  when "User" then "users"
@@ -64,8 +161,15 @@ class OctocatHerder
64
161
  raise ArgumentError.new("Unknown account type: #{account_type}")
65
162
  end
66
163
 
67
- repositories = raw_get(
68
- conn,
164
+ raise ArgumentError.new(
165
+ "Unknown repository type: #{repository_type}"
166
+ ) unless ['all', 'private', 'public', 'member'].include?(repository_type)
167
+
168
+ raise ArgumentError.new(
169
+ "Must provide an authenticated OctocatHerder::Connection when listing private repositories."
170
+ ) if !conn.authenticated_requests? && repository_type == 'private'
171
+
172
+ repositories = conn.get(
69
173
  "/#{url_base}/#{CGI.escape(login)}/repos",
70
174
  :paginated => true,
71
175
  :params => { :type => repository_type }
@@ -76,15 +180,28 @@ class OctocatHerder
76
180
  end
77
181
  end
78
182
 
183
+ # Fetch a single repository.
184
+ #
185
+ # @since 0.0.1
186
+ #
187
+ # @param [String] login Login name of the account.
188
+ #
189
+ # @param [String] repository_name Name of the repository.
190
+ #
191
+ # @param [OctocatHerder::Connection] Default to unauthenticated
192
+ # requests.
193
+ #
194
+ # @return [OctocatHerder::Repository]
79
195
  def self.fetch(login, repository_name, conn = OctocatHerder::Connection.new)
80
- repo_data = raw_get(
81
- conn,
196
+ repo_data = conn.get(
82
197
  "/repos/#{CGI.escape(login)}/#{CGI.escape(repository_name)}"
83
198
  )
84
199
 
85
200
  new(repo_data, conn)
86
201
  end
87
202
 
203
+ private
204
+
88
205
  def additional_attributes
89
206
  ['owner_login', 'owner_id', 'owner_avatar_url', 'owner_url']
90
207
  end
@@ -1,34 +1,133 @@
1
+ require 'cgi'
2
+
1
3
  require 'octocat_herder/base'
2
4
  require 'octocat_herder/connection'
3
5
  require 'octocat_herder/repository'
4
6
 
5
7
  class OctocatHerder
6
- class User < Base
8
+ # Interface to the GitHub v3 API for interacting with users.
9
+ #
10
+ # Currently, this only supports retrieval of information about the
11
+ # requested user.
12
+ class User
13
+ include OctocatHerder::Base
14
+
15
+ # Find a user by login name
16
+ #
17
+ # @since 0.0.1
18
+ # @param [String] user_name The login name of the desired user.
19
+ #
20
+ # @param [OctocatHerder::Connection] conn Defaults to
21
+ # unauthenticated requests.
22
+ #
23
+ # @return [OctocatHerder::User]
7
24
  def self.fetch(user_name, conn = OctocatHerder::Connection.new)
8
- user = raw_get(conn, "/users/#{user_name}")
25
+ user = conn.get("/users/#{CGI.escape(user_name)}")
9
26
 
10
- OctocatHerder::User.new(user, conn)
27
+ new(user, conn)
11
28
  end
12
29
 
30
+ # All repositories owned by the user.
31
+ #
32
+ # @note This is cached locally to the {OctocatHerder::User}
33
+ # instance, but at least one API request will be made to
34
+ # populate it initially.
35
+ #
36
+ # @since 0.0.1
37
+ # @return [Array<OctocatHerder::Repository>]
13
38
  def repositories
14
39
  @repositories ||= OctocatHerder::Repository.list_all(login, user_type, connection)
15
40
  end
16
41
 
17
- # The user id can't be handled by the method_missing magic from
18
- # OctocatHerder::Base, since the id method returns the object id.
42
+ # The ID number of the user.
43
+ #
44
+ # @since 0.0.1
45
+ # @return [Integer]
19
46
  def user_id
47
+ # The user id can't be handled by the method_missing magic from
48
+ # OctocatHerder::Base, since the id method returns the object
49
+ # id.
20
50
  @raw['id']
21
51
  end
22
52
 
23
- # The user type can't be handled by the method_missing magic from
24
- # OctocatHerder::Base, since 'type' is the deprecated form of the
25
- # method 'class'.
53
+ # The type of account. Typically one of +'User'+, or
54
+ # +'Organization'+.
55
+ #
56
+ # @since 0.0.1
57
+ # @return [String]
26
58
  def user_type
59
+ # The user type can't be handled by the method_missing magic
60
+ # from OctocatHerder::Base, since 'type' is the deprecated form
61
+ # of the method 'class'.
27
62
  @raw['type']
28
63
  end
29
64
 
65
+ # List of users following this user.
66
+ #
67
+ # @since development
68
+ # @return [Array<OctocatHerder::User>]
69
+ def followers
70
+ result = connection.get(
71
+ "/users/#{CGI.escape(login)}/followers"
72
+ )
73
+
74
+ result.map do |follower|
75
+ self.class.new(follower, connection)
76
+ end
77
+ end
78
+
79
+ # List of users this user is following.
80
+ #
81
+ # @since development
82
+ # @return [Array<OctocatHerder::User>]
83
+ def following
84
+ users = connection.get(
85
+ "/users/#{CGI.escape(login)}/following"
86
+ )
87
+
88
+ users.map do |stalkee|
89
+ self.class.new(stalkee, connection)
90
+ end
91
+ end
92
+
93
+ # Check if the user authenticated by the provided
94
+ # {OctocatHerder::Connection} is following the specified user.
95
+ #
96
+ # @since development
97
+ #
98
+ # @raise [ArgumentError] If user is not a String or an
99
+ # OctocatHerder::User
100
+ #
101
+ # @raise [ArgumentError] If the connection will not make
102
+ # authenticated requests.
103
+ #
104
+ # @param [String, OctocatHerder::User] user
105
+ #
106
+ # @param [OctocatHerder::Connection] connection An authenticated connection
107
+ #
108
+ # @return [true, false]
109
+ def self.following?(user, connection)
110
+ raise ArgumentError.new(
111
+ "Provided user must be a String, or an OctocatHerder::User."
112
+ ) unless user.is_a?(String) or user.is_a?(OctocatHerder::User)
113
+
114
+ raise ArgumentError.new(
115
+ "Provided connection must make authenticated requests."
116
+ ) unless connection.authenticated_requests?
117
+
118
+ user_name = user.is_a?(OctocatHerder::User) ? user.login : user
119
+
120
+ result = connection.raw_get("/user/following/#{CGI.escape(user_name)}")
121
+
122
+ # The GitHub API gives us back a "204 No Content" if we are
123
+ # following the user.
124
+ result.response.code == "204"
125
+ end
126
+
30
127
  private
31
128
 
129
+ # @api private
130
+ # @since 0.0.1
32
131
  def additional_attributes
33
132
  ['user_id', 'user_type']
34
133
  end