github_api 0.5.1 → 0.5.2

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.
@@ -4,4 +4,4 @@ def settings_file
4
4
  Pathname.new(File.expand_path("../../settings.yml", __FILE__))
5
5
  end
6
6
 
7
- SETTINGS = (File.exists?(settings_file) && yaml= YAML.load_file(settings_file)) ? yaml : {'basic_auth' => 'login:password', 'oauth_token' => 'as79asfd79ads', 'user'=> 'octokat', 'repo' => 'dummy'}
7
+ SETTINGS = (File.exists?(settings_file) && yaml= YAML.load_file(settings_file)) ? yaml : {'basic_auth' => 'login:password', 'oauth_token' => 'as79asfd79ads', 'user'=> 'octokat', 'repo' => 'dummy', 'email' => 'email@example.com'}
@@ -4,6 +4,7 @@ VCR.configure do |conf|
4
4
  conf.hook_into :webmock
5
5
  conf.cassette_library_dir = 'features/cassettes'
6
6
  conf.default_cassette_options = { :record => :new_episodes }
7
+ conf.filter_sensitive_data('<EMAIL>') { SETTINGS['email'] }
7
8
  conf.filter_sensitive_data('<TOKEN>') { SETTINGS['oauth_token'] }
8
9
  conf.filter_sensitive_data('<BASIC_AUTH>') { SETTINGS['basic_auth'] }
9
10
  conf.filter_sensitive_data('<USER>') { SETTINGS['user'] }
@@ -0,0 +1,37 @@
1
+ Feature: Accessing Users Emails API
2
+
3
+ In order to interact with github user emails
4
+ GithubAPI gem
5
+ Should return the expected results depending on passed parameters
6
+
7
+ Background:
8
+ Given I have "Github::Users::Emails" instance
9
+
10
+ Scenario: Lists all emails for the authenticated user
11
+ Given I want to list resources
12
+ When I make request within a cassette named "users/emails/all"
13
+ Then the response status should be 200
14
+ And the response type should be JSON
15
+ And the response should not be empty
16
+
17
+ Scenario: Add email addresses for the authenticated user
18
+ Given I want to add resource with the following params:
19
+ | email1 | email2 |
20
+ | octocat@example.com | terry@example.com |
21
+ When I make request within a cassette named "users/emails/add"
22
+ Then the response status should be 201
23
+ And the response type should be JSON
24
+ And the response should have 3 items
25
+ And the response should contain octocat@example.com
26
+ And the response should contain terry@example.com
27
+
28
+ Scenario: Remove email addresses for the authenticated user
29
+ Given I want to add resource with the following params:
30
+ | email1 | email2 |
31
+ | octocat@example.com | terry@example.com |
32
+ And I make request within a cassette named "users/emails/add"
33
+ And I want to delete resource with the following params:
34
+ | email |
35
+ | octocat@example.com |
36
+ When I make request within a cassette named "users/emails/delete"
37
+ Then the response status should be 204
@@ -8,6 +8,7 @@ require 'github_api/response/helpers'
8
8
  require 'github_api/response/raise_error'
9
9
  require 'github_api/request/oauth2'
10
10
  require 'github_api/request/basic_auth'
11
+ require 'github_api/request/jsonize'
11
12
 
12
13
  module Github
13
14
  module Connection
@@ -51,7 +52,7 @@ module Github
51
52
  Faraday.new(merged_options.merge(connection_options)) do |builder|
52
53
  puts options.inspect if ENV['DEBUG']
53
54
 
54
- builder.use Faraday::Request::JSON
55
+ builder.use Github::Request::Jsonize
55
56
  builder.use Faraday::Request::Multipart
56
57
  builder.use Faraday::Request::UrlEncoded
57
58
  builder.use Faraday::Response::Logger if ENV['DEBUG']
@@ -29,8 +29,8 @@ module Github
29
29
  # List a user's gists.
30
30
  #
31
31
  # = Examples
32
- # github = Github.new :user => 'user-name'
33
- # github.gists.list
32
+ # github = Github.new
33
+ # github.gists.list user: 'user-name'
34
34
  #
35
35
  # List the authenticated user’s gists or if called anonymously,
36
36
  # this will returns all public gists
@@ -39,11 +39,10 @@ module Github
39
39
  # github = Github.new :oauth_token => '...'
40
40
  # github.gists.list
41
41
  #
42
- def list(user_name=nil, params={})
43
- _update_user_repo_params(user_name)
44
- process_params do
45
- normalize params
46
- end
42
+ def list(params={})
43
+ _normalize_params_keys(params)
44
+
45
+ user = params.delete('user')
47
46
 
48
47
  response = if user
