msp-youtube-g 0.4.6 → 0.4.7

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,5 +1,7 @@
1
1
  == trunk
2
-
2
+ * Move network dependent tests to integration-test [msp]
3
+ * Create a parser and a model for upload errors [msp]
4
+ * Stub driven tests for VideoFeedParser, VideosFeedParser, UploadErrorParser [msp]
3
5
  * Add error-handling for video upload errors. [FiXato]
4
6
  * Add error-handling for authentication errors from YouTube during video upload. [FiXato]
5
7
  * Add support for making videos private upon video upload. [FiXato]
@@ -15,11 +15,16 @@ lib/youtube_g/model/rating.rb
15
15
  lib/youtube_g/model/thumbnail.rb
16
16
  lib/youtube_g/model/user.rb
17
17
  lib/youtube_g/model/video.rb
18
+ lib/youtube_g/model/upload_error.rb
18
19
  lib/youtube_g/parser.rb
19
20
  lib/youtube_g/record.rb
20
21
  lib/youtube_g/request/video_search.rb
21
22
  lib/youtube_g/request/video_upload.rb
22
23
  lib/youtube_g/response/video_search.rb
23
- test/test_client.rb
24
- test/test_video.rb
25
- test/test_video_search.rb
24
+ integration-test/test_client.rb
25
+ integration-test/test_video.rb
26
+ integration-test/test_video_search.rb
27
+ test/test_parser.rb
28
+ test/test_upload.rb
29
+ test/search.xml
30
+ test/upload.xml
data/TODO.txt CHANGED
@@ -1,10 +1,10 @@
1
- [ ] stub out http request/response cycle for tests
1
+ [ ] stub out http request/response cycle for tests (partially done in test_parser, need to do the same for pre-existing tests [msp])
2
2
  [ ] consider defaulting the client to no-logger, rather than outputting to STDOUT.
3
3
  [ ] allow specifying values as single items where you don't need to wrap in a list, e.g. :tags => :chickens instead of :tags => [ 'chickens' ]
4
4
  [ ] make sure symbols will work as well as tags everywhere (again, :tags => :chickens is same as :tags => 'chickens')
5
5
  [ ] figure out better structure for class/file (either rename request/video_search.rb or split into one class per file again)
6
6
  [ ] restore spaces after method def names
7
- [ ] use a proxy for testing with static sample result xml so we have repeatable tests
7
+ [ ] use a proxy for testing with static sample result xml so we have repeatable tests (see above [msp])
8
8
  [ ] Clean up tests using Shoulda to define contexts
9
9
  [ ] Consolidate requires
10
10
  [ ] Allow :category and :categories for query DSL
@@ -15,4 +15,4 @@
15
15
  [ ] Profile feed parsing
16
16
  [ ] Playlist feeds
17
17
  [ ] User subscriptions
18
- [ ] Video comments
18
+ [ ] Video comments
@@ -9,11 +9,12 @@ require File.dirname(__FILE__) + '/youtube_g/model/playlist'
9
9
  require File.dirname(__FILE__) + '/youtube_g/model/rating'
10
10
  require File.dirname(__FILE__) + '/youtube_g/model/thumbnail'
11
11
  require File.dirname(__FILE__) + '/youtube_g/model/user'
12
- require File.dirname(__FILE__) + '/youtube_g/model/video'
12
+ require File.dirname(__FILE__) + '/youtube_g/model/video'
13
+ require File.dirname(__FILE__) + '/youtube_g/model/upload_error'
13
14
  require File.dirname(__FILE__) + '/youtube_g/request/video_upload'
14
15
  require File.dirname(__FILE__) + '/youtube_g/request/video_search'
15
16
  require File.dirname(__FILE__) + '/youtube_g/response/video_search'
16
17
 
17
18
  class YouTubeG
18
- VERSION = '0.4.5'
19
+ VERSION = '0.4.7'
19
20
  end
@@ -34,14 +34,23 @@ class YouTubeG
34
34
  SWF = YouTubeG::Model::Video::Format.new(5, :swf)
35
35
 
36
36
  THREE_GPP = YouTubeG::Model::Video::Format.new(6, :three_gpp)
