Search code examples
ruby-on-railsruby-on-rails-3escapingfunctional-testingactioncontroller

assert_select to test raw or html_safe unescaped content


In a Rails 3.2.8 controller test, I'd like to use an assert_select to control the content an unescaped field rendered in my view using the raw or the #html_safe method :

<div id="summary">
    <%= raw @doc.summary %>
</div>

But in my test, both these assertions fail :

# Fixture loading in doc variable, get :show, assert_response ...
assert_select('#summary', doc.summary)
assert_select('#summary', doc.summary.html_safe)

If my summary is something like <p>Stuff:</p><ul><li>Stuff1</li><li>Stuff1</li></ul>, then the test tells me, for both lines, that :

<"<p>Stuff:</p><ul><li>Stuff1</li><li>Stuff2</li></ul>">
expected but was
<"Stuff:\n  \n    Stuff1\n    Stuff2">

When in test mode, it seems to render the view with \n instead of HTML tags, as if escaping for a CLI display.

But when I launch the server and display my page in the browser, this part is rendered with HTML tags and no \n.

Is it a bug in the controller test rendering engine ? Do you know how to avoid it ?


Solution

  • Found the solution :

    assert_select('#summary', :html => doc.summary)
    

    This way, whatever transformation applied to the DOM-selected content is also applied to the second arg before comparison.


    NB: Beware of the way you write your fixtures though.

    The following syntax:

    doc:
      summary: |
        <p>Stuff:</p><ul><li>Stuff1</li><li>Stuff2</li></ul>
    

    gets a final extra \n from the assert_select, compared to :

    doc:
      summary: <p>Stuff:</p><ul><li>Stuff1</li><li>Stuff2</li></ul>
    

    I have no idea why this occurs, but it makes the assert fail.