msp-youtube-g 0.4.6 → 0.4.7

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.
@@ -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