1require "rss-testcase"
2
3require "rss/maker"
4
5module RSS
6  class TestMakerITunes < TestCase
7    def test_author
8      assert_maker_itunes_author(%w(channel))
9      assert_maker_itunes_author(%w(items last))
10    end
11
12    def test_block
13      assert_maker_itunes_block(%w(channel))
14      assert_maker_itunes_block(%w(items last))
15    end
16
17    def test_category
18      assert_maker_itunes_category(%w(channel))
19    end
20
21    def test_image
22      assert_maker_itunes_image(%w(channel))
23    end
24
25    def test_duration
26      assert_maker_itunes_duration(%w(items last))
27    end
28
29    def test_explicit
30      assert_maker_itunes_explicit(%w(channel))
31      assert_maker_itunes_explicit(%w(items last))
32    end
33
34    def test_keywords
35      assert_maker_itunes_keywords(%w(channel))
36      assert_maker_itunes_keywords(%w(items last))
37    end
38
39    def test_new_feed_url
40      assert_maker_itunes_new_feed_url(%w(channel))
41    end
42
43    def test_owner
44      assert_maker_itunes_owner(%w(channel))
45    end
46
47    def test_subtitle
48      assert_maker_itunes_subtitle(%w(channel))
49      assert_maker_itunes_subtitle(%w(items last))
50    end
51
52    def test_summary
53      assert_maker_itunes_summary(%w(channel))
54      assert_maker_itunes_summary(%w(items last))
55    end
56
57    private
58
59    def assert_maker_itunes_author(maker_readers, feed_readers=nil)
60      _wrap_assertion do
61        feed_readers ||= maker_readers
62        author = "John Doe"
63        rss20 = ::RSS::Maker.make("rss2.0") do |maker|
64          setup_dummy_channel(maker)
65          setup_dummy_item(maker)
66
67          target = chain_reader(maker, maker_readers)
68          target.itunes_author = author
69        end
70        target = chain_reader(rss20, feed_readers)
71        assert_equal(author, target.itunes_author)
72      end
73    end
74
75    def _assert_maker_itunes_block(value, boolean_value, maker_readers,
76                                   feed_readers)
77      rss20 = ::RSS::Maker.make("rss2.0") do |maker|
78        setup_dummy_channel(maker)
79        setup_dummy_item(maker)
80
81        target = chain_reader(maker, maker_readers)
82        target.itunes_block = value
83        assert_equal(value, target.itunes_block)
84        assert_equal(boolean_value, target.itunes_block?)
85      end
86      target = chain_reader(rss20, feed_readers)
87      if [true, false].include?(value)
88        feed_expected_value = value = value ? "yes" : "no"
89      else
90        feed_expected_value = value
91      end
92      assert_equal(value, target.itunes_block)
93      assert_equal(boolean_value, target.itunes_block?)
94    end
95
96    def assert_maker_itunes_block(maker_readers, feed_readers=nil)
97      _wrap_assertion do
98        feed_readers ||= maker_readers
99        _assert_maker_itunes_block("yes", true, maker_readers, feed_readers)
100        _assert_maker_itunes_block("Yes", true, maker_readers, feed_readers)
101        _assert_maker_itunes_block("no", false, maker_readers, feed_readers)
102        _assert_maker_itunes_block("", false, maker_readers, feed_readers)
103        _assert_maker_itunes_block(true, true, maker_readers, feed_readers)
104        _assert_maker_itunes_block(false, false, maker_readers, feed_readers)
105        _assert_maker_itunes_block(nil, false, maker_readers, feed_readers)
106      end
107    end
108
109    def _assert_maker_itunes_category(categories, maker_readers, feed_readers)
110      rss20 = ::RSS::Maker.make("rss2.0") do |maker|
111        setup_dummy_channel(maker)
112        setup_dummy_item(maker)
113
114        target = chain_reader(maker, maker_readers)
115        categories.each do |category|
116          sub_target = target.itunes_categories
117          if category.is_a?(Array)
118            category.each do |sub_category|
119              sub_target = sub_target.new_category
120              sub_target.text = sub_category
121            end
122          else
123            sub_target.new_category.text = category
124          end
125        end
126      end
127
128      target = chain_reader(rss20, feed_readers)
129      actual_categories = target.itunes_categories.collect do |category|
130        cat = category.text
131        if category.itunes_categories.empty?
132          cat
133        else
134          [cat, *category.itunes_categories.collect {|c| c.text}]
135        end
136      end
137      assert_equal(categories, actual_categories)
138    end
139
140    def assert_maker_itunes_category(maker_readers, feed_readers=nil)
141      _wrap_assertion do
142        feed_readers ||= maker_readers
143        _assert_maker_itunes_category(["Audio Blogs"],
144                                      maker_readers, feed_readers)
145        _assert_maker_itunes_category([["Arts & Entertainment", "Games"]],
146                                      maker_readers, feed_readers)
147        _assert_maker_itunes_category([["Arts & Entertainment", "Games"],
148                                       ["Technology", "Computers"],
149                                       "Audio Blogs"],
150                                      maker_readers, feed_readers)
151      end
152    end
153
154    def assert_maker_itunes_image(maker_readers, feed_readers=nil)
155      _wrap_assertion do
156        feed_readers ||= maker_readers
157        url = "http://example.com/podcasts/everything/AllAboutEverything.jpg"
158
159        rss20 = ::RSS::Maker.make("rss2.0") do |maker|
160          setup_dummy_channel(maker)
161          setup_dummy_item(maker)
162
163          target = chain_reader(maker, maker_readers)
164          target.itunes_image = url
165        end
166
167        target = chain_reader(rss20, feed_readers)
168        assert_not_nil(target.itunes_image)
169        assert_equal(url, target.itunes_image.href)
170      end
171    end
172
173    def _assert_maker_itunes_duration(hour, minute, second, value,
174                                      maker_readers, feed_readers)
175      _assert_maker_itunes_duration_by_value(hour, minute, second, value,
176                                             maker_readers, feed_readers)
177      _assert_maker_itunes_duration_by_hour_minute_second(hour, minute, second,
178                                                          value,
179                                                          maker_readers,
180                                                          feed_readers)
181    end
182
183    def _assert_maker_itunes_duration_by(hour, minute, second, value,
184                                         maker_readers, feed_readers)
185      expected_value = nil
186      rss20 = ::RSS::Maker.make("rss2.0") do |maker|
187        setup_dummy_channel(maker)
188        setup_dummy_item(maker)
189
190        target = chain_reader(maker, maker_readers)
191        expected_value = yield(target)
192        assert_equal(expected_value, target.itunes_duration)
193        target.itunes_duration do |duration|
194          assert_equal([hour, minute, second, expected_value],
195                       [duration.hour, duration.minute,
196                        duration.second, duration.content])
197        end
198      end
199      target = chain_reader(rss20, feed_readers)
200      duration = target.itunes_duration
201      assert_not_nil(duration)
202      assert_equal([hour, minute, second, expected_value],
203                   [duration.hour, duration.minute,
204                    duration.second, duration.content])
205    end
206
207    def _assert_maker_itunes_duration_by_value(hour, minute, second, value,
208                                               maker_readers, feed_readers)
209      _assert_maker_itunes_duration_by(hour, minute, second, value,
210                                       maker_readers, feed_readers) do |target|
211        target.itunes_duration = value
212        value
213      end
214    end
215
216    def _assert_maker_itunes_duration_by_hour_minute_second(hour, minute, second,
217                                                            value,
218                                                            maker_readers,
219                                                            feed_readers)
220      _assert_maker_itunes_duration_by(hour, minute, second, value,
221                                       maker_readers, feed_readers) do |target|
222        target.itunes_duration do |duration|
223          duration.hour = hour
224          duration.minute = minute
225          duration.second = second
226        end
227        value.split(":").collect {|v| "%02d" % v.to_i}.join(":")
228      end
229    end
230
231    def _assert_maker_itunes_duration_invalid_value(value, maker_readers)
232      assert_raise(ArgumentError) do
233        ::RSS::Maker.make("rss2.0") do |maker|
234          setup_dummy_channel(maker)
235          setup_dummy_item(maker)
236
237          target = chain_reader(maker, maker_readers)
238          target.itunes_duration = value
239        end
240      end
241    end
242
243    def assert_maker_itunes_duration(maker_readers, feed_readers=nil)
244      _wrap_assertion do
245        feed_readers ||= maker_readers
246        _assert_maker_itunes_duration(7, 14, 5, "07:14:05", maker_readers,
247                                      feed_readers)
248        _assert_maker_itunes_duration(7, 14, 5, "7:14:05", maker_readers,
249                                      feed_readers)
250        _assert_maker_itunes_duration(0, 4, 55, "04:55", maker_readers,
251                                      feed_readers)
252        _assert_maker_itunes_duration(0, 4, 5, "4:05", maker_readers,
253                                      feed_readers)
254
255        _assert_maker_itunes_duration_invalid_value("5", maker_readers)
256        _assert_maker_itunes_duration_invalid_value("09:07:14:05", maker_readers)
257        _assert_maker_itunes_duration_invalid_value("10:5", maker_readers)
258        _assert_maker_itunes_duration_invalid_value("10:03:5", maker_readers)
259        _assert_maker_itunes_duration_invalid_value("10:3:05", maker_readers)
260
261        _assert_maker_itunes_duration_invalid_value("xx:xx:xx", maker_readers)
262      end
263    end
264
265    def _assert_maker_itunes_explicit(explicit, value,
266                                      maker_readers, feed_readers)
267      rss20 = ::RSS::Maker.make("rss2.0") do |maker|
268        setup_dummy_channel(maker)
269        setup_dummy_item(maker)
270
271        target = chain_reader(maker, maker_readers)
272        target.itunes_explicit = value
273        assert_equal(explicit, target.itunes_explicit?)
274      end
275      target = chain_reader(rss20, feed_readers)
276      assert_equal(value, target.itunes_explicit)
277      assert_equal(explicit, target.itunes_explicit?)
278    end
279
280    def assert_maker_itunes_explicit(maker_readers, feed_readers=nil)
281      _wrap_assertion do
282        feed_readers ||= maker_readers
283        _assert_maker_itunes_explicit(true, "yes", maker_readers, feed_readers)
284        _assert_maker_itunes_explicit(false, "clean",
285                                      maker_readers, feed_readers)
286        _assert_maker_itunes_explicit(nil, "no", maker_readers, feed_readers)
287      end
288    end
289
290    def _assert_maker_itunes_keywords(keywords, value,
291                                      maker_readers, feed_readers)
292      _assert_maker_itunes_keywords_by_value(keywords, value,
293                                             maker_readers, feed_readers)
294      _assert_maker_itunes_keywords_by_keywords(keywords, maker_readers,
295                                                feed_readers)
296    end
297
298    def _assert_maker_itunes_keywords_by(keywords, maker_readers, feed_readers)
299      rss20 = ::RSS::Maker.make("rss2.0") do |maker|
300        setup_dummy_channel(maker)
301        setup_dummy_item(maker)
302
303        target = chain_reader(maker, maker_readers)
304        yield(target)
305      end
306      assert_nothing_raised do
307        rss20 = ::RSS::Parser.parse(rss20.to_s)
308      end
309      target = chain_reader(rss20, feed_readers)
310      assert_equal(keywords, target.itunes_keywords)
311    end
312
313    def _assert_maker_itunes_keywords_by_value(keywords, value,
314                                               maker_readers, feed_readers)
315      _assert_maker_itunes_keywords_by(keywords, maker_readers,
316                                       feed_readers) do |target|
317        target.itunes_keywords = value
318      end
319    end
320
321    def _assert_maker_itunes_keywords_by_keywords(keywords,
322                                                  maker_readers, feed_readers)
323      _assert_maker_itunes_keywords_by(keywords, maker_readers,
324                                       feed_readers) do |target|
325        target.itunes_keywords = keywords
326      end
327    end
328
329    def assert_maker_itunes_keywords(maker_readers, feed_readers=nil)
330      _wrap_assertion do
331        feed_readers ||= maker_readers
332        _assert_maker_itunes_keywords(["salt"], "salt",
333                                      maker_readers, feed_readers)
334        _assert_maker_itunes_keywords(["salt"], " salt ",
335                                      maker_readers, feed_readers)
336        _assert_maker_itunes_keywords(["salt", "pepper", "shaker", "exciting"],
337                                      "salt, pepper, shaker, exciting",
338                                      maker_readers, feed_readers)
339        _assert_maker_itunes_keywords(["metric", "socket", "wrenches",
340                                       "toolsalt"],
341                                      "metric, socket, wrenches, toolsalt",
342                                      maker_readers, feed_readers)
343        _assert_maker_itunes_keywords(["olitics", "red", "blue", "state"],
344                                      "olitics, red, blue, state",
345                                      maker_readers, feed_readers)
346      end
347    end
348
349    def assert_maker_itunes_new_feed_url(maker_readers, feed_readers=nil)
350      feed_readers ||= maker_readers
351      url = "http://newlocation.com/example.rss"
352
353      rss20 = ::RSS::Maker.make("rss2.0") do |maker|
354        setup_dummy_channel(maker)
355        setup_dummy_item(maker)
356
357        target = chain_reader(maker, maker_readers)
358        target.itunes_new_feed_url = url
359      end
360      target = chain_reader(rss20, feed_readers)
361      assert_equal(url, target.itunes_new_feed_url)
362    end
363
364    def _assert_maker_itunes_owner(name, email, maker_readers, feed_readers)
365      rss20 = ::RSS::Maker.make("rss2.0") do |maker|
366        setup_dummy_channel(maker)
367        setup_dummy_item(maker)
368
369        target = chain_reader(maker, maker_readers)
370        owner = target.itunes_owner
371        owner.itunes_name = name
372        owner.itunes_email = email
373      end
374      owner = chain_reader(rss20, feed_readers).itunes_owner
375      if name.nil? and email.nil?
376        assert_nil(owner)
377      else
378        assert_not_nil(owner)
379        assert_equal(name, owner.itunes_name)
380        assert_equal(email, owner.itunes_email)
381      end
382    end
383
384    def assert_maker_itunes_owner(maker_readers, feed_readers=nil)
385      _wrap_assertion do
386        feed_readers ||= maker_readers
387        _assert_maker_itunes_owner("John Doe", "john.doe@example.com",
388                                   maker_readers, feed_readers)
389
390        not_set_name = (["maker"] + maker_readers + ["itunes_owner"]).join(".")
391        assert_not_set_error(not_set_name, ["itunes_name"]) do
392          _assert_maker_itunes_owner(nil, "john.doe@example.com",
393                                     maker_readers, feed_readers)
394        end
395        assert_not_set_error(not_set_name, ["itunes_email"]) do
396          _assert_maker_itunes_owner("John Doe", nil,
397                                     maker_readers, feed_readers)
398        end
399
400        _assert_maker_itunes_owner(nil, nil, maker_readers, feed_readers)
401      end
402    end
403
404    def _assert_maker_itunes_subtitle(subtitle, maker_readers, feed_readers)
405      rss20 = ::RSS::Maker.make("rss2.0") do |maker|
406        setup_dummy_channel(maker)
407        setup_dummy_item(maker)
408
409        target = chain_reader(maker, maker_readers)
410        target.itunes_subtitle = subtitle
411      end
412
413      target = chain_reader(rss20, feed_readers)
414      assert_equal(subtitle, target.itunes_subtitle)
415    end
416
417    def assert_maker_itunes_subtitle(maker_readers, feed_readers=nil)
418      _wrap_assertion do
419        feed_readers ||= maker_readers
420        _assert_maker_itunes_subtitle("A show about everything",
421                                      maker_readers, feed_readers)
422        _assert_maker_itunes_subtitle("A short primer on table spices",
423                                      maker_readers, feed_readers)
424        _assert_maker_itunes_subtitle("Comparing socket wrenches is fun!",
425                                      maker_readers, feed_readers)
426        _assert_maker_itunes_subtitle("Red + Blue != Purple",
427                                      maker_readers, feed_readers)
428      end
429    end
430
431    def _assert_maker_itunes_summary(summary, maker_readers, feed_readers)
432      rss20 = ::RSS::Maker.make("rss2.0") do |maker|
433        setup_dummy_channel(maker)
434        setup_dummy_item(maker)
435
436        target = chain_reader(maker, maker_readers)
437        target.itunes_summary = summary
438      end
439
440      target = chain_reader(rss20, feed_readers)
441      assert_equal(summary, target.itunes_summary)
442    end
443
444    def assert_maker_itunes_summary(maker_readers, feed_readers=nil)
445      _wrap_assertion do
446        feed_readers ||= maker_readers
447        _assert_maker_itunes_summary("All About Everything is a show about " +
448                                     "everything. Each week we dive into any " +
449                                     "subject known to man and talk about it " +
450                                     "as much as we can. Look for our Podcast " +
451                                     "in the iTunes Music Store",
452                                     maker_readers, feed_readers)
453        _assert_maker_itunes_summary("This week we talk about salt and pepper " +
454                                     "shakers, comparing and contrasting pour " +
455                                     "rates, construction materials, and " +
456                                     "overall aesthetics. Come and join the " +
457                                     "party!",
458                                     maker_readers, feed_readers)
459        _assert_maker_itunes_summary("This week we talk about metric vs. old " +
460                                     "english socket wrenches. Which one is " +
461                                     "better? Do you really need both? Get " +
462                                     "all of your answers here.",
463                                     maker_readers, feed_readers)
464        _assert_maker_itunes_summary("This week we talk about surviving in a " +
465                                     "Red state if you're a Blue person. Or " +
466                                     "vice versa.",
467                                     maker_readers, feed_readers)
468      end
469    end
470  end
471end
472