github_api 0.8.2 → 0.8.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (58) hide show
  1. data/README.md +20 -1
  2. data/features/cassettes/issues/events/get.yml +139 -0
  3. data/features/cassettes/issues/events/list_issue.yml +71 -0
  4. data/features/cassettes/issues/events/list_repo.yml +222 -0
  5. data/features/cassettes/issues/labels/list_repo.yml +65 -0
  6. data/features/cassettes/issues/milestones/create.yml +55 -0
  7. data/features/cassettes/issues/milestones/delete.yml +46 -0
  8. data/features/cassettes/issues/milestones/get.yml +175 -0
  9. data/features/cassettes/issues/milestones/list.yml +54 -0
  10. data/features/cassettes/issues/milestones/update.yml +53 -0
  11. data/features/cassettes/repos/contents/archive.yml +43 -84
  12. data/features/cassettes/say/custom.yml +60 -0
  13. data/features/cassettes/say/random.yml +60 -0
  14. data/features/issues/events.feature +38 -0
  15. data/features/issues/labels.feature +14 -0
  16. data/features/issues/milestones.feature +62 -0
  17. data/features/say.feature +68 -0
  18. data/features/step_definitions/common_steps.rb +6 -0
  19. data/features/support/helpers.rb +4 -0
  20. data/lib/github_api.rb +2 -0
  21. data/lib/github_api/client.rb +8 -0
  22. data/lib/github_api/constants.rb +4 -0
  23. data/lib/github_api/issues.rb +74 -46
  24. data/lib/github_api/issues/assignees.rb +2 -1
  25. data/lib/github_api/issues/events.rb +3 -3
  26. data/lib/github_api/issues/milestones.rb +0 -1
  27. data/lib/github_api/rate_limit.rb +2 -0
  28. data/lib/github_api/result.rb +13 -0
  29. data/lib/github_api/say.rb +24 -0
  30. data/lib/github_api/scopes.rb +19 -0
  31. data/lib/github_api/version.rb +1 -1
  32. data/spec/github/git_data/git_data_spec.rb +19 -0
  33. data/spec/github/issues/assignees/check_spec.rb +46 -0
  34. data/spec/github/issues/assignees/list_spec.rb +47 -0
  35. data/spec/github/issues/assignees_spec.rb +0 -96
  36. data/spec/github/issues/create_spec.rb +60 -0
  37. data/spec/github/issues/edit_spec.rb +61 -0
  38. data/spec/github/issues/events_spec.rb +4 -4
  39. data/spec/github/issues/get_spec.rb +49 -0
  40. data/spec/github/issues/issues_spec.rb +19 -0
  41. data/spec/github/issues/list_spec.rb +90 -0
  42. data/spec/github/issues/milestones/create_spec.rb +56 -0
  43. data/spec/github/issues/milestones/delete_spec.rb +42 -0
  44. data/spec/github/issues/milestones/get_spec.rb +49 -0
  45. data/spec/github/issues/milestones/list_spec.rb +52 -0
  46. data/spec/github/issues/milestones/update_spec.rb +57 -0
  47. data/spec/github/issues/milestones_spec.rb +1 -276
  48. data/spec/github/scopes/list_spec.rb +33 -0
  49. data/spec/github/users/followers/follow_spec.rb +33 -0
  50. data/spec/github/users/followers/following_spec.rb +65 -0
  51. data/spec/github/users/followers/is_following_spec.rb +41 -0
  52. data/spec/github/users/followers/list_spec.rb +2 -8
  53. data/spec/github/users/followers/unfollow_spec.rb +33 -0
  54. data/spec/github/users/users_spec.rb +16 -0
  55. metadata +68 -35
  56. data/spec/github/git_data_spec.rb +0 -11
  57. data/spec/github/issues_spec.rb +0 -284
  58. data/spec/github/users/followers_spec.rb +0 -172
@@ -30,6 +30,8 @@ Then /^the response should be (.*)$/ do |expected_response|
30
30
  true
31
31
  when /\d+/
32
32
  expected_response.to_i
33
+ when /empty/
34
+ []
33
35
  else
34
36
  expected_response
35
37
  end
@@ -62,6 +64,10 @@ Then /^the response should contain (.*)$/ do |item|
62
64
  end
63
65
  end
64
66
 
67
+ Then /^the response should contain:$/ do |string|
68
+ unescape(@response.body).should include(unescape(string))
69
+ end
70
+
65
71
  Then /^the response (.*) link should contain:$/ do |type, table|
66
72
  table.hashes.each do |attributes|