37
+ end
38
+
39
+
40
+ # Used in video uploads only to check the state of the upload
41
+ class AppControl < YouTubeG::Record
42
+ attr_reader :draft
43
+ attr_reader :state
37
44
  end
38
-
45
+
39
46
  attr_reader :duration
40
47
  attr_reader :noembed
41
48
  attr_reader :position
42
49
  attr_reader :racy
43
50
  attr_reader :statistics
44
51
 
52
+ attr_reader :app_control
53
+
45
54
  attr_reader :video_id
46
55
  attr_reader :published_at
47
56
  attr_reader :updated_at
@@ -3,17 +3,55 @@ require 'open-uri'
3
3
  require 'rexml/document'
4
4
 
5
5
  class YouTubeG
6
- module Parser
7
- class FeedParser
8
- def initialize(url)
9
- @url = url
6
+ module Parser
7
+ class FeedParserError < Exception; end
8
+
9
+ class FeedParser
10
+ attr_reader :url_based
11
+ alias :url_based? :url_based
12
+
13
+ def initialize(arg)
14
+ @url_based = assert_valid_url(arg)
15
+ @content = arg
10
16
  end
11
17
 
18
+ def parse
19
+ if @url_based
20
+ parse_content open(@content).read
21
+ else
22
+ parse_content @content
23
+ end
24
+ end
25
+
26
+ private
27
+ def assert_valid_url (url)
28
+ URI::parse(url)
29
+ return true
30
+ rescue
31
+ return false
32
+ end
33
+ end
34
+
35
+ class UploadErrorParser
36
+ def initialize(xml)
37
+ raise YouTubeG::Parser::FeedParserError.new("You must pass some xml") if xml == ''
38
+ @doc = REXML::Document.new(xml)
39
+ end
40
+
12
41
  def parse
13
- parse_content open(@url).read
14
- end
42
+ upload_errors = []
43
+
44
+ @doc.elements.each("//error") do |error|
45
+ location = error.elements["location"].text #[/media:group\/media:(.*)\/text\(\)/,1]
46
+ code = error.elements["code"].text
47
+ domain = error.elements["domain"].text
48
+ upload_errors << YouTubeG::Model::UploadError.new(:location => location, :code => code, :domain => domain)
49
+ end
50
+
51
+ return upload_errors
52
+ end
15
53
  end
16
-
54
+
17
55
  class VideoFeedParser < FeedParser
18
56
 
19
57
  def parse_content(content)
@@ -27,7 +65,15 @@ class YouTubeG
27
65
  def parse_entry(entry)
28
66
  video_id = entry.elements["id"].text
29
67
  published_at = Time.parse(entry.elements["published"].text)
30
- updated_at = Time.parse(entry.elements["updated"].text)
68
+ updated_at = Time.parse(entry.elements["updated"].text)
69
+
70
+ app_control_element = entry.elements["app:control"]
71
+ app_contrlol = nil
72
+ if app_control_element
73
+ app_control = YouTubeG::Model::Video::AppControl.new(
74
+ :draft => app_control_element.elements["app:draft"].text,
75
+ :state => app_control_element.elements["yt:state"].attributes["name"])
76
+ end
31
77
 
32
78
  # parse the category and keyword lists
33
79
  categories = []
@@ -61,14 +107,14 @@ class YouTubeG
61
107
 
62
108
  media_group = entry.elements["media:group"]
63
109
  description = media_group.elements["media:description"].text
64
- duration = media_group.elements["yt:duration"].attributes["seconds"].to_i
110
+ duration = media_group.elements["yt:duration"].attributes["seconds"].to_i if media_group.elements["yt:duration"]
65
111
 
66
112
  media_content = []
67
113
  media_group.elements.each("media:content") do |mce|
68
114
  media_content << parse_media_content(mce)
69
115
  end
70
116
 
71
- player_url = media_group.elements["media:player"].attributes["url"]
117
+ player_url = media_group.elements["media:player"].attributes["url"] if media_group.elements["media:player"]
72
118
 
73
119
  # parse thumbnails
74
120
  thumbnails = []
