assert_select, failure to find desired text - ruby

I am unsure why assert_select ".title", text: "Title".to_s, count: 2, returns 0 results.
index.html.erb:
<p style="color: green"><%= notice %></p>
<h1>Events</h1>
<div id="events">
<% #events.each do |event| %>
<%= render event %>
<p>
<%= link_to "Show this event", event %>
</p>
<% end %>
</div>
<%= link_to "New event", new_event_path %>
_event.html.erb:
<div class="events" id="<%= dom_id event %>">
<p class="title">
Title:
<%= event.title %>
</p>
<p class="description">
<strong>Description:</strong>
<%= event.description %>
</p>
<p class="price">
<strong>Price:</strong>
<%= event.price %>
</p>
<p class="date">
<strong>Date:</strong>
<%= event.date %>
</p>
</div>
views/events/index.html.erb_spec.rb:
require 'rails_helper'
require "date"
RSpec.describe "events/index", type: :view do
before(:each) do
assign(:events, [
Event.create!(
title: "Title",
description: "Description",
price: 2,
date: Date.today
),
Event.create!(
title: "Title",
description: "Description",
price: 2,
date: Date.today
)
])
end
it "renders a list of events" do
render
assert_select ".title", text: "Title".to_s, count: 2
assert_select ".description", text: "Description".to_s, count: 2
assert_select ".price", text: 2.to_s, count: 2
assert_select ".date", text: Date.today.to_s, count: 2
end
end
Failure:
1) events/index renders a list of events
Failure/Error: assert_select ".title", text: "Title".to_s, count: 2
Minitest::Assertion:
<Title> expected but was
<Title:
Title>..
Expected: 2
Actual: 0
# ./spec/views/events/index.html.erb_spec.rb:24:in `block (2 levels) in <main>'
Console of debugger to check what assert_select ".title" returns:
(ruby) assert_select ".title"
[#<Nokogiri::XML::Element:0x8840 name="p" attributes=[#<Nokogiri::XML::Attr:0x8818 name="class" value="title">] children=[#<Nokogiri::XML::Text:0x882c "\n Title:\n Title\n ">]>, #<Nokogiri::XML::Element:0x887c name="p" attributes=[#<Nokogiri::XML::Attr:0x8854 name="class" value="title">] children=[#<Nokogiri::XML::Text:0x8868 "\n Title:\n Title\n ">]>]
(rdbg)
Could someone suggest why assert_select and my search for "Title" is returning 0 results and not the expected 2? :)

You might have to change the matching text from Title to Title: and similarly change Description to Description:.
E.g.
it "renders a list of events" do
render
assert_select ".title", text: "Title:", count: 2
assert_select ".description", text: "Description:", count: 2
assert_select ".price", text: 2.to_s, count: 2
assert_select ".date", text: Date.today.to_s, count: 2
end

Many thanks - it looks like the following using a regex match actually works, though I am not sure if this is best practice:
it "renders a list of events" do
render
assert_select ".title", /Title:/, count: 2
assert_select ".description", /Description:/, count: 2
assert_select ".price", /2/, count: 2
assert_select ".date", /#{Date.today.to_s}/, count: 2
end

Related

RailsTutorial Ch 9 Test fail on pagination and delete link

