1
votes

I'm new and trying to learn Rails using the book Agile Web Development with Rails, Fourth Edition (for Rails 3.2). Been able to get through all of the chapters so far without hiccups. If there were errors, it was usually my sloppy code (forgetting a comma, 'end' statement, etc.). But now I've hit a snag in the chapter on Unit Testing for Models. At the part where we're validating that the image URL ends with either .gif, .jpg, or .png.

I copied the code verbatim from the book for the depot/test/product_test.rb file:

test "image url" do
ok = %w{ fred.gif fred.jpg fred.png FRED.JPG FRED.Jpg http://a.b.c/x/y/z/fred.gif }
bad = %w{ fred.doc fred.gif/more fred.gif.more }

ok.each do |name|
    assert new_product(name).valid?, "#{name} shouldn't be invalid"
end
bad.each do |name|
    assert new_product(name).invalid?, "#{name} shouldn't be valid"
end

But when I run the rake test:units command, I get the following failure...

1) Failure:
test_image_url(ProductTest)[../depot/test/unit/product_test.rb:46]:
fred.gif shouldn't be invalid

4 tests, 13 assertions, 1 failures, 0 errors, 0 skips
rake aborted!

Does this mean that the image URL it's testing is invalid? Why is the test failing if what it says "fred.gif shouldn't be invalid" is correct?

I'm pretty confident that it's this part of the test that must be incorrect because the other tests I have in there (ex. "product attributes must not be empty", "product price must be positive", etc.) run just fine. I get no failures if I take out the "test image url" code block.

Please let me know what I'm doing wrong. If you need me to post the entirety of the ProductTest, I can.


UPDATE: There was a typo in my Products model that was causing the test to fail. All fixed now.

4

4 Answers

3
votes

I had the same problem and I had to change my definition for new_product. In my initial definition, I had quotation marks around 'image url'. Once I removed the quotes, I was fine. Here's the code (my initial mistake was on the fifth line of my code):

def new_product(image_url)
  Product.new(title:       "My Book Title",
               description: "yyy",
               price:       1,
               image_url:   image_url)
end

test "image url" do
  ok = %w{ fred.gif fred.jpg fred.png FRED.JPG FRED.Jpg
         http://a.b.c/x/y/z/fred.gif }
  bad = %w{ fred.doc fred.gif/more fred.gif.more }

  ok.each do |name|
    assert new_product(name).valid?, "#{name} shouldn't be invalid"
  end

  bad.each do |name|
    assert new_product(name).invalid?, "#{name} shouldn't be valid"
  end
end

As you can see, I didn't use the '_' in my test name and my tests passed.

0
votes

I believe the problem is in the definition for function 'new_product'. Make sure the function is setting all fields to valid data. Mine wasn't setting the description to a valid value. I hope this helps. You probably already found this solution already but didn't update your post.

What I'm saying is that the product is failing due to some other field. The test that's failing is checking that there are no errors in a product constructed with each image_url. You just need to check that the constructor function, new_product, can construct a valid product.

0
votes

Seems like you are missing underscore _

test "image url" do

should be

test "image_url" do

You can the paragraph from my file here:

test "image_url" do
ok = %w{ fred.gif fred.jpg fred.png FRED.JPG FRED.Jpg   http://a.b.c/x/y/z.gif}
bad = %w{ fred.doc fred.gif/more fred.gif.more }
ok.each do |name|
    assert new_product(name).valid?, "#{name} shouldn't be invalid"
end
bad.each do |name|
    assert new_product(name).invalid?, "#{name} shouldn't be valid"
end
0
votes

I was just struggling with this. There was also a typo in model. With my validations. I grouped the \Z with the png. It needs to be outside the capture group.

wrong:

class Product < ApplicationRecord
  validates :title, :description, :image_url, presence: true
  validates :price, numericality: { greater_than_or_equal_to: 0.01 }
  validates :title, uniqueness: true
  validates :image_url, allow_blank: true, format: {
    with: %r{\.(gif|jpg|png\Z)}i, # <<<<<----
    message: 'must be a URL for GIF, JPG, or PNG image.'
  }
end

right:

class Product < ApplicationRecord
  validates :title, :description, :image_url, presence: true
  validates :price, numericality: { greater_than_or_equal_to: 0.01 }
  validates :title, uniqueness: true
  validates :image_url, allow_blank: true, format: {
    with: %r{\.(gif|jpg|png)\Z}i, # <<<<<----
    message: 'must be a URL for GIF, JPG, or PNG image.'
  }
end