@@ -99,7 +145,8 @@ class YouTubeG
99
145
  YouTubeG::Model::Video.new(
100
146
  :video_id => video_id,
101
147
  :published_at => published_at,
102
- :updated_at => updated_at,
148
+ :updated_at => updated_at,
149
+ :app_control => app_control,
103
150
  :categories => categories,
104
151
  :keywords => keywords,
105
152
  :title => title,
@@ -131,7 +178,7 @@ class YouTubeG
131
178
  :mime_type => mime_type,
132
179
  :default => default)
133
180
  end
134
- end
181
+ end
135
182
 
136
183
  class VideosFeedParser < VideoFeedParser
137
184
 
@@ -160,6 +207,6 @@ class YouTubeG
160
207
  :videos => videos)
161
208
  end
162
209
  end
163
-
210
+
164
211
  end
165
212
  end
@@ -20,6 +20,7 @@ class YouTubeG
20
20
  class VideoUpload
21
21
 
22
22
  attr_accessor :auth_token
23
+
23
24
  def initialize user, pass, dev_key, client_id = 'youtube_g', auth_token = nil
24
25
  @user, @pass, @dev_key, @client_id, @auth_token = user, pass, dev_key, client_id, auth_token
25
26
  end
@@ -30,7 +31,7 @@ class YouTubeG
30
31
  Logger.new(STDOUT)
31
32
  else
32
33
  eval(get_rails_default_logger_name)
33
- end
34
+ end
34
35
  end
35
36
 
36
37
  def get_rails_default_logger_name
@@ -81,22 +82,18 @@ class YouTubeG
81
82
 
82
83
  Net::HTTP.start(base_url) do |upload|
83
84
  response = upload.post(direct_upload_url, upload_body, upload_header)
84
- if response.code.to_i == 403
85
+ # todo parse this out also
86
+ if response.code.to_i == 403
85
87
  raise AuthenticationError, response.body[/<TITLE>(.+)<\/TITLE>/, 1]
86
- elsif response.code.to_i != 201
87
- upload_error = ''
88
- xml = REXML::Document.new(response.body)
89
- errors = xml.elements["//errors"]
90
- errors.each do |error|
91
- location = error.elements["location"].text[/media:group\/media:(.*)\/text\(\)/,1]
92
- code = error.elements["code"].text
93
- upload_error << sprintf("%s: %s\r\n", location, code)
94
- end
95
- raise UploadError, upload_error
96
- end
88
+ elsif response.code.to_i != 201
89
+ upload_errors = YouTubeG::Parser::UploadErrorParser.new(response.body).parse
90
+ raise UploadError, upload_errors.inspect
91
+ end
92
+ return YouTubeG::Parser::VideoFeedParser.new(response.body).parse
97
93
  end
98
94
 
99
- end
95
+ end
96
+
100
97
 
101
98
  private
102
99
 
@@ -115,7 +112,7 @@ class YouTubeG
115
112
  body = "Email=#{CGI::escape @user}&Passwd=#{CGI::escape @pass}&service=youtube&source=#{CGI::escape @client_id}"
116
113
  logger.debug("auth body [#{body}]")
117
114
  response = http.post("/youtube/accounts/ClientLogin", body, "Content-Type" => "application/x-www-form-urlencoded")
118
- raise UploadError, ""+response.body[/Error=(.+)/,1] if response.code.to_i != 200
115
+ raise UploadError, response.body[/Error=(.+)/,1] if response.code.to_i != 200
119
116
  logger.debug("response.body [#{response.body}]")
120
117
  @auth_token = response.body[/Auth=(.+)/, 1]