49
48
  get_request("/users/#{user}/gists", params)
@@ -31,7 +31,7 @@ module Github
31
31
  'state' => %w[ open closed ],
32
32
  'sort' => %w[ created updated comments ],
33
33
  'direction' => %w[ desc asc ],
34
- 'since' => %r{\d{4}-\d{2}-\d{5}:\d{2}:\d{3}}
34
+ 'since' => %r{\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}Z}
35
35
  }
36
36
 
37
37
  # Creates new Issues API
@@ -75,7 +75,7 @@ module Github
75
75
  #
76
76
  # = Examples
77
77
  # github = Github.new :oauth_token => '...'
78
- # github.issues.list :since => '2011-04-12312:12:121',
78
+ # github.issues.list :since => '2011-04-12T12:12:12Z',
79
79
  # :filter => 'created',
80
80
  # :state => 'open',
81
81
  # :labels => "bug,ui,bla",
@@ -124,6 +124,7 @@ module Github
124
124
  # :sort => 'comments',
125
125
  # :direction => 'asc'
126
126
  #
127
+ # TODO: remove default nils from params
127
128
  def list_repo(user_name=nil, repo_name=nil, params={})
128
129
  _update_user_repo_params(user_name, repo_name)
129
130
  _validate_user_repo_params(user, repo) unless user? && repo?
@@ -143,9 +144,9 @@ module Github
143
144
  #
144
145
  # = Examples
145
146
  # github = Github.new
146
- # github.issues.find 'user-name', 'repo-name', 'issue-id'
147
+ # github.issues.get 'user-name', 'repo-name', 'issue-id'
147
148
  #
148
- def find(user_name, repo_name, issue_id, params={})
149
+ def get(user_name, repo_name, issue_id, params={})
149
150
  _update_user_repo_params(user_name, repo_name)
150
151
  _validate_user_repo_params(user, repo) unless user? && repo?
151
152
  _validate_presence_of issue_id
@@ -155,6 +156,7 @@ module Github
155
156
 
156
157
  get_request("/repos/#{user}/#{repo}/issues/#{issue_id}", params)
157
158
  end
159
+ alias :find :get
158
160
 
159
161
  # Create an issue
160
162
  #
@@ -42,10 +42,11 @@ module Github
42
42
  response = connection(options).send(method) do |request|
43
43
  case method.to_sym
44
44
  when *(METHODS - METHODS_WITH_BODIES)
45
+ request.body = params.delete('data') if params.has_key?('data')
45
46
  request.url(path, params)
46
47
  when *METHODS_WITH_BODIES
47
48
  request.path = path
48
- request.body = MultiJson.dump(_process_params(params)) unless params.empty?
49
+ request.body = _process_params(params) unless params.empty?
49
50
  end
50
51
  end
51
52
  response.body
@@ -54,7 +55,7 @@ module Github
54
55
  private
55
56
 
56
57
  def _process_params(params) # :nodoc:
57
- return params['data'] if params.has_key?('data') && !params['data'].nil?
58
+ return params['data'] if params.has_key?('data') and !params['data'].nil?
58
59
  return params
59
60
  end
60
61
 
@@ -0,0 +1,46 @@
1
+ # encoding: utf-8
2
+
3
+ require 'faraday'
4
+
5
+ module Github
6
+ class Request::Jsonize < Faraday::Middleware
7
+
8
+ CONTENT_TYPE = 'Content-Type'.freeze
9
+ MIME_TYPE = 'application/json'.freeze
10
+
11
+ dependency 'multi_json'
12
+
13
+ def call(env)
14
+ if request_with_body?(env)
15
+ env[:request_headers][CONTENT_TYPE] ||= MIME_TYPE
16
+ env[:body] = encode_body env unless env[:body].respond_to?(:to_str)
17
+ end
18
+ @app.call env
19
+ end
20
+
21
+ def encode_body(env)
22
+ if MultiJson.respond_to?(:dump)
23
+ MultiJson.dump env[:body]
24
+ else
25
+ MultiJson.encode env[:body]
26
+ end
27
+ end
28
+
29
+ def request_with_body?(env)
30
+ type = request_type(env)
31
+ has_body?(env) and (type.empty? or type == MIME_TYPE)
32
+ end
33
+
34
+ # Don't encode bodies in string form
35
+ def has_body?(env)
36
+ body = env[:body] and !(body.respond_to?(:to_str) and body.empty?)
37
+ end
38
+
39
+ def request_type(env)
40
+ type = env[:request_headers][CONTENT_TYPE].to_s
41
+ type = type.split(';', 2).first if type.index(';')
42
+ type
43
+ end
44
+
45
+ end # Request::Jsonize
46
+ end # Github
@@ -5,29 +5,38 @@ require 'faraday'
5
5
  module Github
