ruby-on-railsrubymodelrspecactioncontroller

Why does Rails sanitize() perform differently in rspec than in a model?


In my config/initializers I added the following to the String class:

class String
  def sanitize(options={ tags: %w(div p span strong b em i br ol ul li) })
    ActionController::Base.helpers.sanitize(self, options)
  end
end

On my local development site, this converts all disallowed tags to encoded html, so

"<span><img src=\"nonexistent.png\" onerror=\"alert('This alert should not be shown');\"></span><p>Build something</p>"

becomes

"<span>&lt;img src=\"nonexistent.png\" onerror=\"alert('This alert should not be shown');\"/&gt;</span><p>Build something</p> "

But in rspec, calling the same method on the same string results in:

"<span></span><p>Build something</p>"

It is not encoding the image tag anymore; it is just stripping the tag out altogether. What is the cause of this different behavior in a model spec than in a model?


Solution

  • Hard to know. Easy to find out. Mostly: don't do that.

    Hard to know: Something else is clobbering your sanitize method or you're clobbering someone else's?

    Easy to find out: Write a test. Set a breakpoint before calling sanitize. Step into it and keep stepping. You'll probably see what's going on pretty quickly.

    Don't do that:

    1. Other things either add that method or you can call sanitize from something else. I'm not sure what the right solution is for you, but probably a controller or helper method sanitize(string, options) is better than doing what you've done. After all, that's what you're calling.
    2. If you have to add a method, don't open the class and clobber like you've done:
    module StringSanitizer
      def sanitize(...)
        super # if appropriate - see if it already exists in the class or if something else has already added it
        ActionController::Base.helpers.sanitize(self, options)
      end
    end
    String.prepend(StringSanitizer)