I am working with: ruby 3.0.0p0 and Rails 7.0.4 and rspec-rails (6.0.1)
I want to test my views. I created Product model with rails scaffolding. I tested all views but I am not sure about _form.html.erb testing. Because I have two status for this view. One of them is New page and other is Edit page. If I go to Edit page the fields have value but I go to New page the fields have no value.
views/products/_form.html.erb
<%= form_with(model: product, class: "contents") do |form| %>
<% if product.errors.any? %>
<div id="error_explanation" class="bg-red-50 text-red-500 px-3 py-2 font-medium rounded-lg mt-3">
<h2><%= pluralize(product.errors.count, "error") %> prohibited this product from being saved:</h2>
<ul>
<% product.errors.each do |error| %>
<li><%= error.full_message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="my-5">
<%= form.label :title %>
<%= form.text_field :title, class: "block shadow rounded-md border border-gray-200 outline-none px-3 py-2 mt-2 w-full" %>
</div>
<div class="my-5">
<%= form.label :description %>
<%= form.text_area :description, rows: 4, class: "block shadow rounded-md border border-gray-200 outline-none px-3 py-2 mt-2 w-full" %>
</div>
<div class="my-5">
<%= form.label :image_url %>
<%= form.text_field :image_url, class: "block shadow rounded-md border border-gray-200 outline-none px-3 py-2 mt-2 w-full" %>
</div>
<div class="my-5">
<%= form.label :price %>
<%= form.text_field :price, class: "block shadow rounded-md border border-gray-200 outline-none px-3 py-2 mt-2 w-full" %>
</div>
<div class="inline">
<%= form.submit class: "rounded-lg py-3 px-5 bg-blue-600 text-white inline-block font-medium cursor-pointer" %>
</div>
<% end %>
So I used Nokogiri for catching inputs value. But I am not sure about that and I couldn't best practice for that.
This is my code:
spec/views/products/_form.html.erb_spec.rb
require "rails_helper"
RSpec.describe "rendering locals in a partial", type: :view do
subject { Nokogiri::HTML(rendered) }
it "form for editing the product" do
product = Product.create!(title: "dicer", description: "Hello World 2", price: 10.1)
render :partial => "products/form", :locals => { :product => product }
aggregate_failures do
expect(subject.at('input[@name="product[title]"]')['value']).to eq(product.title)
expect(subject.at('textarea[@name="product[description]"]').text.strip).to eq(product.description)
expect(subject.at('input[@name="product[image_url]"]')['value']).to eq(product.image_url)
expect(subject.at('input[@name="product[price]"]')['value'].to_f).to eq(product.price.to_f)
expect(rendered).to have_button('Update Product')
end
end
it "form for creating a product" do
product = Product.new
render :partial => "products/form", :locals => { :product => product }
aggregate_failures do
expect(subject.at('input[@name="product[title]"]')['value']).to eq(nil)
expect(subject.at('textarea[@name="product[description]"]').text.strip).to eq("")
expect(subject.at('input[@name="product[image_url]"]')['value']).to eq(nil)
expect(subject.at('input[@name="product[price]"]')['value']).to eq(nil)
expect(rendered).to have_button('Create Product')
end
end
end