67
73
  attributes.each do |key, val|
@@ -5,3 +5,7 @@ def convert_to_constant(classes)
5
5
  end
6
6
  return constant
7
7
  end
8
+
9
+ def unescape(string)
10
+ string.gsub('\n', "\n").gsub('\"', '"').gsub('\e', "\e")
11
+ end
data/lib/github_api.rb CHANGED
@@ -77,6 +77,8 @@ module Github
77
77
  :Users => 'users',
78
78
  :Emojis => 'emojis',
79
79
  :Search => 'search',
80
+ :Say => 'say',
81
+ :Scopes => 'scopes',
80
82
  :Markdown => 'markdown',
81
83
  :CoreExt => 'core_ext',
82
84
  :MimeType => 'mime_type',
@@ -60,6 +60,14 @@ module Github
60
60
  end
61
61
  alias :repositories :repos
62
62
 
63
+ def octocat(options = {})
64
+ @octocat ||= ApiFactory.new 'Say', options
65
+ end
66
+
67
+ def scopes(options = {})
68
+ @scopes ||= ApiFactory.new 'Scopes', options
69
+ end
70
+
63
71
  def search(options = {})
64
72
  @search ||= ApiFactory.new 'Search', options
65
73
  end
@@ -27,6 +27,10 @@ module Github
27
27
 
28
28
  ACCEPT_CHARSET = 'Accept-Charset'.freeze
29
29
 
30
+ OAUTH_SCOPES = 'X-Oauth-Scopes'.freeze
31
+
32
+ ACCEPTED_OAUTH_SCOPES = 'X-Accepted-Oauth-Scopes'.freeze
33
+
30
34
  # Link headers
31
35
  HEADER_LINK = "Link".freeze
32
36
 
@@ -25,6 +25,7 @@ module Github
25
25
  body
26
26
  resource
27
27
  mime_type
28
+ org
28
29
  ].freeze
29
30
 
