githubris 0.0.6 → 0.0.7
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/.travis.yml +5 -5
- data/Rakefile +11 -2
- data/githubris.gemspec +3 -2
- data/lib/githubris.rb +1 -11
- data/lib/githubris/api.rb +61 -40
- data/lib/githubris/api/gist.rb +40 -3
- data/lib/githubris/api/http.rb +13 -4
- data/lib/githubris/api/json.rb +16 -0
- data/lib/githubris/base.rb +2 -64
- data/lib/githubris/custom_attributes.rb +40 -0
- data/lib/githubris/gist.rb +53 -7
- data/lib/githubris/oauth.rb +23 -18
- data/lib/githubris/publicity.rb +2 -2
- data/lib/githubris/version.rb +1 -1
- data/spec/githubris/api/gist_spec.rb +2 -6
- data/spec/githubris/api_spec.rb +3 -22
- data/spec/githubris/base_spec.rb +1 -1
- data/spec/githubris/gist_spec.rb +117 -26
- data/spec/githubris/oauth_spec.rb +12 -0
- data/spec/githubris/publicity_spec.rb +4 -4
- data/spec/githubris/user_spec.rb +2 -10
- data/spec/githubris_spec.rb +2 -5
- data/spec/support/fixtures/vcr_cassettes/Githubris.yml +137 -0
- data/spec/support/fixtures/vcr_cassettes/Githubris_API.yml +118 -0
- data/spec/support/fixtures/vcr_cassettes/Githubris_API/_authenticated_/when_authenticated_with_good_credentials.yml +6 -6
- data/spec/support/fixtures/vcr_cassettes/Githubris_API_Gist.yml +197 -0
- data/spec/support/fixtures/vcr_cassettes/Githubris_API_User/_get_authenticated_user/without_credentials.yml +3 -3
- data/spec/support/fixtures/vcr_cassettes/Githubris_API_User/_get_user.yml +5 -5
- data/spec/support/fixtures/vcr_cassettes/Githubris_Gist.yml +1009 -0
- data/spec/support/fixtures/vcr_cassettes/Githubris_User.yml +196 -0
- data/spec/support/vcr.rb +1 -0
- metadata +78 -39
- data/lib/githubris/comment.rb +0 -1
- data/lib/githubris/gist/file.rb +0 -2
- data/lib/githubris/issue.rb +0 -6
- data/lib/githubris/organization.rb +0 -5
- data/lib/githubris/repository.rb +0 -7
- data/spec/support/fixtures/vcr_cassettes/Githubris/_find_gist.yml +0 -44
- data/spec/support/fixtures/vcr_cassettes/Githubris/_find_user.yml +0 -40
- data/spec/support/fixtures/vcr_cassettes/Githubris/_public_gists.yml +0 -55
- data/spec/support/fixtures/vcr_cassettes/Githubris_API/_authenticated_/when_authenticated_with_bad_credentials.yml +0 -40
- data/spec/support/fixtures/vcr_cassettes/Githubris_API/_authenticated_/when_there_are_no_credentials.yml +0 -42
- data/spec/support/fixtures/vcr_cassettes/Githubris_API_Gist/_get_gist.yml +0 -44
- data/spec/support/fixtures/vcr_cassettes/Githubris_API_Gist/_get_public_gists.yml +0 -107
- data/spec/support/fixtures/vcr_cassettes/Githubris_API_Gist/_get_user_gists.yml +0 -43
- data/spec/support/fixtures/vcr_cassettes/Githubris_Gist/_save.yml +0 -42
- data/spec/support/fixtures/vcr_cassettes/Githubris_Gist/_save/when_authenticated.yml +0 -44
- data/spec/support/fixtures/vcr_cassettes/Githubris_Gist/any_gist.yml +0 -44
- data/spec/support/fixtures/vcr_cassettes/Githubris_Gist/given_a_gist_full_of_data.yml +0 -44
- data/spec/support/fixtures/vcr_cassettes/Githubris_Gist/on_a_gist_with_an_id.yml +0 -44
- data/spec/support/fixtures/vcr_cassettes/Githubris_Gist/on_a_gist_with_an_id/_reload.yml +0 -44
- data/spec/support/fixtures/vcr_cassettes/Githubris_User/_gists.yml +0 -43
- data/spec/support/fixtures/vcr_cassettes/Githubris_User/_reload.yml +0 -40
- data/spec/support/fixtures/vcr_cassettes/Githubris_User/_reload/on_a_user_with_a_login.yml +0 -40
- data/spec/support/fixtures/vcr_cassettes/Githubris_User/_reload/on_a_user_without_a_login.yml +0 -40
- data/spec/support/fixtures/vcr_cassettes/Githubris_User/_starred_gists/on_an_authenticated_user.yml +0 -82
data/lib/githubris/gist.rb
CHANGED
@@ -1,8 +1,4 @@
|
|
1
|
-
require 'date'
|
2
|
-
|
3
1
|
class Githubris::Gist < Githubris::Base
|
4
|
-
autoload :File, 'githubris/gist/file'
|
5
|
-
|
6
2
|
include Githubris::Publicity
|
7
3
|
|
8
4
|
datetime_attribute :created_at, :updated_at
|
@@ -14,15 +10,65 @@ class Githubris::Gist < Githubris::Base
|
|
14
10
|
@user ||= Githubris::User.new(@attributes[:user])
|
15
11
|
end
|
16
12
|
|
13
|
+
def star!
|
14
|
+
@api.put_gist_star(@attributes[:id])
|
15
|
+
end
|
16
|
+
|
17
|
+
def unstar!
|
18
|
+
@api.delete_gist_star(@attributes[:id])
|
19
|
+
end
|
20
|
+
|
21
|
+
def starred?
|
22
|
+
@api.get_gist_starred?(@attributes[:id])
|
23
|
+
end
|
24
|
+
|
25
|
+
def unstarred?
|
26
|
+
!starred?
|
27
|
+
end
|
28
|
+
|
29
|
+
def delete!
|
30
|
+
@api.delete_gist(@attributes[:id])
|
31
|
+
end
|
32
|
+
|
33
|
+
def history
|
34
|
+
@attributes[:history].map do |gist_data|
|
35
|
+
Githubris::Gist.new(gist_data)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
17
39
|
def reload
|
18
|
-
|
40
|
+
if @attributes[:id]
|
41
|
+
gist = @api.get_gist @attributes[:id]
|
42
|
+
elsif @attributes[:url]
|
43
|
+
gist = Githubris::Gist.new @api._get @attributes[:url]
|
44
|
+
else
|
45
|
+
raise Githubris::Error, 'Missing a unique identifier, such as an id or a url'
|
46
|
+
end
|
47
|
+
swap_attributes gist
|
19
48
|
end
|
20
49
|
|
21
50
|
def save
|
22
|
-
|
51
|
+
if new?
|
52
|
+
saved_attributes = @api.post_gist(saving_attributes)
|
53
|
+
else
|
54
|
+
saved_attributes = @api.patch_gist(@attributes[:id], saving_attributes)
|
55
|
+
end
|
56
|
+
swap_attributes saved_attributes
|
57
|
+
end
|
58
|
+
|
59
|
+
def saving_attributes
|
60
|
+
{
|
23
61
|
:description => @attributes[:description],
|
24
62
|
:public => @attributes[:public],
|
25
63
|
:files => @attributes[:files]
|
26
|
-
|
64
|
+
}
|
65
|
+
end
|
66
|
+
|
67
|
+
def new?
|
68
|
+
reload
|
69
|
+
rescue Githubris::Error
|
70
|
+
true
|
71
|
+
else
|
72
|
+
false
|
27
73
|
end
|
28
74
|
end
|
data/lib/githubris/oauth.rb
CHANGED
@@ -1,36 +1,41 @@
|
|
1
1
|
class Githubris::OAuth
|
2
|
-
REQUEST_ACCESS_URL = "https://github.com/login/oauth/authorize"
|
2
|
+
REQUEST_ACCESS_URL = Addressable::URI.parse("https://github.com/login/oauth/authorize")
|
3
3
|
|
4
|
-
def initialize(client_id, client_secret)
|
4
|
+
def initialize(client_id, client_secret, api=Githubris::API.new)
|
5
5
|
@client_id = client_id
|
6
6
|
@client_secret = client_secret
|
7
|
+
@api = api
|
7
8
|
end
|
8
9
|
|
9
|
-
def request_access_url(
|
10
|
-
|
11
|
-
|
12
|
-
|
10
|
+
def request_access_url(query={})
|
11
|
+
add_query_params_to(REQUEST_ACCESS_URL, query).to_s
|
12
|
+
end
|
13
|
+
|
14
|
+
def access_token(code)
|
15
|
+
@api.post_oauth_access_token(access_token_params(code))
|
16
|
+
end
|
13
17
|
|
14
|
-
|
15
|
-
query_values[:redirect_uri] = redirect_uri if redirect_uri
|
18
|
+
private
|
16
19
|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
20
|
+
def add_query_params_to(uri, query)
|
21
|
+
uri.tap do |uri|
|
22
|
+
uri.query_values = query_values(query)
|
23
|
+
uri.query = URI.decode(uri.query)
|
21
24
|
end
|
25
|
+
end
|
22
26
|
|
23
|
-
|
24
|
-
|
25
|
-
|
27
|
+
def query_values(query)
|
28
|
+
query_values = { :client_id => @client_id }
|
29
|
+
query_values[:scopes] = query[:scopes].join(',') if query[:scopes]
|
30
|
+
query_values[:redirect_uri] = query[:redirect_uri] if query[:redirect_uri]
|
31
|
+
query_values
|
26
32
|
end
|
27
33
|
|
28
|
-
def
|
29
|
-
|
34
|
+
def access_token_params(code)
|
35
|
+
{
|
30
36
|
:client_id => @client_id,
|
31
37
|
:client_secret => @client_secret,
|
32
38
|
:code => code
|
33
39
|
}
|
34
|
-
Githubris::API.new.post_oauth_access_token(access_token_params)
|
35
40
|
end
|
36
41
|
end
|
data/lib/githubris/publicity.rb
CHANGED
data/lib/githubris/version.rb
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe Githubris::API::Gist do
|
4
|
+
use_vcr_cassette
|
5
|
+
|
4
6
|
subject do
|
5
7
|
Githubris::API.new
|
6
8
|
end
|
7
9
|
|
8
10
|
describe '#get_user_gists' do
|
9
|
-
use_vcr_cassette
|
10
|
-
|
11
11
|
let(:login) {'GithubrisTestUser'}
|
12
12
|
|
13
13
|
it 'gets /users/:username/gists' do
|
@@ -18,8 +18,6 @@ describe Githubris::API::Gist do
|
|
18
18
|
end
|
19
19
|
|
20
20
|
describe '#get_public_gists' do
|
21
|
-
use_vcr_cassette
|
22
|
-
|
23
21
|
it 'returns an array of gists' do
|
24
22
|
subject.get_public_gists.should be_instance_of Array
|
25
23
|
subject.get_public_gists.each do |gist|
|
@@ -29,8 +27,6 @@ describe Githubris::API::Gist do
|
|
29
27
|
end
|
30
28
|
|
31
29
|
describe '#get_gist' do
|
32
|
-
use_vcr_cassette
|
33
|
-
|
34
30
|
let(:id) { 1 }
|
35
31
|
it 'is a Githubris::Gist' do
|
36
32
|
subject.get_gist(id).should be_instance_of Githubris::Gist
|
data/spec/githubris/api_spec.rb
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe Githubris::API do
|
4
|
+
use_vcr_cassette
|
5
|
+
|
4
6
|
let(:api) { Githubris::API.new }
|
5
7
|
|
6
8
|
describe '#authenticated?' do
|
@@ -15,14 +17,10 @@ describe Githubris::API do
|
|
15
17
|
api.authenticated?
|
16
18
|
end
|
17
19
|
|
18
|
-
use_vcr_cassette
|
19
|
-
|
20
20
|
it { should be_true }
|
21
21
|
end
|
22
22
|
|
23
23
|
context 'when authenticated with bad credentials' do
|
24
|
-
use_vcr_cassette
|
25
|
-
|
26
24
|
subject do
|
27
25
|
api.basic_auth('GithubrisTestFakeUser', 'password')
|
28
26
|
api.authenticated?
|
@@ -32,8 +30,6 @@ describe Githubris::API do
|
|
32
30
|
end
|
33
31
|
|
34
32
|
context 'when there are no credentials' do
|
35
|
-
use_vcr_cassette
|
36
|
-
|
37
33
|
subject do
|
38
34
|
api.authenticated?
|
39
35
|
end
|
@@ -48,25 +44,9 @@ describe Githubris::API do
|
|
48
44
|
client_secret = 'client_secret'
|
49
45
|
subject.oauth(client_id, client_secret).should be_instance_of Githubris::OAuth
|
50
46
|
end
|
51
|
-
|
52
|
-
it 'returns a Githubris::OAuth initialized with the client id and secret' do
|
53
|
-
client_id = 'client_id'
|
54
|
-
client_secret = 'client_secret'
|
55
|
-
Githubris::OAuth.should_receive(:new).with(client_id, client_secret)
|
56
|
-
subject.oauth(client_id, client_secret)
|
57
|
-
end
|
58
|
-
|
59
|
-
it 'can take options' do
|
60
|
-
client_id = 'client_id'
|
61
|
-
client_secret = 'client_secret'
|
62
|
-
Githubris::OAuth.should_receive(:new).with(client_id, client_secret)
|
63
|
-
subject.oauth(client_id, client_secret)
|
64
|
-
end
|
65
47
|
end
|
66
48
|
|
67
49
|
describe '#post_oauth_access_token' do
|
68
|
-
use_vcr_cassette
|
69
|
-
|
70
50
|
before do
|
71
51
|
access_token_response =<<-RESPONSE
|
72
52
|
HTTP/1.1 200 OK
|
@@ -96,6 +76,7 @@ RESPONSE
|
|
96
76
|
subject.post_oauth_access_token({})
|
97
77
|
end.should_not raise_error
|
98
78
|
end
|
79
|
+
|
99
80
|
it 'returns a string' do
|
100
81
|
subject.post_oauth_access_token({}).should be_instance_of String
|
101
82
|
end
|
data/spec/githubris/base_spec.rb
CHANGED
@@ -28,7 +28,7 @@ describe Githubris::Base do
|
|
28
28
|
end
|
29
29
|
|
30
30
|
describe '::accessible_attribute' do
|
31
|
-
it 'defines an instance method that returns
|
31
|
+
it 'defines an instance method that returns the attribute named by the method' do
|
32
32
|
mock_class.class_eval do
|
33
33
|
accessible_attribute :foo
|
34
34
|
end
|
data/spec/githubris/gist_spec.rb
CHANGED
@@ -1,52 +1,143 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe Githubris::Gist do
|
4
|
-
|
5
|
-
subject { described_class.new :id => id }
|
4
|
+
use_vcr_cassette
|
6
5
|
|
7
|
-
|
8
|
-
|
6
|
+
describe '#new?' do
|
7
|
+
it 'seems new if there are issues when reloading' do
|
8
|
+
gist_without_id = Githubris::Gist.new
|
9
|
+
gist_without_id.should be_new
|
10
|
+
end
|
9
11
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
subject.reload.object_id.should == obj_id
|
14
|
-
end
|
12
|
+
it 'seems to not be new if there are no issues' do
|
13
|
+
gist = Githubris::Gist.new :id => 1
|
14
|
+
gist.should_not be_new
|
15
15
|
end
|
16
16
|
end
|
17
17
|
|
18
|
-
|
19
|
-
|
18
|
+
describe '#reload' do
|
19
|
+
it 'works with or without an id' do
|
20
|
+
gist = Githubris::Gist.new :url => 'https://api.github.com/gists/1'
|
21
|
+
lambda { gist.reload }.should_not raise_error
|
22
|
+
gist = Githubris::Gist.new :id => 1
|
23
|
+
lambda { gist.reload }.should_not raise_error
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'returns the same object' do
|
27
|
+
gist = Githubris::Gist.new :id => 1
|
28
|
+
obj_id = gist.object_id
|
29
|
+
gist.reload.object_id.should == obj_id
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'errors when any indication of identity is absent' do
|
33
|
+
gist = Githubris::Gist.new
|
34
|
+
lambda { gist.reload }.should raise_error Githubris::Error
|
35
|
+
end
|
36
|
+
end
|
20
37
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
38
|
+
context 'on a gist with an id' do
|
39
|
+
let(:id) { 1 }
|
40
|
+
subject { described_class.new :id => 1 }
|
41
|
+
|
42
|
+
context 'given a gist full of data' do
|
43
|
+
describe '#user' do
|
44
|
+
it 'returns a user' do
|
45
|
+
subject.reload
|
46
|
+
subject.user.should be_instance_of Githubris::User
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
describe '#history' do
|
52
|
+
context 'on a gist with history' do
|
53
|
+
it 'is an array of gists' do
|
54
|
+
subject.reload
|
55
|
+
subject.history.each do |gist|
|
56
|
+
gist.should be_instance_of Githubris::Gist
|
57
|
+
end
|
58
|
+
end
|
25
59
|
end
|
26
60
|
end
|
27
61
|
end
|
28
62
|
|
29
63
|
describe '#save' do
|
30
|
-
use_vcr_cassette
|
31
|
-
|
32
64
|
it 'for a public, anonymous gist' do
|
33
65
|
gist = described_class.new :public => true, :files => {'gistfile.txt' => {:content => 'foobar'}}
|
34
66
|
lambda { gist.save }.should_not raise_error
|
35
67
|
end
|
68
|
+
end
|
36
69
|
|
37
|
-
|
38
|
-
|
70
|
+
context 'when authenticated' do
|
71
|
+
let(:api) { Githubris::API.new }
|
72
|
+
let(:user) { api.get_authenticated_user }
|
39
73
|
|
40
|
-
|
74
|
+
before do
|
75
|
+
api.basic_auth 'GithubrisTestUser', 'password'
|
76
|
+
api.should be_authenticated
|
77
|
+
end
|
41
78
|
|
42
|
-
|
43
|
-
|
79
|
+
describe '#delete!' do
|
80
|
+
let(:gist) { api.get_authenticated_user.gists.first }
|
81
|
+
|
82
|
+
it 'deletes the gist' do
|
83
|
+
gist.delete!
|
84
|
+
lambda do
|
85
|
+
gist.reload
|
86
|
+
end.should raise_error
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
describe '#star!' do
|
91
|
+
let(:gist) { Githubris::Gist.new(:id => 1, :_api => api).reload }
|
92
|
+
|
93
|
+
it 'stars the gist' do
|
94
|
+
gist.star!
|
95
|
+
gist.should be_starred
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
describe '#unstar!' do
|
100
|
+
let(:gist) { api.get_authenticated_user.starred_gists.first }
|
101
|
+
|
102
|
+
it 'unstars the gist' do
|
103
|
+
gist.unstar!
|
104
|
+
gist.should be_unstarred
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
describe '#save' do
|
109
|
+
context "when creating a public gist" do
|
110
|
+
it 'does not raise an error' do
|
111
|
+
gist = described_class.new :_api => api, :public => true, :files => {'gistfile.txt' => {:content => 'foobar'}}
|
112
|
+
lambda { gist.save }.should_not raise_error
|
113
|
+
gist.user.login.should == 'GithubrisTestUser'
|
114
|
+
end
|
44
115
|
end
|
45
116
|
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
117
|
+
context 'when creating a private gist' do
|
118
|
+
it 'does not raise an error' do
|
119
|
+
gist = described_class.new :_api => api, :public => false, :files => {'gistfile.txt' => {:content => 'foobar'}}
|
120
|
+
lambda { gist.save }.should_not raise_error
|
121
|
+
gist.user.login.should == 'GithubrisTestUser'
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
context 'editing a file' do
|
126
|
+
it 'can be used to edit a file' do
|
127
|
+
gist = api.get_authenticated_user.gists.last
|
128
|
+
expected_id = gist.id
|
129
|
+
gist.files['gistfile.txt'] = {}
|
130
|
+
file = gist.files['gistfile.txt']
|
131
|
+
content = <<-EOF
|
132
|
+
lorem ipsum, all the time.
|
133
|
+
EOF
|
134
|
+
|
135
|
+
file[:content] = content
|
136
|
+
lambda { gist.save }.should_not raise_error
|
137
|
+
|
138
|
+
file[:content].should == content
|
139
|
+
gist.id.should == expected_id
|
140
|
+
end
|
50
141
|
end
|
51
142
|
end
|
52
143
|
end
|
@@ -53,6 +53,18 @@ RESPONSE
|
|
53
53
|
url.should match /scopes=user,public_repo,repo,gist/
|
54
54
|
url.should match /redirect_uri=#{URI.encode(redirect_uri)}/
|
55
55
|
end
|
56
|
+
|
57
|
+
it 'does not include a redirect_uri when none is given' do
|
58
|
+
url = oauth.request_access_url
|
59
|
+
|
60
|
+
url.should_not match /redirect_uri=/
|
61
|
+
end
|
62
|
+
|
63
|
+
it 'does not include scopes when none are given' do
|
64
|
+
url = oauth.request_access_url
|
65
|
+
|
66
|
+
url.should_not match /scopes=/
|
67
|
+
end
|
56
68
|
end
|
57
69
|
|
58
70
|
describe '#access_token' do
|