koala 1.0.0 → 1.2.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.
Files changed (54) hide show
  1. data/.autotest +12 -0
  2. data/.gitignore +3 -1
  3. data/.travis.yml +9 -0
  4. data/CHANGELOG +62 -2
  5. data/Gemfile +8 -0
  6. data/Rakefile +0 -1
  7. data/autotest/discover.rb +1 -0
  8. data/koala.gemspec +13 -14
  9. data/lib/koala/batch_operation.rb +74 -0
  10. data/lib/koala/graph_api.rb +145 -132
  11. data/lib/koala/graph_batch_api.rb +97 -0
  12. data/lib/koala/graph_collection.rb +59 -0
  13. data/lib/koala/http_service.rb +176 -0
  14. data/lib/koala/oauth.rb +191 -0
  15. data/lib/koala/realtime_updates.rb +23 -29
  16. data/lib/koala/rest_api.rb +13 -8
  17. data/lib/koala/test_users.rb +33 -17
  18. data/lib/koala/uploadable_io.rb +153 -87
  19. data/lib/koala/utils.rb +11 -0
  20. data/lib/koala/version.rb +3 -0
  21. data/lib/koala.rb +59 -217
  22. data/readme.md +92 -53
  23. data/spec/cases/{api_base_spec.rb → api_spec.rb} +31 -6
  24. data/spec/cases/error_spec.rb +32 -0
  25. data/spec/cases/graph_and_rest_api_spec.rb +12 -21
  26. data/spec/cases/graph_api_batch_spec.rb +582 -0
  27. data/spec/cases/graph_api_spec.rb +11 -14
  28. data/spec/cases/graph_collection_spec.rb +116 -0
  29. data/spec/cases/http_service_spec.rb +446 -0
  30. data/spec/cases/koala_spec.rb +54 -0
  31. data/spec/cases/oauth_spec.rb +319 -213
  32. data/spec/cases/realtime_updates_spec.rb +45 -31
  33. data/spec/cases/rest_api_spec.rb +23 -7
  34. data/spec/cases/test_users_spec.rb +123 -75
  35. data/spec/cases/uploadable_io_spec.rb +120 -37
  36. data/spec/cases/utils_spec.rb +10 -0
  37. data/spec/fixtures/cat.m4v +0 -0
  38. data/spec/fixtures/facebook_data.yml +26 -24
  39. data/spec/fixtures/mock_facebook_responses.yml +203 -78
  40. data/spec/spec_helper.rb +30 -5
  41. data/spec/support/graph_api_shared_examples.rb +149 -118
  42. data/spec/support/json_testing_fix.rb +42 -0
  43. data/spec/support/koala_test.rb +187 -0
  44. data/spec/support/mock_http_service.rb +62 -58
  45. data/spec/support/ordered_hash.rb +205 -0
  46. data/spec/support/rest_api_shared_examples.rb +139 -15
  47. data/spec/support/uploadable_io_shared_examples.rb +2 -8
  48. metadata +90 -114
  49. data/lib/koala/http_services.rb +0 -146
  50. data/spec/cases/http_services/http_service_spec.rb +0 -54
  51. data/spec/cases/http_services/net_http_service_spec.rb +0 -350
  52. data/spec/cases/http_services/typhoeus_service_spec.rb +0 -144
  53. data/spec/support/live_testing_data_helper.rb +0 -40
  54. data/spec/support/setup_mocks_or_live.rb +0 -52
@@ -9,25 +9,45 @@ module Koala::MIME
9
9
  end
10
10
 
11
11
  describe "Koala::UploadableIO" do
12
+ def rails_3_mocks
13
+ tempfile = stub('Tempfile', :path => "foo")
14
+ uploaded_file = stub('ActionDispatch::Http::UploadedFile',
15
+ :content_type => true,
16
+ :tempfile => tempfile,
17
+ :original_filename => "bar"
18
+ )
19
+ tempfile.stub!(:respond_to?).with(:path).and_return(true)
20
+
21
+ [tempfile, uploaded_file]
22
+ end
23
+
24
+ def sinatra_mocks
25
+ {:type => "type", :tempfile => "Tempfile", :filename => "foo.bar"}
26
+ end
27
+
12
28
  describe "the constructor" do
