octocat_herder 0.0.2 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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