opsb-octopussy 0.3.0

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.
@@ -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