13
29
  describe "when given a file path" do
14
30
  before(:each) do
15
- @koala_io_params = [File.open(BEACH_BALL_PATH)]
31
+ @path = BEACH_BALL_PATH
32
+ @koala_io_params = [@path]
16
33
  end
17
34
 
18
35
  describe "and a content type" do
19
36
  before :each do
20
- @koala_io_params.concat([stub("image/jpg")])
37
+ @stub_type = stub("image/jpg")
38
+ @koala_io_params.concat([@stub_type])
21
39
  end
22
40
 
23
- it "should return an UploadIO with the same file path" do
24
- stub_path = @koala_io_params[0] = "/stub/path/to/file"
25
- Koala::UploadableIO.new(*@koala_io_params).io_or_path.should == stub_path
41
+ it "returns an UploadIO with the same file path" do
42
+ Koala::UploadableIO.new(*@koala_io_params).io_or_path.should == @path
26
43
  end
27
44
 
28
- it "should return an UploadIO with the same content type" do
29
- stub_type = @koala_io_params[1] = stub('Content Type')
30
- Koala::UploadableIO.new(*@koala_io_params).content_type.should == stub_type
45
+ it "returns an UploadIO with the same content type" do
46
+ Koala::UploadableIO.new(*@koala_io_params).content_type.should == @stub_type
47
+ end
48
+
49
+ it "returns an UploadIO with the file's name" do
50
+ Koala::UploadableIO.new(*@koala_io_params).filename.should == File.basename(@path)
31
51
  end
32
52
  end
33
53
 
@@ -38,7 +58,8 @@ describe "Koala::UploadableIO" do
38
58
 
39
59
  describe "when given a File object" do
40
60
  before(:each) do
41
- @koala_io_params = [File.open(BEACH_BALL_PATH)]
61
+ @file = File.open(BEACH_BALL_PATH)
62
+ @koala_io_params = [@file]
42
63
  end
43
64
 
44
65
  describe "and a content type" do
@@ -46,14 +67,18 @@ describe "Koala::UploadableIO" do
46
67
  @koala_io_params.concat(["image/jpg"])
47
68
  end
48
69
 
49
- it "should return an UploadIO with the same io" do
70
+ it "returns an UploadIO with the same io" do
50
71
  Koala::UploadableIO.new(*@koala_io_params).io_or_path.should == @koala_io_params[0]
51
72
  end
52
73
 
53
- it "should return an UplaodIO with the same content_type" do
74
+ it "returns an UploadableIO with the same content_type" do
54
75
  content_stub = @koala_io_params[1] = stub('Content Type')
55
76
  Koala::UploadableIO.new(*@koala_io_params).content_type.should == content_stub
56
77
  end
78
+
79
+ it "returns an UploadableIO with the right filename" do
80
+ Koala::UploadableIO.new(*@koala_io_params).filename.should == File.basename(@file.path)
81
+ end
57
82
  end
58
83
 
59
84
  describe "and no content type" do
@@ -61,39 +86,70 @@ describe "Koala::UploadableIO" do
61
86
  end
62
87
  end
63
88
 
89
+ describe "when given an IO object" do
90
+ before(:each) do
91
+ @io = StringIO.open("abcdefgh")
92
+ @koala_io_params = [@io]
93
+ end
94
+
95
+ describe "and a content type" do
96
+ before :each do
97
+ @koala_io_params.concat(["image/jpg"])
98
+ end
99
+
100
+ it "returns an UploadableIO with the same io" do
101
+ Koala::UploadableIO.new(*@koala_io_params).io_or_path.should == @koala_io_params[0]
102
+ end
103
+
104
+ it "returns an UploadableIO with the same content_type" do
105
+ content_stub = @koala_io_params[1] = stub('Content Type')
106
+ Koala::UploadableIO.new(*@koala_io_params).content_type.should == content_stub
107
+ end
108
+ end
109
+
110
+ describe "and no content type" do
111
+ it "raises an exception" do
112
+ lambda { Koala::UploadableIO.new(*@koala_io_params) }.should raise_exception(Koala::KoalaError)
113
+ end
114
+ end
115
+ end
116
+
64
117
  describe "when given a Rails 3 ActionDispatch::Http::UploadedFile" do
