vibedeck-youtube_it 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (37) hide show
  1. data/README.rdoc +234 -0
  2. data/Rakefile +35 -0
  3. data/lib/youtube_it/chain_io.rb +76 -0
  4. data/lib/youtube_it/client.rb +367 -0
  5. data/lib/youtube_it/middleware/faraday_authheader.rb +24 -0
  6. data/lib/youtube_it/middleware/faraday_oauth.rb +21 -0
  7. data/lib/youtube_it/middleware/faraday_youtubeit.rb +30 -0
  8. data/lib/youtube_it/model/author.rb +13 -0
  9. data/lib/youtube_it/model/category.rb +11 -0
  10. data/lib/youtube_it/model/comment.rb +16 -0
  11. data/lib/youtube_it/model/contact.rb +16 -0
  12. data/lib/youtube_it/model/content.rb +18 -0
  13. data/lib/youtube_it/model/playlist.rb +11 -0
  14. data/lib/youtube_it/model/rating.rb +23 -0
  15. data/lib/youtube_it/model/subscription.rb +7 -0
  16. data/lib/youtube_it/model/thumbnail.rb +17 -0
  17. data/lib/youtube_it/model/user.rb +26 -0
  18. data/lib/youtube_it/model/video.rb +225 -0
  19. data/lib/youtube_it/parser.rb +357 -0
  20. data/lib/youtube_it/record.rb +12 -0
  21. data/lib/youtube_it/request/base_search.rb +72 -0
  22. data/lib/youtube_it/request/error.rb +15 -0
  23. data/lib/youtube_it/request/standard_search.rb +43 -0
  24. data/lib/youtube_it/request/user_search.rb +47 -0
  25. data/lib/youtube_it/request/video_search.rb +102 -0
  26. data/lib/youtube_it/request/video_upload.rb +415 -0
  27. data/lib/youtube_it/response/video_search.rb +41 -0
  28. data/lib/youtube_it/version.rb +4 -0
  29. data/lib/youtube_it.rb +75 -0
  30. data/test/helper.rb +10 -0
  31. data/test/test_chain_io.rb +63 -0
  32. data/test/test_client.rb +418 -0
  33. data/test/test_field_search.rb +48 -0
  34. data/test/test_video.rb +43 -0
  35. data/test/test_video_feed_parser.rb +271 -0
  36. data/test/test_video_search.rb +141 -0
  37. metadata +150 -0
