github_api 0.4.2 → 0.4.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.
- 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
|