65
118
  before(:each) do
66
- @tempfile = stub('Tempfile', :path => "foo")
67
- @uploaded_file = stub('ActionDispatch::Http::UploadedFile',
68
- :content_type => true,
69
- :tempfile => @tempfile
70
- )
119
+ @tempfile, @uploaded_file = rails_3_mocks
120
+ end
71
121
 
72
- @tempfile.stub!(:respond_to?).with(:path).and_return(true)
122
+ it "gets the path from the tempfile associated with the UploadedFile" do
123
+ expected_path = stub('Tempfile')
124
+ @tempfile.should_receive(:path).and_return(expected_path)
125
+ Koala::UploadableIO.new(@uploaded_file).io_or_path.should == expected_path
73
126
  end
74
127
 
75
- it "should get the content type via the content_type method" do
128
+ it "gets the content type via the content_type method" do
76
129
  expected_content_type = stub('Content Type')
77
130
  @uploaded_file.should_receive(:content_type).and_return(expected_content_type)
78
131
  Koala::UploadableIO.new(@uploaded_file).content_type.should == expected_content_type
79
132
  end
80
133
 
81
- it "should get the path from the tempfile associated with the UploadedFile" do
82
- expected_path = stub('Tempfile')
83
- @tempfile.should_receive(:path).and_return(expected_path)
84
- Koala::UploadableIO.new(@uploaded_file).io_or_path.should == expected_path
134
+ it "gets the filename from the UploadedFile" do
135
+ Koala::UploadableIO.new(@uploaded_file).filename.should == @uploaded_file.original_filename
85
136
  end
86
137
  end
87
138
 
88
139
  describe "when given a Sinatra file parameter hash" do
89
140
  before(:each) do
90
- @file_hash = {
91
- :type => "type",
92
- :tempfile => "Tempfile"
93
- }
141
+ @file_hash = sinatra_mocks
94
142
  end
95
143
 
96
- it "should get the content type from the :type key" do
144
+ it "gets the io_or_path from the :tempfile key" do
145
+ expected_file = stub('File')
146
+ @file_hash[:tempfile] = expected_file
147
+
148
+ uploadable = Koala::UploadableIO.new(@file_hash)
149
+ uploadable.io_or_path.should == expected_file
150
+ end
151
+
152
+ it "gets the content type from the :type key" do
97
153
  expected_content_type = stub('Content Type')
98
154
  @file_hash[:type] = expected_content_type
99
155
 
@@ -101,12 +157,9 @@ describe "Koala::UploadableIO" do
101
157
  uploadable.content_type.should == expected_content_type
102
158
  end
103
159
 
104
- it "should get the io_or_path from the :tempfile key" do
105
- expected_file = stub('File')
106
- @file_hash[:tempfile] = expected_file
107
-
160
+ it "gets the content type from the :type key" do
108
161
  uploadable = Koala::UploadableIO.new(@file_hash)
109
- uploadable.io_or_path.should == expected_file
162
+ uploadable.filename.should == @file_hash[:filename]
110
163
  end
111
164
  end
112
165
 
@@ -130,14 +183,24 @@ describe "Koala::UploadableIO" do
130
183
  UploadIO.stub!(:new).with(anything, anything, anything).and_return(@upload_io)
131
184
  end
132
185
 
133
- it "should call the constructor with the content type, file name, and a dummy file name" do
134
- UploadIO.should_receive(:new).with(BEACH_BALL_PATH, "content/type", anything).and_return(@upload_io)
135
- Koala::UploadableIO.new(BEACH_BALL_PATH, "content/type").to_upload_io.should == @upload_io
186
+ context "if no filename was provided" do
187
+ it "should call the constructor with the content type, file name, and a dummy file name" do
188
+ UploadIO.should_receive(:new).with(BEACH_BALL_PATH, "content/type", anything).and_return(@upload_io)
189
+ Koala::UploadableIO.new(BEACH_BALL_PATH, "content/type").to_upload_io.should == @upload_io
190
+ end
191
+ end
192
+
193
+ context "if a filename was provided" do
194
+ it "should call the constructor with the content type, file name, and the filename" do
195
+ filename = "file"
196
+ UploadIO.should_receive(:new).with(BEACH_BALL_PATH, "content/type", filename).and_return(@upload_io)
197
+ Koala::UploadableIO.new(BEACH_BALL_PATH, "content/type", filename).to_upload_io
198
+ end
136
199
  end