6
6
  module Request
7
7
  class OAuth2 < Faraday::Middleware
8
+ include Github::Utils::Url
9
+
10
+ ACCESS_TOKEN = 'access_token'.freeze
11
+ AUTH_HEADER = 'Authorization'.freeze
12
+
8
13
  dependency 'oauth2'
9
14
 
10
15
  def call(env)
11
- # puts "ENV: #{env.inspect}"
12
- # puts "TOKEN : #{@token}"
13
- # puts "APP: #{@app}"
14
-
15
16
  # Extract parameters from the query
16
- params = env[:url].query_values || {}
17
-
18
- env[:url].query_values = { 'access_token' => @token }.merge(params)
17
+ params = { ACCESS_TOKEN => @token }.update query_params(env[:url])
19
18
 
20
- token = env[:url].query_values['access_token']
21
-
22
- env[:request_headers].merge!('Authorization' => "Token token=\"#{token}\"")
19
+ if token = params[ACCESS_TOKEN] and !token.empty?
20
+ env[:url].query = build_query params
21
+ env[:request_headers].merge!(AUTH_HEADER => "Token token=\"#{token}\"")
22
+ end
23
23
 
24
24
  @app.call env
25
25
  end
26
26
 
27
27
  def initialize(app, *args)
28
+ super app
28
29
  @app = app
29
30
  @token = args.shift
30
31
  end
32
+
33
+ def query_params(url)
34
+ if url.query.nil? or url.query.empty?
35
+ {}
36
+ else
37
+ parse_query url.query
38
+ end
39
+ end
31
40
  end # OAuth2
32
41
  end # Request
33
42
  end # Github
@@ -0,0 +1,6 @@
1
+
2
+ module Github
3
+ class Resource
4
+
5
+ end
6
+ end
@@ -1,4 +1,5 @@
1
1
  # encoding: utf-8
2
+ require 'cgi'
2
3
 
3
4
  module Github
4
5
  class Users::Emails < API
@@ -30,7 +31,7 @@ module Github
30
31
  def add(*args)
31
32
  params = _extract_parameters(args)
32
33
  _normalize_params_keys(params)
33
- params['data'] = [args].flatten if args
34
+ params['data'] = args if args
34
35
  post_request("/user/emails", params)
35
36
  end
36
37
  alias :<< :add
@@ -47,7 +48,7 @@ module Github
47
48
  def delete(*args)
48
49
  params = _extract_parameters(args)
49
50
  _normalize_params_keys(params)
50
- params['data'] = [args].flatten
51
+ params['data'] = args if args
51
52
  delete_request("/user/emails", params)
52
53
  end
53
54
 
@@ -13,6 +13,16 @@ module Github
13
13
 
14
14
  def unescape(s) CGI.unescape s.to_s end
15
15
 
16
+ def build_query(params)
17
+ params.map { |k, v|
18
+ if v.class == Array
19
+ build_query(v.map { |x| [k, x] })
20
+ else
21
+ v.nil? ? escape(k) : "#{escape(k)}=#{escape(v)}"
22
+ end
23
+ }.join("&")
24
+ end
25
+
16
26
  def parse_query(query_string)
17
27
  return '' if query_string.nil? || query_string.empty?
18
28
  params = {}
@@ -4,7 +4,7 @@ module Github
4
4
  module VERSION
5
5
  MAJOR = 0
6
6
  MINOR = 5
7
- PATCH = 1
7
+ PATCH = 2
8
8
  BUILD = nil
9
9
 
10
10
  STRING = [MAJOR, MINOR, PATCH, BUILD].compact.join('.');
@@ -21,23 +21,23 @@ describe Github::Gists do
21
21
  end
22
22
 
23
23
  it "should get the resources" do
24
- github.gists.list user
24
+ github.gists.list :user => user
25
25
  a_get("/users/#{user}/gists").should have_been_made
26
26
  end
27
27
 
28
28
  it "should return array of resources" do
29
- gists = github.gists.list user
29
+ gists = github.gists.list :user => user
30
30
  gists.should be_an Array
31
31
  gists.should have(1).items
32
32
  end
33
33
 
34
34
  it "should be a mash type" do
35
- gists = github.gists.list user
35
+ gists = github.gists.list :user => user
36
36
  gists.first.should be_a Hashie::Mash
37
37
  end
38
38
 
39
39
  it "should get gist information" do
40
- gists = github.gists.list user
40
+ gists = github.gists.list :user => user
41
41
  gists.first.user.login.should == 'octocat'
42
42
  end
43
43
 
