1require "rexml/document" 2 3require "rss-testcase" 4 5require "rss/maker" 6require "rss/1.0" 7require "rss/2.0" 8require "rss/content" 9require "rss/dublincore" 10require "rss/syndication" 11require "rss/trackback" 12 13module RSS 14 class TestToS < TestCase 15 def setup 16 @image_url = "http://example.com/foo.png" 17 @textinput_link = "http://example.com/search.cgi" 18 @item_links = [ 19 "http://example.com/1", 20 "http://example.com/2", 21 ] 22 23 setup_xml_declaration_info 24 setup_xml_stylesheet_infos 25 setup_channel_info 26 setup_item_infos 27 setup_image_info 28 setup_textinput_info 29 30 setup_dublin_core_info 31 setup_syndication_info 32 setup_content_info 33 setup_trackback_info 34 end 35 36 def test_to_s_10 37 rss = RSS::Maker.make("1.0") do |maker| 38 setup_full(maker) 39 end 40 41 assert_xml_declaration(@version, @encoding, @standalone, rss) 42 assert_xml_stylesheets(@xs_infos, rss.xml_stylesheets) 43 assert_channel10(@channel_info, rss.channel) 44 assert_items10(@item_infos, rss.items) 45 rss.items.each do |item| 46 assert_trackback(@trackback_info, item) 47 end 48 assert_image10(@image_info, rss.image) 49 assert_textinput10(@textinput_info, rss.textinput) 50 51 rss = RSS::Parser.parse(rss.to_s) 52 53 assert_xml_declaration(@version, @encoding, @standalone, rss) 54 assert_xml_stylesheets(@xs_infos, rss.xml_stylesheets) 55 assert_channel10(@channel_info, rss.channel) 56 assert_items10(@item_infos, rss.items) 57 assert_image10(@image_info, rss.image) 58 assert_textinput10(@textinput_info, rss.textinput) 59 end 60 61 def test_to_s_09 62 rss = RSS::Maker.make("0.91") do |maker| 63 setup_full(maker) 64 end 65 66 assert_xml_declaration(@version, @encoding, @standalone, rss) 67 assert_xml_stylesheets(@xs_infos, rss.xml_stylesheets) 68 assert_channel09(@channel_info, rss.channel) 69 assert_items09(@item_infos, rss.items) 70 assert_image09(@image_info, rss.image) 71 assert_textinput09(@textinput_info, rss.textinput) 72 73 rss = RSS::Parser.parse(rss.to_s) 74 75 assert_xml_declaration(@version, @encoding, @standalone, rss) 76 assert_xml_stylesheets(@xs_infos, rss.xml_stylesheets) 77 assert_channel09(@channel_info, rss.channel) 78 assert_items09(@item_infos, rss.items) 79 assert_image09(@image_info, rss.image) 80 assert_textinput09(@textinput_info, rss.textinput) 81 end 82 83 def test_to_s_20 84 rss = RSS::Maker.make("2.0") do |maker| 85 setup_full(maker) 86 end 87 88 assert_xml_declaration(@version, @encoding, @standalone, rss) 89 assert_xml_stylesheets(@xs_infos, rss.xml_stylesheets) 90 assert_channel20(@channel_info, rss.channel) 91 assert_items20(@item_infos, rss.items) 92 assert_image20(@image_info, rss.image) 93 assert_textinput20(@textinput_info, rss.textinput) 94 95 rss = RSS::Parser.parse(rss.to_s) 96 97 assert_xml_declaration(@version, @encoding, @standalone, rss) 98 assert_xml_stylesheets(@xs_infos, rss.xml_stylesheets) 99 assert_channel20(@channel_info, rss.channel) 100 assert_items20(@item_infos, rss.items) 101 assert_image20(@image_info, rss.image) 102 assert_textinput20(@textinput_info, rss.textinput) 103 end 104 105 private 106 def setup_xml_declaration_info 107 @version = "1.0" 108 @encoding = "UTF-8" 109 @standalone = false 110 end 111 112 def setup_xml_stylesheet_infos 113 @xs_infos = [ 114 { 115 "href" => "XXX.xsl", 116 "type" => "text/xsl", 117 "title" => "XXX", 118 "media" => "print", 119 "alternate" => "no", 120 }, 121 { 122 "href" => "YYY.css", 123 "type" => "text/css", 124 "title" => "YYY", 125 "media" => "all", 126 "alternate" => "no", 127 }, 128 ] 129 end 130 131 def setup_channel_info 132 @channel_info = { 133 "about" => "http://example.com/index.rdf", 134 "title" => "Sample RSS", 135 "link" => "http://example.com/", 136 "description" => "Sample\n\n\n\n\nSite", 137 "language" => "en", 138 "copyright" => "FDL", 139 "managingEditor" => "foo@example.com", 140 "webMaster" => "webmaster@example.com", 141 "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))', 142 "docs" => "http://backend.userland.com/rss091", 143 "skipDays" => [ 144 "Monday", 145 "Friday", 146 ], 147 "skipHours" => [ 148 "12", 149 "23", 150 ], 151 "date" => Time.now, 152 "lastBuildDate" => Time.now - 3600, 153 "generator" => "RSS Maker", 154 "ttl" => "60", 155 "cloud" => { 156 "domain" => "rpc.sys.com", 157 "port" => "80", 158 "path" => "/RPC2", 159 "registerProcedure" => "myCloud.rssPleaseNotify", 160 "protocol" => "xml-rpc", 161 }, 162 "category" => { 163 "domain" => "http://example.com/misc/", 164 "content" => "misc", 165 }, 166 167 "image" => { 168 "resource" => @image_url, 169 }, 170 171 "textinput" => { 172 "resource" => @textinput_link, 173 }, 174 175 "items" => @item_links.collect{|link| {"resource" => link}}, 176 } 177 end 178 179 def setup_item_infos 180 @item_infos = [ 181 { 182 "title" => "Sample item1", 183 "link" => @item_links[0], 184 "description" => "Sample description1", 185 "date" => Time.now - 3600, 186 "author" => "foo@example.com", 187 "comments" => "http://example.com/1/comments", 188 "guid" => { 189 "isPermaLink" => "true", 190 "content" => "http://example.com/1", 191 }, 192 "enclosure" => { 193 "url" => "http://example.com/1.mp3", 194 "length" => "100", 195 "type" => "audio/mpeg", 196 }, 197 "source" => { 198 "url" => "http:/example.com/", 199 "content" => "Sample site", 200 }, 201 "category" => { 202 "domain" => "http://example.com/misc/", 203 "content" => "misc", 204 }, 205 }, 206 207 { 208 "title" => "Sample item2", 209 "link" => @item_links[1], 210 "description" => "Sample description2", 211 "date" => Time.now - 7200, 212 "author" => "foo@example.com", 213 "comments" => "http://example.com/2/comments", 214 "guid" => { 215 "isPermaLink" => "false", 216 "content" => "http://example.com/2", 217 }, 218 "enclosure" => { 219 "url" => "http://example.com/2.mp3", 220 "length" => "200", 221 "type" => "audio/mpeg", 222 }, 223 "source" => { 224 "url" => "http:/example.com/", 225 "content" => "Sample site", 226 }, 227 "category" => { 228 "domain" => "http://example.com/misc/", 229 "content" => "misc", 230 }, 231 }, 232 ] 233 end 234 235 def setup_image_info 236 @image_info = { 237 "title" => "Sample image", 238 "url" => @image_url, 239 "width" => "88", 240 "height" => "31", 241 "description" => "Sample", 242 } 243 end 244 245 def setup_textinput_info 246 @textinput_info = { 247 "title" => "Sample textinput", 248 "description" => "Search", 249 "name" => "key", 250 "link" => @textinput_link, 251 } 252 end 253 254 def setup_dublin_core_info 255 @dc_info = { 256 "title" => "DC title", 257 "description" => "DC desc", 258 "creator" => "DC creator", 259 "subject" => "DC subject", 260 "publisher" => "DC publisher", 261 "contributor" => "DC contributor", 262 "type" => "DC type", 263 "format" => "DC format", 264 "identifier" => "DC identifier", 265 "source" => "DC source", 266 "language" => "ja", 267 "relation" => "DC relation", 268 "coverage" => "DC coverage", 269 "rights" => "DC rights", 270 "date" => Time.now - 60, 271 } 272 end 273 274 def setup_syndication_info 275 @sy_info = { 276 "updatePeriod" => "hourly", 277 "updateFrequency" => "2", 278 "updateBase" => Time.now - 3600, 279 } 280 end 281 282 def setup_content_info 283 @content_info = { 284 "encoded" => "<p>p</p>", 285 } 286 end 287 288 def setup_trackback_info 289 @trackback_info = { 290 "ping" => "http://example.com/tb.cgi?tb_id=XXX", 291 "abouts" => [ 292 "http://example.net/tb.cgi?tb_id=YYY", 293 "http://example.org/tb.cgi?tb_id=ZZZ", 294 ] 295 } 296 end 297 298 299 def setup_full(maker) 300 setup_xml_declaration(maker) 301 setup_xml_stylesheets(maker) 302 setup_channel(maker) 303 setup_image(maker) 304 setup_items(maker) 305 setup_textinput(maker) 306 end 307 308 def setup_xml_declaration(maker) 309 %w(version encoding standalone).each do |name| 310 maker.__send__("#{name}=", instance_eval("@#{name}")) 311 end 312 end 313 314 def setup_xml_stylesheets(maker) 315 @xs_infos.each do |info| 316 xs = maker.xml_stylesheets.new_xml_stylesheet 317 info.each do |name, value| 318 xs.__send__("#{name}=", value) 319 end 320 end 321 end 322 323 def setup_channel(maker) 324 channel = maker.channel 325 info = @channel_info 326 327 %w(about title link description language copyright 328 managingEditor webMaster rating docs date 329 lastBuildDate generator ttl).each do |name| 330 channel.__send__("#{name}=", info[name]) 331 end 332 333 skipDays = channel.skipDays 334 info["skipDays"].each do |day| 335 new_day = skipDays.new_day 336 new_day.content = day 337 end 338 339 skipHours = channel.skipHours 340 info["skipHours"].each do |hour| 341 new_hour = skipHours.new_hour 342 new_hour.content = hour 343 end 344 345 cloud = channel.cloud 346 %w(domain port path registerProcedure protocol).each do |name| 347 cloud.__send__("#{name}=", info["cloud"][name]) 348 end 349 350 category = channel.categories.new_category 351 %w(domain content).each do |name| 352 category.__send__("#{name}=", info["category"][name]) 353 end 354 end 355 356 def setup_image(maker) 357 image = maker.image 358 info = @image_info 359 360 %w(title url width height description).each do |name| 361 image.__send__("#{name}=", info[name]) 362 end 363 end 364 365 def setup_items(maker) 366 items = maker.items 367 368 @item_infos.each do |info| 369 item = items.new_item 370 %w(title link description date author comments).each do |name| 371 item.__send__("#{name}=", info[name]) 372 end 373 374 guid = item.guid 375 %w(isPermaLink content).each do |name| 376 guid.__send__("#{name}=", info["guid"][name]) 377 end 378 379 enclosure = item.enclosure 380 %w(url length type).each do |name| 381 enclosure.__send__("#{name}=", info["enclosure"][name]) 382 end 383 384 source = item.source 385 %w(url content).each do |name| 386 source.__send__("#{name}=", info["source"][name]) 387 end 388 389 category = item.categories.new_category 390 %w(domain content).each do |name| 391 category.__send__("#{name}=", info["category"][name]) 392 end 393 394 setup_trackback(item) 395 end 396 end 397 398 def setup_textinput(maker) 399 textinput = maker.textinput 400 info = @textinput_info 401 402 %w(title description name link).each do |name| 403 textinput.__send__("#{name}=", info[name]) 404 end 405 end 406 407 def setup_content(target) 408 prefix = "content" 409 %w(encoded).each do |name| 410 target.__send__("#{prefix}_#{name}=", @content_info[name]) 411 end 412 end 413 414 def setup_dublin_core(target) 415 prefix = "dc" 416 %w(title description creator subject publisher 417 contributor type format identifier source language 418 relation coverage rights).each do |name| 419 target.__send__("#{prefix}_#{name}=", @dc_info[name]) 420 end 421 end 422 423 def setup_syndicate(target) 424 prefix = "sy" 425 %w(updatePeriod updateFrequency updateBase).each do |name| 426 target.__send__("#{prefix}_#{name}=", @sy_info[name]) 427 end 428 end 429 430 def setup_trackback(target) 431 target.trackback_ping = @trackback_info["ping"] 432 @trackback_info["abouts"].each do |about| 433 new_about = target.trackback_abouts.new_about 434 new_about.value = about 435 end 436 end 437 438 439 def assert_channel10(attrs, channel) 440 _wrap_assertion do 441 n_attrs = normalized_attrs(attrs) 442 443 names = %w(about title link description) 444 assert_attributes(attrs, names, channel) 445 446 %w(image items textinput).each do |name| 447 value = n_attrs[name] 448 if value 449 target = channel.__send__(name) 450 __send__("assert_channel10_#{name}", value, target) 451 end 452 end 453 end 454 end 455 456 def assert_channel10_image(attrs, image) 457 _wrap_assertion do 458 assert_attributes(attrs, %w(resource), image) 459 end 460 end 461 462 def assert_channel10_textinput(attrs, textinput) 463 _wrap_assertion do 464 assert_attributes(attrs, %w(resource), textinput) 465 end 466 end 467 468 def assert_channel10_items(attrs, items) 469 _wrap_assertion do 470 assert_equal(items.resources, items.Seq.lis.collect {|x| x.resource}) 471 items.Seq.lis.each_with_index do |li, i| 472 assert_attributes(attrs[i], %w(resource), li) 473 end 474 end 475 end 476 477 def assert_image10(attrs, image) 478 _wrap_assertion do 479 names = %w(about title url link) 480 assert_attributes(attrs, names, image) 481 end 482 end 483 484 def assert_items10(attrs, items) 485 _wrap_assertion do 486 names = %w(about title link description) 487 items.each_with_index do |item, i| 488 assert_attributes(attrs[i], names, item) 489 end 490 end 491 end 492 493 def assert_textinput10(attrs, textinput) 494 _wrap_assertion do 495 names = %w(about title description name link) 496 assert_attributes(attrs, names, textinput) 497 end 498 end 499 500 501 def assert_channel09(attrs, channel) 502 _wrap_assertion do 503 n_attrs = normalized_attrs(attrs) 504 505 names = %w(title description link language rating 506 copyright pubDate lastBuildDate docs 507 managingEditor webMaster) 508 assert_attributes(attrs, names, channel) 509 510 %w(skipHours skipDays).each do |name| 511 value = n_attrs[name] 512 if value 513 target = channel.__send__(name) 514 __send__("assert_channel09_#{name}", value, target) 515 end 516 end 517 end 518 end 519 520 def assert_channel09_skipDays(contents, skipDays) 521 _wrap_assertion do 522 days = skipDays.days 523 contents.each_with_index do |content, i| 524 assert_equal(content, days[i].content) 525 end 526 end 527 end 528 529 def assert_channel09_skipHours(contents, skipHours) 530 _wrap_assertion do 531 hours = skipHours.hours 532 contents.each_with_index do |content, i| 533 assert_equal(content.to_i, hours[i].content) 534 end 535 end 536 end 537 538 def assert_image09(attrs, image) 539 _wrap_assertion do 540 names = %w(url link title description) 541 names << ["width", :integer] 542 names << ["height", :integer] 543 assert_attributes(attrs, names, image) 544 end 545 end 546 547 def assert_items09(attrs, items) 548 _wrap_assertion do 549 names = %w(title link description) 550 items.each_with_index do |item, i| 551 assert_attributes(attrs[i], names, item) 552 end 553 end 554 end 555 556 def assert_textinput09(attrs, textinput) 557 _wrap_assertion do 558 names = %w(title description name link) 559 assert_attributes(attrs, names, textinput) 560 end 561 end 562 563 564 def assert_channel20(attrs, channel) 565 _wrap_assertion do 566 n_attrs = normalized_attrs(attrs) 567 568 names = %w(title link description language copyright 569 managingEditor webMaster pubDate 570 lastBuildDate generator docs rating) 571 names << ["ttl", :integer] 572 assert_attributes(attrs, names, channel) 573 574 %w(cloud categories skipHours skipDays).each do |name| 575 value = n_attrs[name] 576 if value 577 target = channel.__send__(name) 578 __send__("assert_channel20_#{name}", value, target) 579 end 580 end 581 end 582 end 583 584 def assert_channel20_skipDays(contents, skipDays) 585 assert_channel09_skipDays(contents, skipDays) 586 end 587 588 def assert_channel20_skipHours(contents, skipHours) 589 assert_channel09_skipHours(contents, skipHours) 590 end 591 592 def assert_channel20_cloud(attrs, cloud) 593 _wrap_assertion do 594 names = %w(domain path registerProcedure protocol) 595 names << ["port", :integer] 596 assert_attributes(attrs, names, cloud) 597 end 598 end 599 600 def assert_channel20_categories(attrs, categories) 601 _wrap_assertion do 602 names = %w(domain content) 603 categories.each_with_index do |category, i| 604 assert_attributes(attrs[i], names, category) 605 end 606 end 607 end 608 609 def assert_image20(attrs, image) 610 _wrap_assertion do 611 names = %w(url link title description) 612 names << ["width", :integer] 613 names << ["height", :integer] 614 assert_attributes(attrs, names, image) 615 end 616 end 617 618 def assert_items20(attrs, items) 619 _wrap_assertion do 620 names = %w(about title link description) 621 items.each_with_index do |item, i| 622 assert_attributes(attrs[i], names, item) 623 624 n_attrs = normalized_attrs(attrs[i]) 625 626 %w(source enclosure categories guid).each do |name| 627 value = n_attrs[name] 628 if value 629 target = item.__send__(name) 630 __send__("assert_items20_#{name}", value, target) 631 end 632 end 633 end 634 end 635 end 636 637 def assert_items20_source(attrs, source) 638 _wrap_assertion do 639 assert_attributes(attrs, %w(url content), source) 640 end 641 end 642 643 def assert_items20_enclosure(attrs, enclosure) 644 _wrap_assertion do 645 names = ["url", ["length", :integer], "type"] 646 assert_attributes(attrs, names, enclosure) 647 end 648 end 649 650 def assert_items20_categories(attrs, categories) 651 _wrap_assertion do 652 assert_channel20_categories(attrs, categories) 653 end 654 end 655 656 def assert_items20_guid(attrs, guid) 657 _wrap_assertion do 658 names = [["isPermaLink", :boolean], ["content"]] 659 assert_attributes(attrs, names, guid) 660 end 661 end 662 663 def assert_textinput20(attrs, textinput) 664 _wrap_assertion do 665 names = %w(title description name link) 666 assert_attributes(attrs, names, textinput) 667 end 668 end 669 end 670end 671