Going through rails tutorial and stuck on chapter 9 for this last error.
FAIL["test_index_as_admin_including_pagination_and_delete_links", UsersIndexTest, 1.799453]
test_index_as_admin_including_pagination_and_delete_links#UsersIndexTest (1.80s)
<delete> expected but was
<User 19>..
Expected 0 to be >= 1.
test/integration/users_index_test.rb:18:in `block (2 levels) in <class:UsersIndexTest>'
test/integration/users_index_test.rb:15:in `block in <class:UsersIndexTest>'
Here is my test block from users_index_test.rb
test "index as admin including pagination and delete links" do
log_in_as(#admin)
get users_path
assert_template 'users/index'
assert_select 'div.pagination'
first_page_of_users = User.paginate(page: 1)
first_page_of_users.each do |user|
assert_select 'a[href=?]', user_path(user), text: user.name
unless user == #admin
assert_select 'a[href=?]', user_path(user), text: 'delete'
end
end
assert_difference 'User.count', -1 do
delete user_path(#non_admin)
end
end
Had a typo in my app/views/users/_users.html.erb, fixing it helped me pass the test.
Right code is as -
<li>
<%= gravatar_for user, size: 50 %>
<%= link_to user.name, user %>
<% if current_user.admin? && !current_user?(user) %>
| <%= link_to "delete", user, method: :delete,
data: { confirm: "You sure?" } %>
<% end %>
</li>

Carrierwave error messages not being displayed

I have a form that uploads files via an ajax call (using the remotipart gem), not sure if this is related but when validation fails with file type (using carrierwave white list), I can't get the error message to display in the view, even though other error messages will show (say when file size is to large).
So in my Uploader class
class MediaUploader < CarrierWave::Uploader::Base
def extension_white_list
%w(jpg jpeg gif png docx mp4 pdf)
end
end
So in my form I will attatch a csv file, click submit and the request and responses look like so
Processing by DocumentsController#create as JS
Parameters: {"utf8"=>"✓",
"document"=>
{"skill_id"=>"1",
"media_cache"=>"",
"media"=>#<ActionDispatch::Http::UploadedFile:0x000000070157a0 #tempfile=#<Tempfile:/tmp/RackMultipart20150205-4409-ltyy7t.csv>, #original_filename="csvtest.csv", #content_type="text/csv", #headers="Content-Disposition: form-data; name=\"document[media]\"; filename=\"csvtest.csv\"\r\nContent-Type: text/csv\r\n">},
"commit"=>"Upload",
"remotipart_submitted"=>"true",
"authenticity_token"=>"token here",
"X-Requested-With"=>"IFrame",
"X-Http-Accept"=>"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript, */*; q=0.01"
}
(1.8ms) BEGIN
(2.7ms) ROLLBACK
In my controller I have grabbed the error messages #document.errors
#<ActiveModel::Errors:0x0000000666e418
#base=#
<Document id: nil,
media: nil,
user_id: 1,
skill_id: 1,
created_at: nil,
updated_at: nil>,
#messages={:media=>[
"You are not allowed to upload \"csv\" files, allowed types: jpg, jpeg, gif, png, docx, mp4, pdf",
"At least 1 File is required"
]
}>
After this the relevant controller action/views are called
Rendered documents/_document_form.html.erb (5.1ms)
Rendered documents/create.js.erb (7.7ms)
Completed 200 OK in 167ms (Views: 83.2ms | ActiveRecord: 64.6ms)
My form is set out to iterate through each of the error messages but it doesn't display them
_document_form
<%= form_for #document, remote: true, html: { multipart: true, id: #document.object_id.to_s, class: 'upload_document' } do |f| %>
<% if #document.errors.any? %>
<h2><%= pluralize(#document.errors.count, "error") %> prohibited this record from being saved</h2>
<ul class="error_list">
<% #document.errors.full_messages.each do |msg| %>
<li><%= error_edit(msg) %></li>
<% end %>
</ul>
<% end %>
<%= f.hidden_field :skill_id %>
<%= f.label :media %>
<%= f.file_field :media %>
<%= f.submit 'Upload', class: 'btn btn-success' %>
<div class="js-error"></div>
<% end %>
create action
def create
#document = current_user.documents.new(document_params)
respond_to do |format|
if #document.save
format.html { redirect_to root_path, notice: success_save_msg }
#format.js { render :js => "window.location.href='"+root_path+"'", notice: success_save_msg }
else
format.html
format.js { render action: 'create.js.erb' }
ap(#document.errors)
end
end
end
create.js.erb
$("#<%= #document.skill_id %>").html("<%= j render(partial: 'documents/document_form', locals: { skill_id: #document.skill_id }) %>")
Also I'm looking at the response in the net tab and it's clearly returning the error messages:
<textarea data-type="text/javascript" data-status="200" data-statusText="OK">$
("#1").html("<\n<form id=\"55100200\" class=\"upload_document\" enctype=\"multipart/form-data\" action=\"/documents\" accept-charset=\"UTF-8\" data-remote=\"true\" method=\"post\"><input name=\"utf8\" type=\"hidden\" value=\"✓\" />\n <div id=\"error_explanation\" class=\"alert alert-dismissable\">\n <button type=\"button\" class=\"close\" data-dismiss=\"alert\"><span aria-hidden=\"true\">×<\/span><span class=\"sr-only\">Close<\/span><\/button>\n <h2>2 errors prohibited this record from being saved<\/h2>\n <ul class=\"error_list\">\n <li> You are not allowed to upload "csv" files, allowed types: jpg, jpeg, gif, png, docx, mp4, pdf<\/li>\n <li> At least 1 File is required<\/li>\n <\/ul>\n <\/div>\n\n <input value=\"1\" class=\"skill_id\" type=\"hidden\" name=\"document[skill_id]\" id=\"document_skill_id\" />\n\n <label class=\"custom-file-upload btn btn-info\" for=\"document_media_60835260\">\n <span class=\"glyphicon glyphicon-cloud-upload\"><\/span>\n Find File\n<\/label>\n <input class=\"document_file_field\" id=\"document_media_60835260\" type=\"file\" name=\"document[media]\" />\n <input type=\"hidden\" name=\"document[media_cache]\" id=\"document_media_cache\" />\n\n <input type=\"submit\" name=\"commit\" value=\"Upload\" class=\"btn btn-success\" />\n <div class=\"js-error\"><\/div>\n\n<\/form>")
</textarea>
Can anyone see why the error messages would not display when coming from carrierwave as opposed to a validation from within my Document model?
Thought I Would share this so if anyone else has the same problem it might help. I came across this this Blog. Which then led me to This stackoverflow post.
Turns out i just needed to set the message (or custom message if I wanted) in my en.yml file and carrierwave did the rest
en:
errors:
messages:
extension_white_list_error: 'My Custom Message'
Hope this helps someone
Thats my en.yml
en:
hello: "Hello world"
errors:
messages:
extension_white_list_error: 'My Custom Message'
EDIT This fixed my script
en:
# hello: "Hello world"
errors:
messages:
extension_whitelist_error: "You are not allowed to upload %{extension} files, allowed types: %{allowed_types}"

Ruby on Rails disabled field in form select not working

<%= f.select :minutes, options_for_select([['1 hour', 60], ['1 hour and a half', 90], ['2 hours', 120]][0..(#minutes_to_schedule/30-2)], 60), {}, {disabled: true} %>
I checked the Form Helper API but despite following suit my options were still not disabled, is there anything I'm overlooking? I looked at the other stacked posts and it doesn't seem like I'm doing anything wrong
<%= form_for(#session_date, html: {class: 'no_custom'}) do |f| %>
<%= f.hidden_field :student_id, value: #student.id %>
<%= hidden_field_tag 'from', schedule_student_path(id: #student.id) %>
<div id="appointment_display"></div>
<input id="appointment_at" type="datetime-local" name="appointment[at]" step="900" min= "some_time" max="max_time" required="required" placeholder="Use Chrome!" style="width: auto; display: none;"/>
<br/>
<div id="appointment_location_display"></div>
<br/>
<%= f.select :minutes, options_for_select(#appointment_time_options, 60) %>
<br/>
<%= f.collection_select(:location_id, Location.order('city, state, address'), :id, :name, {}, {class: 'dont_display'}) %>
<%= f.submit 'Create Appointment' %>
<br/>
<% end %>
disabled: true should be the 4th parameter
Check the definition below
options_from_collection_for_select(collection, value_method, text_method, selected = nil)
So, the correct way to do it ...
<%= f.select : minutes, options_for_select( ([['1 hour', 60], ['1 hour and a half', 90], ['2 hours', 120]]), {}, {}, { disabled: true } )%>
This looks correct.
When I copy/paste this:
<%= f.select : minutes, options_for_select([['1 hour', 60], ['1 hour and a half', 90], ['2 hours', 120]]), {}, { disabled: true }%>
Into a Rails app, the correct form element gets generated:
<select disabled="disabled" id="post_minutes" name="post[minutes]">
<option value="60">1 hour</option>
<option value="90">1 hour and a half</option>
<option value="120">2 hours</option>
</select>
and the element is disabled like it should be. Is there any JS manipulating this field? Would you mind providing your whole form so I can help you out?

rails 3 - I18n::InvalidLocaleData

I am making my website multilanguage using this railscast
But at the very beginning I get an error:
I18n::InvalidLocaleData in Users#index
Showing .../app/views/users/index.html.erb where line #1 raised:
can not load translations from .../config/locales/en.yml, expected it to return a hash, but does not
index.html.erb:
<% provide(:title, t('users.index.title.site_title')) %>
<h1><%= t 'users.index.title.head' %></h1>
<%= form_tag users_path, :method => 'get' do %>
<%= hidden_field_tag :direction, params[:direction] %>
<%= hidden_field_tag :sort, params[:sort] %>
<p>
<%= text_field_tag :search, params[:search] %>
<%= submit_tag (t 'users.index.search_form.search'), :name => nil %>
</p>
<% end %>
config/locales/en.yml
en:
users:
index:
title:
site_title: "Users"
head: "Users"
search_form:
search: "Search"
Locale data should be indented two spaces, not four, so correct version is:
en:
users:
index:
title:
site_title: "Users"
head: "Users"
search_form:
search: "Search"
Also, check if you're using spaces or tabs, latter will cause troubles.

Rails tutorial - Section 5.2 Routing/Rspec error

Ruby newbie here. I'm following the Rails Tutorial and got stuck around 5.3 re: routes.
I have 5 pages(home, about, help, contact), all with similar test set, and rspec is only failing for the tests on 'home'. Since I'm using application_helper, I shouldn't need to specify in home.html.erb, right? I also took the advise of understanding rails routes: match vs root in routes.rb and added "match '/static_pages/home' => 'static_pages#home'" to routes.db.
Been stuck on these 2 errors for a while. Please help. Thanks!
Errors:
1) Static pages Home page should have the h1 'Sample App'
Failure/Error: page.should have_selector('h1', text: 'Sample App')
expected css "h1" with text "Sample App" to return something
# ./spec/requests/static_pages_spec.rb:9:in `block (3 levels) in <top (required)>'
2) Static pages Home page should have the base title
Failure/Error: page.should have_selector('title',
expected css "title" with text "Ruby on Rails Tutorial Sample App" to return something
# ./spec/requests/static_pages_spec.rb:13:in `block (3 levels) in <top (required)>'
home.html.erb
<div class="center hero-unit">
<h1>Welcome to the Sample App</h1>
<h2>
This is the home page for the
Ruby on Rails Tutorial
sample application.
</h2>
<%= link_to "Sign up now!", '#', class: "btn btn-large btn-primary" %>
</div>
<%= link_to image_tag("rails.png", alt: "Rails"), 'http://rubyonrails.org/' %>
static_pages_spec.rb
require 'spec_helper'
describe "Static pages" do
describe "Home page" do
it "should have the h1 'Sample App'" do
visit root_path
page.should have_selector('h1', text: 'Sample App')
end
it "should have the base title" do
visit root_path
page.should have_selector('title', text: "Ruby on Rails Tutorial Sample App")
end
it "should not have a custom page title" do
visit root_path
page.should_not have_selector('title', text: '| Home')
end
end
application.html.erb
<!DOCTYPE html>
<html>
<head>
<title><%= full_title(yield(:title)) %></title>
<%= stylesheet_link_tag "application", media: "all" %>
<%= javascript_include_tag "application" %>
<%= csrf_meta_tags %>
<%= render 'layouts/shim' %>
</head>
<body>
<%= render 'layouts/header' %>
<div class="container">
<%= yield %>
<%= render 'layouts/footer' %>
</div>
</body>
</html>
application_helper.rb
module ApplicationHelper
# Returns the full title on a per-page basis.
def full_title (page_title)
base_title = "Ruby on Rails Tutorial Sample App"
if page_title.empty?
base_title
else
"#{base_title} | #{page_title}"
end
end
end
routes.rb
SampleApp::Application.routes.draw do
match '/help', to: 'static_pages#help'
match '/about', to: 'static_pages#about'
match '/contact', to: 'static_pages#contact'
match '/static_pages/home' => 'static_pages#home'
root to: 'static_pages#home'
end
Let me know if you need anything else. Thanks!
Have you removed the public/index.html file and visually verified that you can get to / in your browser, and that the expected template is being rendered? Your spec looks OK otherwise.

Resources