github_api 0.4.2 → 0.4.3
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +2 -2
- data/features/authentication.feature +8 -0
- data/features/cassettes/errors/repos/create.yml +36 -0
- data/features/cassettes/gists/gist.yml +64 -0
- data/features/cassettes/gists/gist/first.yml +65 -0
- data/features/cassettes/gists/gists/public_all.yml +71 -0
- data/features/cassettes/gists/gists/user_all.yml +48 -0
- data/features/cassettes/gists/star.yml +34 -0
- data/features/cassettes/pagination/repos/per_page/1.yml +134 -0
- data/features/cassettes/pagination/repos/per_page/each_page.yml +395 -0
- data/features/cassettes/pagination/repos/per_page/first.yml +135 -0
- data/features/error_codes.feature +13 -0
- data/features/gists.feature +31 -0
- data/features/pagination.feature +10 -0
- data/features/repos.feature +12 -10
- data/features/step_definitions/github_api_steps.rb +20 -5
- data/features/support/env.rb +8 -0
- data/features/support/helpers.rb +7 -0
- data/lib/github_api.rb +6 -6
- data/lib/github_api/api.rb +19 -11
- data/lib/github_api/authorization.rb +3 -3
- data/lib/github_api/connection.rb +1 -1
- data/lib/github_api/core_ext/array.rb +1 -2
- data/lib/github_api/core_ext/hash.rb +16 -2
- data/lib/github_api/deprecation.rb +39 -0
- data/lib/github_api/gists.rb +27 -10
- data/lib/github_api/page_uri_processor.rb +6 -2
- data/lib/github_api/response/raise_error.rb +1 -1
- data/lib/github_api/result.rb +2 -1
- data/lib/github_api/version.rb +1 -1
- data/spec/fixtures/gists/gist.json +58 -0
- data/spec/fixtures/gists/gists.json +28 -0
- data/spec/github/api_spec.rb +15 -0
- data/spec/github/authorization_spec.rb +5 -0
- data/spec/github/client_spec.rb +4 -0
- data/spec/github/core_ext/hash_spec.rb +45 -18
- data/spec/github/deprecation_spec.rb +31 -0
- data/spec/github/gists_spec.rb +461 -3
- data/spec/github/repos/watching_spec.rb +12 -4
- data/spec/github/request_spec.rb +3 -0
- data/spec/github_spec.rb +34 -29
- data/spec/spec_helper.rb +1 -0
- metadata +22 -4
@@ -0,0 +1,13 @@
|
|
1
|
+
Feature: Handles HTTP error codes
|
2
|
+
|
3
|
+
In order to handle error cases accordingly
|
4
|
+
As a developer
|
5
|
+
I want to be informed of non-successful responses
|
6
|
+
|
7
|
+
Scenario: A response of '401 - Unauthorised access'
|
8
|
+
Given I have "Github::Repos" instance
|
9
|
+
When I am looking for "create_repo"
|
10
|
+
And I pass the following request options:
|
11
|
+
| name |
|
12
|
+
| basic_auth |
|
13
|
+
Then request should fail with "Github::Unauthorised" within a cassette named "errors/repos/create"
|
@@ -0,0 +1,31 @@
|
|
1
|
+
Feature: Accessing Gists Main API
|
2
|
+
In order to interact with github gists
|
3
|
+
GithubAPI gem
|
4
|
+
Should return the expected results depending on passed parameters
|
5
|
+
|
6
|
+
Background:
|
7
|
+
Given I have "Github::Gists" instance
|
8
|
+
|
9
|
+
Scenario: Lists all user's gists
|
10
|
+
When I am looking for "gists" with the following params:
|
11
|
+
| user |
|
12
|
+
| peter-murach |
|
13
|
+
And I make request within a cassette named "gists/gists/user_all"
|
14
|
+
Then the response should be "200"
|
15
|
+
And the response type should be "JSON"
|
16
|
+
|
17
|
+
Scenario: Lists all public gists
|
18
|
+
When I am looking for "gists" with the following params:
|
19
|
+
| user |
|
20
|
+
| nil |
|
21
|
+
And I make request within a cassette named "gists/gists/public_all"
|
22
|
+
Then the response should be "200"
|
23
|
+
And the response type should be "JSON"
|
24
|
+
|
25
|
+
Scenario: Gets a single gist
|
26
|
+
When I am looking for "gist" with the following params:
|
27
|
+
| gist_id |
|
28
|
+
| 1738161 |
|
29
|
+
And I make request within a cassette named "gists/gist"
|
30
|
+
Then the response should be "200"
|
31
|
+
And the response type should be "JSON"
|
data/features/pagination.feature
CHANGED
@@ -65,3 +65,13 @@ Feature: Githu API pagination
|
|
65
65
|
And the response should have 30 items
|
66
66
|
And the response collection of resources is different for "sha" attribute
|
67
67
|
|
68
|
+
Scenario: Requesting resources with per_page helper
|
69
|
+
Given I have "Github::Repos" instance
|
70
|
+
When I am looking for "repos"
|
71
|
+
And I pass the following request options:
|
72
|
+
| user |
|
73
|
+
| wycats |
|
74
|
+
And I make request within a cassette named "pagination/repos/per_page/first"
|
75
|
+
Then the response should be "200"
|
76
|
+
When I iterate through collection pages within a cassette named "pagination/repos/per_page/each_page"
|
77
|
+
Then this collection should include first page
|
data/features/repos.feature
CHANGED
@@ -3,28 +3,30 @@ Feature: Accessing Repos Main API
|
|
3
3
|
GithubAPI gem
|
4
4
|
Should return the expected results depending on passed parameters
|
5
5
|
|
6
|
-
|
6
|
+
Background:
|
7
7
|
Given I have "Github::Repos" instance
|
8
|
+
|
9
|
+
Scenario: Returning all repository branches
|
8
10
|
When I am looking for "branches" with the following params:
|
9
11
|
| user | repo |
|
10
12
|
| peter-murach | github |
|
11
|
-
|
13
|
+
And I make request within a cassette named "repos/branches"
|
12
14
|
Then the response should be "200"
|
13
|
-
|
15
|
+
And the response type should be "JSON"
|
14
16
|
|
15
17
|
Scenario: Returning all repository tags
|
16
|
-
Given I have "Github::Repos" instance
|
17
18
|
When I am looking for "tags" with the following params:
|
18
19
|
| user | repo |
|
19
20
|
| peter-murach | github |
|
20
|
-
|
21
|
+
And I make request within a cassette named "repos/tags"
|
21
22
|
Then the response should be "200"
|
23
|
+
And the response type should be "JSON"
|
22
24
|
|
23
25
|
Scenario: Returning all repositories for the user
|
24
|
-
Given I have "Github::Repos" instance
|
25
26
|
When I am looking for "list_repos"
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
27
|
+
And I pass the following request options:
|
28
|
+
| user |
|
29
|
+
| peter-murach |
|
30
|
+
And I make request within a cassette named "repos/tags"
|
30
31
|
Then the response should be "200"
|
32
|
+
And the response type should be "JSON"
|
@@ -3,11 +3,7 @@ Given /^I have github instance$/ do
|
|
3
3
|
end
|
4
4
|
|
5
5
|
Given /^I have "([^"]*)" instance$/ do |api_classes|
|
6
|
-
|
7
|
-
api_classes.split('::').each do |api_class|
|
8
|
-
constant = constant.const_get api_class
|
9
|
-
end
|
10
|
-
@instance = constant.new
|
6
|
+
@instance = convert_to_constant(api_classes).new
|
11
7
|
end
|
12
8
|
|
13
9
|
When /^I fetch "([^"]*)"$/ do |method|
|
@@ -45,6 +41,25 @@ When /^I request "([^"]*)" page$/ do |link|
|
|
45
41
|
@next_response = @response.send :"#{link}_page"
|
46
42
|
end
|
47
43
|
|
44
|
+
When /^I iterate through collection pages$/ do
|
45
|
+
@pages = []
|
46
|
+
@response.each_page do |page|
|
47
|
+
@pages << page.flatten
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
48
51
|
Then /^the response collection of resources is different for "([^"]*)" attribute$/ do |attr|
|
49
52
|
@next_response.first.send(:"#{attr}").should_not eql @response.first.send(:"#{attr}")
|
50
53
|
end
|
54
|
+
|
55
|
+
Then /^this collection should include first page$/ do
|
56
|
+
@pages.flatten.map(&:name).should include @response.first.name
|
57
|
+
end
|
58
|
+
|
59
|
+
Then /^request should fail with "([^"]*)"$/ do |exception|
|
60
|
+
@options ||= {}
|
61
|
+
@attributes ||= {}
|
62
|
+
expect {
|
63
|
+
@response = @instance.send @method, *@attributes.values, @options
|
64
|
+
}.to raise_error(convert_to_constant(exception))
|
65
|
+
end
|
data/features/support/env.rb
CHANGED
@@ -7,6 +7,14 @@ rescue Bundler::BundlerError => e
|
|
7
7
|
exit e.status_code
|
8
8
|
end
|
9
9
|
|
10
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__) + '/../../spec')
|
11
|
+
|
12
|
+
if RUBY_VERSION > '1.9' and ENV['COVERAGE']
|
13
|
+
require 'coverage_adapter'
|
14
|
+
SimpleCov.start 'github_api'
|
15
|
+
SimpleCov.coverage_dir 'coverage/cucumber'
|
16
|
+
end
|
17
|
+
|
10
18
|
$LOAD_PATH.unshift(File.dirname(__FILE__) + '/../../lib')
|
11
19
|
require 'github_api'
|
12
20
|
|
data/lib/github_api.rb
CHANGED
@@ -5,21 +5,21 @@ require 'github_api/configuration'
|
|
5
5
|
require 'github_api/constants'
|
6
6
|
require 'github_api/utils/url'
|
7
7
|
require 'github_api/connection'
|
8
|
+
require 'github_api/deprecation'
|
8
9
|
|
9
10
|
module Github
|
10
11
|
extend Configuration
|
11
12
|
|
12
13
|
class << self
|
14
|
+
|
15
|
+
# Handle for the client instance
|
16
|
+
attr_accessor :api_client
|
17
|
+
|
13
18
|
# Alias for Github::Client.new
|
14
19
|
#
|
15
20
|
# @return [Github::Client]
|
16
21
|
def new(options = {}, &block)
|
17
|
-
|
18
|
-
end
|
19
|
-
|
20
|
-
# Returns handle for the client instance
|
21
|
-
def api_client
|
22
|
-
@@api_client
|
22
|
+
@api_client = Github::Client.new(options, &block)
|
23
23
|
end
|
24
24
|
|
25
25
|
# Delegate to Github::Client
|
data/lib/github_api/api.rb
CHANGED
@@ -44,6 +44,7 @@ module Github
|
|
44
44
|
send("#{key}=", options[key])
|
45
45
|
end
|
46
46
|
_process_basic_auth(options[:basic_auth])
|
47
|
+
_set_api_client
|
47
48
|
client if client_id? && client_secret?
|
48
49
|
|
49
50
|
self.instance_eval(&block) if block_given?
|
@@ -55,14 +56,27 @@ module Github
|
|
55
56
|
def _process_basic_auth(auth)
|
56
57
|
case auth
|
57
58
|
when String
|
58
|
-
login = auth.split(':').first
|
59
|
-
password = auth.split(':').last
|
59
|
+
self.login = auth.split(':').first
|
60
|
+
self.password = auth.split(':').last
|
60
61
|
when Hash
|
61
|
-
login = auth[:login]
|
62
|
-
password = auth[:password]
|
62
|
+
self.login = auth[:login]
|
63
|
+
self.password = auth[:password]
|
63
64
|
end
|
64
65
|
end
|
65
66
|
|
67
|
+
# Assigns current api class
|
68
|
+
def _set_api_client
|
69
|
+
Github.api_client = self
|
70
|
+
end
|
71
|
+
|
72
|
+
# Passes configuration options to instantiated class
|
73
|
+
def _create_instance(klass, options)
|
74
|
+
options.symbolize_keys!
|
75
|
+
instance = klass.send :new, options
|
76
|
+
Github.api_client = instance
|
77
|
+
instance
|
78
|
+
end
|
79
|
+
|
66
80
|
# Responds to attribute query or attribute clear
|
67
81
|
def method_missing(method, *args, &block) # :nodoc:
|
68
82
|
case method.to_s
|
@@ -77,7 +91,7 @@ module Github
|
|
77
91
|
|
78
92
|
def _validate_inputs(required, provided) # :nodoc:
|
79
93
|
required.all? do |key|
|
80
|
-
provided.
|
94
|
+
provided.has_deep_key? key
|
81
95
|
end
|
82
96
|
end
|
83
97
|
|
@@ -187,12 +201,6 @@ module Github
|
|
187
201
|
end
|
188
202
|
end
|
189
203
|
|
190
|
-
# Passes configuration options to instantiated class
|
191
|
-
def _create_instance(klass, options)
|
192
|
-
options.symbolize_keys!
|
193
|
-
klass.new(options)
|
194
|
-
end
|
195
|
-
|
196
204
|
def _token_required
|
197
205
|
end
|
198
206
|
|
@@ -54,10 +54,10 @@ module Github
|
|
54
54
|
|
55
55
|
# Select authentication parameters
|
56
56
|
def authentication
|
57
|
-
if
|
58
|
-
{ :login => login, :password => password }
|
59
|
-
elsif basic_auth?
|
57
|
+
if basic_auth?
|
60
58
|
{ :basic_auth => basic_auth }
|
59
|
+
elsif login? && password?
|
60
|
+
{ :login => login, :password => password }
|
61
61
|
else
|
62
62
|
{ }
|
63
63
|
end
|
@@ -54,7 +54,7 @@ module Github
|
|
54
54
|
builder.use Faraday::Request::JSON
|
55
55
|
builder.use Faraday::Request::Multipart
|
56
56
|
builder.use Faraday::Request::UrlEncoded
|
57
|
-
builder.use Faraday::Response::Logger
|
57
|
+
builder.use Faraday::Response::Logger if ENV['DEBUG']
|
58
58
|
|
59
59
|
builder.use Github::Request::OAuth2, oauth_token if oauth_token?
|
60
60
|
builder.use Github::Request::BasicAuth, authentication if basic_authed?
|
@@ -1,7 +1,6 @@
|
|
1
1
|
class Array # :nodoc:
|
2
2
|
|
3
3
|
def except(*keys) # :nodoc:
|
4
|
-
puts "module except works!!!"
|
5
4
|
self.dup.except!(*keys)
|
6
5
|
end unless method_defined?(:except)
|
7
6
|
|
@@ -11,4 +10,4 @@ class Array # :nodoc:
|
|
11
10
|
copy
|
12
11
|
end unless method_defined?(:except!)
|
13
12
|
|
14
|
-
end #
|
13
|
+
end # Array
|
@@ -1,7 +1,6 @@
|
|
1
1
|
class Hash # :nodoc:
|
2
2
|
|
3
3
|
def except(*items) # :nodoc:
|
4
|
-
puts "array except works!!!"
|
5
4
|
self.dup.except!(*items)
|
6
5
|
end unless method_defined?(:except)
|
7
6
|
|
@@ -16,7 +15,7 @@ class Hash # :nodoc:
|
|
16
15
|
hash[(key.to_sym rescue key) || key] = value
|
17
16
|
hash
|
18
17
|
end
|
19
|
-
end
|
18
|
+
end unless method_defined?(:symbolize_keys)
|
20
19
|
|
21
20
|
def symbolize_keys! # :nodoc:
|
22
21
|
hash = symbolize_keys
|
@@ -39,4 +38,19 @@ class Hash # :nodoc:
|
|
39
38
|
self.map { |key, val| [key, val].join("=") }.join("&")
|
40
39
|
end unless method_defined?(:serialize)
|
41
40
|
|
41
|
+
def all_keys # :nodoc:
|
42
|
+
keys = self.keys
|
43
|
+
keys.each do |key|
|
44
|
+
if self[key].is_a?(Hash)
|
45
|
+
keys << self[key].all_keys.compact.flatten
|
46
|
+
next
|
47
|
+
end
|
48
|
+
end
|
49
|
+
keys.flatten
|
50
|
+
end unless method_defined?(:all_keys)
|
51
|
+
|
52
|
+
def has_deep_key?(key)
|
53
|
+
self.all_keys.include? key
|
54
|
+
end unless method_defined?(:has_deep_key?)
|
55
|
+
|
42
56
|
end # Hash
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module Github
|
4
|
+
|
5
|
+
DEPRECATION_PREFIX = "[GithubAPI] Deprecation warning:"
|
6
|
+
|
7
|
+
class << self
|
8
|
+
|
9
|
+
attr_writer :deprecation_tracker
|
10
|
+
|
11
|
+
def deprecation_tracker
|
12
|
+
@deprecation_tracker ||= []
|
13
|
+
end
|
14
|
+
|
15
|
+
# Displays deprecation message to the user.
|
16
|
+
# Each message is printed once.
|
17
|
+
def deprecate(method, alternate_method=nil)
|
18
|
+
return if deprecation_tracker.include? method
|
19
|
+
deprecation_tracker << method
|
20
|
+
|
21
|
+
message = <<-NOTICE
|
22
|
+
#{DEPRECATION_PREFIX}
|
23
|
+
|
24
|
+
* #{method} is deprecated.
|
25
|
+
NOTICE
|
26
|
+
if alternate_method
|
27
|
+
message << <<-ADDITIONAL
|
28
|
+
* please use #{alternate_method} instead.
|
29
|
+
ADDITIONAL
|
30
|
+
end
|
31
|
+
warn_deprecation(message)
|
32
|
+
end
|
33
|
+
|
34
|
+
def warn_deprecation(message)
|
35
|
+
send :warn, message
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
end # Github
|
data/lib/github_api/gists.rb
CHANGED
@@ -9,7 +9,12 @@ module Github
|
|
9
9
|
|
10
10
|
include Github::Gists::Comments
|
11
11
|
|
12
|
-
REQUIRED_GIST_INPUTS = %w[
|
12
|
+
REQUIRED_GIST_INPUTS = %w[
|
13
|
+
description
|
14
|
+
public
|
15
|
+
files
|
16
|
+
content
|
17
|
+
].freeze
|
13
18
|
|
14
19
|
# Creates new Gists API
|
15
20
|
def initialize(options = {})
|
@@ -53,19 +58,25 @@ module Github
|
|
53
58
|
#
|
54
59
|
def starred(params={})
|
55
60
|
_normalize_params_keys(params)
|
56
|
-
|
61
|
+
|
62
|
+
response = get("/gists/starred", params)
|
63
|
+
return response unless block_given?
|
64
|
+
response.each { |el| yield el }
|
57
65
|
end
|
58
66
|
|
59
67
|
# Get a single gist
|
60
68
|
#
|
61
69
|
# = Examples
|
62
|
-
# @github = Github.new
|
70
|
+
# @github = Github.new
|
63
71
|
# @github.gists.get_gist 'gist-id'
|
64
72
|
#
|
65
|
-
def
|
73
|
+
def gist(gist_id, params={})
|
66
74
|
_normalize_params_keys(params)
|
75
|
+
_validate_presence_of(gist_id)
|
76
|
+
|
67
77
|
get("/gists/#{gist_id}", params)
|
68
78
|
end
|
79
|
+
alias :get_gist :gist
|
69
80
|
|
70
81
|
# Create a gist
|
71
82
|
#
|
@@ -78,8 +89,8 @@ module Github
|
|
78
89
|
# <tt>:content</tt> - Required string - File contents.
|
79
90
|
#
|
80
91
|
# = Examples
|
81
|
-
# @github = Github.new
|
82
|
-
# @github.gists.create_gist
|
92
|
+
# @github = Github.new
|
93
|
+
# @github.gists.create_gist
|
83
94
|
# 'description' => 'the description for this gist',
|
84
95
|
# 'public' => true,
|
85
96
|
# 'files' => {
|
@@ -90,7 +101,11 @@ module Github
|
|
90
101
|
#
|
91
102
|
def create_gist(params={})
|
92
103
|
_normalize_params_keys(params)
|
93
|
-
|
104
|
+
|
105
|
+
unless _validate_inputs(REQUIRED_GIST_INPUTS, params)
|
106
|
+
raise ArgumentError,
|
107
|
+
"Required parameters are: #{REQUIRED_GIST_INPUTS.join(', ')}"
|
108
|
+
end
|
94
109
|
|
95
110
|
post("/gists", params)
|
96
111
|
end
|
@@ -126,7 +141,6 @@ module Github
|
|
126
141
|
def edit_gist(gist_id, params={})
|
127
142
|
_validate_presence_of(gist_id)
|
128
143
|
_normalize_params_keys(params)
|
129
|
-
_filter_params_keys(REQUIRED_GIST_INPUTS, params)
|
130
144
|
|
131
145
|
patch("/gists/#{gist_id}", params)
|
132
146
|
end
|
@@ -150,14 +164,14 @@ module Github
|
|
150
164
|
# @github = Github.new
|
151
165
|
# @github.gists.unstar 'gist-id'
|
152
166
|
#
|
153
|
-
def
|
167
|
+
def unstar(gist_id, params={})
|
154
168
|
_validate_presence_of(gist_id)
|
155
169
|
_normalize_params_keys(params)
|
156
170
|
|
157
171
|
delete("/gists/#{gist_id}/star", params)
|
158
172
|
end
|
159
173
|
|
160
|
-
# Check if a gist is starred
|
174
|
+
# Check if a gist is starred
|
161
175
|
#
|
162
176
|
# = Examples
|
163
177
|
# @github = Github.new
|
@@ -168,6 +182,9 @@ module Github
|
|
168
182
|
_normalize_params_keys(params)
|
169
183
|
|
170
184
|
get("/gists/#{gist_id}/star", params)
|
185
|
+
true
|
186
|
+
rescue Github::ResourceNotFound
|
187
|
+
false
|
171
188
|
end
|
172
189
|
|
173
190
|
# Fork a gist
|