data/lib/youtube_it.rb ADDED
@@ -0,0 +1,75 @@
1
+ require 'logger'
2
+ require 'open-uri'
3
+ require 'net/https'
4
+ require 'digest/md5'
5
+ require 'rexml/document'
6
+ require 'builder'
7
+ require 'oauth'
8
+ require 'faraday'
9
+
10
+ class YouTubeIt
11
+
12
+ # Base error class for the extension
13
+ class Error < RuntimeError
14
+ end
15
+
16
+ # URL-escape a string. Stolen from Camping (wonder how many Ruby libs in the wild can say the same)
17
+ def self.esc(s) #:nodoc:
18
+ s.to_s.gsub(/[^ \w.-]+/n){'%'+($&.unpack('H2'*$&.size)*'%').upcase}.tr(' ', '+')
19
+ end
20
+
21
+ # Set the logger for the library
22
+ def self.logger=(any_logger)
23
+ @logger = any_logger
24
+ end
25
+
26
+ # Get the logger for the library (by default will log to STDOUT). TODO: this is where we grab the Rails logger too
27
+ def self.logger
28
+ @logger ||= create_default_logger
29
+ end
30
+
31
+ # Gets mixed into the classes to provide the logger method
32
+ module Logging #:nodoc:
33
+
34
+ # Return the base logger set for the library
35
+ def logger
36
+ YouTubeIt.logger
37
+ end
38
+ end
39
+
40
+ private
41
+ def self.create_default_logger
42
+ logger = Logger.new(STDOUT)
43
+ logger.level = Logger::DEBUG
44
+ logger
45
+ end
46
+ end
47
+
48
+ %w(
49
+ version
50
+ client
51
+ record
52
+ parser
53
+ model/author
54
+ model/category
55
+ model/comment
56
+ model/contact
57
+ model/content
58
+ model/playlist
59
+ model/rating
60
+ model/subscription
61
+ model/thumbnail
62
+ model/user
63
+ model/video
64
+ request/base_search
65
+ request/error
66
+ request/user_search
67
+ request/standard_search
68
+ request/video_upload
69
+ request/video_search
70
+ response/video_search
71
+ middleware/faraday_authheader.rb
72
+ middleware/faraday_oauth.rb
73
+ middleware/faraday_youtubeit.rb
74
+ chain_io
75
+ ).each{|m| require File.dirname(__FILE__) + '/youtube_it/' + m }
data/test/helper.rb ADDED
@@ -0,0 +1,10 @@
1
+ require 'rubygems'
2
+ require 'date'
3
+ require 'test/unit'
4
+ require 'pp'
5
+ require 'open-uri'
6
+ require 'nokogiri'
7
+ require File.dirname(__FILE__) + '/../lib/youtube_it'
8
+
9
+ YouTubeIt.logger.level = Logger::ERROR
10
+
@@ -0,0 +1,63 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/helper')
2
+
3
+ class TestChainIO < Test::Unit::TestCase
4
+ def setup
5
+ @klass = YouTubeIt::ChainIO # save typing
6
+ end
7
+
8
+ def test_should_support_read_from_one_io
9
+ io = @klass.new "abcd"
10
+ assert io.respond_to?(:read)
11
+ assert_equal "ab", io.read(2)
12
+ assert_equal "cd", io.read(2)
13
+ assert_equal false, io.read(2)
14
+ end
15
+
16
+ def test_should_skip_over_depleted_streams
17
+ io = @klass.new '', '', '', '', 'ab'
18
+ assert_equal 'ab', io.read(2)
19
+ end
20
+
21
+ def test_should_read_across_nultiple_streams_with_large_offset
22
+ io = @klass.new 'abc', '', 'def', '', 'ghij'
23
+ assert_equal 'abcdefgh', io.read(8)
24
+ end
25
+
26
+ def test_should_return_false_for_empty_items
27
+ io = @klass.new '', '', '', '', ''
28
+ assert_equal false, io.read(8)
29
+ end
30
+
31
+ def test_should_support_overzealous_read
32
+ io = @klass.new "ab"
33
+ assert_equal "ab", io.read(5000)
34
+ end
35
+
36
+ def test_should_predict_expected_length
37
+ io = @klass.new "ab", "cde"
38
+ assert_equal 5, io.expected_length
39
+ end
40
+
41
+ def test_should_predict_expected_length_with_prepositioned_io
42
+ first_buf = StringIO.new("ab")
43
+ first_buf.read(1)
44
+
45
+ io = @klass.new first_buf, "cde"
46
+ assert_equal 4, io.expected_length
47
+ end
48
+
49
+ def test_should_predict_expected_length_with_file_handle
50
+ test_size = File.size(__FILE__)
51
+ first_buf = StringIO.new("ab")
52
+ first_buf.read(1)
53
+
54
+ io = @klass.new File.open(__FILE__), first_buf
55
+ assert_equal test_size + 1, io.expected_length
56
+ end
57
+
58
+ def test_greedy
59
+ io = YouTubeIt::GreedyChainIO.new("a" * (1024 * 513))
60
+ chunk = io.read(123)
61
+ assert_equal 1024 * 512, chunk.length, "Should have read the first 512 KB chunk at once instead"
62
+ end
63
+ end
@@ -0,0 +1,418 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/helper')
2
+
3
+ class TestClient < Test::Unit::TestCase
4
+
5
+ OPTIONS = {:title => "test title",
6
+ :description => "test description",
7
+ :category => 'People',
8
+ :keywords => %w[test]}
9
+ ACCOUNT = {:user => "tubeit20101", :passwd => "youtube_it", :dev_key => "AI39si411VBmO4Im9l0rfRsORXDI6F5AX5NlTIA4uHSWqa-Cgf-jUQG-6osUBB3PTLawLHlkKXPLr3B0pNcGU9wkNd11gIgdPg" }
10
+ RAILS_ENV = "test"
11
+
12
+ def setup
13
+ #clientlogin
14
+ @client = YouTubeIt::Client.new(:username => ACCOUNT[:user], :password => ACCOUNT[:passwd] , :dev_key => ACCOUNT[:dev_key])
15
+ #authsub
16
+ #@client = YouTubeIt::AuthSubClient.new(:token => "1/vqYlJytmn4eWRjJnORHT94mENNfZzZsLutMOrvvygB4" , :dev_key => ACCOUNT[:dev_key])
17
+ end
18
+
19
+ def test_should_respond_to_a_basic_query
20
+ response = @client.videos_by(:query => "penguin")
21
+
22
+ assert_equal "tag:youtube.com,2008:videos", response.feed_id
23
+ assert_equal 25, response.max_result_count
24
+ assert_equal 25, response.videos.length
25
+ assert_equal 1, response.offset
26
+ assert(response.total_result_count > 100)
27
+ assert_instance_of Time, response.updated_at
28
+
29
+ response.videos.each { |v| assert_valid_video v }
30
+ end
31
+
32
+ def test_should_respond_to_a_basic_query_with_offset_and_max_results
33
+ response = @client.videos_by(:query => "penguin", :offset => 15, :max_results => 30)
34
+
35
+ assert_equal "tag:youtube.com,2008:videos", response.feed_id
36
+ assert_equal 30, response.max_result_count
37
+ assert_equal 30, response.videos.length
38
+ assert_equal 15, response.offset
39
+ assert(response.total_result_count > 100)
40
+ assert_instance_of Time, response.updated_at
41
+
42
+ response.videos.each { |v| assert_valid_video v }
43
+ end
44
+
45
+ def test_should_respond_to_a_basic_query_with_paging
46
+ response = @client.videos_by(:query => "penguin")
47
+ assert_equal "tag:youtube.com,2008:videos", response.feed_id
48
+ assert_equal 25, response.max_result_count
49
+ assert_equal 1, response.offset
50
+
51
+ response = @client.videos_by(:query => "penguin", :page => 2)
52
+ assert_equal "tag:youtube.com,2008:videos", response.feed_id
53
+ assert_equal 25, response.max_result_count
54
+ assert_equal 26, response.offset
55
+
56
+ response2 = @client.videos_by(:query => "penguin", :page => 3)
57
+ assert_equal "tag:youtube.com,2008:videos", response2.feed_id
58
+ assert_equal 25, response2.max_result_count
59
+ assert_equal 51, response2.offset
60
+ end
61
+
62
+ def test_should_get_videos_for_multiword_metasearch_query
63
+ response = @client.videos_by(:query => 'christina ricci')
64
+
65
+ assert_equal "tag:youtube.com,2008:videos", response.feed_id
66
+ assert_equal 25, response.max_result_count
67
+ assert_equal 25, response.videos.length
68
+ assert_equal 1, response.offset
69
+ assert(response.total_result_count > 100)
70
+ assert_instance_of Time, response.updated_at
71
+
72
+ response.videos.each { |v| assert_valid_video v }
73
+ end
74
+
75
+ def test_should_handle_video_not_yet_viewed
76
+ response = @client.videos_by(:query => "CE62FSEoY28")
77
+
78
+ assert_equal 1, response.videos.length
79
+ response.videos.each { |v| assert_valid_video v }
80
+ end
81
+
82
+ def test_should_get_videos_for_one_tag
83
+ response = @client.videos_by(:tags => ['panther'])
84
+ response.videos.each { |v| assert_valid_video v }
85
+ end
86
+
87
+ def test_should_get_videos_for_multiple_tags
88
+ response = @client.videos_by(:tags => ['tiger', 'leopard'])
89
+ response.videos.each { |v| assert_valid_video v }
90
+ end
91
+
92
+ def test_should_get_videos_for_one_category
93
+ response = @client.videos_by(:categories => [:news])
94
+ response.videos.each { |v| assert_valid_video v }
95
+ end
96
+
97
+ def test_should_get_videos_for_multiple_categories
98
+ response = @client.videos_by(:categories => [:news, :sports])
99
+ response.videos.each { |v| assert_valid_video v }
100
+ end
101
+
102
+ # TODO: Need to do more specific checking in these tests
103
+ # Currently, if a URL is valid, and videos are found, the test passes regardless of search criteria
104
+ def test_should_get_videos_for_categories_and_tags
105
+ response = @client.videos_by(:categories => [:news, :sports], :tags => ['soccer', 'football'])
106
+ response.videos.each { |v| assert_valid_video v }
107
+ end
108
+
109
+ def test_should_get_most_viewed_videos
110
+ response = @client.videos_by(:most_viewed)
111
+ response.videos.each { |v| assert_valid_video v }
112
+ end
113
+
114
+ def test_should_get_top_rated_videos_for_today
115
+ response = @client.videos_by(:top_rated, :time => :today)
116
+ response.videos.each { |v| assert_valid_video v }
117
+ end
118
+
119
+ def test_should_get_videos_for_categories_and_tags_with_category_boolean_operators
120
+ response = @client.videos_by(:categories => { :either => [:news, :sports], :exclude => [:comedy] },
121
+ :tags => { :include => ['football'], :exclude => ['soccer'] })
122
+ response.videos.each { |v| assert_valid_video v }
123
+ end
124
+
125
+ def test_should_get_videos_for_categories_and_tags_with_tag_boolean_operators
126
+ response = @client.videos_by(:categories => { :either => [:news, :sports], :exclude => [:comedy] },
127
+ :tags => { :either => ['football', 'soccer', 'polo'] })
128
+ response.videos.each { |v| assert_valid_video v }
129
+ end
130
+
131
+ def test_should_get_videos_by_user
132
+ response = @client.videos_by(:user => 'liz')
133
+ response.videos.each { |v| assert_valid_video v }
134
+ end
135
+
136
+ def test_should_get_videos_by_user_with_pagination_and_ordering
137
+ response = @client.videos_by(:user => 'liz', :page => 2, :per_page => '2', :order_by => 'published')
138
+ response.videos.each { |v| assert_valid_video v }
139
+ assert_equal 3, response.offset
140
+ assert_equal 2, response.max_result_count
141
+ end
142
+
143
+
144
+ def test_should_get_favorite_videos_by_user
145
+ response = @client.videos_by(:favorites, :user => 'drnicwilliams')
146
+ assert_equal "tag:youtube.com,2008:user:drnicwilliams:favorites", response.feed_id
147
+ assert_valid_video response.videos.first
148
+ end
149
+
150
+ def test_should_get_videos_for_query_search_with_categories_excluded
151
+ video = @client.video_by("EkF4JD2rO3Q")
152
+ assert_equal "<object width=\"425\" height=\"350\">\n <param name=\"movie\" value=\"http://www.youtube.com/v/EkF4JD2rO3Q&feature=youtube_gdata_player\"></param>\n <param name=\"wmode\" value=\"transparent\"></param>\n <embed src=\"http://www.youtube.com/v/EkF4JD2rO3Q&feature=youtube_gdata_player\" type=\"application/x-shockwave-flash\"\n wmode=\"transparent\" width=\"425\" height=\"350\"></embed>\n</object>\n", video.embed_html
153
+ assert_valid_video video
154
+ end
155
+
156
+ def test_should_get_video_from_user
157
+ video = @client.video_by_user("chebyte","FQK1URcxmb4")
158
+ assert_equal "<object width=\"425\" height=\"350\">\n <param name=\"movie\" value=\"http://www.youtube.com/v/FQK1URcxmb4&feature=youtube_gdata_player\"></param>\n <param name=\"wmode\" value=\"transparent\"></param>\n <embed src=\"http://www.youtube.com/v/FQK1URcxmb4&feature=youtube_gdata_player\" type=\"application/x-shockwave-flash\"\n wmode=\"transparent\" width=\"425\" height=\"350\"></embed>\n</object>\n", video.embed_html
159
+ assert_valid_video video
160
+ end
161
+
162
+ def test_should_always_return_a_logger
163
+ @client = YouTubeIt::Client.new
164
+ assert_not_nil @client.logger
165
+ end
166
+
167
+ def test_should_not_bail_if_debug_is_true
168
+ assert_nothing_raised { YouTubeIt::Client.new(:debug => true) }
169
+ end
170
+
171
+ def test_should_determine_if_embeddable_video_is_embeddable
172
+ response = @client.videos_by(:query => "strongbad")
173
+
174
+ video = response.videos.first
175
+ assert video.embeddable?
176
+ end
177
+
178
+ def test_should_retrieve_video_by_id
179
+ video = @client.video_by("http://gdata.youtube.com/feeds/videos/EkF4JD2rO3Q")
180
+ assert_valid_video video
181
+
182
+ video = @client.video_by("EkF4JD2rO3Q")
183
+ assert_valid_video video
184
+ end
185
+
186
+ def test_return_upload_info_for_upload_from_browser
187
+ response = @client.upload_token(OPTIONS)
188
+ assert response.kind_of?(Hash)
189
+ assert_equal response.size, 2
190
+ response.each do |k,v|
191
+ assert v
192
+ end
193
+ end
194
+
195
+ def test_should_upload_a_video
196
+ video = @client.video_upload(File.open("test/test.mov"), OPTIONS)
197
+ assert_valid_video video
198
+ @client.video_delete(video.unique_id)
199
+ end
200
+
201
+ def test_should_update_a_video
202
+ OPTIONS[:title] = "title changed"
203
+ video = @client.video_upload(File.open("test/test.mov"), OPTIONS)
204
+ updated_video = @client.video_update(video.unique_id, OPTIONS)
205
+ assert updated_video.title == "title changed"
206
+ @client.video_delete(video.unique_id)
207
+ end
208
+
209
+ def test_should_delete_video
210
+ video = @client.video_upload(File.open("test/test.mov"), OPTIONS)
211
+ assert_valid_video video
212
+ assert @client.video_delete(video.unique_id)
213
+ end
214
+
215
+ def test_should_denied_comments
216
+ video = @client.video_upload(File.open("test/test.mov"), OPTIONS.merge(:comment => "denied"))
217
+ assert_valid_video video
218
+ doc = Nokogiri::HTML(open("http://www.youtube.com/watch?v=#{video.unique_id}"))
219
+ doc.css('.comments-disabled-message').each{|tag| assert (tag.content.strip == "Adding comments has been disabled for this video.")}
220
+ @client.video_delete(video.unique_id)
221
+ end
222
+
223
+ def test_should_denied_rate
224
+ video = @client.video_upload(File.open("test/test.mov"), OPTIONS.merge(:rate => "denied"))
225
+ assert_valid_video video
226
+ doc = Nokogiri::HTML(open("http://www.youtube.com/watch?v=#{video.unique_id}"))
227
+ doc.css('#watch-like').each{|tag|; assert (tag.attributes["title"].to_s == "Ratings have been disabled for this video.")}
228
+ @client.video_delete(video.unique_id)
229
+ end
230
+
231
+ def test_should_denied_embed
232
+ video = @client.video_upload(File.open("test/test.mov"), OPTIONS.merge(:embed => "denied"))
233
+ assert video.noembed
234
+ @client.video_delete(video.unique_id)
235
+ end
236
+
237
+
238
+ def test_should_add_new_comment
239
+ video = @client.video_upload(File.open("test/test.mov"), OPTIONS)
240
+ @client.add_comment(video.unique_id, "test comment")
241
+ comment = @client.comments(video.unique_id).first.content
242
+ assert comment.match(/test comment/)
243
+ @client.video_delete(video.unique_id)
244
+ end
245
+
246
+ def test_should_add_and_delete_video_from_playlist
247
+ playlist = @client.add_playlist(:title => "youtube_it test!", :description => "test playlist")
248
+ video = @client.add_video_to_playlist(playlist.playlist_id,"iKqJ8z1DPrQ")
249
+ assert_equal video[:code].to_i, 201
250
+ assert @client.delete_video_from_playlist(playlist.playlist_id, video[:playlist_entry_id])
251
+ assert @client.delete_playlist(playlist.playlist_id)
252
+ end
253
+
254
+ def test_should_add_and_delete_new_playlist
255
+ result = @client.add_playlist(:title => "youtube_it test4!", :description => "test playlist")
256
+ assert result.title, "youtube_it test!"
257
+ sleep 4
258
+ assert @client.delete_playlist(result.playlist_id)
259
+ end
260
+
261
+ def test_should_update_playlist
262
+ playlist = @client.add_playlist(:title => "youtube_it test!", :description => "test playlist")
263
+ playlist_updated = @client.update_playlist(playlist.playlist_id, :title => "title changed")
264
+ assert_equal playlist_updated.title, "title changed"
265
+ assert @client.delete_playlist(playlist.playlist_id)
266
+ end
267
+
268
+ def test_should_list_playlist_for_user
269
+ result = @client.playlists('chebyte')
270
+ assert result.last.title, "rock"
271
+ end
272
+
273
+ def test_should_determine_if_widescreen_video_is_widescreen
274
+ widescreen_id = 'QqQVll-MP3I'
275
+
276
+ video = @client.video_by(widescreen_id)
277
+ assert video.widescreen?
278
+ end
279
+
280
+ def test_get_current_user
281
+ assert_equal @client.current_user, 'tubeit20101'
282
+ end
283
+
284
+ def test_should_get_my_videos
285
+ video = @client.video_upload(File.open("test/test.mov"), OPTIONS)
286
+ assert_valid_video video
287
+ result = @client.my_videos
288
+ assert_equal result.videos.first.unique_id, video.unique_id
289
+ @client.video_delete(video.unique_id)
290
+ end
291
+
292
+ def test_should_get_my_video
293
+ video = @client.video_upload(File.open("test/test.mov"), OPTIONS)
294
+ assert_valid_video video
295
+ result = @client.my_video(video.unique_id)
296
+ assert_equal result.unique_id, video.unique_id
297
+ @client.video_delete(video.unique_id)
298
+ end
299
+
300
+ def test_should_add_like_to_video
301
+ r = @client.like_video("CE62FSEoY28")
302
+ assert_equal r[:code], 201
303
+ @client.dislike_video("CE62FSEoY28")
304
+ end
305
+
306
+ def test_should_dislike_to_video
307
+ @client.like_video("CE62FSEoY28")
308
+ r = @client.dislike_video("CE62FSEoY28")
309
+ assert_equal r[:code], 201
310
+ end
311
+
312
+
313
+ def test_should_subscribe_to_channel
314
+ r = @client.subscribe_channel("TheWoWArthas")
315
+ assert_equal r[:code], 201
316
+ assert_equal @client.subscriptions.first.title, "Videos published by : TheWoWArthas"
317
+ @client.unsubscribe_channel(@client.subscriptions.first.id)
318
+ end
319
+
320
+ def test_should_unsubscribe_to_channel
321
+ @client.subscribe_channel("TheWoWArthas")
322
+ r = @client.unsubscribe_channel(@client.subscriptions.first.id)
323
+ assert_equal r[:code], 200
324
+ end
325
+
326
+ def test_should_list_subscriptions
327
+ @client.subscribe_channel("TheWoWArthas")
328
+ assert @client.subscriptions.count == 1
329
+ assert_equal @client.subscriptions.first.title, "Videos published by : TheWoWArthas"
330
+ @client.unsubscribe_channel(@client.subscriptions.first.id)
331
+ end
332
+
333
+ def test_should_get_profile
334
+ profile = @client.profile
335
+ assert_equal profile.username, "tubeit20101"
336
+ end
337
+
338
+ def test_should_add_and_delete_video_to_favorite
339
+ video_id ="j5raG94IGCc"
340
+ result = @client.add_favorite(video_id)
341
+ assert_equal result[:code], 201
342
+ sleep 4
343
+ assert @client.delete_favorite(video_id)
344
+ end
345
+
346
+ private
347
+
348
+ def assert_valid_video (video)
349
+ # check general attributes
350
+ assert_instance_of YouTubeIt::Model::Video, video
351
+ assert_instance_of Fixnum, video.duration
352
+ assert_instance_of String, video.html_content if video.html_content
353
+
354
+ # validate media content records
355
+ video.media_content.each do |media_content|
356
+ assert_valid_url media_content.url
357
+ assert_instance_of YouTubeIt::Model::Video::Format, media_content.format
358
+ assert_instance_of String, media_content.mime_type
359
+ assert_match(/^[^\/]+\/[^\/]+$/, media_content.mime_type)
360
+ end
361
+
362
+ default_content = video.default_media_content
363
+ if default_content
364
+ assert_instance_of YouTubeIt::Model::Content, default_content
365
+ assert default_content.is_default?
366
+ end
367
+
368
+ # validate keywords
369
+ video.keywords.each { |kw| assert_instance_of(String, kw) }
370
+
371
+ # http://www.youtube.com/watch?v=IHVaXG1thXM
372
+ assert_valid_url video.player_url
373
+ assert_instance_of Time, video.published_at
374
+
375
+ # validate optionally-present rating
376
+ if video.rating
377
+ assert_instance_of YouTubeIt::Model::Rating, video.rating
378
+ assert_instance_of Float, video.rating.average
379
+ assert_instance_of Fixnum, video.rating.max
380
+ assert_instance_of Fixnum, video.rating.min
381
+ assert_instance_of Fixnum, video.rating.rater_count
382
+ end
383
+
384
+ # validate thumbnails
385
+ assert(video.thumbnails.size > 0)
386
+
387
+ assert_not_nil video.title
388
+ assert_instance_of String, video.title
389
+ assert(video.title.length > 0)
390
+
391
+ assert_instance_of Time, video.updated_at
392
+ # http://gdata.youtube.com/feeds/videos/IHVaXG1thXM
393
+ assert_valid_url video.unique_id
394
+ assert_instance_of Fixnum, video.view_count
395
+ assert_instance_of Fixnum, video.favorite_count
396
+
397
+ # validate author
398
+ assert_instance_of YouTubeIt::Model::Author, video.author
399
+ assert_instance_of String, video.author.name
400
+ assert(video.author.name.length > 0)
401
+ assert_valid_url video.author.uri
402
+
403
+ # validate categories
404
+ video.categories.each do |cat|
405
+ assert_instance_of YouTubeIt::Model::Category, cat
406
+ assert_instance_of String, cat.label
407
+ assert_instance_of String, cat.term
408
+ end
409
+ end
410
+
411
+ def assert_valid_url (url)
412
+ URI::parse(url)
413
+ return true
414
+ rescue
415
+ return false
416
+ end
417
+ end
418
+
@@ -0,0 +1,48 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/helper')
2
+
3
+ class YouTubeIt
4
+ module Request
5
+ class TestSearch < BaseSearch
6
+ include FieldSearch
7
+
8
+ def initialize(params={})
9
+ @url = fields_to_params(params.delete(:fields))
10
+ end
11
+ end
12
+ end
13
+ end
14
+
15
+ class TestFieldSearch < Test::Unit::TestCase
16
+ include YouTubeIt::Request
17
+
18
+ def default_fields
19
+ "id,updated,openSearch:totalResults,openSearch:startIndex,openSearch:itemsPerPage"
20
+ end
21
+
22
+ def test_should_search_for_range_of_recoreded_on_dates
23
+ starts_at = Date.today - 4
24
+ ends_at = Date.today
25
+ request = TestSearch.new(:fields => {:recorded => (starts_at..ends_at)})
26
+ assert_equal URI.escape("&fields=#{default_fields},entry[xs:date(yt:recorded) > xs:date('#{starts_at.strftime('%Y-%m-%d')}') and xs:date(yt:recorded) < xs:date('#{ends_at.strftime('%Y-%m-%d')}')]"), request.url
27
+ end
28
+
29
+ def test_should_search_for_recoreded_on_date
30
+ recorded_at = Date.today
31
+ request = TestSearch.new(:fields => {:recorded => recorded_at})
32
+ assert_equal URI.escape("&fields=#{default_fields},entry[xs:date(yt:recorded) = xs:date('#{recorded_at.strftime('%Y-%m-%d')}')]"), request.url
33
+ end
34
+
35
+ def test_should_search_for_range_of_published_on_dates
36
+ starts_at = Date.today - 4
37
+ ends_at = Date.today
38
+ request = TestSearch.new(:fields => {:published => (starts_at..ends_at)})
39
+ assert_equal URI.escape("&fields=#{default_fields},entry[xs:dateTime(published) > xs:dateTime('#{starts_at.strftime('%Y-%m-%d')}T00:00:00') and xs:dateTime(published) < xs:dateTime('#{ends_at.strftime('%Y-%m-%d')}T00:00:00')]"), request.url
40
+ end
41
+
42
+ def test_search_for_published_on_date
43
+ published_at = Date.today
44
+ request = TestSearch.new(:fields => {:published => published_at})
45
+ assert_equal URI.escape("&fields=#{default_fields},entry[xs:date(published) = xs:date('#{published_at.strftime('%Y-%m-%d')}')]"), request.url
46
+ end
47
+ end
48
+
@@ -0,0 +1,43 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/helper')
2
+
3
+ class TestVideo < Test::Unit::TestCase
4
+ def test_should_extract_unique_id_from_video_id
5
+ video = YouTubeIt::Model::Video.new(:video_id => "tag:youtube.com,2008:video:ZTUVgYoeN_o")
6
+ assert_equal "ZTUVgYoeN_o", video.unique_id
7
+ end
8
+
9
+ def test_should_extract_unique_id_with_hypen_from_video_id
10
+ video = YouTubeIt::Model::Video.new(:video_id => "tag:youtube.com,2008:video:BDqs-OZWw9o")
11
+ assert_equal "BDqs-OZWw9o", video.unique_id
12
+ end
13
+
14
+ def test_should_have_related_videos
15
+ video = YouTubeIt::Model::Video.new(:video_id => "tag:youtube.com,2008:video:BDqs-OZWw9o")
16
+ response = video.related
17
+
18
+ assert_equal "http://gdata.youtube.com/feeds/api/videos/BDqs-OZWw9o/related", response.feed_id
19
+ assert_equal 25, response.max_result_count
20
+ assert_equal 25, response.videos.length
21
+ assert_equal 1, response.offset
22
+ assert(response.total_result_count > 0)
23
+ assert_instance_of Time, response.updated_at
24
+ end
25
+
26
+ def test_should_have_response_videos
27
+ video = YouTubeIt::Model::Video.new(:video_id => "tag:youtube.com,2008:video:BDqs-OZWw9o")
28
+ response = video.responses
29
+
30
+ assert_equal "http://gdata.youtube.com/feeds/api/videos/BDqs-OZWw9o/responses", response.feed_id
31
+ assert_equal 25, response.max_result_count
32
+ assert_equal 25, response.videos.length
33
+ assert_equal 1, response.offset
34
+ assert(response.total_result_count > 0)
35
+ assert_instance_of Time, response.updated_at
36
+ end
37
+
38
+ def test_should_scale_video_embed
39
+ video = YouTubeIt::Model::Video.new(:video_id => "tag:youtube.com,2008:video:EkF4JD2rO3Q", :player_url=>"http://www.youtube.com/v/EkF4JD2rO3Q&feature=youtube_gdata_player", :widescreen => true)
40
+ assert_equal "<object width=\"1280\" height=\"745\">\n<param name=\"movie\" value=\"http://www.youtube.com/v/EkF4JD2rO3Q&feature=youtube_gdata_player\"></param>\n<param name=\"wmode\" value=\"transparent\"></param>\n<embed src=\"http://www.youtube.com/v/EkF4JD2rO3Q&feature=youtube_gdata_player\" type=\"application/x-shockwave-flash\"\nwmode=\"transparent\" width=\"1280\" height=\"745\"></embed>\n</object>\n", video.embed_html_with_width(1280)
41
+ end
42
+ end
43
+