137
200
  end
138
201
 
139
202
  describe "getting a file" do
140
- it "should return the File if initialized with a file" do
203
+ it "returns the File if initialized with a file" do
141
204
  f = File.new(BEACH_BALL_PATH)
142
205
  Koala::UploadableIO.new(f).to_file.should == f
143
206
  end
@@ -148,4 +211,24 @@ describe "Koala::UploadableIO" do
148
211
  Koala::UploadableIO.new(BEACH_BALL_PATH).to_file.should == result
149
212
  end
150
213
  end
151
- end # describe UploadableIO
214
+
215
+ describe "#binary_content?" do
216
+ it "returns true for Rails 3 file uploads" do
217
+ Koala::UploadableIO.binary_content?(rails_3_mocks.last).should be_true
218
+ end
219
+
220
+ it "returns true for Sinatra file uploads" do
221
+ Koala::UploadableIO.binary_content?(rails_3_mocks.last).should be_true
222
+ end
223
+
224
+ it "returns true for File objects" do
225
+ Koala::UploadableIO.binary_content?(File.open(BEACH_BALL_PATH)).should be_true
226
+ end
227
+
228
+ it "returns false for everything else" do
229
+ Koala::UploadableIO.binary_content?(StringIO.new).should be_false
230
+ Koala::UploadableIO.binary_content?(BEACH_BALL_PATH).should be_false
231
+ Koala::UploadableIO.binary_content?(nil).should be_false
232
+ end
233
+ end
234
+ end # describe UploadableIO
@@ -0,0 +1,10 @@
1
+ require 'spec_helper'
2
+
3
+ describe Koala::Utils do
4
+ it "has a deprecate method" do
5
+ Koala::Utils.should respond_to(:deprecate)
6
+ end
7
+
8
+ # AFAIK there's no way to test that (Kernel.)warn receives the text
9
+ # Kernel.should_receive(:warn) doesn't seem to work, even though the text gets printed
10
+ end
Binary file
@@ -1,23 +1,24 @@
1
- # Check out http://oauth.twoalex.com/ to easily generate tokens, cookies, etc.
2
- # Those values will work with the default settings in this yaml.
1
+ # Testing data
2
+
3
+ # IMPORTANT NOTE: live tests will run against a test users automatically
4
+ # If you want to run them against a real user or test users on a different account, you can
5
+ # by enter an OAuth token, code, and session_key (for real users) or changing the app_id and secret (for test users)
6
+ # (note for real users: this will leave some photos and videos posted to your wall, since they can't be deleted through the API)
7
+
8
+ # These values are configured to work with the OAuth Playground app by default
3
9
  # Of course, you can change this to work with your own app.
4
- # Just remember to update all fields!
5
-
6
- # You must supply this value yourself to test the GraphAPI class.
7
- # Your OAuth token should have publish_stream, read_stream, and user_photos permissions.
8
- oauth_token:
10
+ # Check out http://oauth.twoalex.com/ to easily generate tokens, cookies, etc.
9
11
 
10
- # for testing the OAuth class
12
+ # Your OAuth token should have the read_stream, publish_stream, user_photos, user_videos, and read_insights permissions.
13
+ oauth_token:
14
+
15
+ # for testing the OAuth class
11
16
  # baseline app
12
- oauth_test_data:
13
- # You must supply this value yourself, since they will expire.
14
- code:
15
- # easiest way to get session keys: use multiple test accounts with the Javascript login at http://oauth.twoalex.com
16
- session_key:
17
- multiple_session_keys:
18
- -
19
- -
20
-
17
+ oauth_test_data:
18
+ # the following two values are not needed for most of the test suite, but the relevant tests will not run if they're not present
19
+ code:
20
+ session_key:
21
+
21
22
  # These values will work out of the box
22
23
  app_id: 119908831367602
23
24
  secret: e45e55a333eec232d4206d2703de1307
