rest-graph 1.5.0 → 1.6.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.
- data/.specification +309 -0
- data/CHANGES +78 -0
- data/Gemfile +4 -2
- data/Gemfile.lock +12 -7
- data/README +20 -9
- data/README.rdoc +20 -9
- data/Rakefile +2 -1
- data/TODO +2 -0
- data/example/multi/config.ru +44 -0
- data/example/multi/rainbows.rb +5 -0
- data/example/rails2/test/functional/application_controller_test.rb +6 -6
- data/lib/rest-graph.rb +179 -75
- data/lib/rest-graph/rails_util.rb +2 -13
- data/lib/rest-graph/test_util.rb +95 -0
- data/lib/rest-graph/version.rb +1 -1
- data/rest-graph.gemspec +305 -57
- data/test/common.rb +3 -3
- data/test/test_api.rb +12 -11
- data/test/test_cache.rb +3 -3
- data/test/test_default.rb +2 -2
- data/test/test_error.rb +3 -3
- data/test/test_handler.rb +13 -10
- data/test/test_load_config.rb +1 -1
- data/test/test_misc.rb +14 -12
- data/test/test_multi.rb +126 -0
- data/test/test_oauth.rb +4 -4
- data/test/test_old.rb +8 -8
- data/test/test_page.rb +70 -14
- data/test/test_parse.rb +9 -9
- data/test/test_serialize.rb +13 -4
- data/test/test_test_util.rb +74 -0
- data/test/test_timeout.rb +20 -0
- metadata +56 -30
data/test/common.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
|
2
|
-
require 'rubygems' if RUBY_VERSION < '1.9.
|
3
|
-
require 'rack' if RUBY_VERSION < '1.9.
|
2
|
+
require 'rubygems' if RUBY_VERSION < '1.9.2'
|
3
|
+
require 'rack' if RUBY_VERSION < '1.9.2' # autoload broken in 1.8?
|
4
4
|
require 'rest-graph'
|
5
5
|
|
6
6
|
require 'rr'
|
@@ -11,7 +11,7 @@ require 'bacon'
|
|
11
11
|
require 'yaml'
|
12
12
|
|
13
13
|
include RR::Adapters::RRMethods
|
14
|
-
include WebMock
|
14
|
+
include WebMock::API
|
15
15
|
WebMock.disable_net_connect!
|
16
16
|
Bacon.summary_on_exit
|
17
17
|
|
data/test/test_api.rb
CHANGED
@@ -7,23 +7,23 @@ end
|
|
7
7
|
|
8
8
|
describe RestGraph do
|
9
9
|
after do
|
10
|
-
reset_webmock
|
10
|
+
WebMock.reset_webmock
|
11
11
|
RR.verify
|
12
12
|
end
|
13
13
|
|
14
|
-
|
14
|
+
should 'generate correct url' do
|
15
15
|
TestHelper.normalize_url(
|
16
16
|
RestGraph.new(:access_token => 'awesome').url('path', :query => 'str')).
|
17
17
|
should ==
|
18
18
|
'https://graph.facebook.com/path?access_token=awesome&query=str'
|
19
19
|
end
|
20
20
|
|
21
|
-
|
21
|
+
should 'request to correct server' do
|
22
22
|
stub_request(:get, 'http://nothing.godfat.org/me').with(
|
23
23
|
:headers => {'Accept' => 'text/plain',
|
24
24
|
'Accept-Language' => 'zh-tw',
|
25
25
|
'Accept-Encoding' => 'gzip, deflate', # this is by ruby
|
26
|
-
}.merge(RUBY_VERSION
|
26
|
+
}.merge(RUBY_VERSION < '1.9.2' ?
|
27
27
|
{} :
|
28
28
|
{'User-Agent' => 'Ruby'})). # this is by ruby
|
29
29
|
to_return(:body => '{"data": []}')
|
@@ -33,7 +33,7 @@ describe RestGraph do
|
|
33
33
|
:accept => 'text/plain').get('me').should == {'data' => []}
|
34
34
|
end
|
35
35
|
|
36
|
-
|
36
|
+
should 'post right' do
|
37
37
|
stub_request(:post, 'https://graph.facebook.com/feed/me').
|
38
38
|
with(:body => 'message=hi%20there').to_return(:body => 'ok')
|
39
39
|
|
@@ -41,7 +41,7 @@ describe RestGraph do
|
|
41
41
|
post('feed/me', :message => 'hi there').should == 'ok'
|
42
42
|
end
|
43
43
|
|
44
|
-
|
44
|
+
should 'suppress auto-decode in an api call' do
|
45
45
|
stub_request(:get, 'https://graph.facebook.com/woot').
|
46
46
|
to_return(:body => 'bad json')
|
47
47
|
|
@@ -50,16 +50,17 @@ describe RestGraph do
|
|
50
50
|
rg.auto_decode.should == true
|
51
51
|
end
|
52
52
|
|
53
|
-
|
54
|
-
|
53
|
+
should 'call post_request after request' do
|
54
|
+
url = 'https://graph.facebook.com/feed/me'
|
55
|
+
stub_request(:put, url).
|
55
56
|
with(:body => 'message=hi%20there').to_return(:body => '[]')
|
56
57
|
|
57
|
-
mock.proxy(rg = RestGraph.new).post_request('[]', {})
|
58
|
+
mock.proxy(rg = RestGraph.new).post_request('[]', url, {})
|
58
59
|
rg.put('feed/me', :message => 'hi there').
|
59
60
|
should == []
|
60
61
|
end
|
61
62
|
|
62
|
-
|
63
|
+
should 'not raise exception when encountering error' do
|
63
64
|
[500, 401, 402, 403].each{ |status|
|
64
65
|
stub_request(:delete, 'https://graph.facebook.com/123').to_return(
|
65
66
|
:body => '[]', :status => status)
|
@@ -68,7 +69,7 @@ describe RestGraph do
|
|
68
69
|
}
|
69
70
|
end
|
70
71
|
|
71
|
-
|
72
|
+
should 'convert query to string' do
|
72
73
|
mock(o = Object.new).to_s{ 'i am mock' }
|
73
74
|
stub_request(:get, "https://graph.facebook.com/search?q=i%20am%20mock").
|
74
75
|
to_return(:body => 'ok')
|
data/test/test_cache.rb
CHANGED
@@ -7,11 +7,11 @@ end
|
|
7
7
|
|
8
8
|
describe RestGraph do
|
9
9
|
after do
|
10
|
-
reset_webmock
|
10
|
+
WebMock.reset_webmock
|
11
11
|
RR.verify
|
12
12
|
end
|
13
13
|
|
14
|
-
|
14
|
+
should 'enable cache if passing cache' do
|
15
15
|
url, body = "https://graph.facebook.com/cache", '{"message":"ok"}'
|
16
16
|
stub_request(:get, url).to_return(:body => body).times(1)
|
17
17
|
|
@@ -21,7 +21,7 @@ describe RestGraph do
|
|
21
21
|
cache.should == {rg.send(:cache_key, url) => body}
|
22
22
|
end
|
23
23
|
|
24
|
-
|
24
|
+
should 'not cache post/put/delete' do
|
25
25
|
[:put, :post, :delete].each{ |meth|
|
26
26
|
url, body = "https://graph.facebook.com/cache", '{"message":"ok"}'
|
27
27
|
stub_request(meth, url).to_return(:body => body).times(3)
|
data/test/test_default.rb
CHANGED
@@ -6,7 +6,7 @@ else
|
|
6
6
|
end
|
7
7
|
|
8
8
|
describe RestGraph do
|
9
|
-
|
9
|
+
should 'honor default attributes' do
|
10
10
|
TestHelper.attrs_no_callback.each{ |name|
|
11
11
|
RestGraph.new.send(name).should ==
|
12
12
|
RestGraph.send("default_#{name}")
|
@@ -16,7 +16,7 @@ describe RestGraph do
|
|
16
16
|
}
|
17
17
|
end
|
18
18
|
|
19
|
-
|
19
|
+
should 'use module to override default attributes' do
|
20
20
|
module BlahAttributes
|
21
21
|
def default_app_id
|
22
22
|
'1829'
|
data/test/test_error.rb
CHANGED
@@ -7,11 +7,11 @@ end
|
|
7
7
|
|
8
8
|
describe RestGraph::Error do
|
9
9
|
after do
|
10
|
-
reset_webmock
|
10
|
+
WebMock.reset_webmock
|
11
11
|
RR.verify
|
12
12
|
end
|
13
13
|
|
14
|
-
|
14
|
+
should 'have the right ancestors' do
|
15
15
|
RestGraph::Error::AccessToken .should < RestGraph::Error
|
16
16
|
|
17
17
|
RestGraph::Error::InvalidAccessToken.should <
|
@@ -21,7 +21,7 @@ describe RestGraph::Error do
|
|
21
21
|
RestGraph::Error::AccessToken
|
22
22
|
end
|
23
23
|
|
24
|
-
|
24
|
+
should 'parse right' do
|
25
25
|
%w[OAuthInvalidTokenException OAuthException].each{ |type|
|
26
26
|
RestGraph::Error.parse('error' => {'type' => type}).
|
27
27
|
should.kind_of?(RestGraph::Error::InvalidAccessToken)
|
data/test/test_handler.rb
CHANGED
@@ -7,12 +7,12 @@ end
|
|
7
7
|
|
8
8
|
describe RestGraph do
|
9
9
|
after do
|
10
|
-
reset_webmock
|
10
|
+
WebMock.reset_webmock
|
11
11
|
RR.verify
|
12
12
|
end
|
13
13
|
|
14
14
|
describe 'log handler' do
|
15
|
-
|
15
|
+
should 'log whenever doing network request' do
|
16
16
|
stub_request(:get, 'https://graph.facebook.com/me').
|
17
17
|
to_return(:body => '{}')
|
18
18
|
|
@@ -30,7 +30,7 @@ describe RestGraph do
|
|
30
30
|
|
31
31
|
describe 'with Graph API' do
|
32
32
|
before do
|
33
|
-
@id = lambda{ |obj| obj }
|
33
|
+
@id = lambda{ |obj, url| obj }
|
34
34
|
@error = '{"error":{"type":"Exception","message":"(#2500)"}}'
|
35
35
|
@error_hash = RestGraph.json_decode(@error)
|
36
36
|
|
@@ -38,16 +38,17 @@ describe RestGraph do
|
|
38
38
|
to_return(:body => @error)
|
39
39
|
end
|
40
40
|
|
41
|
-
|
41
|
+
should 'call error_handler if error occurred' do
|
42
42
|
RestGraph.new(:error_handler => @id).get('me').should == @error_hash
|
43
43
|
end
|
44
44
|
|
45
|
-
|
45
|
+
should 'raise ::RestGraph::Error in default error_handler' do
|
46
46
|
begin
|
47
47
|
RestGraph.new.get('me')
|
48
48
|
rescue ::RestGraph::Error => e
|
49
49
|
e.error .should == @error_hash
|
50
|
-
e.message.should ==
|
50
|
+
e.message.should ==
|
51
|
+
"#{@error_hash.inspect} from https://graph.facebook.com/me"
|
51
52
|
end
|
52
53
|
end
|
53
54
|
end
|
@@ -60,7 +61,7 @@ describe RestGraph do
|
|
60
61
|
# {"key":"query","value":
|
61
62
|
# "SELECT name FROM bad_table WHERE uid=12345"}]}
|
62
63
|
before do
|
63
|
-
@id = lambda{ |obj| obj }
|
64
|
+
@id = lambda{ |obj, url| obj }
|
64
65
|
@fql_error = '{"error_code":603,"error_msg":"Unknown table: bad"}'
|
65
66
|
@fql_error_hash = RestGraph.json_decode(@fql_error)
|
66
67
|
|
@@ -71,17 +72,19 @@ describe RestGraph do
|
|
71
72
|
stub_request(:get, bad_fql_request).to_return(:body => @fql_error)
|
72
73
|
end
|
73
74
|
|
74
|
-
|
75
|
+
should 'call error_handler if error occurred' do
|
75
76
|
RestGraph.new(:error_handler => @id).fql(@bad_fql_query).
|
76
77
|
should == @fql_error_hash
|
77
78
|
end
|
78
79
|
|
79
|
-
|
80
|
+
should 'raise ::RestGraph::Error in default error_handler' do
|
80
81
|
begin
|
81
82
|
RestGraph.new.fql(@bad_fql_query)
|
82
83
|
rescue ::RestGraph::Error => e
|
83
84
|
e.error .should == @fql_error_hash
|
84
|
-
e.message.should
|
85
|
+
e.message.should.start_with?(
|
86
|
+
"#{@fql_error_hash.inspect} from " \
|
87
|
+
"https://api.facebook.com/method/fql.query?")
|
85
88
|
end
|
86
89
|
end
|
87
90
|
end
|
data/test/test_load_config.rb
CHANGED
data/test/test_misc.rb
CHANGED
@@ -7,16 +7,16 @@ end
|
|
7
7
|
|
8
8
|
describe RestGraph do
|
9
9
|
after do
|
10
|
-
reset_webmock
|
10
|
+
WebMock.reset_webmock
|
11
11
|
RR.verify
|
12
12
|
end
|
13
13
|
|
14
|
-
|
14
|
+
should 'return true in authorized? if there is an access_token' do
|
15
15
|
RestGraph.new(:access_token => '1').authorized?.should == true
|
16
16
|
RestGraph.new(:access_token => nil).authorized?.should == false
|
17
17
|
end
|
18
18
|
|
19
|
-
|
19
|
+
should 'treat oauth_token as access_token as well' do
|
20
20
|
rg = RestGraph.new
|
21
21
|
hate_facebook = 'why the hell two different name?'
|
22
22
|
rg.data['oauth_token'] = hate_facebook
|
@@ -24,23 +24,23 @@ describe RestGraph do
|
|
24
24
|
rg.access_token == hate_facebook
|
25
25
|
end
|
26
26
|
|
27
|
-
|
27
|
+
should 'build correct headers' do
|
28
28
|
rg = RestGraph.new(:accept => 'text/html',
|
29
29
|
:lang => 'zh-tw')
|
30
30
|
rg.send(:build_headers).should == {'Accept' => 'text/html',
|
31
31
|
'Accept-Language' => 'zh-tw'}
|
32
32
|
end
|
33
33
|
|
34
|
-
|
34
|
+
should 'build empty query string' do
|
35
35
|
RestGraph.new.send(:build_query_string).should == ''
|
36
36
|
end
|
37
37
|
|
38
|
-
|
38
|
+
should 'create access_token in query string' do
|
39
39
|
RestGraph.new(:access_token => 'token').send(:build_query_string).
|
40
40
|
should == '?access_token=token'
|
41
41
|
end
|
42
42
|
|
43
|
-
|
43
|
+
should 'build correct query string' do
|
44
44
|
TestHelper.normalize_query(
|
45
45
|
RestGraph.new(:access_token => 'token').send(:build_query_string,
|
46
46
|
:message => 'hi!!')).
|
@@ -52,20 +52,21 @@ describe RestGraph do
|
|
52
52
|
should == '?message=hi%21%21&subject=%28%26oh%26%29'
|
53
53
|
end
|
54
54
|
|
55
|
-
|
55
|
+
should 'auto decode json' do
|
56
56
|
RestGraph.new(:auto_decode => true).send(:post_request, '[]').
|
57
57
|
should == []
|
58
58
|
end
|
59
59
|
|
60
|
-
|
60
|
+
should 'not auto decode json' do
|
61
61
|
RestGraph.new(:auto_decode => false).send(:post_request, '[]').
|
62
62
|
should == '[]'
|
63
63
|
end
|
64
64
|
|
65
|
-
|
65
|
+
should 'give better inspect string' do
|
66
66
|
RestGraph.new(:auto_decode => false).inspect.should =~ Regexp.new(
|
67
67
|
'#<struct RestGraph auto_decode=false,' \
|
68
68
|
' strict=false,' \
|
69
|
+
' timeout=10,' \
|
69
70
|
' graph_server="https://graph.facebook.com/",' \
|
70
71
|
' old_server="https://api.facebook.com/",' \
|
71
72
|
' accept="text/javascript",' \
|
@@ -74,7 +75,8 @@ describe RestGraph do
|
|
74
75
|
' secret=nil,' \
|
75
76
|
' data=\{\},' \
|
76
77
|
' cache=nil,' \
|
77
|
-
'
|
78
|
-
' log_handler=nil
|
78
|
+
' log_method=nil,' \
|
79
|
+
' log_handler=nil,' \
|
80
|
+
' error_handler=#<Proc:.+>>')
|
79
81
|
end
|
80
82
|
end
|
data/test/test_multi.rb
ADDED
@@ -0,0 +1,126 @@
|
|
1
|
+
|
2
|
+
if respond_to?(:require_relative, true)
|
3
|
+
require_relative 'common'
|
4
|
+
else
|
5
|
+
require File.dirname(__FILE__) + '/common'
|
6
|
+
end
|
7
|
+
|
8
|
+
require 'em-http-request'
|
9
|
+
load 'webmock/http_lib_adapters/em_http_request.rb'
|
10
|
+
|
11
|
+
describe 'RestGraph#multi' do
|
12
|
+
after do
|
13
|
+
WebMock.reset_webmock
|
14
|
+
RR.verify
|
15
|
+
end
|
16
|
+
|
17
|
+
should 'do multi query with em-http-request' do
|
18
|
+
url = 'https://graph.facebook.com/me'
|
19
|
+
stub_request(:get, url).to_return(:body => '{"data":"get"}')
|
20
|
+
stub_request(:put, url).to_return(:body => '{"data":"put"}')
|
21
|
+
rg = RestGraph.new
|
22
|
+
mock.proxy(rg).request_em(anything, anything)
|
23
|
+
EM.run{
|
24
|
+
rg.multi([[:get, 'me'], [:put, 'me']]){ |results|
|
25
|
+
results.should == [{'data' => 'get'}, {'data' => 'put'}]
|
26
|
+
EM.stop
|
27
|
+
}
|
28
|
+
}
|
29
|
+
end
|
30
|
+
|
31
|
+
should 'call aget, aput family with multi' do
|
32
|
+
url = 'https://graph.facebook.com/me'
|
33
|
+
%w[aget adelete apost aput].each{ |meth|
|
34
|
+
stub_request("#{meth[1..-1]}".to_sym, url).
|
35
|
+
to_return(:body => "{\"data\":\"#{meth}\"}")
|
36
|
+
rg = RestGraph.new
|
37
|
+
mock.proxy(rg).request_em(anything, anything)
|
38
|
+
EM.run{
|
39
|
+
rg.send(meth, 'me', {}){ |result|
|
40
|
+
result.should == {'data' => meth.to_s}
|
41
|
+
EM.stop
|
42
|
+
}
|
43
|
+
}
|
44
|
+
}
|
45
|
+
end
|
46
|
+
|
47
|
+
should 'for_pages' do
|
48
|
+
rg = RestGraph.new
|
49
|
+
|
50
|
+
args = [is_a(Hash), is_a(Array)]
|
51
|
+
mock.proxy(rg).request_em(*args) # at least one time
|
52
|
+
stub.proxy(rg).request_em(*args)
|
53
|
+
|
54
|
+
%w[next previous].each{ |type|
|
55
|
+
kind = "#{type}_page"
|
56
|
+
data = {'paging' => {type => 'http://z'}, 'data' => ['z']}
|
57
|
+
|
58
|
+
# invalid pages or just the page itself
|
59
|
+
# not really need network
|
60
|
+
nils = 0
|
61
|
+
ranges = -1..1
|
62
|
+
ranges.each{ |page|
|
63
|
+
rg.for_pages(data, page, {:async => true}, kind){ |r|
|
64
|
+
if r
|
65
|
+
r.should == data
|
66
|
+
else
|
67
|
+
nils += 1
|
68
|
+
end
|
69
|
+
}.should == data
|
70
|
+
}
|
71
|
+
nils.should == ranges.to_a.size
|
72
|
+
|
73
|
+
(2..4).each{ |pages|
|
74
|
+
# merge data
|
75
|
+
stub_request(:get, 'z').to_return(:body => '{"data":["y"]}')
|
76
|
+
expects = [{'data' => %w[y]}, nil]
|
77
|
+
|
78
|
+
EM.run{
|
79
|
+
rg.for_pages(data, pages, {:async => true}, kind){ |r|
|
80
|
+
r.should == expects.shift
|
81
|
+
EM.stop if expects.empty?
|
82
|
+
}
|
83
|
+
}
|
84
|
+
|
85
|
+
# this data cannot be merged
|
86
|
+
stub_request(:get, 'z').to_return(:body => '{"data":"y"}')
|
87
|
+
expects = [{'data' => 'y'}, nil]
|
88
|
+
|
89
|
+
EM.run{
|
90
|
+
rg.for_pages(data, pages, {:async => true}, kind){ |r|
|
91
|
+
r.should == expects.shift
|
92
|
+
EM.stop if expects.empty?
|
93
|
+
}
|
94
|
+
}
|
95
|
+
}
|
96
|
+
|
97
|
+
stub_request(:get, 'z').to_return(:body =>
|
98
|
+
'{"paging":{"'+type+'":"http://yyy"},"data":["y"]}')
|
99
|
+
stub_request(:get, 'yyy').to_return(:body => '{"data":["x"]}')
|
100
|
+
expects = [{'data' => %w[y]}, {'data' => %w[x]}, nil]
|
101
|
+
|
102
|
+
EM.run{
|
103
|
+
rg.for_pages(data, 3, {:async => true}, kind){ |rr|
|
104
|
+
rr.frozen?.should == true unless rr.nil? && RUBY_VERSION < '1.9.2'
|
105
|
+
if rr
|
106
|
+
r = rr.dup
|
107
|
+
r.delete('paging')
|
108
|
+
else
|
109
|
+
r = rr
|
110
|
+
end
|
111
|
+
r.should == expects.shift
|
112
|
+
EM.stop if expects.empty?
|
113
|
+
}
|
114
|
+
}
|
115
|
+
}
|
116
|
+
end
|
117
|
+
|
118
|
+
# should 'cache in multi' do
|
119
|
+
# end
|
120
|
+
#
|
121
|
+
# should 'logging' do
|
122
|
+
# end
|
123
|
+
#
|
124
|
+
# should 'error handler?' do
|
125
|
+
# end
|
126
|
+
end
|