Search code examples
ruby-on-railsrspecfactoryfaker

Rspec controller test failing with Apostrophe Character?


Right now I have unit tests that are failing using the "Faker" Company Name.

it seems like the expect(response.body).to match(@thing.name) is whats getting messed up.

When looking at the error, the Faker Company names will sometimes have things like "O'Brian Company" or "O'Hare Company" or similar.

Is faker an encoded string? since I know it's not a good idea to match on encoded strings, and I really don't want to just specify a specific company name in the Factory im using.

Thanks


Solution

  • Faker won't do any encoding for you. It will just give you a string like O'Malley. But the response should have HTML escaping (or some other kind, depending on the format), like O'Malley. You could always puts response.body to see for sure.

    The RSpec matches matcher is really designed for either expected or actual to be a regular expression, but in your case both are strings. Because the code has an optimization calling values_match? which does a simple comparison, you are effectively saying expect(response.body).to eq(@thing.name).

    If you do want a regular expression, you are right that you should be careful using uncontrolled values to create it. Fortunately Ruby has Regexp.escape for that, so you can say Regexp.new("foo" + Regexp.escape(@thing.name) + "bar"). But from your objection to include, it sounds like you actually want the response to contain nothing but the name, right? In that case, you don't need a regex at all.

    In any case, the problem isn't about what's around the name, but how the name is escaped. So before comparing you should either (1) decode the response or (2) encode the faker string. It doesn't really matter which. Both are pretty easy:

    expect(CGI.unescapeHTML(response.body)).to eq @thing.name
    

    or

    expect(response.body).to eq CGI.escapeHTML(@thing.name)
    

    Naturally, if your response is JSON, you should replace all this HTML escaping stuff with JSON, etc.