@@ -25,15 +26,16 @@ oauth_test_data:
25
26
  app_access_token: 119908831367602|o3wswWQ88LYjEC9-ukR_gjRIOMw.
26
27
  raw_token_string: "access_token=119908831367602|2.6GneoQbnEqtSiPppZzDU4Q__.3600.1273366800-2905623|3OLa3w0x1K4C1S5cOgbs07TytAk.&expires=6621"
27
28
  raw_offline_access_token_string: access_token=119908831367602|2.6GneoQbnEqtSiPppZzDU4Q__.3600.1273366800-2905623|3OLa3w0x1K4C1S5cOgbs07TytAk.
28
- valid_cookies:
29
+ valid_cookies:
29
30
  # note: the tests stub the time class so these default cookies are always valid (if you're using the default app)
30
31
  # if not you may want to remove the stubbing to test expiration
31
32
  fbs_119908831367602: '"access_token=119908831367602|2.LKE7ksSPOx0V_8mHPr2NHQ__.3600.1273363200-2905623|CMpi0AYbn03Oukzv94AUha2qbO4.&expires=1273363200&secret=lT_9zm5r5IbJ6Aa5O54nFw__&session_key=2.LKE7ksSPOx0V_8mHPr2NHQ__.3600.1273363200-2905623&sig=9515e93113921f9476a4efbdd4a3c746&uid=2905623"'
32
- expired_cookies:
33
- fbs_119908831367602: '"access_token=119908831367602|2.xv9mi6QSOpr474s4n2X_pw__.3600.1273287600-2905623|yVt5WH_S6J5p3gFa5_5lBzckhws.&expires=1273287600&secret=V_E79ovQnXqxGctFuC_n5A__&session_key=2.xv9mi6QSOpr474s4n2X_pw__.3600.1273287600-2905623&sig=eeef60838c0c800258d89b7e6ddddddb&uid=2905623"'
34
- offline_access_cookies:
33
+ offline_access_cookies:
35
34
  # note: I've revoked the offline access for security reasons, so you can't make calls against this :)
36
35
  fbs_119908831367602: '"access_token=119908831367602|08170230801eb225068e7a70-2905623|Q3LDCYYF8CX9cstxnZLsxiR0nwg.&expires=0&secret=78abaee300b392e275072a9f2727d436&session_key=08170230801eb225068e7a70-2905623&sig=423b8aa4b6fa1f9a571955f8e929d567&uid=2905623"'
36
+ valid_signed_cookies:
37
+ "fbsr_119908831367602": "f1--LHwjHVCxfs97hRHL-4cF-0jNxZRc6MGzo1qHLb0.eyJhbGdvcml0aG0iOiJITUFDLVNIQTI1NiIsImNvZGUiOiIyLkFRQm90a0pBWlhVY1l3RkMuMzYwMC4xMzE0ODEzNjAwLjEtMjkwNTYyM3x4V2xya0d0UmJIZlpIclRnVWwxQmxJcVhRbjQiLCJpc3N1ZWRfYXQiOjEzMTQ4MDY2NTUsInVzZXJfaWQiOiIyOTA1NjIzIn0"
38
+
37
39
 
38
40
  # These values from the OAuth Playground (see above) will work out of the box
39
41
  # You can update this to live data if desired
@@ -44,17 +46,17 @@ oauth_test_data:
44
46
  algorithm: HMAC-SHA256
45
47
  user_id: "2905623"
46
48
  oauth_token: 119908831367602|2.zVF_6NrMELHuJa4gIU9tKw__.3600.1301922000-2905623|zgqPsr2BG9LoOK9kekGgRURZx0k
47
- user:
49
+ user:
48
50
  country: de
49
51
  locale: de_DE
50
- age:
52
+ age:
51
53
  min: 21
52
54
  issued_at: 1301917299
53
55
 
54
56
  subscription_test_data:
55
57
  subscription_path: http://oauth.twoalex.com/subscriptions
56
58
  verify_token: "myverificationtoken|1f54545d5f722733e17faae15377928f"
57
- challenge_data:
59
+ challenge_data:
58
60
  "hub.challenge": "1290024882"
59
61
  "hub.verify_token": "myverificationtoken|1f54545d5f722733e17faae15377928f"
60
62
  "hub.mode": "subscribe"