Skip to content

Commit 17a8696

Browse files
committed
Add starring api feature.
1 parent b0303b6 commit 17a8696

5 files changed

Lines changed: 356 additions & 7 deletions

File tree

lib/github_api/repos.rb

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,8 @@ class Repos < API
1515
:Keys => 'keys',
1616
:Watching => 'watching',
1717
:PubSubHubbub => 'pub_sub_hubbub',
18-
:Statuses => 'statuses'
18+
:Starring => 'starring',
19+
:Statuses => 'statuses'
1920

2021
DEFAULT_REPO_OPTIONS = {
2122
"homepage" => "https://github.com",
@@ -78,20 +79,25 @@ def keys
7879
@keys ||= ApiFactory.new 'Repos::Keys'
7980
end
8081

81-
# Access to Repos::Watchin API
82-
def watching
83-
@watching ||= ApiFactory.new 'Repos::Watching'
84-
end
85-
8682
# Access to Repos::Watchin API
8783
def pubsubhubbub
8884
@pubsubhubbub ||= ApiFactory.new 'Repos::PubSubHubbub'
8985
end
9086

87+
# Access to Repos::Starring API
88+
def starring
89+
@starring ||= ApiFactory.new 'Repos::Starring'
90+
end
91+
9192
# Access to Repos::Statuses API
9293
def statuses
9394
@statuses ||= ApiFactory.new 'Repos::Statuses'
94-
end
95+
end
96+
97+
# Access to Repos::Watching API
98+
def watching
99+
@watching ||= ApiFactory.new 'Repos::Watching'
100+
end
95101

96102
# List branches
97103
#

lib/github_api/repos/starring.rb

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
# encoding: utf-8
2+
3+
module Github
4+
# Repository Starring is a feature that lets users bookmark repositories.
5+
# Stars are shown next to repositories to show an approximate level of interest. # Stars have no effect on notifications or the activity feed.
6+
class Repos::Starring < API
7+
8+
# List stargazers
9+
#
10+
# = Examples
11+
# github = Github.new :user => 'user-name', :repo => 'repo-name'
12+
# github.repos.starring.list
13+
# github.repos.starring.list { |star| ... }
14+
#
15+
def list(user_name, repo_name, params={})
16+
_update_user_repo_params(user_name, repo_name)
17+
_validate_user_repo_params(user, repo) unless user? && repo?
18+
normalize! params
19+
20+
response = get_request("/repos/#{user}/#{repo}/stargazers", params)
21+
return response unless block_given?
22+
response.each { |el| yield el }
23+
end
24+
alias :all :list
25+
26+
# List repos being starred by a user
27+
#
28+
# = Examples
29+
# github = Github.new
30+
# github.repos.starring.starred :user => 'user-name'
31+
#
32+
# List repos being starred by the authenticated user
33+
#
34+
# = Examples
35+
# github = Github.new :oauth_token => '...'
36+
# github.repos.starring.starred
37+
#
38+
def starred(*args)
39+
params = args.extract_options!
40+
normalize! params
41+
42+
response = if (user_name = params.delete('user'))
43+
get_request("/users/#{user_name}/starred", params)
44+
else
45+
get_request("/user/starred", params)
46+
end
47+
return response unless block_given?
48+
response.each { |el| yield el }
49+
end
50+
51+
# Check if you are starring a repository
52+
#
53+
# Returns <tt>true</tt> if this repo is starred by you,<tt>false</tt> otherwise
54+
#
55+
# = Examples
56+
# github = Github.new
57+
# github.repos.starring.starring? 'user-name', 'repo-name'
58+
#
59+
def starring?(user_name, repo_name, params={})
60+
_validate_presence_of user_name, repo_name
61+
normalize! params
62+
get_request("/user/starred/#{user_name}/#{repo_name}", params)
63+
true
64+
rescue Github::Error::NotFound
65+
false
66+
end
67+
68+
# Star a repository
69+
#
70+
# You need to be authenticated to star a repository
71+
#
72+
# = Examples
73+
# github = Github.new
74+
# github.repos.starring.star 'user-name', 'repo-name'
75+
#
76+
def star(user_name, repo_name, params={})
77+
_validate_presence_of user_name, repo_name
78+
normalize! params
79+
put_request("/user/starred/#{user_name}/#{repo_name}", params)
80+
end
81+
82+
# Unstar a repository
83+
#
84+
# You need to be authenticated to unstar a repository.
85+
#
86+
# = Examples
87+
# github = Github.new
88+
# github.repos.starring.unstar 'user-name', 'repo-name'
89+
#
90+
def unstar(user_name, repo_name, params={})
91+
_validate_presence_of user_name, repo_name
92+
normalize! params
93+
delete_request("/user/starred/#{user_name}/#{repo_name}", params)
94+
end
95+
96+
end # Repos::Starring
97+
end # Github
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
[
2+
{
3+
"login": "octocat",
4+
"id": 1,
5+
"avatar_url": "https://github.com/images/error/octocat_happy.gif",
6+
"gravatar_id": "somehexcode",
7+
"url": "https://api.github.com/users/octocat"
8+
}
9+
]

spec/fixtures/repos/starred.json

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
[
2+
{
3+
"url": "https://api.github.com/repos/octocat/Hello-World",
4+
"html_url": "https://github.com/octocat/Hello-World",
5+
"clone_url": "https://github.com/octocat/Hello-World.git",
6+
"git_url": "git://github.com/octocat/Hello-World.git",
7+
"ssh_url": "[email protected]:octocat/Hello-World.git",
8+
"svn_url": "https://svn.github.com/octocat/Hello-World",
9+
"mirror_url": "git://git.example.com/octocat/Hello-World",
10+
"id": 1296269,
11+
"owner": {
12+
"login": "octocat",
13+
"id": 1,
14+
"avatar_url": "https://github.com/images/error/octocat_happy.gif",
15+
"gravatar_id": "somehexcode",
16+
"url": "https://api.github.com/users/octocat"
17+
},
18+
"name": "Hello-World",
19+
"full_name": "octocat/Hello-World",
20+
"description": "This your first repo!",
21+
"homepage": "https://github.com",
22+
"language": null,
23+
"private": false,
24+
"fork": false,
25+
"forks": 9,
26+
"watchers": 80,
27+
"size": 108,
28+
"master_branch": "master",
29+
"open_issues": 0,
30+
"pushed_at": "2011-01-26T19:06:43Z",
31+
"created_at": "2011-01-26T19:01:12Z",
32+
"updated_at": "2011-01-26T19:14:43Z"
33+
}
34+
]

spec/github/repos/starring_spec.rb

Lines changed: 203 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,203 @@
1+
# encoding: utf-8
2+
3+
require 'spec_helper'
4+
5+
describe Github::Repos::Starring do
6+
let(:github) { Github.new }
7+
let(:user) { 'peter-murach' }
8+
let(:repo) { 'github' }
9+
10+
after { github.user, github.repo, github.oauth_token = nil, nil, nil }
11+
12+
describe "#list" do
13+
before do
14+
stub_get("/repos/#{user}/#{repo}/stargazers").
15+
to_return(:body => fixture("repos/stargazers.json"),
16+
:status => 200, :headers => {})
17+
end
18+
19+
it "should fail to get resource without username" do
20+
expect {
21+
github.repos.starring.list
22+
}.to raise_error(ArgumentError)
23+
end
24+
25+
it "should yield iterator if block given" do
26+
github.repos.starring.should_receive(:list).
27+
with(user, repo).and_yield('github')
28+
github.repos.starring.list(user, repo) { |param| 'github' }
29+
end
30+
31+
it "should get the resources" do
32+
github.repos.starring.list user, repo
33+
a_get("/repos/#{user}/#{repo}/stargazers").should have_been_made
34+
end
35+
36+
it "should return array of resources" do
37+
stargazers = github.repos.starring.list user, repo
38+
stargazers.should be_an Array
39+
stargazers.should have(1).items
40+
end
41+
42+
it "should return result of mash type" do
43+
stargazers = github.repos.starring.list user, repo
44+
stargazers.first.should be_a Hashie::Mash
45+
end
46+
47+
it "should get watcher information" do
48+
stargazers = github.repos.starring.list user, repo
49+
stargazers.first.login.should == 'octocat'
50+
end
51+
52+
context "fail to find resource" do
53+
before do
54+
stub_get("/repos/#{user}/#{repo}/stargazers").
55+
to_return(:body => "", :status => 404)
56+
end
57+
58+
it "should return 404 not found message" do
59+
expect {
60+
github.repos.starring.list user, repo
61+
}.to raise_error(Github::Error::NotFound)
62+
end
63+
end
64+
end
65+
66+
describe "#starred" do
67+
context "if user unauthenticated" do
68+
it "should fail to get resource without username " do
69+
stub_get("/user/starred").
70+
to_return(:body => '', :status => 401, :headers => {})
71+
expect {
72+
github.repos.starring.starred
73+
}.to raise_error(Github::Error::Unauthorized)
74+
end
75+
76+
it "should get the resource with username" do
77+
stub_get("/users/#{user}/starred").
78+
to_return(:body => fixture("repos/starred.json"), :status => 200, :headers => {})
79+
github.repos.starring.starred :user => user
80+
a_get("/users/#{user}/starred").should have_been_made
81+
end
82+
end
83+
84+
context "if user authenticated" do
85+
before do
86+
github.oauth_token = OAUTH_TOKEN
87+
stub_get("/user/starred").
88+
with(:query => {:access_token => OAUTH_TOKEN}).
89+
to_return(:body => fixture("repos/starred.json"),
90+
:status => 200, :headers => {})
91+
end
92+
93+
it "should get the resources" do
94+
github.repos.starring.starred
95+
a_get("/user/starred").with(:query => {:access_token => OAUTH_TOKEN}).
96+
should have_been_made
97+
end
98+
99+
it "should return array of resources" do
100+
starred = github.repos.starring.starred
101+
starred.should be_an Array
102+
starred.should have(1).items
103+
end
104+
105+
it "should get starred information" do
106+
starred = github.repos.starring.starred
107+
starred.first.name.should == 'Hello-World'
108+
starred.first.owner.login.should == 'octocat'
109+
end
110+
end
111+
end # starred
112+
113+
describe "starring?" do
114+
context "with username ane reponame passed" do
115+
context "this repo is being watched by the user"
116+
before do
117+
stub_get("/user/starred/#{user}/#{repo}").
118+
to_return(:body => "", :status => 404,
119+
:headers => {:user_agent => github.user_agent})
120+
end
121+
122+
it "should return false if resource not found" do
123+
starring = github.repos.starring.starring? user, repo
124+
starring.should be_false
125+
end
126+
127+
it "should return true if resoure found" do
128+
stub_get("/user/starred/#{user}/#{repo}").
129+
to_return(:body => "", :status => 200,
130+
:headers => {:user_agent => github.user_agent})
131+
starring = github.repos.starring.starring? user, repo
132+
starring.should be_true
133+
end
134+
end
135+
136+
context "without username and reponame passed" do
137+
it "should fail validation " do
138+
expect {
139+
github.repos.starring.starring?(nil, nil)
140+
}.to raise_error(ArgumentError)
141+
end
142+
end
143+
end # starring?
144+
145+
describe "#star" do
146+
context "user authenticated" do
147+
context "with correct information" do
148+
before do
149+
github.oauth_token = OAUTH_TOKEN
150+
stub_put("/user/starred/#{user}/#{repo}").
151+
with(:query => {:access_token => OAUTH_TOKEN}).
152+
to_return(:body => "", :status => 204, :headers => {})
153+
end
154+
155+
it "should successfully star a repo" do
156+
github.repos.starring.star user, repo
157+
a_put("/user/starred/#{user}/#{repo}").
158+
with(:query => {:access_token => OAUTH_TOKEN}).
159+
should have_been_made
160+
end
161+
end
162+
end
163+
164+
context "user unauthenticated" do
165+
it "should fail" do
166+
stub_put("/user/starred/#{user}/#{repo}").
167+
to_return(:body => "", :status => 401, :headers => {})
168+
expect {
169+
github.repos.starring.star user, repo
170+
}.to raise_error(Github::Error::Unauthorized)
171+
end
172+
end
173+
end # star
174+
175+
describe "#unstar" do
176+
context "user authenticated" do
177+
context "with correct information" do
178+
before do
179+
github.oauth_token = OAUTH_TOKEN
180+
stub_delete("/user/starred/#{user}/#{repo}?access_token=#{OAUTH_TOKEN}").
181+
to_return(:body => "", :status => 204, :headers => {})
182+
end
183+
184+
it "should successfully unstar a repo" do
185+
github.repos.starring.unstar user, repo
186+
a_delete("/user/starred/#{user}/#{repo}?access_token=#{OAUTH_TOKEN}").
187+
should have_been_made
188+
end
189+
end
190+
end
191+
192+
context "user unauthenticated" do
193+
it "should fail" do
194+
stub_delete("/user/starred/#{user}/#{repo}").
195+
to_return(:body => "", :status => 401, :headers => {})
196+
expect {
197+
github.repos.starring.unstar user, repo
198+
}.to raise_error(Github::Error::Unauthorized)
199+
end
200+
end
201+
end # stop_watching
202+
203+
end # Github::Respos::Starring

0 commit comments

Comments
 (0)