opsb-octopussy 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,77 @@
1
+ module Octopussy
2
+ class Event
3
+
4
+ def self.load_from_atom(entry)
5
+ entry = entry.to_mash if entry.is_a?(Hash)
6
+
7
+ event = Hashie::Mash.new({:user => entry.author, :title => entry.title})
8
+ event.published = (entry.published.is_a?(String) ? DateTime.parse(entry.published) : entry.published)
9
+ event.id = entry.id.split("/").pop.to_i
10
+
11
+ event.links = entry.links
12
+ event.content = entry.content
13
+
14
+ case entry.id
15
+ when /CreateEvent/
16
+ case entry.title
17
+ when /created tag/
18
+ event.event_type = 'tag'
19
+ event.tag = entry.links.first.split('/').pop
20
+ when /created branch/
21
+ event.event_type = 'branch'
22
+ event.branch = entry.links.first.split('/').pop
23
+ when /created repository/
24
+ event.event_type = 'repo'
25
+ end
26
+
27
+ when /MemberEvent/
28
+ event.event_type = 'member'
29
+ event.target_user = entry.title.split(" ")[2]
30
+ when /PushEvent/
31
+ event.event_type = 'push'
32
+ event.branch = entry.links.first.split('/').pop
33
+ when /ForkApplyEvent/
34
+ event.event_type = 'fork_apply'
35
+ event.branch = entry.links.first.split('/').pop
36
+ when /ForkEvent/
37
+ event.event_type = 'fork'
38
+ segments = entry.title.split(" ")
39
+ event.forked_from = Repo.new(segments.last)
40
+ when /WatchEvent/
41
+ event.event_type = 'watch'
42
+
43
+ when /FollowEvent/
44
+ event.event_type = 'follow'
45
+ event.target_user = entry.links.first.split("/").pop
46
+ when /IssuesEvent/
47
+ event.event_type = 'issue'
48
+ event.action = entry.title[/closed|opened|reopened/]
49
+ event.issue_number = entry.title[/\s\d+\s/].strip.to_i
50
+ when /GistEvent/
51
+ event.event_type = 'gist'
52
+ event.gist_number = entry.links.first.split('/').pop.to_i
53
+ when /WikiEvent/
54
+ event.event_type = 'wiki'
55
+ event.page = entry.links.first.split('/').pop
56
+ when /CommitCommentEvent/
57
+ event.event_type = 'comment'
58
+ when /DeleteEvent/
59
+ event.event_type = 'delete'
60
+ segments = entry.title.split(' ')
61
+ event.branch = segments[3]
62
+ event.repo = Repo.new(segments[5])
63
+ when /PublicEvent/
64
+ event.event_type = 'public'
65
+ event.repo = Repo.new(entry.title.split(" ")[3])
66
+ when /DownloadEvent/
67
+ event.event_type = 'download'
68
+ segments = entry.title.split(' ')
69
+ event.repo = Repo.new(segments[5])
70
+ else
71
+ puts "Unknown event type: #{entry.id}"
72
+ end
73
+ event.repo = Repo.from_url(entry.links.first) unless %w(follow gist delete public download).include?(event.event_type)
74
+ event
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,49 @@
1
+ module Octopussy
2
+ class Repo
3
+ attr_accessor :username, :name
4
+
5
+ def initialize(repo)
6
+ if repo.is_a?(String)
7
+ repo = repo.split("/")
8
+ @name = repo.pop
9
+ @username = repo.pop
10
+ elsif repo.is_a?(Repo)
11
+ @username = repo.username
12
+ @name = repo.name
13
+ elsif repo.is_a?(Hash)
14
+ @name = repo[:repo] ||= repo[:name]
15
+ @username = repo[:username] ||= repo[:user] ||= repo[:owner]
16
+ end
17
+ end
18
+
19
+ def slug
20
+ "#{@username}/#{@name}"
21
+ end
22
+
23
+ def to_s
24
+ self.slug
25
+ end
26
+
27
+ def url
28
+ "http://github.com/#{slug}"
29
+ end
30
+
31
+ def user
32
+ @username
33
+ end
34
+
35
+ def repo
36
+ @name
37
+ end
38
+
39
+ def user=(val)
40
+ @username = val
41
+ end
42
+
43
+ def self.from_url(url)
44
+ return if url.nil?
45
+ username, name = url.gsub("http://github.com/", "").split("/")
46
+ Repo.new("#{username}/#{name}")
47
+ end
48
+ end
49
+ end
data/test/helper.rb ADDED
@@ -0,0 +1,40 @@
1
+ require 'test/unit'
2
+ require 'pathname'
3
+
4
+ require 'shoulda'
5
+ require 'matchy'
6
+ require 'mocha'
7
+ require 'fakeweb'
8
+
9
+ require 'redgreen'
10
+
11
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
12
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
13
+ require 'octopussy'
14
+
15
+ FakeWeb.allow_net_connect = false
16
+
17
+ class Test::Unit::TestCase
18
+ end
19
+
20
+ def fixture_file(filename)
21
+ return '' if filename == ''
22
+ file_path = File.expand_path(File.dirname(__FILE__) + '/fixtures/' + filename)
23
+ File.read(file_path)
24
+ end
25
+
26
+ def github_url(url)
27
+ url =~ /^http/ ? url : "http://github.com/api/v2/json#{url}"
28
+ end
29
+
30
+ def stub_request(method, url, filename, status=nil)
31
+ options = {:body => ""}
32
+ options.merge!({:body => fixture_file(filename)}) if filename
33
+ options.merge!({:body => status.last}) if status
34
+ options.merge!({:status => status}) if status
35
+
36
+ FakeWeb.register_uri(method, github_url(url), options)
37
+ end
38
+
39
+ def stub_get(*args); stub_request(:get, *args) end
40
+ def stub_post(*args); stub_request(:post, *args) end
@@ -0,0 +1,769 @@
1
+ require File.dirname(__FILE__) + '/helper'
2
+
3
+ class OctopussyTest < Test::Unit::TestCase
4
+
5
+ context "when authenticated" do
6
+ setup do
7
+ @client = Octopussy::Client.new(:login => 'pengwynn', :token => 'OU812')
8
+ end
9
+
10
+ should "authenticate via basic auth" do
11
+ stub_get("http://pengwynn:OU812@github.com/api/v2/json/user/show/pengwynn", "full_user.json")
12
+ client = Octopussy::Client.new(:login => 'pengwynn', :password => 'OU812')
13
+ user = client.user
14
+ user.plan.name.should == 'free'
15
+ user.plan.space.should == 307200
16
+ end
17
+
18
+ should "should search users" do
19
+ stub_get("/user/search/wynn", "search.json")
20
+ users = @client.search_users("wynn")
21
+ users.first.username.should == 'pengwynn'
22
+ end
23
+
24
+ should "return full user info for the authenticated user" do
25
+ stub_get("/user/show/pengwynn?login=pengwynn&token=OU812", "full_user.json")
26
+ user = @client.user
27
+ user.plan.name.should == 'free'
28
+ user.plan.space.should == 307200
29
+ end
30
+
31
+ should "return followers for a user" do
32
+ stub_get("/user/show/pengwynn/followers", "followers.json")
33
+ followers = @client.followers("pengwynn")
34
+ followers.size.should == 21
35
+ assert followers.include?("adamstac")
36
+ end
37
+
38
+ should "return followers for the authenticated user" do
39
+ stub_get("/user/show/pengwynn/followers", "followers.json")
40
+ followers = @client.followers
41
+ followers.size.should == 21
42
+ assert followers.include?("adamstac")
43
+ end
44
+
45
+ should "return users a user follows" do
46
+ stub_get("/user/show/pengwynn/following", "followers.json")
47
+ followers = @client.following("pengwynn")
48
+ followers.size.should == 21
49
+ assert followers.include?("adamstac")
50
+ end
51
+
52
+ should "return the users the authenticated user follows" do
53
+ stub_get("/user/show/pengwynn/following", "followers.json")
54
+ followers = @client.following
55
+ followers.size.should == 21
56
+ assert followers.include?("adamstac")
57
+ end
58
+
59
+ should "indicate if one user follows another" do
60
+ stub_get("/user/show/pengwynn/following", "followers.json")
61
+ @client.follows?('adamstac')
62
+ end
63
+
64
+ should "return the repos a user watches" do
65
+ stub_get("/repos/watched/pengwynn", "repos.json")
66
+ repos = @client.watched
67
+ repos.first.owner.should == 'jnunemaker'
68
+ repos.first.forks.should == 120
69
+ end
70
+
71
+ should "return the repos the authenticated user watched" do
72
+ stub_get("/repos/watched/pengwynn", "repos.json")
73
+ repos = @client.watched('pengwynn')
74
+ repos.first.owner.should == 'jnunemaker'
75
+ repos.first.forks.should == 120
76
+ end
77
+
78
+ should "update user info" do
79
+ stub_post("/user/show/pengwynn?login=pengwynn&token=OU812", "user.json")
80
+ user = @client.update_user(:location => "Dallas, TX")
81
+ user.location.should == 'Dallas, TX'
82
+ end
83
+
84
+ should "return emails for the authenticated user" do
85
+ stub_get("/user/emails?login=pengwynn&token=OU812", "emails.json")
86
+ emails = @client.emails
87
+ emails.size.should == 3
88
+ assert emails.include? "wynn@orrka.com"
89
+ end
90
+
91
+ should "add an email for the authenticated user" do
92
+ stub_post("/user/email/add?login=pengwynn&token=OU812", "emails.json")
93
+ emails = @client.add_email('wynn@orrka.com')
94
+ emails.size.should == 3
95
+ assert emails.include? "wynn@orrka.com"
96
+ end
97
+
98
+ should "remove an email for the authenticated user" do
99
+ stub_post("/user/email/remove?login=pengwynn&token=OU812", "emails.json")
100
+ emails = @client.remove_email('wynn@squeejee.com')
101
+ emails.size.should == 3
102
+ end
103
+
104
+ should "return keys for the authenticated user" do
105
+ stub_get("/user/keys?login=pengwynn&token=OU812", "keys.json")
106
+ keys = @client.keys
107
+ keys.size.should == 6
108
+ keys.last.title.should == 'wynn@pengwynn.local'
109
+ end
110
+
111
+ should "add an key for the authenticated user" do
112
+ stub_post("/user/key/add?login=pengwynn&token=OU812", "keys.json")
113
+ keys = @client.add_key('pengwynn', 'ssh-rsa 009aasd0kalsdfa-sd9a-sdf')
114
+ keys.size.should == 6
115
+ keys.last.title.should == 'wynn@pengwynn.local'
116
+ end
117
+
118
+ should "remove an key for the authenticated user" do
119
+ stub_post("/user/key/remove?login=pengwynn&token=OU812", "keys.json")
120
+ keys = @client.remove_key(1234)
121
+ keys.size.should == 6
122
+ end
123
+
124
+ should "open an issue" do
125
+ stub_post "/issues/open/pengwynn/linkedin", "open_issue.json"
126
+ issue = @client.open_issue({:username => "pengwynn", :repo => "linkedin"}, "testing", "Testing api")
127
+ issue.title.should == "testing"
128
+ issue.number.should == 2
129
+ end
130
+
131
+ should "close an issue" do
132
+ stub_post "/issues/close/pengwynn/linkedin/2", "close_issue.json"
133
+ issue = @client.close_issue({:username => "pengwynn", :repo => "linkedin"}, 2)
134
+ issue.title.should == "testing"
135
+ issue.number.should == 2
136
+ end
137
+
138
+ should "reopen an issue" do
139
+ stub_post "/issues/reopen/pengwynn/linkedin/2", "reopen_issue.json"
140
+ issue = @client.close_issue({:username => "pengwynn", :repo => "linkedin"}, 2)
141
+ issue.title.should == "testing"
142
+ issue.number.should == 2
143
+ end
144
+
145
+ should "edit an issue" do
146
+ stub_post "/issues/edit/pengwynn/linkedin/2", "open_issue.json"
147
+ issue = @client.update_issue("pengwynn/linkedin", 2, "testing", "Testing api")
148
+ issue.title.should == "testing"
149
+ issue.number.should == 2
150
+ end
151
+
152
+ should "list issue labels for a repo" do
153
+ stub_get "/issues/labels/pengwynn/linkedin", "labels.json"
154
+ labels = @client.labels("pengwynn/linkedin")
155
+ labels.first.should == 'oauth'
156
+ end
157
+
158
+ should "add a label to an issue" do
159
+ stub_post("/issues/label/add/pengwynn/linkedin/oauth/2", "labels.json")
160
+ labels = @client.add_label('pengwynn/linkedin', 2, 'oauth')
161
+ assert labels.include?("oauth")
162
+ end
163
+
164
+ should "remove a label from an issue" do
165
+ stub_post("/issues/label/remove/pengwynn/linkedin/oauth/2", "labels.json")
166
+ labels = @client.remove_label('pengwynn/linkedin', 2, 'oauth')
167
+ assert labels.is_a?(Array)
168
+ end
169
+
170
+ should "add a comment to an issue" do
171
+ stub_post("/issues/comment/pengwynn/linkedin/2", "comment.json")
172
+ comment = @client.add_comment('pengwynn/linkedin', 2, 'Nice catch!')
173
+ comment.comment.should == 'Nice catch!'
174
+ end
175
+
176
+ should "watch a repository" do
177
+ stub_post("/repos/watch/pengwynn/linkedin?login=pengwynn&token=OU812", "repo.json")
178
+ repo = @client.watch('pengwynn/linkedin')
179
+ repo.homepage.should == "http://bit.ly/ruby-linkedin"
180
+ end
181
+
182
+ should "unwatch a repository" do
183
+ stub_post("/repos/unwatch/pengwynn/linkedin?login=pengwynn&token=OU812", "repo.json")
184
+ repo = @client.unwatch('pengwynn/linkedin')
185
+ repo.homepage.should == "http://bit.ly/ruby-linkedin"
186
+ end
187
+
188
+ should "fork a repository" do
189
+ stub_post("/repos/fork/pengwynn/linkedin?login=pengwynn&token=OU812", "repo.json")
190
+ repo = @client.fork('pengwynn/linkedin')
191
+ repo.homepage.should == "http://bit.ly/ruby-linkedin"
192
+ end
193
+
194
+ should "create a repository" do
195
+ stub_post("/repos/create?login=pengwynn&token=OU812", "repo.json")
196
+ repo = @client.create(:name => 'linkedin', :description => 'Ruby wrapper for the LinkedIn API', :homepage => 'http://bit.ly/ruby-linkedin', :public => 1)
197
+ repo.homepage.should == "http://bit.ly/ruby-linkedin"
198
+ end
199
+
200
+ # should "return a delete_token when calling delete without supplying a delete_token" do
201
+ #
202
+ # end
203
+
204
+ should "set a repo's visibility to private" do
205
+ stub_post("/repos/set/private/linkedin?login=pengwynn&token=OU812", "repo.json")
206
+ repo = @client.set_private('linkedin')
207
+ repo.homepage.should == "http://bit.ly/ruby-linkedin"
208
+ end
209
+
210
+ should "set a repo's visibility to public" do
211
+ stub_post("/repos/set/public/linkedin?login=pengwynn&token=OU812", "repo.json")
212
+ repo = @client.set_public('linkedin')
213
+ repo.homepage.should == "http://bit.ly/ruby-linkedin"
214
+ end
215
+
216
+ should "return deploy keys for a repo" do
217
+ stub_get("/repos/keys/linkedin?login=pengwynn&token=OU812", "keys.json")
218
+ keys = @client.deploy_keys('linkedin')
219
+ keys.size.should == 6
220
+ keys.last.title.should == 'wynn@pengwynn.local'
221
+ end
222
+
223
+ should "add a deploy key for a repo" do
224
+ stub_post("/repos/key/linkedin/add?login=pengwynn&token=OU812", "keys.json")
225
+ keys = @client.add_deploy_key('pengwynn/linkedin', 'ssh-rsa 009aasd0kalsdfa-sd9a-sdf')
226
+ keys.size.should == 6
227
+ keys.last.title.should == 'wynn@pengwynn.local'
228
+ end
229
+
230
+ should "remove a deploy key for a repo" do
231
+ stub_post("/repos/key/linkedin/remove?login=pengwynn&token=OU812", "keys.json")
232
+ keys = @client.remove_deploy_key('linkedin', 1234)
233
+ keys.size.should == 6
234
+ end
235
+
236
+ should "add a collaborator to a repo" do
237
+ stub_post("/repos/collaborators/linkedin/add/adamstac?login=pengwynn&token=OU812", "collaborators.json")
238
+ collaborators = @client.add_collaborator("linkedin", "adamstac")
239
+ collaborators.first.should == 'pengwynn'
240
+ end
241
+
242
+ should "remove a collaborator from a repo" do
243
+ stub_post("/repos/collaborators/linkedin/remove/adamstac?login=pengwynn&token=OU812", "collaborators.json")
244
+ collaborators = @client.remove_collaborator("linkedin", "adamstac")
245
+ collaborators.last.should == 'adamstac'
246
+ end
247
+
248
+ should "fetch a user's public timeline" do
249
+ stub_get("http://github.com/pengwynn.json", "timeline.json")
250
+ events = @client.public_timeline('pengwynn')
251
+ events.first['type'].should == 'FollowEvent'
252
+ events[1].repository.name.should == 'octopussy'
253
+ end
254
+
255
+ should "fetch a user's private timeline" do
256
+ stub_get("http://github.com/pengwynn.private.json?login=pengwynn&token=OU812", "timeline.json")
257
+ events = @client.timeline
258
+ events.first['type'].should == 'FollowEvent'
259
+ events[1].repository.name.should == 'octopussy'
260
+ end
261
+ end
262
+
263
+
264
+ context "when unauthenticated" do
265
+
266
+ should "search users" do
267
+ stub_get("/user/search/wynn", "search.json")
268
+ users = Octopussy.search_users("wynn")
269
+ users.first.username.should == 'pengwynn'
270
+ end
271
+
272
+ should "return user info" do
273
+ stub_get("/user/show/pengwynn", "user.json")
274
+ user = Octopussy.user("pengwynn")
275
+ user.login.should == 'pengwynn'
276
+ user.blog.should == 'http://wynnnetherland.com'
277
+ user.name.should == 'Wynn Netherland'
278
+ end
279
+
280
+ should "return followers for a user" do
281
+ stub_get("/user/show/pengwynn/followers", "followers.json")
282
+ followers = Octopussy.followers("pengwynn")
283
+ followers.size.should == 21
284
+ assert followers.include?("adamstac")
285
+ end
286
+
287
+ should "indicate if one user follows another" do
288
+ stub_get("/user/show/pengwynn/following", "followers.json")
289
+ assert Octopussy.follows?('pengwynn', 'adamstac')
290
+ end
291
+
292
+ should "return users a user follows" do
293
+ stub_get("/user/show/pengwynn/following", "followers.json")
294
+ followers = Octopussy.following("pengwynn")
295
+ followers.size.should == 21
296
+ assert followers.include?("adamstac")
297
+ end
298
+
299
+ should "return the repos a user watches" do
300
+ stub_get("/repos/watched/pengwynn", "repos.json")
301
+ repos = Octopussy.watched('pengwynn')
302
+ repos.first.owner.should == 'jnunemaker'
303
+ repos.first.forks.should == 120
304
+ end
305
+
306
+ should "search issues for a repo" do
307
+ stub_get("/issues/search/jnunemaker/twitter/open/httparty", "issues.json")
308
+ issues = Octopussy.search_issues({:username => 'jnunemaker', :repo => 'twitter'}, 'open', 'httparty')
309
+ issues.first.title.should == 'Crack error when creating friendship'
310
+ issues.first.votes.should == 2
311
+ end
312
+
313
+ should "list issues for a repo" do
314
+ stub_get("/issues/list/jnunemaker/twitter/open", "issues.json")
315
+ issues = Octopussy.issues({:username => 'jnunemaker', :repo => 'twitter'}, 'open')
316
+ issues.first.title.should == 'Crack error when creating friendship'
317
+ issues.first.votes.should == 2
318
+ end
319
+
320
+ should "return issue info" do
321
+ stub_get("/issues/show/jnunemaker/twitter/3", "issue.json")
322
+ issue = Octopussy.issue({:username => 'jnunemaker', :repo => 'twitter'}, 3)
323
+ issue.title.should == 'Crack error when creating friendship'
324
+ issue.votes.should == 2
325
+ end
326
+
327
+ # Repos
328
+
329
+ should "search repos" do
330
+ stub_get("/repos/search/compass", "repo_search.json")
331
+ repos = Octopussy.search_repos("compass")
332
+ repos.first.username.should == 'chriseppstein'
333
+ repos.first.language.should == 'Ruby'
334
+ end
335
+
336
+ should "return repo information" do
337
+ stub_get("/repos/show/pengwynn/linkedin", "repo.json")
338
+ repo = Octopussy.repo({:username => "pengwynn", :repo => "linkedin"})
339
+ repo.homepage.should == "http://bit.ly/ruby-linkedin"
340
+ end
341
+
342
+ should "return a repo's contributors list" do
343
+ stub_get("/repos/show/pengwynn/linkedin/contributors", "contributors.json")
344
+ contributors_list = Octopussy.contributors({:username => "pengwynn", :repo => "linkedin"})
345
+ assert contributors_list.include?(["holman", 1])
346
+ end
347
+
348
+ should "list repos for a user" do
349
+ stub_get("/repos/show/pengwynn", "repos.json")
350
+ repos = Octopussy.list_repos('pengwynn')
351
+ repos.first.name.should == 'twitter'
352
+ repos.first.watchers.should == 609
353
+ end
354
+
355
+ should "list collaborators for a repo" do
356
+ stub_post("/repos/show/pengwynn/octopussy/collaborators", "collaborators.json")
357
+ users = Octopussy.collaborators({:username => "pengwynn", :repo => "octopussy"})
358
+ users.last.should == 'adamstac'
359
+ end
360
+
361
+ should "show the network for a repo" do
362
+ stub_get("/repos/show/pengwynn/linkedin/network", "network.json")
363
+ network = Octopussy.network({:username => 'pengwynn', :repo => "linkedin"})
364
+ network.last.owner.should == 'nfo'
365
+ end
366
+
367
+ should "show the language breakdown for a repo" do
368
+ stub_get("/repos/show/pengwynn/linkedin/languages", "languages.json")
369
+ languages = Octopussy.languages({:username => 'pengwynn', :repo => "linkedin"})
370
+ languages['Ruby'].should == 21515
371
+ end
372
+
373
+ should "list all the tags in a repo" do
374
+ stub_get("/repos/show/pengwynn/linkedin/tags", "tags.json")
375
+ tags = Octopussy.tags(:username => 'pengwynn', :repo => "linkedin")
376
+ assert tags.include?("v0.0.1")
377
+ end
378
+
379
+ should "list all the branches in a repo" do
380
+ stub_get("/repos/show/pengwynn/linkedin/branches", "branches.json")
381
+ branches = Octopussy.branches(:username => 'pengwynn', :repo => "linkedin")
382
+ assert branches.include?("integration")
383
+ end
384
+
385
+
386
+ # network
387
+ should "return network meta info for a repo" do
388
+ stub_get("http://github.com/schacon/simplegit/network_meta", "network_meta.json")
389
+ info = Octopussy.network_meta(:username => "schacon", :repo => "simplegit")
390
+ info.users.first.name.should == 'schacon'
391
+ info.users.first.repo.should == 'simplegit'
392
+ end
393
+
394
+ should "return first 100 commits by branch" do
395
+ stub_get("http://github.com/schacon/simplegit/network_data_chunk?nethash=fa8fe264b926cdebaab36420b6501bd74402a6ff", "network_data.json")
396
+ info = Octopussy.network_data({:username => "schacon", :repo => "simplegit"}, "fa8fe264b926cdebaab36420b6501bd74402a6ff")
397
+ assert info.is_a?(Array)
398
+ end
399
+
400
+ # trees
401
+ should "return contents of a tree by tree SHA" do
402
+ stub_get("http://github.com/api/v2/json/tree/show/defunkt/facebox/a47803c9ba26213ff194f042ab686a7749b17476", "trees.json")
403
+ trees = Octopussy.tree({:username => "defunkt", :repo => "facebox"}, "a47803c9ba26213ff194f042ab686a7749b17476")
404
+ trees.first.name.should == '.gitignore'
405
+ trees.first.sha.should == 'e43b0f988953ae3a84b00331d0ccf5f7d51cb3cf'
406
+ end
407
+
408
+ should "return data about a blob by tree SHA and path" do
409
+ stub_get("http://github.com/api/v2/json/blob/show/defunkt/facebox/d4fc2d5e810d9b4bc1ce67702603080e3086a4ed/README.txt", "blob.json")
410
+ blob = Octopussy.blob({:username => "defunkt", :repo => "facebox"}, "d4fc2d5e810d9b4bc1ce67702603080e3086a4ed", "README.txt")
411
+ blob.name.should == 'README.txt'
412
+ blob.sha.should == 'd4fc2d5e810d9b4bc1ce67702603080e3086a4ed'
413
+ end
414
+
415
+ should "return the contents of a blob with the blob's SHA" do
416
+ stub_get("http://github.com/api/v2/yaml/blob/show/defunkt/facebox/4bf7a39e8c4ec54f8b4cd594a3616d69004aba69", "raw_git_data.yaml")
417
+ raw_text = Octopussy.raw({:username => "defunkt", :repo => "facebox"}, "4bf7a39e8c4ec54f8b4cd594a3616d69004aba69")
418
+ assert raw_text.include?("cd13d9a61288dceb0a7aa73b55ed2fd019f4f1f7")
419
+ end
420
+
421
+ #commits
422
+ should "list commits for a repo's master branch by default" do
423
+ stub_get("http://github.com/api/v2/json/commits/list/defunkt/facebox/master", "list_commits.json")
424
+ commits_list = Octopussy.list_commits({:username => "defunkt", :repo => "facebox"})
425
+ assert commits_list.any? { |c| c.message == "Fixed CSS expression, throwing errors in IE6." }
426
+ end
427
+
428
+ should "list commits for a repo on a given branch" do
429
+ stub_get("http://github.com/api/v2/json/commits/list/schacon/simplegit/m/dev/cp", "list_branch_commits.json")
430
+ commits_list = Octopussy.list_commits({:username => "schacon", :repo => "simplegit"}, "m/dev/cp")
431
+ assert commits_list.any? { |c| c.message == "removed unnecessary test code" }
432
+ end
433
+
434
+ should "show a specific commit for a repo given its SHA" do
435
+ sha = "1ff368f79b0f0aa0e1f1d78bcaa8691f94f9703e"
436
+ stub_get("http://github.com/api/v2/json/commits/show/defunkt/facebox/#{sha}", "show_commit.json")
437
+ show_commit = Octopussy.commit({:username => "defunkt", :repo => "facebox"}, sha)
438
+ assert show_commit.message == "Fixed CSS expression, throwing errors in IE6."
439
+ end
440
+
441
+ #timeline
442
+
443
+ should "fetch the public timeline" do
444
+ stub_get("http://github.com/timeline.json", "timeline.json")
445
+ events = Octopussy.public_timeline
446
+ events.first['type'].should == 'FollowEvent'
447
+ events[1].repository.name.should == 'octopussy'
448
+ end
449
+
450
+ should "fetch a user's public timeline" do
451
+ stub_get("http://github.com/pengwynn.json", "timeline.json")
452
+ events = Octopussy.public_timeline('pengwynn')
453
+ events.first['type'].should == 'FollowEvent'
454
+ events[1].repository.name.should == 'octopussy'
455
+ end
456
+
457
+ end
458
+
459
+ context "when Github responds with an error" do
460
+ {
461
+ ["401", "Unauthorized"] => Octopussy::Unauthorized,
462
+ ["403", "Rate Limit Exceeded"] => Octopussy::RateLimitExceeded,
463
+ ["404", "Not Found"] => Octopussy::NotFound,
464
+ ["406", "Not Acceptable"] => Octopussy::ClientError,
465
+ ["500", "Server Error"] => Octopussy::ServerError,
466
+ ["501", "Not Implemented"] => Octopussy::ServerError
467
+ }.each do |status, exception|
468
+ context "#{status.first}, a get" do
469
+ should "raise an #{exception.name} error" do
470
+ stub_get("/user/show/pengwynn", nil, status)
471
+ lambda { Octopussy.user("pengwynn") }.should raise_error(exception)
472
+ end
473
+ end
474
+
475
+ context "#{status.first}, a post" do
476
+ should "raise an #{exception.name} error" do
477
+ stub_post("/user/show/pengwynn?login=pengwynn&token=OU812", nil, status)
478
+ client = Octopussy::Client.new(:login => 'pengwynn', :token => 'OU812')
479
+ lambda { client.update_user(:location => "Dallas, TX") }.should raise_error(exception)
480
+ end
481
+ end
482
+ end
483
+ end
484
+
485
+ context "when consuming feeds" do
486
+
487
+ should "should set user, title, and published time for the event" do
488
+ entry = Hashie::Mash.new({
489
+ :id => 'tag:github.com,2008:CreateEvent/110645788',
490
+ :published => '2009-12-12T11:24:14-08:00',
491
+ :updated => '2009-12-12T11:24:14-08:00',
492
+ :links => ['http://github.com/jnunemaker/twitter/tree/v0.7.10'],
493
+ :title => 'pengwynn created tag v0.7.10 at jnunemaker/twitter',
494
+ :author => 'pengwynn'
495
+ })
496
+
497
+ event = Octopussy::Event.load_from_atom(entry)
498
+ event.user.should == 'pengwynn'
499
+ event.published.year.should == 2009
500
+ event.published.month.should == 12
501
+ event.id.should == 110645788
502
+ event.title.should == 'pengwynn created tag v0.7.10 at jnunemaker/twitter'
503
+ event.links.first.should == 'http://github.com/jnunemaker/twitter/tree/v0.7.10'
504
+ end
505
+
506
+ should "should create a repo event from an atom entry" do
507
+ entry = Hashie::Mash.new({
508
+ :id => 'tag:github.com,2008:CreateEvent/110645788',
509
+ :published => '2009-12-12T11:24:14-08:00',
510
+ :updated => '2009-12-12T11:24:14-08:00',
511
+ :links => ['http://github.com/Tanner/Team-1261---Java'],
512
+ :title => 'Tanner created repository Team-1261---Java',
513
+ :author => 'Tanner'
514
+ })
515
+
516
+ event = Octopussy::Event.load_from_atom(entry)
517
+ event.event_type.should == 'repo'
518
+ event.repo.username.should == 'Tanner'
519
+ event.repo.name.should == 'Team-1261---Java'
520
+ end
521
+
522
+ should "should create a tag event from an atom entry" do
523
+ entry = Hashie::Mash.new({
524
+ :id => 'tag:github.com,2008:CreateEvent/110645788',
525
+ :published => '2009-12-12T11:24:14-08:00',
526
+ :updated => '2009-12-12T11:24:14-08:00',
527
+ :links => ['http://github.com/jnunemaker/twitter/tree/v0.7.10'],
528
+ :title => 'pengwynn created tag v0.7.10 at jnunemaker/twitter',
529
+ :author => 'pengwynn'
530
+ })
531
+
532
+ event = Octopussy::Event.load_from_atom(entry)
533
+ event.event_type.should == 'tag'
534
+ event.repo.username.should == 'jnunemaker'
535
+ event.repo.name.should == 'twitter'
536
+ event.tag.should == 'v0.7.10'
537
+ end
538
+
539
+ should "should create a branch event from an atom entry" do
540
+ entry = Hashie::Mash.new({
541
+ :id => 'tag:github.com,2008:CreateEvent/110645788',
542
+ :published => '2009-12-12T11:24:14-08:00',
543
+ :updated => '2009-12-12T11:24:14-08:00',
544
+ :links => ['http://github.com/Fabi/cwcore/tree/cwcore-0.1'],
545
+ :title => 'cwcore created branch cwcore-0.1 at Fabi/cwcore',
546
+ :author => 'cwcore'
547
+ })
548
+
549
+ event = Octopussy::Event.load_from_atom(entry)
550
+ event.event_type.should == 'branch'
551
+ event.repo.username.should == 'Fabi'
552
+ event.repo.name.should == 'cwcore'
553
+ event.user.should == 'cwcore'
554
+ event.branch.should == 'cwcore-0.1'
555
+ end
556
+
557
+ should "should create a push event from an atom entry" do
558
+ entry = Hashie::Mash.new({
559
+ :id => 'tag:github.com,2008:PushEvent/110645788',
560
+ :published => '2009-12-12T11:24:14-08:00',
561
+ :updated => '2009-12-12T11:24:14-08:00',
562
+ :links => ['http://github.com/jnunemaker/twitter/commits/master'],
563
+ :title => 'pengwynn pushed to master at jnunemaker/twitter',
564
+ :author => 'pengwynn'
565
+ })
566
+
567
+ event = Octopussy::Event.load_from_atom(entry)
568
+ event.event_type.should == 'push'
569
+ event.repo.name.should == 'twitter'
570
+ event.branch.should == 'master'
571
+ end
572
+
573
+ should "should create a fork event from an atom entry" do
574
+ entry = Hashie::Mash.new({
575
+ :id => 'tag:github.com,2008:ForkEvent/110645788',
576
+ :published => '2009-12-12T11:24:14-08:00',
577
+ :updated => '2009-12-12T11:24:14-08:00',
578
+ :links => ['http://github.com/klauge/aeon/'],
579
+ :title => 'klauge forked djh/aeon',
580
+ :author => 'klauge'
581
+ })
582
+
583
+ event = Octopussy::Event.load_from_atom(entry)
584
+ event.event_type.should == 'fork'
585
+ event.repo.username.should == 'klauge'
586
+ event.repo.name.should == 'aeon'
587
+ event.forked_from.username.should == 'djh'
588
+ end
589
+
590
+ should "should create a watch event from an atom entry" do
591
+ entry = Hashie::Mash.new({
592
+ :id => 'tag:github.com,2008:WatchEvent/110645788',
593
+ :published => '2009-12-12T11:24:14-08:00',
594
+ :updated => '2009-12-12T11:24:14-08:00',
595
+ :links => ['http://github.com/bogolisk/egg'],
596
+ :title => 'jpablobr started watching bogolisk/egg',
597
+ :author => 'jpablobr'
598
+ })
599
+
600
+ event = Octopussy::Event.load_from_atom(entry)
601
+ event.event_type.should == 'watch'
602
+ event.repo.username.should == 'bogolisk'
603
+ event.repo.name.should == 'egg'
604
+ end
605
+
606
+ should "should create a follow event from an atom entry" do
607
+ entry = Hashie::Mash.new({
608
+ :id => 'tag:github.com,2008:FollowEvent/110645788',
609
+ :published => '2009-12-12T11:24:14-08:00',
610
+ :updated => '2009-12-12T11:24:14-08:00',
611
+ :links => ['http://github.com/swistak'],
612
+ :title => 'pengwynn started following swistak',
613
+ :author => 'pengwynn'
614
+ })
615
+
616
+ event = Octopussy::Event.load_from_atom(entry)
617
+ event.event_type.should == 'follow'
618
+ event.repo.should == nil
619
+ event.target_user.should == 'swistak'
620
+ end
621
+
622
+ should "should create an issues event from an atom entry" do
623
+ entry = Hashie::Mash.new({
624
+ :id => 'tag:github.com,2008:IssuesEvent/110645788',
625
+ :published => '2009-12-12T11:24:14-08:00',
626
+ :updated => '2009-12-12T11:24:14-08:00',
627
+ :links => ['http://github.com/jnunemaker/twitter/issues/19/find'],
628
+ :title => 'pengwynn closed issue 19 on jnunemaker/twitter',
629
+ :author => 'pengwynn'
630
+ })
631
+
632
+ event = Octopussy::Event.load_from_atom(entry)
633
+ event.event_type.should == 'issue'
634
+ event.repo.name.should == 'twitter'
635
+ event.action.should == 'closed'
636
+ event.issue_number.should == 19
637
+ end
638
+
639
+ should "should create a gist event from an atom entry" do
640
+ entry = Hashie::Mash.new({
641
+ :id => 'tag:github.com,2008:GistEvent/110645788',
642
+ :published => '2009-12-12T11:24:14-08:00',
643
+ :updated => '2009-12-12T11:24:14-08:00',
644
+ :links => ['http://gist.github.com/253987'],
645
+ :title => 'pengwynn created gist: 253987',
646
+ :author => 'pengwynn'
647
+ })
648
+
649
+ event = Octopussy::Event.load_from_atom(entry)
650
+ event.event_type.should == 'gist'
651
+ event.repo.should == nil
652
+ event.gist_number.should == 253987
653
+ end
654
+
655
+ should "should create a member event from an atom entry" do
656
+ entry = Hashie::Mash.new({
657
+ :id => 'tag:github.com,2008:MemberEvent/110645788',
658
+ :published => '2009-12-12T11:24:14-08:00',
659
+ :updated => '2009-12-12T11:24:14-08:00',
660
+ :links => ['http://github.com/pengwynn/octopussy'],
661
+ :title => 'pengwynn added adamstac to octopussy',
662
+ :author => 'pengwynn'
663
+ })
664
+
665
+ event = Octopussy::Event.load_from_atom(entry)
666
+ event.event_type.should == 'member'
667
+ event.repo.name.should == 'octopussy'
668
+ event.target_user.should == 'adamstac'
669
+ end
670
+
671
+ should "should create a fork_apply event from an atom entry" do
672
+ entry = Hashie::Mash.new({
673
+ :id => 'tag:github.com,2008:ForkApplyEvent/110645788',
674
+ :published => '2009-12-12T11:24:14-08:00',
675
+ :updated => '2009-12-12T11:24:14-08:00',
676
+ :links => ['http://github.com/pengwynn/linkedin/tree/integration'],
677
+ :title => 'pengwynn applied fork commits to linkedin/integration',
678
+ :author => 'pengwynn'
679
+ })
680
+
681
+ event = Octopussy::Event.load_from_atom(entry)
682
+ event.event_type.should == 'fork_apply'
683
+ event.repo.name.should == 'linkedin'
684
+ event.branch.should == 'integration'
685
+ end
686
+
687
+ should "should create a wiki event from an atom entry" do
688
+ entry = Hashie::Mash.new({
689
+ :id => 'tag:github.com,2008:WikiEvent/110645788',
690
+ :published => '2009-12-12T11:24:14-08:00',
691
+ :updated => '2009-12-12T11:24:14-08:00',
692
+ :links => ['http://github.com/dxw/Fammel/wikis/documentation'],
693
+ :title => 'dxw edited a page in the dxw/Fammel wiki',
694
+ :author => 'dxw'
695
+ })
696
+
697
+ event = Octopussy::Event.load_from_atom(entry)
698
+ event.event_type.should == 'wiki'
699
+ event.repo.name.should == 'Fammel'
700
+ event.page.should == 'documentation'
701
+ end
702
+
703
+ should "should create a comment event from an atom entry" do
704
+ entry = Hashie::Mash.new({
705
+ :id => 'tag:github.com,2008:CommitCommentEvent/110645788',
706
+ :published => '2009-12-12T11:24:14-08:00',
707
+ :updated => '2009-12-12T11:24:14-08:00',
708
+ :links => ['http://github.com/fakechris/resque/commit/46f7ff1f73ae16ca8060fa3b051900562b51d5c2#-P0'],
709
+ :title => 'defunkt commented on fakechris/resque',
710
+ :author => 'defunkt'
711
+ })
712
+
713
+ event = Octopussy::Event.load_from_atom(entry)
714
+ event.event_type.should == 'comment'
715
+ event.repo.name.should == 'resque'
716
+ end
717
+
718
+ should "should create a delete event from an atom entry" do
719
+ entry = Hashie::Mash.new({
720
+ :id => 'tag:github.com,2008:DeleteEvent/110645788',
721
+ :published => '2009-12-12T11:24:14-08:00',
722
+ :updated => '2009-12-12T11:24:14-08:00',
723
+ :links => ['http://github.com/jinzhu'],
724
+ :title => 'jinzhu deleted branch search at jinzhu/vimlike-smooziee',
725
+ :author => 'jinzhu'
726
+ })
727
+
728
+ event = Octopussy::Event.load_from_atom(entry)
729
+ event.event_type.should == 'delete'
730
+ event.repo.name.should == 'vimlike-smooziee'
731
+ event.branch.should == 'search'
732
+ end
733
+
734
+ should "should create a public event from an atom entry" do
735
+ entry = Hashie::Mash.new({
736
+ :id => 'tag:github.com,2008:PublicEvent/110645788',
737
+ :published => '2009-12-12T11:24:14-08:00',
738
+ :updated => '2009-12-12T11:24:14-08:00',
739
+ :links => ['http://github.com/intalio'],
740
+ :title => 'intalio open sourced bpmn2',
741
+ :author => 'intalio'
742
+ })
743
+
744
+ event = Octopussy::Event.load_from_atom(entry)
745
+ event.event_type.should == 'public'
746
+ event.repo.name.should == 'bpmn2'
747
+ end
748
+
749
+ should "should create a download event from an atom entry" do
750
+ entry = Hashie::Mash.new({
751
+ :id => 'tag:github.com,2008:DownloadEvent/110645788',
752
+ :published => '2009-12-12T11:24:14-08:00',
753
+ :updated => '2009-12-12T11:24:14-08:00',
754
+ :links => ['http://github.com/tobie'],
755
+ :title => 'tobie uploaded a file to sstephenson/prototype',
756
+ :author => 'tobie'
757
+ })
758
+
759
+ event = Octopussy::Event.load_from_atom(entry)
760
+ event.event_type.should == 'download'
761
+ event.repo.name.should == 'prototype'
762
+ end
763
+
764
+
765
+ end
766
+
767
+
768
+
769
+ end