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.
Files changed (56) hide show
  1. data/.travis.yml +5 -5
  2. data/Rakefile +11 -2
  3. data/githubris.gemspec +3 -2
  4. data/lib/githubris.rb +1 -11
  5. data/lib/githubris/api.rb +61 -40
  6. data/lib/githubris/api/gist.rb +40 -3
  7. data/lib/githubris/api/http.rb +13 -4
  8. data/lib/githubris/api/json.rb +16 -0
  9. data/lib/githubris/base.rb +2 -64
  10. data/lib/githubris/custom_attributes.rb +40 -0
  11. data/lib/githubris/gist.rb +53 -7
  12. data/lib/githubris/oauth.rb +23 -18
  13. data/lib/githubris/publicity.rb +2 -2
  14. data/lib/githubris/version.rb +1 -1
  15. data/spec/githubris/api/gist_spec.rb +2 -6
  16. data/spec/githubris/api_spec.rb +3 -22
  17. data/spec/githubris/base_spec.rb +1 -1
  18. data/spec/githubris/gist_spec.rb +117 -26
  19. data/spec/githubris/oauth_spec.rb +12 -0
  20. data/spec/githubris/publicity_spec.rb +4 -4
  21. data/spec/githubris/user_spec.rb +2 -10
  22. data/spec/githubris_spec.rb +2 -5
  23. data/spec/support/fixtures/vcr_cassettes/Githubris.yml +137 -0
  24. data/spec/support/fixtures/vcr_cassettes/Githubris_API.yml +118 -0
  25. data/spec/support/fixtures/vcr_cassettes/Githubris_API/_authenticated_/when_authenticated_with_good_credentials.yml +6 -6
  26. data/spec/support/fixtures/vcr_cassettes/Githubris_API_Gist.yml +197 -0
  27. data/spec/support/fixtures/vcr_cassettes/Githubris_API_User/_get_authenticated_user/without_credentials.yml +3 -3
  28. data/spec/support/fixtures/vcr_cassettes/Githubris_API_User/_get_user.yml +5 -5
  29. data/spec/support/fixtures/vcr_cassettes/Githubris_Gist.yml +1009 -0
  30. data/spec/support/fixtures/vcr_cassettes/Githubris_User.yml +196 -0
  31. data/spec/support/vcr.rb +1 -0
  32. metadata +78 -39
  33. data/lib/githubris/comment.rb +0 -1
  34. data/lib/githubris/gist/file.rb +0 -2
  35. data/lib/githubris/issue.rb +0 -6
  36. data/lib/githubris/organization.rb +0 -5
  37. data/lib/githubris/repository.rb +0 -7
  38. data/spec/support/fixtures/vcr_cassettes/Githubris/_find_gist.yml +0 -44
  39. data/spec/support/fixtures/vcr_cassettes/Githubris/_find_user.yml +0 -40
  40. data/spec/support/fixtures/vcr_cassettes/Githubris/_public_gists.yml +0 -55
  41. data/spec/support/fixtures/vcr_cassettes/Githubris_API/_authenticated_/when_authenticated_with_bad_credentials.yml +0 -40
  42. data/spec/support/fixtures/vcr_cassettes/Githubris_API/_authenticated_/when_there_are_no_credentials.yml +0 -42
  43. data/spec/support/fixtures/vcr_cassettes/Githubris_API_Gist/_get_gist.yml +0 -44
  44. data/spec/support/fixtures/vcr_cassettes/Githubris_API_Gist/_get_public_gists.yml +0 -107
  45. data/spec/support/fixtures/vcr_cassettes/Githubris_API_Gist/_get_user_gists.yml +0 -43
  46. data/spec/support/fixtures/vcr_cassettes/Githubris_Gist/_save.yml +0 -42
  47. data/spec/support/fixtures/vcr_cassettes/Githubris_Gist/_save/when_authenticated.yml +0 -44
  48. data/spec/support/fixtures/vcr_cassettes/Githubris_Gist/any_gist.yml +0 -44
  49. data/spec/support/fixtures/vcr_cassettes/Githubris_Gist/given_a_gist_full_of_data.yml +0 -44
  50. data/spec/support/fixtures/vcr_cassettes/Githubris_Gist/on_a_gist_with_an_id.yml +0 -44
  51. data/spec/support/fixtures/vcr_cassettes/Githubris_Gist/on_a_gist_with_an_id/_reload.yml +0 -44
  52. data/spec/support/fixtures/vcr_cassettes/Githubris_User/_gists.yml +0 -43
  53. data/spec/support/fixtures/vcr_cassettes/Githubris_User/_reload.yml +0 -40
  54. data/spec/support/fixtures/vcr_cassettes/Githubris_User/_reload/on_a_user_with_a_login.yml +0 -40
  55. data/spec/support/fixtures/vcr_cassettes/Githubris_User/_reload/on_a_user_without_a_login.yml +0 -40
  56. data/spec/support/fixtures/vcr_cassettes/Githubris_User/_starred_gists/on_an_authenticated_user.yml +0 -82