30
31
  VALID_ISSUE_PARAM_VALUES = {
@@ -67,61 +68,66 @@ module Github
67
68
 
68
69
  # List your issues
69
70
  #
70
- # = Parameters
71
- # <tt>:filter</tt>
72
- # * <tt>assigned</tt>: Issues assigned to you (default)
73
- # * <tt>created</tt>: Issues assigned to you (default)
74
- # * <tt>mentioned</tt>: Issues assigned to you (default)
75
- # * <tt>subscribed</tt>: Issues assigned to you (default)
76
- # <tt>:state</tt> - <tt>open</tt>, <tt>closed</tt>, default: <tt>open</tt>
77
- # <tt>:labels</tt> - String list of comma separated Label names. Example: bug,ui,@high
78
- # <tt>:sort</tt> - <tt>created</tt>, <tt>updated</tt>, <tt>comments</tt>, default: <tt>created</tt>
79
- # <tt>:direction</tt> - <tt>asc</tt>, <tt>desc</tt>, default: <tt>desc</tt>
80
- # <tt>:since</tt> - Optional string of a timestamp in ISO 8601 format: YYYY-MM-DDTHH:MM:SSZ
71
+ # List all issues across all the authenticated user’s visible repositories
72
+ # including owned repositories, member repositories,
73
+ # and organization repositories.
81
74
  #
82
- # = Examples
75
+ # = Example
83
76
  # github = Github.new :oauth_token => '...'
84
- # github.issues.list :since => '2011-04-12T12:12:12Z',
85
- # :filter => 'created',
86
- # :state => 'open',
87
- # :labels => "bug,ui,bla",
88
- # :sort => 'comments',
89
- # :direction => 'asc'
77
+ # github.issues.list
78
+ #
79
+ # List all issues across owned and member repositories for the
80
+ # authenticated user.
81
+ #
82
+ # = Example
83
+ # github = Github.new :oauth_token => '...'
84
+ # github.issues.list :user
85
+ #
86
+ # List all issues for a given organization for the authenticated user.
87
+ #
88
+ # = Example
89
+ # github = Github.new :oauth_token => '...'
90
+ # github.issues.list :org => 'org-name'
90
91
  #
91
- def list(*args)
92
- params = args.extract_options!
93
- normalize! params
94
- filter! VALID_ISSUE_PARAM_NAMES, params
95
- # _merge_mime_type(:issue, params)
96
- assert_valid_values(VALID_ISSUE_PARAM_VALUES, params)
97
-
98
- response = get_request("/issues", params)
99
- return response unless block_given?
100
- response.each { |el| yield el }
101
- end
102
- alias :all :list
103
-
104
92
  # List issues for a repository
105
93
  #
94
+ # = Example
95
+ # github = Github.new
96
+ # github.issues.list :user => 'user-name', :repo => 'repo-name'
97
+ #
106
98
  # = Parameters
99
+ # <tt>:filter</tt>
100
+ # * <tt>assigned</tt> Issues assigned to you (default)
101
+ # * <tt>created</tt> Issues assigned to you (default)
102
+ # * <tt>mentioned</tt> Issues assigned to you (default)
103
+ # * <tt>subscribed</tt> Issues assigned to you (default)
107
104
  # <tt>:milestone</tt>
108
105
  # * Integer Milestone number
109
106
  # * <tt>none</tt> for Issues with no Milestone.
110
- # * <tt>*</tt> for Issues with any Milestone
111
- # <tt>:state</tt> - <tt>open</tt>, <tt>closed</tt>, default: <tt>open</tt>
107
+ # * <tt>*</tt> for Issues with any Milestone
108
+ # <tt>:state</tt> - <tt>open</tt>, <tt>closed</tt>, default: <tt>open</tt>
109
+ # <tt>:labels</tt> - String list of comma separated Label names.
110
+ # Example: bug,ui,@high
112
111
  # <tt>:assignee</tt>
113
112
  # * String User login
114
113
  # * <tt>none</tt> for Issues with no assigned User.
115
- # * <tt>*</tt> for Issues with any assigned User.
114
+ # * <tt>*</tt> for Issues with any assigned User.
116
115
  # <tt>:mentioned</tt> String User login
117
- # <tt>:labels</tt> - String list of comma separated Label names. Example: bug,ui,@high
118
- # <tt>:sort</tt> - <tt>created</tt>, <tt>updated</tt>, <tt>comments</tt>, default: <tt>created</tt>
119
- # <tt>:direction</tt> - <tt>asc</tt>, <tt>desc</tt>, default: <tt>desc</tt>
120
- # <tt>:since</tt> - Optional string of a timestamp in ISO 8601 format: YYYY-MM-DDTHH:MM:SSZ
121
- # <tt></tt>, default: <tt>due_date</tt>
116
+ # <tt>:sort</tt> - <tt>created</tt>, <tt>updated</tt>, <tt>comments</tt>,
117
+ # default: <tt>created</tt>
122
118
  # <tt>:direction</tt> - <tt>asc</tt>, <tt>desc</tt>, default: <tt>desc</tt>
119
+ # <tt>:since</tt> - Optional string of a timestamp in ISO 8601
120
+ # format: YYYY-MM-DDTHH:MM:SSZ
123
121
  #
124
122
  # = Examples
123
+ # github = Github.new :oauth_token => '...'
124
+ # github.issues.list :since => '2011-04-12T12:12:12Z',
125
+ # :filter => 'created',
126
+ # :state => 'open',
127
+ # :labels => "bug,ui,bla",
128
+ # :sort => 'comments',
129
+ # :direction => 'asc'
130
+ #
125
131
  # github = Github.new :user => 'user-name', :repo => 'repo-name'
126
132
  # github.issues.list_repo :milestone => 1,
127
133
  # :state => 'open',
@@ -131,20 +137,42 @@ module Github
131
137
  # :sort => 'comments',
132
138
  # :direction => 'asc'
133
139
  #
134
- def list_repo(user_name, repo_name, params={})
140
+ def list(*args)
141
+ params = args.extract_options!
142
+ normalize! params
143
+ # filter! VALID_ISSUE_PARAM_NAMES, params
144
+ # _merge_mime_type(:issue, params)
145
+ # assert_valid_values(VALID_ISSUE_PARAM_VALUES, params)
146
+
147
+ response = if (org = params.delete('org'))
148
+ get_request("/orgs/#{org}/issues", params)
149
+
150
+ elsif (user_name = params.delete('user')) &&
151
+ (repo_name = params.delete('repo'))
152
+
153
+ list_repo user_name, repo_name, params
154
+ elsif args.include? :user
155
+ get_request("/user/issues", params)
156
+ else
157
+ get_request("/issues", params)
158
+ end
159
+ return response unless block_given?
160
+ response.each { |el| yield el }
161
+ end
162
+ alias :all :list
163
+
164
+ # List issues for a repository
165
+ #
166
+ def list_repo(user_name, repo_name, params)
135
167
  set :user => user_name, :repo => repo_name
136
168
  assert_presence_of user, repo
137
169
 
138
- normalize! params
139
170
  filter! VALID_ISSUE_PARAM_NAMES, params
140
- # _merge_mime_type(:issue, params)
141
171
  assert_valid_values(VALID_ISSUE_PARAM_VALUES, params)
142
172
 
143
- response = get_request("/repos/#{user}/#{repo}/issues", params)
144
- return response unless block_given?
145
- response.each { |el| yield el }
173
+ get_request("/repos/#{user}/#{repo}/issues", params)
146
174
  end
147
- alias :list_repository :list_repo
175
+ private :list_repo
148
176
 
149
177
  # Get a single issue
150
178
  #
@@ -3,7 +3,7 @@
3
3
  module Github
4
4
  class Issues::Assignees < API
5
5
 
6
- # lists all the available assignees (owner + collaborators)
6
+ # lists all the available assignees (owner + collaborators)
7
7
  # to which issues may be assigned.
8
8
  #
9
9
  # = Examples
@@ -19,6 +19,7 @@ module Github
19
19
  return response unless block_given?
20
20
  response.each { |el| yield el }
21
21
  end
22
+ alias :all :list
22
23
 
23
24
  # Check to see if a particular user is an assignee for a repository.
24
25
  #
@@ -12,7 +12,7 @@ module Github
12
12
  #
13
13
  # = Examples
14
14
  # github = Github.new
15
- # github.issues.events.list 'user-name', 'repo-name', 'issue-id'
15
+ # github.issues.events.list 'user-name', 'repo-name', issue_id: 'issue-id'
16
16
  #
17
17
  # List events for a repository
18
18
  #
@@ -20,12 +20,12 @@ module Github
20
20
  # github = Github.new
21
21
  # github.issues.events.list 'user-name', 'repo-name'
22
22
  #
23
- def list(user_name, repo_name, issue_id=nil, params={})
23
+ def list(user_name, repo_name, params={})
24
24
  set :user => user_name, :repo => repo_name
25
25
  assert_presence_of user, repo
26
26
  normalize! params
27
27
 
28
- response = if issue_id
28
+ response = if (issue_id = params.delete('issue_id'))
29
29
  get_request("/repos/#{user}/#{repo}/issues/#{issue_id}/events", params)
30
30
  else
31
31
  get_request("/repos/#{user}/#{repo}/issues/events", params)
@@ -115,7 +115,6 @@ module Github
115
115
 
116
116
  normalize! params
117
117
  filter! VALID_MILESTONE_INPUTS, params
118
- assert_required_keys(%w[ title ], params)
119
118
 
120
119
  patch_request("/repos/#{user}/#{repo}/milestones/#{milestone_id}", params)
121
120
  end
@@ -1,3 +1,5 @@
1
+ # encoding: utf-8
2
+
1
3
  module Github
2
4
  module RateLimit
3
5
 
@@ -6,6 +6,19 @@ module Github
6
6
 
7
7
  # TODO Add result counts method to check total items looking at result links
8
8
 
9
+ # All request headers
10
+ def headers
11
+ loaded? ? @env[:response_headers] : nil
12
+ end
13
+
14
+ def oauth_scopes
15
+ loaded? ? @env[:response_headers][OAUTH_SCOPES] : nil
16
+ end
17
+
18
+ def accepted_oauth_scopes
19
+ loaded? ? @env[:response_headers][ACCEPTED_OAUTH_SCOPES] : nil
20
+ end
21
+
9
22
  # Requests are limited to API v3 to 5000 per hour.
10
23
  def ratelimit_limit
11
24
  loaded? ? @env[:response_headers][RATELIMIT_LIMIT] : nil
@@ -0,0 +1,24 @@
1
+ # encoding: utf-8
2
+
3
+ module Github
4
+ class Say < API
5
+
6
+ # Generate ASCII octocat with speech bubble.
7
+ #
8
+ # = Examples
9
+ # Github::Say.new.say "My custom string..."
10
+ #
11
+ # github = Github.new
12
+ # github.octocat.say "My custom string..."
13
+ #
14
+ def say(*args)
15
+ params = args.extract_options!
16
+ normalize! params
17
+
18
+ params[:s] = args.shift unless args.empty?
19
+
20
+ get_request('/octocat', params, :raw => true)
21
+ end
22
+
23
+ end # Say
24
+ end # Github
@@ -0,0 +1,19 @@
1
+ # encoding: utf-8
2
+
3
+ module Github
4
+ class Scopes < API
5
+
6
+ # Check what OAuth scopes you have.
7
+ #
8
+ # = Examples
9
+ # github = Github.new :oauth_token => 'token'
10
+ # github.scopes.all
11
+ #
12
+ def list(params={})
13
+ response = get_request("/user", params)
14
+ response.oauth_scopes ? response.oauth_scopes.split(',') : response
15
+ end
16
+ alias :all :list
17
+
18
+ end
19
+ end # Github
@@ -4,7 +4,7 @@ module Github
4
4
  module VERSION
5
5
  MAJOR = 0
6
6
  MINOR = 8
7
- PATCH = 2
7
+ PATCH = 3
8
8
  BUILD = nil
9
9
 
10
10
  STRING = [MAJOR, MINOR, PATCH, BUILD].compact.join('.');
@@ -0,0 +1,19 @@
1
+ require 'spec_helper'
2
+
3
+ describe Github::GitData, 'integration' do
4
+
5
+ after { reset_authentication_for subject }
6
+
7
+ it_should_behave_like 'api interface'
8
+
9
+ its(:blobs) { should be_a Github::GitData::Blobs }
10
+
11
+ its(:commits) { should be_a Github::GitData::Commits }
12
+
13
+ its(:references) { should be_a Github::GitData::References }
14
+
15
+ its(:tags) { should be_a Github::GitData::Tags }
16
+
17
+ its(:trees) { should be_a Github::GitData::Trees }
18
+
19
+ end # Github::GitData
@@ -0,0 +1,46 @@
1
+ # encoding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Github::Issues::Assignees, '#check' do
6
+ let(:user) { 'peter-murach' }
7
+ let(:repo) { 'github' }
8
+ let(:assignee) { 'octocat' }
9
+ let(:request_path) { "/repos/#{user}/#{repo}/assignees/#{assignee}" }
10
+
11
+ before {
12
+ stub_get(request_path).to_return(:body => body, :status => status,
13
+ :headers => {:content_type => "application/json; charset=utf-8"})
14
+ }
15
+
16
+ after { reset_authentication_for(subject) }
17
+
18
+ context "resource found " do
19
+ let(:body) { '[]' }
20
+ let(:status) { 204 }
21
+
22
+ it "should fail to get resource without collaborator name" do
23
+ expect { subject.check user, repo, nil }.to raise_error(ArgumentError)
24
+ end
25
+
26
+ it "should get the resource" do
27
+ subject.check user, repo, assignee
28
+ a_get(request_path).should have_been_made
29
+ end
30
+
31
+ it "should find assignee" do
32
+ subject.should_receive(:check).with(user, repo, assignee) { true }
33
+ subject.check user, repo, assignee
34
+ end
35
+ end
36
+
37
+ context "resource not found" do
38
+ let(:body) { '[]' }
39
+ let(:status) { 404 }
40
+
41
+ it "should fail to retrieve resource" do
42
+ subject.should_receive(:check).with(user, repo, assignee) { false }
43
+ subject.check user, repo, assignee
44
+ end
45
+ end
46
+ end # check
@@ -0,0 +1,47 @@
1
+ # encoding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Github::Issues::Assignees, '#list' do
6
+ let(:user) { 'peter-murach' }
7
+ let(:repo) { 'github' }
8
+ let(:request_path) { "/repos/#{user}/#{repo}/assignees" }
9
+
10
+ before {
11
+ stub_get(request_path).to_return(:body => body, :status => status,
12
+ :headers => {:content_type => "application/json; charset=utf-8"})
13
+ }
14
+
15
+ after { reset_authentication_for(subject) }
16
+
17
+ context 'resources found' do
18
+ let(:body) { fixture('repos/assignees.json') }
19
+ let(:status) { 200 }
20
+
21
+ it { should respond_to(:all) }
22
+
23
+ it 'should get the resources' do
24
+ subject.list user, repo
25
+ a_get(request_path).should have_been_made
26
+ end
27
+
28
+ it_should_behave_like 'an array of resources' do
29
+ let(:requestable) { subject.list user, repo }
30
+ end
31
+
32
+ it "should get collaborator information" do
33
+ assignees = subject.list user, repo
34
+ assignees.first.login.should == 'octocat'
35
+ end
36
+
37
+ it "should yield to a block" do
38
+ yielded = []
39
+ result = subject.list(user, repo) { |obj| yielded << obj }
40
+ yielded.should == result
41
+ end
42
+ end
43
+
44
+ it_should_behave_like 'request failure' do
45
+ let(:requestable) { subject.list user, repo }
46
+ end
47
+ end # list