121
118
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: msp-youtube-g
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.6
4
+ version: 0.4.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Shane Vitarana
@@ -1,226 +0,0 @@
1
- require 'rubygems'
2
- require 'test/unit'
3
- require 'pp'
4
-
5
- require 'youtube_g'
6
-
7
- class TestClient < Test::Unit::TestCase
8
- def setup
9
- @client = YouTubeG::Client.new
10
- end
11
-
12
- def test_should_respond_to_a_basic_query
13
- response = @client.videos_by(:query => "penguin")
14
-
15
- assert_equal "http://gdata.youtube.com/feeds/api/videos?start-index=1&max-results=25&vq=penguin", response.feed_id
16
- assert_equal 25, response.max_result_count
17
- assert_equal 25, response.videos.length
18
- assert_equal 1, response.offset
19
- assert(response.total_result_count > 100)
20
- assert_instance_of Time, response.updated_at
21
-
22
- response.videos.each { |v| assert_valid_video v }
23
- end
24
-
25
- def test_should_get_videos_for_multiword_metasearch_query
26
- response = @client.videos_by(:query => 'christina ricci')
27
-
28
- assert_equal "http://gdata.youtube.com/feeds/api/videos?start-index=1&max-results=25&vq=christina+ricci", response.feed_id
29
- assert_equal 25, response.max_result_count
30
- assert_equal 25, response.videos.length
31
- assert_equal 1, response.offset
32
- assert(response.total_result_count > 100)
33
- assert_instance_of Time, response.updated_at
34
-
35
- response.videos.each { |v| assert_valid_video v }
36
- end
37
-
38
- def test_should_handle_video_not_yet_viewed
39
- response = @client.videos_by(:query => "YnqHZDh_t2Q")
40
-
41
- assert_equal 1, response.videos.length
42
- response.videos.each { |v| assert_valid_video v }
43
- end
44
-
45
- # TODO: this doesn't work because the returned feed is in an unknown format
46
- # def test_should_get_video_for_search_by_video_id
47
- # response = @client.videos_by(:video_id => "T7YazwP8GtY")
48
- # response.videos.each { |v| assert_valid_video v }
49
- # end
50
-
51
- def test_should_get_videos_for_one_tag
52
- response = @client.videos_by(:tags => ['panther'])
53
- response.videos.each { |v| assert_valid_video v }
54
- end
55
-
56
- def test_should_get_videos_for_multiple_tags
57
- response = @client.videos_by(:tags => ['tiger', 'leopard'])
58
- response.videos.each { |v| assert_valid_video v }
59
- end
60
-
61
- def test_should_get_videos_for_one_category
62
- response = @client.videos_by(:categories => [:news])
63
- response.videos.each { |v| assert_valid_video v }
64
- end
65
-
66
- def test_should_get_videos_for_multiple_categories
67
- response = @client.videos_by(:categories => [:news, :sports])
68
- response.videos.each { |v| assert_valid_video v }
69
- end
70
-
71
- # TODO: Need to do more specific checking in these tests
72
- # Currently, if a URL is valid, and videos are found, the test passes regardless of search criteria
73
- def test_should_get_videos_for_categories_and_tags
74
- response = @client.videos_by(:categories => [:news, :sports], :tags => ['soccer', 'football'])
75
- response.videos.each { |v| assert_valid_video v }
76
- end
77
-
78
- def test_should_get_most_viewed_videos
79
- response = @client.videos_by(:most_viewed)
80
- response.videos.each { |v| assert_valid_video v }
81
- end
82
-
83
- def test_should_get_top_rated_videos_for_today
84
- response = @client.videos_by(:top_rated, :time => :today)
85
- response.videos.each { |v| assert_valid_video v }
86
- end
87
-
88
- def test_should_get_videos_for_categories_and_tags_with_category_boolean_operators
89
- response = @client.videos_by(:categories => { :either => [:news, :sports], :exclude => [:comedy] },
90
- :tags => { :include => ['football'], :exclude => ['soccer'] })
91
- response.videos.each { |v| assert_valid_video v }
92
- end
93
-
94
- def test_should_get_videos_for_categories_and_tags_with_tag_boolean_operators
95
- response = @client.videos_by(:categories => { :either => [:news, :sports], :exclude => [:comedy] },
96
- :tags => { :either => ['football', 'soccer', 'polo'] })
97
- response.videos.each { |v| assert_valid_video v }
98
- end
99
-
100
- def test_should_get_videos_by_user
101
- response = @client.videos_by(:user => 'liz')
102
- response.videos.each { |v| assert_valid_video v }
103
- end
104
-
105
- # HTTP 403 Error
106
- # def test_should_get_favorite_videos_by_user
107
- # response = @client.videos_by(:favorites, :user => 'liz')
108
- # response.videos.each { |v| assert_valid_video v }
109
- # end
110
-
111
- def test_should_get_videos_for_query_search_with_categories_excluded
112
- response = @client.videos_by(:query => 'bench press', :categories => { :exclude => [:comedy, :entertainment] },
113
- :max_results => 10)
114
- assert_equal "<object width=\"425\" height=\"350\">\n <param name=\"movie\" value=\"http://www.youtube.com/v/BlDWdfTAx8o\"></param>\n <param name=\"wmode\" value=\"transparent\"></param>\n <embed src=\"http://www.youtube.com/v/BlDWdfTAx8o\" type=\"application/x-shockwave-flash\" \n wmode=\"transparent\" width=\"425\" height=\"350\"></embed>\n</object>\n", response.videos.first.embed_html
115
- response.videos.each { |v| assert_valid_video v }
116
- end
117
-
118
- def test_should_be_able_to_pass_in_logger
119
- @client = YouTubeG::Client.new(Logger.new(STDOUT))
120
- assert_not_nil @client.logger
121
- end
122
-
123
- def test_should_create_logger_if_not_passed_in
124
- @client = YouTubeG::Client.new
125
- assert_not_nil @client.logger
126
- end
127
-
128
- def test_should_determine_if_nonembeddable_video_is_embeddable
129
- response = @client.videos_by(:query => "avril lavigne girlfriend")
130
-
131
- video = response.videos.first
132
- assert !video.can_embed?
133
- end
134
-
135
- def test_should_determine_if_embeddable_video_is_embeddable
136
- response = @client.videos_by(:query => "strongbad")
137
-
138
- video = response.videos.first
139
- assert video.can_embed?
140
- end
141
-
142
- def test_should_retrieve_video_by_id
143
- video = @client.video_by("http://gdata.youtube.com/feeds/videos/EkF4JD2rO3Q")
144
- assert_valid_video video
145
-
146
- video = @client.video_by("EkF4JD2rO3Q")
147
- assert_valid_video video
148
- end
149
-
150
- private
151
-
152
- def assert_valid_video (video)
153
- # pp video
154
-
155
- # check general attributes
156
- assert_instance_of YouTubeG::Model::Video, video
157
- assert_instance_of Fixnum, video.duration
158
- assert(video.duration > 0)
159
- #assert_match(/^<div style=.*?<\/div>/m, video.html_content)
160
- assert_instance_of String, video.html_content
161
-
162
- # validate media content records
163
- video.media_content.each do |media_content|
164
- # http://www.youtube.com/v/IHVaXG1thXM
165
- assert_valid_url media_content.url
166
- assert(media_content.duration > 0)
167
- assert_instance_of YouTubeG::Model::Video::Format, media_content.format
168
- assert_instance_of String, media_content.mime_type
169
- assert_match(/^[^\/]+\/[^\/]+$/, media_content.mime_type)
170
- end
171
-
172
- default_content = video.default_media_content
173
- if default_content
174
- assert_instance_of YouTubeG::Model::Content, default_content
175
- assert default_content.is_default?
176
- end
177
-
178
- # validate keywords
179
- video.keywords.each { |kw| assert_instance_of(String, kw) }
180
-
181
- # http://www.youtube.com/watch?v=IHVaXG1thXM
182
- assert_valid_url video.player_url
183
- assert_instance_of Time, video.published_at
184
-
185
- # validate optionally-present rating
186
- if video.rating
187
- assert_instance_of YouTubeG::Model::Rating, video.rating
188
- assert_instance_of Float, video.rating.average
189
- assert_instance_of Fixnum, video.rating.max
190
- assert_instance_of Fixnum, video.rating.min
191
- assert_instance_of Fixnum, video.rating.rater_count
192
- end
193
-
194
- # validate thumbnails
195
- assert(video.thumbnails.size > 0)
196
-
197
- assert_not_nil video.title
198
- assert_instance_of String, video.title
199
- assert(video.title.length > 0)
200
-
201
- assert_instance_of Time, video.updated_at
202
- # http://gdata.youtube.com/feeds/videos/IHVaXG1thXM
203
- assert_valid_url video.video_id
204
- assert_instance_of Fixnum, video.view_count
205
-
206
- # validate author
207
- assert_instance_of YouTubeG::Model::Author, video.author
208
- assert_instance_of String, video.author.name
209
- assert(video.author.name.length > 0)
210
- assert_valid_url video.author.uri
211
-
212
- # validate categories
213
- video.categories.each do |cat|
214
- assert_instance_of YouTubeG::Model::Category, cat
215
- assert_instance_of String, cat.label
216
- assert_instance_of String, cat.term
217
- end
218
- end
219
-
220
- def assert_valid_url (url)
221
- URI::parse(url)
222
- return true
223
- rescue
224
- return false
225
- end
226
- end
@@ -1,30 +0,0 @@
1
- require 'rubygems'
2
- require 'test/unit'
3
- require 'pp'
4
-
5
- require 'youtube_g'
6
-
7
- class TestVideo < Test::Unit::TestCase
8
- def test_should_extract_unique_id_from_video_id
9
- video = YouTubeG::Model::Video.new(:video_id => "http://gdata.youtube.com/feeds/videos/ZTUVgYoeN_o")
10
- assert_equal "ZTUVgYoeN_o", video.unique_id
11
- end
12
-
13
- def test_should_extract_unique_id_with_hypen_from_video_id
14
- video = YouTubeG::Model::Video.new(:video_id => "http://gdata.youtube.com/feeds/videos/BDqs-OZWw9o")
15
- assert_equal "BDqs-OZWw9o", video.unique_id
16
- end
17
-
18
- def test_should_have_related_videos
19
- video = YouTubeG::Model::Video.new(:video_id => "http://gdata.youtube.com/feeds/videos/BDqs-OZWw9o")
20
- response = video.related
21
-
22
- assert_equal "http://gdata.youtube.com/feeds/api/videos/BDqs-OZWw9o/related", 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
- puts response.total_result_count
27
- assert(response.total_result_count > 0)
28
- assert_instance_of Time, response.updated_at
29
- end
30
- end
@@ -1,118 +0,0 @@
1
- require 'rubygems'
2
- require 'test/unit'
3
- require 'pp'
4
-
5
- require 'youtube_g'
6
-
7
- class TestVideoSearch < Test::Unit::TestCase
8
-
9
- def test_should_build_basic_query_url
10
- request = YouTubeG::Request::VideoSearch.new(:query => "penguin")
11
- assert_equal "http://gdata.youtube.com/feeds/api/videos?vq=penguin", request.url
12
- end
13
-
14
- def test_should_build_multiword_metasearch_query_url
15
- request = YouTubeG::Request::VideoSearch.new(:query => 'christina ricci')
16
- assert_equal "http://gdata.youtube.com/feeds/api/videos?vq=christina+ricci", request.url
17
- end
18
-
19
- def test_should_build_video_id_url
20
- request = YouTubeG::Request::VideoSearch.new(:video_id => 'T7YazwP8GtY')
21
- assert_equal "http://gdata.youtube.com/feeds/api/videos/T7YazwP8GtY", request.url
22
- end
23
-
24
- def test_should_build_one_tag_querl_url
25
- request = YouTubeG::Request::VideoSearch.new(:tags => ['panther'])
26
- assert_equal "http://gdata.youtube.com/feeds/api/videos/-/panther/", request.url
27
- end
28
-
29
- def test_should_build_multiple_tags_query_url
30
- request = YouTubeG::Request::VideoSearch.new(:tags => ['tiger', 'leopard'])
31
- assert_equal "http://gdata.youtube.com/feeds/api/videos/-/tiger/leopard/", request.url
32
- end
33
-
34
- def test_should_build_one_category_query_url
35
- request = YouTubeG::Request::VideoSearch.new(:categories => [:news])
36
- assert_equal "http://gdata.youtube.com/feeds/api/videos/-/News/", request.url
37
- end
38
-
39
- def test_should_build_multiple_categories_query_url
40
- request = YouTubeG::Request::VideoSearch.new(:categories => [:news, :sports])
41
- assert_equal "http://gdata.youtube.com/feeds/api/videos/-/News/Sports/", request.url
42
- end
43
-
44
- def test_should_build_categories_and_tags_query_url
45
- request = YouTubeG::Request::VideoSearch.new(:categories => [:news, :sports], :tags => ['soccer', 'football'])
46
- assert_equal "http://gdata.youtube.com/feeds/api/videos/-/News/Sports/soccer/football/", request.url
47
- end
48
-
49
- def test_should_build_categories_and_tags_url_with_max_results
50
- request = YouTubeG::Request::VideoSearch.new(:categories => [:music], :tags => ['classic', 'rock'], :max_results => 2)
51
- assert_equal "http://gdata.youtube.com/feeds/api/videos/-/Music/classic/rock/?max-results=2", request.url
52
- end
53
-
54
- def test_should_build_author_query_url
55
- request = YouTubeG::Request::VideoSearch.new(:author => "davidguetta")
56
- assert_equal "http://gdata.youtube.com/feeds/api/videos?author=davidguetta", request.url
57
- end
58
- # -- Standard Feeds --------------------------------------------------------------------------------
59
-
60
- def test_should_build_url_for_most_viewed
61
- request = YouTubeG::Request::StandardSearch.new(:most_viewed)
62
- assert_equal "http://gdata.youtube.com/feeds/api/standardfeeds/most_viewed", request.url
63
- end
64
-
65
- def test_should_raise_exception_for_invalid_type
66
- assert_raise RuntimeError do
67
- request = YouTubeG::Request::StandardSearch.new(:most_viewed_yo)
68
- end
69
- end
70
-
71
- def test_should_build_url_for_top_rated_for_today
72
- request = YouTubeG::Request::StandardSearch.new(:top_rated, :time => :today)
73
- assert_equal "http://gdata.youtube.com/feeds/api/standardfeeds/top_rated?time=today", request.url
74
- end
75
-
76
- # -- Complex Video Queries -------------------------------------------------------------------------
77
-
78
- def test_should_build_url_for_boolean_or_case_for_categories
79
- request = YouTubeG::Request::VideoSearch.new(:categories => { :either => [:news, :sports] })
80
- assert_equal "http://gdata.youtube.com/feeds/api/videos/-/News%7CSports/", request.url
81
- end
82
-
83
- def test_should_build_url_for_boolean_or_and_exclude_case_for_categories
84
- request = YouTubeG::Request::VideoSearch.new(:categories => { :either => [:news, :sports], :exclude => [:comedy] })
85
- assert_equal "http://gdata.youtube.com/feeds/api/videos/-/News%7CSports/-Comedy/", request.url
86
- end
87
-
88
- def test_should_build_url_for_exclude_case_for_tags
89
- request = YouTubeG::Request::VideoSearch.new(:categories => { :either => [:news, :sports], :exclude => [:comedy] },
90
- :tags => { :include => ['football'], :exclude => ['soccer'] })
91
- assert_equal "http://gdata.youtube.com/feeds/api/videos/-/News%7CSports/-Comedy/football/-soccer/", request.url
92
- end
93
-
94
- def test_should_build_url_for_either_case_for_tags
95
- request = YouTubeG::Request::VideoSearch.new(:categories => { :either => [:news, :sports], :exclude => [:comedy] },
96
- :tags => { :either => ['soccer', 'football', 'donkey'] })
97
- assert_equal "http://gdata.youtube.com/feeds/api/videos/-/News%7CSports/-Comedy/soccer%7Cfootball%7Cdonkey/", request.url
98
- end
99
-
100
- def test_should_build_url_for_query_search_with_categories_excluded
101
- request = YouTubeG::Request::VideoSearch.new(:query => 'bench press',
102
- :categories => { :exclude => [:comedy, :entertainment] },
103
- :max_results => 10)
104
- assert_equal "http://gdata.youtube.com/feeds/api/videos/-/-Comedy/-Entertainment/?vq=bench+press&max-results=10", request.url
105
- end
106
-
107
- # -- User Queries ---------------------------------------------------------------------------------
108
-
109
- def test_should_build_url_for_videos_by_user
110
- request = YouTubeG::Request::UserSearch.new(:user => 'liz')
111
- assert_equal "http://gdata.youtube.com/feeds/api/users/liz/uploads", request.url
112
- end
113
-
114
- def test_should_build_url_for_favorite_videos_by_user
115
- request = YouTubeG::Request::UserSearch.new(:favorites, :user => 'liz')
116
- assert_equal "http://gdata.youtube.com/feeds/api/users/liz/favorites", request.url
117
- end
118
- end