@@ -55,7 +55,7 @@ describe Github::Gists do
55
55
 
56
56
  it "should return 404 with a message 'Not Found'" do
57
57
  expect {
58
- github.gists.list user
58
+ github.gists.list :user => user
59
59
  }.to raise_error(Github::Error::NotFound)
60
60
  end
61
61
  end
@@ -122,7 +122,8 @@ describe Github::Issues do
122
122
  end
123
123
  end # list_repo
124
124
 
125
- describe "#find" do
125
+ describe "#get" do
126
+ it { github.issues.should respond_to :find }
126
127
 
127
128
  context "resource found" do
128
129
  before do
@@ -133,22 +134,22 @@ describe Github::Issues do
133
134
  end
134
135
 
135
136
  it "should fail to get resource without issue id" do
136
- expect { github.issues.find(user, repo, nil)}.to raise_error(ArgumentError)
137
+ expect { github.issues.get(user, repo, nil)}.to raise_error(ArgumentError)
137
138
  end
138
139
 
139
140
  it "should get the resource" do
140
- github.issues.find user, repo, issue_id
141
+ github.issues.get user, repo, issue_id
141
142
  a_get("/repos/#{user}/#{repo}/issues/#{issue_id}").should have_been_made
142
143
  end
143
144
 
144
145
  it "should get issue information" do
145
- issue = github.issues.find user, repo, issue_id
146
+ issue = github.issues.get user, repo, issue_id
146
147
  issue.number.should == issue_id
147
148
  issue.title.should == 'Found a bug'
148
149
  end
149
150
 
150
151
  it "should return mash" do
151
- issue = github.issues.find user, repo, issue_id
152
+ issue = github.issues.get user, repo, issue_id
152
153
  issue.should be_a Hashie::Mash
153
154
  end
154
155
  end
@@ -163,7 +164,7 @@ describe Github::Issues do
163
164
 
164
165
  it "should fail to retrive resource" do
165
166
  expect {
166
- github.issues.find user, repo, issue_id
167
+ github.issues.get user, repo, issue_id
167
168
  }.to raise_error(Github::Error::NotFound)
168
169
  end
169
170
  end
@@ -0,0 +1,88 @@
1
+ require 'spec_helper'
2
+
3
+ describe Github::Request::Jsonize do
4
+
5
+ let(:middleware) { described_class.new(lambda { |env| env }) }
6
+
7
+ def process(body, content_type=nil)
8
+ env = {:body => body, :request_headers => {} }
9
+ env[:request_headers]['Content-Type'] = content_type if content_type
10
+ middleware.call(env)
11
+ end
12
+
13
+ def result_body() result[:body] end
14
+ def result_type() result[:request_headers]['Content-Type'] end
15
+
16
+ context 'no body' do
17
+ let(:result) { process(nil) }
18
+
19
+ it "doesn't change body" do
20
+ result_body.should be_nil
21
+ end
22
+
23
+ it "doesn't add content type" do
24
+ result_type.should be_nil
25
+ end
26
+ end
27
+
28
+ context 'empty body' do
29
+ let(:result) { process('') }
30
+
31
+ it "doesn't change body" do
32
+ result_body.should be_empty
33
+ end
34
+
35
+ it "doesn't add conten type" do
36
+ result_type.should be_nil
37
+ end
38
+ end
39
+
40
+ context 'string body' do
41
+ let(:result) { process('{"a":1}')}
42
+
43
+ it "doesn't change body" do
44
+ result_body.should eql '{"a":1}'
45
+ end
46
+
47
+ it "adds content type" do
48
+ result_type.should eql 'application/json'
49
+ end
50
+ end
51
+
52
+ context "object body" do
53
+ let(:result) { process({:a => 1})}
54
+
55
+ it "encodes body" do
56
+ result_body.should eql '{"a":1}'
57
+ end
58
+
59
+ it "adds content type" do
60
+ result_type.should eql 'application/json'
61
+ end
62
+ end
63
+
64
+ context "empty object body" do
65
+ let(:result) { process({})}
66
+
67
+ it "encodes body" do
68
+ result_body.should eql '{}'
69
+ end
70
+
71
+ it "adds content type" do
72
+ result_type.should eql 'application/json'
73
+ end
74
+ end
75
+
76
+ context 'object body with json type' do
77
+ let(:result) { process({:a => 1}, 'application/json; charset=utf-8')}
78
+
79
+ it "encodes body" do
80
+ result_body.should eql '{"a":1}'
81
+ end
82
+
83
+ it "doesn't change content type" do
84
+ result_type.should eql 'application/json; charset=utf-8'
85
+ end
86
+ end
87
+
88
+ end # Github::Request::Jsonize