@@ -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
- swap_attributes @api.get_gist @attributes[:id]
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
- swap_attributes @api.post_gist(
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
@@ -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(options={})
10
- url = Addressable::URI.parse REQUEST_ACCESS_URL
11
- query_values = {}
12
- query_values[:client_id] = @client_id
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
- redirect_uri = options.delete(:redirect_uri)
15
- query_values[:redirect_uri] = redirect_uri if redirect_uri
18
+ private
16
19
 
17
- scopes = options.delete :scopes
18
- if scopes
19
- scopes = scopes.join ','
20
- query_values[:scopes] = scopes
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
- url.query_values = query_values
24
- url.query = URI.decode(url.query)
25
- url.to_s
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 access_token(code)
29
- access_token_params = {
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
@@ -3,11 +3,11 @@ module Githubris::Publicity
3
3
  @attributes[:public]
4
4
  end
5
5
 
6
- def publicize
6
+ def publicize!
7
7
  @attributes[:public] = true
8
8
  end
9
9
 
10
- def privatize
10
+ def privatize!
11
11
  @attributes[:public] = false
12
12
  end
13
13
  end
@@ -1,3 +1,3 @@
1
1
  class Githubris
2
- VERSION = "0.0.6"
2
+ VERSION = "0.0.7"
3
3
  end
@@ -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
@@ -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
@@ -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 a URI object' do
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
@@ -1,52 +1,143 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Githubris::Gist do
4
- let(:id) { 1 }
5
- subject { described_class.new :id => id }
4
+ use_vcr_cassette
6
5
 
7
- context 'on a gist with an id' do
8
- use_vcr_cassette
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
- describe '#reload' do
11
- it 'returns the same object' do
12
- obj_id = subject.object_id
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
- context 'given a gist full of data' do
19
- use_vcr_cassette
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
- describe '#user' do
22
- it 'returns a user' do
23
- subject.reload
24
- subject.user.should be_instance_of Githubris::User
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
- context 'when authenticated' do
38
- use_vcr_cassette
70
+ context 'when authenticated' do
71
+ let(:api) { Githubris::API.new }
72
+ let(:user) { api.get_authenticated_user }
39
73
 
40
- let(:api) { Githubris::API.new }
74
+ before do
75
+ api.basic_auth 'GithubrisTestUser', 'password'
76
+ api.should be_authenticated
77
+ end
41
78
 
42
- before do
43
- api.basic_auth('GithubrisTestUser', 'password')
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
- it 'for a gist by an authenticated user' do
47
- gist = described_class.new :_api => api, :public => true, :files => {'gistfile.txt' => {:content => 'foobar'}}
48
- lambda { gist.save }.should_not raise_error
49
- gist.user.login.should == 'GithubrisTestUser'
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