1require "rexml/document"
2
3require "rss-testcase"
4
5module RSS
6  class TestRSS20Core < TestCase
7
8    def setup
9      @rss_version = "2.0"
10    end
11
12    def test_Rss
13      version = "1.0"
14      encoding = "UTF-8"
15      standalone = false
16
17      rss = Rss.new(@rss_version, version, encoding, standalone)
18      setup_rss20(rss)
19
20      doc = REXML::Document.new(rss.to_s(false))
21
22      xmldecl = doc.xml_decl
23
24      assert_equal(version, xmldecl.version)
25      assert_equal(encoding, xmldecl.encoding.to_s)
26      assert_equal(standalone, !xmldecl.standalone.nil?)
27
28      assert_equal("", doc.root.namespace)
29      assert_equal(@rss_version, doc.root.attributes["version"])
30    end
31
32    def test_not_displayed_xml_stylesheets
33      rss = Rss.new(@rss_version)
34      plain_rss = rss.to_s
35      3.times do
36        rss.xml_stylesheets.push(XMLStyleSheet.new)
37        assert_equal(plain_rss, rss.to_s)
38      end
39    end
40
41    def test_xml_stylesheets
42      [
43        [{:href => "a.xsl", :type => "text/xsl"}],
44        [
45          {:href => "a.xsl", :type => "text/xsl"},
46          {:href => "a.css", :type => "text/css"},
47        ],
48      ].each do |attrs_ary|
49        rss = Rss.new(@rss_version)
50        setup_rss20(rss)
51        assert_xml_stylesheet_pis(attrs_ary, rss)
52      end
53    end
54
55    def test_channel
56      h = {
57        'title' => "fugafuga",
58        'link' => "http://hoge.com",
59        'description' => "fugafugafugafuga",
60
61        'language' => "en-us",
62        'copyright' => "Copyright 2002, Spartanburg Herald-Journal",
63        'managingEditor' => "geo@herald.com (George Matesky)",
64        'webMaster' => "betty@herald.com (Betty Guernsey)",
65        'pubDate' => Time.parse("Sat, 07 Sep 2002 00:00:01 GMT"),
66        'lastBuildDate' => Time.parse("Sat, 07 Sep 2002 09:42:31 GMT"),
67        'generator' => "MightyInHouse Content System v2.3",
68        'docs' => "http://blogs.law.harvard.edu/tech/rss",
69        'ttl' => "60",
70        'rating' => '(PICS-1.1 "http://www.rsac.org/ratingsv01.html" l gen true comment "RSACi North America Server" for "http://www.rsac.org" on "1996.04.16T08:15-0500" r (n 0 s 0 v 0 l 0))',
71      }
72      categories = [
73        {
74          :content => "Newspapers",
75        },
76        {
77          :domain => "Syndic8",
78          :content => "1765",
79        }
80      ]
81
82      channel = Rss::Channel.new
83
84      elems = %w(title link description language copyright
85                 managingEditor webMaster pubDate lastBuildDate
86                 generator docs ttl rating)
87      elems.each do |x|
88        value = h[x]
89        value = value.rfc822 if %w(pubDate lastBuildDate).include?(x)
90        channel.__send__("#{x}=", value)
91      end
92      categories.each do |cat|
93        channel.categories << Rss::Channel::Category.new(cat[:domain],
94                                                         cat[:content])
95      end
96
97      doc = REXML::Document.new(make_rss20(channel.to_s))
98      c = doc.root.elements[1]
99
100      elems.each do |x|
101        elem = c.elements[x]
102        assert_equal(x, elem.name)
103        assert_equal("", elem.namespace)
104        expected = h[x]
105        case x
106        when "pubDate", "lastBuildDate"
107          assert_equal(expected, Time.parse(elem.text))
108        when "ttl"
109          expected = channel.__send__(x)
110          assert_equal(expected, elem.text.to_i)
111        else
112          assert_equal(expected, elem.text)
113        end
114      end
115      categories.each_with_index do |cat, i|
116        cat = cat.dup
117        cat[:domain] ||= nil
118        category = c.elements["category[#{i+1}]"]
119        actual = {
120          :domain => category.attributes["domain"],
121          :content => category.text,
122        }
123        assert_equal(cat, actual)
124      end
125    end
126
127    def test_channel_cloud
128      cloud_params = {
129        :domain => "rpc.sys.com",
130        :port => "80",
131        :path => "/RPC2",
132        :registerProcedure => "myCloud.rssPleaseNotify",
133        :protocol => "xml-rpc",
134      }
135      cloud = Rss::Channel::Cloud.new(cloud_params[:domain],
136                                      cloud_params[:port],
137                                      cloud_params[:path],
138                                      cloud_params[:registerProcedure],
139                                      cloud_params[:protocol])
140      cloud_params[:port] = cloud.port
141
142      doc = REXML::Document.new(cloud.to_s)
143      cloud_elem = doc.root
144
145      actual = {}
146      cloud_elem.attributes.each do |name, value|
147        value = value.to_i if name == "port"
148        actual[name.intern] = value
149      end
150      assert_equal(cloud_params, actual)
151    end
152
153    def test_channel_image
154      image_params = {
155        :url => "http://hoge.com/hoge.png",
156        :title => "fugafuga",
157        :link => "http://hoge.com",
158        :width => "144",
159        :height => "400",
160        :description => "an image",
161      }
162      image = Rss::Channel::Image.new(image_params[:url],
163                                      image_params[:title],
164                                      image_params[:link],
165                                      image_params[:width],
166                                      image_params[:height],
167                                      image_params[:description])
168
169      doc = REXML::Document.new(image.to_s)
170      image_elem = doc.root
171
172      image_params.each do |name, value|
173        value = image.__send__(name)
174        actual = image_elem.elements[name.to_s].text
175        actual = actual.to_i if [:width, :height].include?(name)
176        assert_equal(value, actual)
177      end
178    end
179
180    def test_channel_textInput
181      textInput_params = {
182        :title => "fugafuga",
183        :description => "text hoge fuga",
184        :name => "hoge",
185        :link => "http://hoge.com",
186      }
187      textInput = Rss::Channel::TextInput.new(textInput_params[:title],
188                                              textInput_params[:description],
189                                              textInput_params[:name],
190                                              textInput_params[:link])
191
192      doc = REXML::Document.new(textInput.to_s)
193      input_elem = doc.root
194
195      textInput_params.each do |name, value|
196        actual = input_elem.elements[name.to_s].text
197        assert_equal(value, actual)
198      end
199    end
200
201    def test_channel_skip_days
202      skipDays_values = [
203        "Sunday",
204        "Monday",
205      ]
206      skipDays = Rss::Channel::SkipDays.new
207      skipDays_values.each do |value|
208        skipDays.days << Rss::Channel::SkipDays::Day.new(value)
209      end
210
211      doc = REXML::Document.new(skipDays.to_s)
212      days_elem = doc.root
213
214      skipDays_values.each_with_index do |value, i|
215        assert_equal(value, days_elem.elements[i + 1].text)
216      end
217    end
218
219    def test_channel_skip_hours
220      skipHours_values = [
221        "0",
222        "13",
223      ]
224      skipHours = Rss::Channel::SkipHours.new
225      skipHours_values.each do |value|
226        skipHours.hours << Rss::Channel::SkipHours::Hour.new(value)
227      end
228
229      doc = REXML::Document.new(skipHours.to_s)
230      hours_elem = doc.root
231
232      skipHours_values.each_with_index do |value, i|
233        expected = skipHours.hours[i].content
234        assert_equal(expected, hours_elem.elements[i + 1].text.to_i)
235      end
236    end
237
238    def test_item
239      h = {
240        'title' => "fugafuga",
241        'link' => "http://hoge.com/",
242        'description' => "text hoge fuga",
243        'author' => "oprah@oxygen.net",
244        'comments' => "http://www.myblog.org/cgi-local/mt/mt-comments.cgi?entry_id=290",
245        'pubDate' => Time.parse("Sat, 07 Sep 2002 00:00:01 GMT"),
246      }
247      categories = [
248        {
249          :content => "Newspapers",
250        },
251        {
252          :domain => "Syndic8",
253          :content => "1765",
254        }
255      ]
256
257      channel = Rss::Channel.new
258      channel.title = "title"
259      channel.link = "http://example.com/"
260      channel.description = "description"
261
262      item = Rss::Channel::Item.new
263      channel.items << item
264
265      elems = %w(title link description author comments pubDate)
266      elems.each do |x|
267        value = h[x]
268        value = value.rfc822 if x == "pubDate"
269        item.__send__("#{x}=", value)
270      end
271      categories.each do |cat|
272        item.categories << Rss::Channel::Category.new(cat[:domain],
273                                                      cat[:content])
274      end
275
276      doc = REXML::Document.new(channel.to_s)
277      channel_elem = doc.root
278
279      item_elem = channel_elem.elements["item[1]"]
280      elems.each do |x|
281        elem = item_elem.elements[x]
282        assert_equal(x, elem.name)
283        assert_equal("", elem.namespace)
284        expected = h[x]
285        case x
286        when "pubDate"
287          assert_equal(expected, Time.parse(elem.text))
288        else
289          assert_equal(expected, elem.text)
290        end
291      end
292      categories.each_with_index do |cat, i|
293        cat = cat.dup
294        cat[:domain] ||= nil
295        category = item_elem.elements["category[#{i+1}]"]
296        actual = {
297          :domain => category.attributes["domain"],
298          :content => category.text,
299        }
300        assert_equal(cat, actual)
301      end
302    end
303
304    def test_item_enclosure
305      enclosure_params = {
306        :url => "http://www.scripting.com/mp3s/weatherReportSuite.mp3",
307        :length => "12216320",
308        :type => "audio/mpeg",
309      }
310
311      enclosure = Rss::Channel::Item::Enclosure.new(enclosure_params[:url],
312                                                    enclosure_params[:length],
313                                                    enclosure_params[:type])
314      enclosure_params[:length] = enclosure.length
315
316      doc = REXML::Document.new(enclosure.to_s)
317      enclosure_elem = doc.root
318
319      actual = {}
320      enclosure_elem.attributes.each do |name, value|
321        value = value.to_i if name == "length"
322        actual[name.intern] = value
323      end
324      assert_equal(enclosure_params, actual)
325    end
326
327    def test_item_guid
328      test_params = [
329        {
330          :content => "http://some.server.com/weblogItem3207",
331        },
332        {
333          :isPermaLink => "true",
334          :content => "http://inessential.com/2002/09/01.php#a2",
335        },
336      ]
337
338      test_params.each do |guid_params|
339        guid = Rss::Channel::Item::Guid.new(guid_params[:isPermaLink],
340                                            guid_params[:content])
341        if guid_params.has_key?(:isPermaLink)
342          guid_params[:isPermaLink] = guid.isPermaLink
343        end
344        if guid.isPermaLink.nil?
345          assert_equal(true, guid.PermaLink?)
346        else
347          assert_equal(guid.isPermaLink, guid.PermaLink?)
348        end
349
350        doc = REXML::Document.new(guid.to_s)
351        guid_elem = doc.root
352
353        actual = {}
354        actual[:content] = guid_elem.text if guid_elem.text
355        guid_elem.attributes.each do |name, value|
356          value = value == "true" if name == "isPermaLink"
357          actual[name.intern] = value
358        end
359        assert_equal(guid_params, actual)
360      end
361    end
362
363    def test_item_source
364      source_params = {
365        :url => "http://www.tomalak.org/links2.xml",
366        :content => "Tomalak's Realm",
367      }
368
369      source = Rss::Channel::Item::Source.new(source_params[:url],
370                                              source_params[:content])
371
372      doc = REXML::Document.new(source.to_s)
373      source_elem = doc.root
374
375      actual = {}
376      actual[:content] = source_elem.text
377      source_elem.attributes.each do |name, value|
378        actual[name.intern] = value
379      end
380      assert_equal(source_params, actual)
381    end
382
383    def test_to_xml
384      rss = RSS::Parser.parse(make_sample_rss20)
385      assert_equal(rss.to_s, rss.to_xml)
386      assert_equal(rss.to_s, rss.to_xml("2.0"))
387      rss09_xml = rss.to_xml("0.91") do |maker|
388        setup_dummy_image(maker)
389      end
390      rss09 = RSS::Parser.parse(rss09_xml)
391      assert_equal("0.91", rss09.rss_version)
392      rss10 = rss.to_xml("1.0") do |maker|
393        maker.channel.about = "http://www.example.com/index.rdf"
394      end
395      rss10 = RSS::Parser.parse(rss10)
396      assert_equal("1.0", rss10.rss_version)
397
398      atom_xml = rss.to_xml("atom1.0") do |maker|
399        maker.channel.id = "http://www.example.com/atom.xml"
400        maker.channel.author = "Alice"
401        maker.channel.updated = Time.now
402        maker.items.each do |item|
403          item.author = "Bob"
404          item.updated = Time.now
405        end
406      end
407      atom = RSS::Parser.parse(atom_xml)
408      assert_equal(["atom", "1.0", "feed"], atom.feed_info)
409    end
410  end
411end
412