A Rails 4.2 application has several models with attributes containing URLs. URL validation is done at the model with validates :website_url, format: { with: /\A(https?|ftp):\/\/(-\.)?([^\s\/?\.#-]+\.?)+(\/[^\s]*)?\z/i }
.
I need to test the URL validation with RSpec 3.5. It is important to ensure that some well-known XSS patterns do not pass validation and that the most commonly used URL patterns pass validation.
Ideally, I'd like to avoid adding one test for each valid and invalid URL I'm testing so the rspec -fd
output is not polluted. However, that would probably require creating two tests (one for valid URLs and other for invalid URLs) and adding multiple expectations to each test (one expectation per URL), which does not seem like good idea.
The best solution I've come up with so far are the following shared examples. Can you think of a better way to test URL validation thoroughly?
RSpec.shared_examples "url validation" do |attribute|
INVALID_URLS = [
"invalidurl",
"inval.lid/urlexample",
"javascript:dangerousJs()//http://www.validurl.com",
# Literal array is required for \n to be parsed
"http://www.validurl.com\n<script>dangerousJs();</script>"
]
VALID_URLS = [
"http://validurl.com",
"http://ift.tt/2ufhCLR"
]
INVALID_URLS.each do |url|
it "is invalid with #{url} in #{attribute}" do
object = FactoryGirl.build(factory_name(subject), attribute => url)
object.valid?
expect(object.errors[attribute]).to include("is invalid")
end
end
VALID_URLS.each do |url|
it "is valid with #{url} in #{attribute}" do
object = FactoryGirl.build(factory_name(subject), attribute => url)
object.valid?
expect(object).to be_valid
end
end
end
Within the model specs:
include_examples "url validation", :website_url
Aucun commentaire:
Enregistrer un commentaire