This post originated from an RSS feed registered with Ruby Buzz
by Rick DeNatale.
Original Post: Validating RSS Feeds with RSpec
Feed Title: Talk Like A Duck
Feed URL: http://talklikeaduck.denhaven2.com/articles.atom
Feed Description: Musings on Ruby, Rails, and other topics by an experienced object technologist.
One of my current Rails projects involves generating an RSS feed. While I was working on this the other night, it seemed to be working, so I deployed it to the staging server. Everything looked fine. If I fetched it with Firefox, the browser offered to let me subscribe to the feed with Google Reader, and if I used Safari I'd see a nice view of the feed just like I expected.
So I sent a note via our campfire to check it out, and a colleague replied that his Safari was saying that it was in an invalid format.
So I went to the W3 RSS Feed Validation Service and worked through the validation issues, after which his browser was as happy as mine.
Of course, having been through that, I wanted to make sure that RSS validation was covered in the specs for the project.
I then found the feedvalidator gem which provides a Ruby interface to the SOAP interface to the W3 feed validator. You would think that W3 would be providing a REST interface! The gem already provides assertions for use with Test::Unit, so I just built an RSpec matcher.
class BeValidFeedrequire'feed_validator'require'tmpdir'require'md5'def matches?(response)returntrueifvalidity_checks_disabled?v=W3C::FeedValidator.new()fragment=response.bodyfilename=File.joinDir::tmpdir,'feed.'+MD5.md5(fragment).to_sbeginresponse=File.openfilenamedo|f|Marshal.load(f)endv.parse(response)rescueunlessv.validate_data(fragment)@failure=" could not access w3 validator to validate the feed."returnfalseendFile.openfilename,'w+'do|f|Marshal.dumpv.response,fendendv.valid?enddef description"be valid xhtml"enddef failure_message@failure||" expected xhtml to be valid, but validation produced these errors:\n#{@message}"enddef negative_failure_message" expected to not be valid, but was (missing validation?)"endprivatedef validity_checks_disabled?ENV["NONET"]=='true'endenddef be_valid_feedBeValidFeed.newend
I saved this as spec/be_valid_feed.rb
And in a view or controller spec, I can include this file, and test a response with:
response.should be_valid_feed
If you use this in a controller spec, you will need to tell RSpec to integrate_views, or you won't have much of a feed to check. If you use nested example groups, integrate_views needs to be inside the inner group.