improves consistency of error messages [#110]

This commit is contained in:
rgarcia
2015-08-16 15:49:07 +02:00
parent e4406e5916
commit a81612b226
26 changed files with 222 additions and 166 deletions

View File

@@ -25,6 +25,7 @@ gem 'acts_as_commentable_with_threading'
gem 'acts-as-taggable-on'
gem "responders"
gem 'foundation-rails'
gem 'foundation_rails_helper'
gem 'acts_as_votable'
gem 'simple_captcha2', require: 'simple_captcha'
gem 'ckeditor'

View File

@@ -126,6 +126,12 @@ GEM
foundation-rails (5.5.2.1)
railties (>= 3.1.0)
sass (>= 3.3.0, < 3.5)
foundation_rails_helper (1.0.0)
actionpack (~> 4.1, >= 4.1.1)
activemodel (~> 4.1, >= 4.1.1)
activesupport (~> 4.1, >= 4.1.1)
railties (~> 4.1, >= 4.1.1)
tzinfo (~> 1.2, >= 1.2.2)
globalid (0.3.6)
activesupport (>= 4.1.0)
highline (1.7.3)
@@ -315,6 +321,7 @@ DEPENDENCIES
email_spec
factory_girl_rails
foundation-rails
foundation_rails_helper
i18n-tasks
initialjs-rails
jquery-rails

View File

@@ -3,6 +3,9 @@ App.Comments =
add_response: (parent_id, response_html) ->
$(response_html).insertAfter($("#js-comment-form-#{parent_id}"))
display_error: (field_with_errors, error_html) ->
$(error_html).insertAfter($("#{field_with_errors}"))
reset_and_hide_form: (id) ->
form_container = $("#js-comment-form-#{id}")
input = form_container.find("form textarea")

View File

@@ -1,17 +1,19 @@
class CommentsController < ApplicationController
before_action :authenticate_user!
before_action :build_comment, only: :create
before_action :parent, only: :create
load_and_authorize_resource
respond_to :html, :js
def create
@comment.save!
@comment.move_to_child_of(parent) if reply?
if @comment.save
@comment.move_to_child_of(parent) if reply?
Mailer.comment(@comment).deliver_now if email_on_debate_comment?
Mailer.reply(@comment).deliver_now if email_on_comment_reply?
respond_with @comment
Mailer.comment(@comment).deliver_now if email_on_debate_comment?
Mailer.reply(@comment).deliver_now if email_on_comment_reply?
else
render :new
end
end
def vote

View File

@@ -2,53 +2,38 @@
<div class="small-12 column">
<%= link_to t("account.show.change_credentials_link"), edit_user_registration_path, class: 'button radius small secondary right' %>
<h2 class="inline-block"><%= t("account.show.title") %></h2>
<h1 class="inline-block"><%= t("account.show.title") %></h1>
<%= form_for @account, as: :account, url: account_path do |f| %>
<% if @account.errors.any? %>
<div id="error_explanation" class="alert-box alert radius">
<p><strong><%= pluralize(@account.errors.count, t("debates.form.error"), t("debates.form.errors")) %> <%= t("debates.form.not_saved") %></strong></p>
<ul>
<% @account.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<%= render 'shared/errors', resource: @account %>
<div class="row">
<div class="small-12 medium-6 column">
<h3><%= t("account.show.personal")%></h3>
<%= f.label :first_name, t("account.show.first_name_label") %>
<h2><%= t("account.show.personal")%></h2>
<%= f.text_field :first_name, placeholder: t("account.show.first_name_label") %>
<%= f.label :last_name, t("account.show.last_name_label") %>
<%= f.text_field :last_name, placeholder: t("account.show.last_name_label") %>
<%= f.label :nickname, t("account.show.nickname_label") %>
<%= f.text_field :nickname, placeholder: t("account.show.nickname_label") %>
<%= f.label :use_nickname do %>
<%= f.check_box :use_nickname %>
<span class="checkbox"><%= t("account.show.use_nickname_label") %></span>
<% end %>
<%= f.check_box :use_nickname, label: false %>
<span class="checkbox"><%= t("account.show.use_nickname_label") %></span>
</div>
<div class="small-12 medium-6 column">
<h3><%= t("account.show.avatar")%></h3>
<h2><%= t("account.show.avatar")%></h2>
<%= avatar_image(@account, size: 100) %>
<h3><%= t("account.show.notifications")%></h3>
<h2><%= t("account.show.notifications")%></h2>
<%= f.label :email_on_debate_comment do %>
<%= f.check_box :email_on_debate_comment %>
<div>
<%= f.check_box :email_on_debate_comment, label: false %>
<span class="checkbox"><%= t("account.show.email_on_debate_comment_label") %></span>
<% end %>
</div>
<%= f.label :email_on_comment_reply do %>
<%= f.check_box :email_on_comment_reply %>
<div>
<%= f.check_box :email_on_comment_reply, label: false %>
<span class="checkbox"><%= t("account.show.email_on_comment_reply_label") %></span>
<% end %>
</div>
</div>
<div class="small-12 column">

View File

@@ -0,0 +1,2 @@
<div><%= t("errors.messages.blank").capitalize %></div>

View File

@@ -0,0 +1,2 @@
var field_with_errors = "#js-comment-form-<%= dom_id(@parent) %> #comment_body";
App.Comments.display_error(field_with_errors, "<%= j render('comments/errors') %>");

View File

@@ -1,14 +1,5 @@
<%= form_for(@debate) do |f| %>
<% if @debate.errors.any? %>
<div id="error_explanation" class="alert-box alert radius">
<p><strong><%= pluralize(@debate.errors.count, t("debates.form.error"), t("debates.form.errors")) %> <%= t("debates.form.not_saved") %></strong></p>
<ul>
<% @debate.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<%= render 'shared/errors', resource: @debate %>
<div class="row">
<div class="small-12 column">
@@ -36,13 +27,12 @@
<div class="small-12 column">
<% if @debate.new_record? %>
<%= f.check_box :terms_of_service %>
<span class="checkbox"><%= t("debates.form.accept_terms") %></span>
<%= f.check_box :terms_of_service, label: t("form.accept_terms") %>
<% end %>
</div>
<div class="small-12 column">
<%= f.simple_captcha %>
<%= f.simple_captcha input_html: { required: false } %>
</div>
<div class="actions small-12 column">

View File

@@ -4,11 +4,10 @@
<h1 class="text-center"><%= t("devise_views.confirmations.title") %></h1>
<%= form_for(resource, as: resource_name, url: confirmation_path(resource_name), html: { method: :post }) do |f| %>
<%= devise_error_messages! %>
<%= render 'shared/errors', resource: resource %>
<div class="row">
<div class="small-12 columns">
<%= f.label :email, t("devise_views.confirmations.email_label") %>
<%= f.email_field :email, autofocus: true, placeholder: t("devise_views.confirmations.email_label"), value: (resource.pending_reconfirmation? ? resource.unconfirmed_email : resource.email) %>
</div>

View File

@@ -1,25 +1,30 @@
<h2><%= t("devise_views.passwords.edit.title") %></h2>
<div class="row auth">
<div class="small-12 medium-8 large-5 column small-centered">
<div class="panel">
<h1 class="text-center"><%= t("devise_views.passwords.edit.title") %></h1>
<%= form_for(resource, as: resource_name, url: password_path(resource_name), html: { method: :put }) do |f| %>
<%= devise_error_messages! %>
<%= f.hidden_field :reset_password_token %>
<%= form_for(resource, as: resource_name, url: password_path(resource_name), html: { method: :put }) do |f| %>
<%= render 'shared/errors', resource: resource %>
<div class="field">
<%= f.label :password, t("devise_views.passwords.edit.password_label") %><br />
<% if @minimum_password_length %>
<em><%= t("devise_views.passwords.edit.min_length", min: @minimum_password_length) %></em>
<% end %><br />
<%= f.password_field :password, autofocus: true, autocomplete: "off" %>
<%= f.hidden_field :reset_password_token %>
<div class="field">
<%= f.password_field :password, autofocus: true, autocomplete: "off",
label: t("devise_views.passwords.edit.password_label") %>
</div>
<div class="field">
<%= f.password_field :password_confirmation, autocomplete: "off",
label: t("devise_views.passwords.edit.password_confirmation_label") %>
</div>
<div class="actions">
<%= f.submit t("devise_views.passwords.edit.change_submit") %>
</div>
<% end %>
<%= render "devise/shared/links" %>
</div>
</div>
<div class="field">
<%= f.label :password_confirmation, t("devise_views.passwords.edit.password_confirmation_label") %><br />
<%= f.password_field :password_confirmation, autocomplete: "off" %>
</div>
<div class="actions">
<%= f.submit t("devise_views.passwords.edit.change_submit") %>
</div>
<% end %>
<%= render "devise/shared/links" %>
</div>

View File

@@ -3,10 +3,10 @@
<div class="panel">
<h1 class="text-center"><%= t("devise_views.passwords.new.title") %></h1>
<%= form_for(resource, as: resource_name, url: password_path(resource_name), html: { method: :post }) do |f| %>
<%= devise_error_messages! %>
<%= render 'shared/errors', resource: resource %>
<div class="row">
<div class="small-12 column">
<%= f.label :email, t("devise_views.passwords.new.email_label") %>
<%= f.email_field :email, autofocus: true, placeholder: t("devise_views.passwords.new.email_label") %>
</div>

View File

@@ -6,10 +6,10 @@
<h2><%= t("devise_views.registrations.edit.edit") %> <%= resource_name.to_s.humanize %></h2>
<%= form_for(resource, as: resource_name, url: registration_path(resource_name), html: { method: :put }) do |f| %>
<%= devise_error_messages! %>
<%= render 'shared/errors', resource: resource %>
<div class="row">
<div class="small-12 column">
<%= f.label :email, t("devise_views.registrations.edit.email_label") %>
<%= f.email_field :email, autofocus: true, placeholder: t("devise_views.registrations.edit.email_label") %>
</div>
@@ -22,18 +22,21 @@
<div class="small-12 column">
<%= f.label :password, t("devise_views.registrations.edit.password_label") %>
<span class="note"><%= t("devise_views.registrations.edit.leave_blank") %></span>
<%= f.password_field :password, autocomplete: "off", placeholder: t("devise_views.registrations.edit.password_label") %>
<%= f.password_field :password, autocomplete: "off",
label: false,
placeholder: t("devise_views.registrations.edit.password_label") %>
</div>
<div class="small-12 column">
<%= f.label :password_confirmation, t("devise_views.registrations.edit.password_confirmation_label") %>
<%= f.password_field :password_confirmation, autocomplete: "off", placeholder: t("devise_views.registrations.edit.password_confirmation_label") %>
</div>
<div class="small-12 column">
<%= f.label :current_password, t("devise_views.registrations.edit.current_password_label") %>
<span class="note"><%= t("devise_views.registrations.edit.need_current") %></span>
<%= f.password_field :current_password, autocomplete: "off", placeholder: t("devise_views.registrations.edit.current_password_label") %>
<%= f.password_field :current_password, autocomplete: "off",
label: false,
placeholder: t("devise_views.registrations.edit.current_password_label") %>
</div>
<div class="small-12 column">

View File

@@ -4,36 +4,26 @@
<h2><%= t("devise_views.registrations.new.title") %></h2>
<%= form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f| %>
<%= devise_error_messages! %>
<%= render 'shared/errors', resource: resource %>
<div class="row">
<div class="small-12 column">
<%= f.label :first_name, t("devise_views.registrations.new.first_name_label") %>
<%= f.text_field :first_name, autofocus: true, placeholder: t("devise_views.registrations.new.first_name_label") %>
<%= f.text_field :first_name, autofocus: true,
placeholder: t("devise_views.registrations.new.first_name_label") %>
<%= f.text_field :last_name, placeholder: t("devise_views.registrations.new.last_name_label") %>
<%= f.email_field :email, placeholder: t("devise_views.registrations.new.email_label") %>
<%= f.text_field :nickname, placeholder: t("devise_views.registrations.new.nickname_label") %>
<%= f.label :last_name, t("devise_views.registrations.new.last_name_label") %>
<%= f.text_field :last_name, placeholder: t("devise_views.registrations.new.last_name_label") %>
<%= f.check_box :use_nickname, label: t("devise_views.registrations.new.use_nickname_label") %>
<%= f.label :email, t("devise_views.registrations.new.email_label") %>
<%= f.email_field :email, placeholder: t("devise_views.registrations.new.email_label") %>
<%= f.password_field :password, autocomplete: "off",
placeholder: t("devise_views.registrations.new.password_label") %>
<%= f.label :nickname, t("devise_views.registrations.new.nickname_label") %>
<%= f.text_field :nickname, placeholder: t("devise_views.registrations.new.nickname_label") %>
<%= f.password_field :password_confirmation, autocomplete: "off",
label: t("devise_views.registrations.new.password_confirmation_label"),
placeholder: t("devise_views.registrations.new.password_confirmation_label") %>
<%= f.label :use_nickname do %>
<%= f.check_box :use_nickname %>
<span class="checkbox"><%= t("devise_views.registrations.new.use_nickname_label") %></span>
<% end %>
<%= f.label :password, t("devise_views.registrations.new.password_label"), class: "inline-block" %>
<% if @minimum_password_length %>
<span class="inline-block"><%= t("devise_views.registrations.new.min_length", min: @minimum_password_length) %></span>
<% end %>
<%= f.password_field :password, autocomplete: "off", placeholder: t("devise_views.registrations.new.password_label") %>
<%= f.label :password_confirmation, t("devise_views.registrations.new.password_confirmation_label") %>
<%= f.password_field :password_confirmation, autocomplete: "off", placeholder: t("devise_views.registrations.new.password_confirmation_label") %>
<%= f.simple_captcha %>
<%= f.simple_captcha input_html: {required: false} %>
<%= f.submit t("devise_views.registrations.new.submit"), class: "button radius expand" %>
</div>

View File

@@ -6,21 +6,16 @@
<%= form_for(resource, as: resource_name, url: session_path(resource_name)) do |f| %>
<div class="row">
<div class="small-12 columns">
<%= f.label :email, t("devise_views.sessions.new.email_label") %>
<%= f.email_field :email, autofocus: true, placeholder: t("devise_views.sessions.new.email_label") %>
</div>
<div class="small-12 columns">
<%= f.label :password, t("devise_views.sessions.new.password_label") %>
<%= f.password_field :password, autocomplete: "off", placeholder: t("devise_views.sessions.new.password_label") %>
</div>
<% if devise_mapping.rememberable? -%>
<div class="small-12 columns">
<%= f.label :remember_me do %>
<%= f.check_box :remember_me %>
<span class="checkbox"><%= t("devise_views.sessions.new.remember_me") %>
<% end %>
<%= f.check_box :remember_me, label: t("devise_views.sessions.new.remember_me") %>
</div>
<% end -%>

View File

@@ -1,16 +1,23 @@
<h2><%= t("devise_views.unlocks.new.title") %></h2>
<div class="row auth">
<div class="small-12 medium-8 large-5 column small-centered">
<div class="panel">
<h1 class="text-center"><%= t("devise_views.unlocks.new.title") %></h1>
<%= form_for(resource, as: resource_name, url: unlock_path(resource_name), html: { method: :post }) do |f| %>
<%= devise_error_messages! %>
<%= form_for(resource, as: resource_name, url: unlock_path(resource_name), html: { method: :post }) do |f| %>
<%= render 'shared/errors', resource: resource %>
<div class="field">
<%= f.label :email, t("devise_views.unlocks.new.email_label") %><br />
<%= f.email_field :email, autofocus: true %>
<div class="field">
<%= f.email_field :email, autofocus: true,
label: t("devise_views.unlocks.new.email_label") %>
</div>
<div class="actions">
<%= f.submit t("devise_views.unlocks.new.submit") %>
</div>
<% end %>
<%= render "devise/shared/links" %>
</div>
</div>
<div class="actions">
<%= f.submit t("devise_views.unlocks.new.submit") %>
</div>
<% end %>
<%= render "devise/shared/links" %>
</div>

View File

@@ -0,0 +1,10 @@
<% if resource.errors.any? %>
<div id="error_explanation" class="alert-box alert radius">
<p>
<strong>
<%= pluralize resource.errors.count, t("form.error"), t("form.errors") %>
<%= t("form.not_saved", resource: t("form.#{resource.class.to_s.downcase}")) %>
</strong>
</p>
</div>
<% end %>

View File

@@ -89,6 +89,7 @@ search:
# - '{devise,simple_form}.*'
ignore_missing:
- 'unauthorized.*'
- 'errors.messages.blank'
## Consider these keys used:
ignore_unused:

View File

@@ -29,7 +29,6 @@ en:
edit:
title: "Change your password"
password_label: "New password"
min_length: "%{min} characters minimum"
password_confirmation_label: "Confirm new password"
change_submit: "Change my password"
new:
@@ -56,7 +55,6 @@ en:
use_nickname_label: "Use nickname"
email_label: "Email"
password_label: "Password"
min_length: "(%{min} characters minimum)"
password_confirmation_label: "Confirm password"
submit: "Sign up"
sessions:

View File

@@ -29,7 +29,6 @@ es:
edit:
title: "Cambia tu contraseña"
password_label: "Contraseña nueva"
min_length: "Mínimo %{min} caracteres"
password_confirmation_label: "Confirmar contraseña nueva"
change_submit: "Cambiar mi contraseña"
new:
@@ -56,7 +55,6 @@ es:
use_nickname_label: "Usar pseudónimo"
email_label: "Email"
password_label: "Contraseña"
min_length: "(mínimo %{min} caracteres)"
password_confirmation_label: "Confirmar contraseña"
submit: "Registrarse"
sessions:

View File

@@ -17,6 +17,13 @@ en:
moderation: Moderation
footer:
copyright: "Ayuntamiento de Madrid, 2015. All rights reserved"
form:
error: error
errors: errors
not_saved: "prohibited this %{resource} from being saved:"
accept_terms: I accept the privacy policy and the legal terms
user: account
debate: debate
debates:
index:
create_debate: Create a debate
@@ -41,9 +48,6 @@ en:
other: "%{count} votes"
votes_weighted_score: "Total: %{score}"
form:
error: error
errors: errors
not_saved: "prohibited this debate from being saved:"
debate_title: Debate title
title_instructions: "SBe clear and precise with the title, but make it informative"
debate_text: Ellaborate your opinion
@@ -53,7 +57,6 @@ en:
Tag this idea. You can choose among our proposals on the list or add any other topic you want by
writing them separated by "," and then pressing "enter".
Some suggestions:
accept_terms: I accept the privacy policy and the legal terms
show:
back_link: Back
comments_title: Comments
@@ -105,6 +108,7 @@ en:
simple_captcha:
placeholder: "Enter the image value"
label: "Enter the code in the box"
refresh_button_text: "Refresh"
message:
user: "secret code did not match with the image"
debate: "secret code did not match with the image"

View File

@@ -17,6 +17,13 @@ es:
moderation: Moderar
footer:
copyright: "Ayuntamiento de Madrid, %{year}. Todos los derechos reservados"
form:
error: error
errors: errores
not_saved: "impidieron guardar %{resource}:"
accept_terms: Acepto la política de privacidad y el aviso legal
user: la cuenta
debate: el debate
debates:
index:
create_debate: Crea un debate
@@ -41,9 +48,6 @@ es:
other: "%{count} votos"
votes_weighted_score: "Total: %{score}"
form:
error: error
errors: errores
not_saved: "impidieron guardar el debate:"
debate_title: Título del debate
title_instructions: "Sé claro y conciso a la hora de poner un título, pero recuerda que debe explicar bien tu idea, ¡es tu carta de entrada!"
debate_text: Describe tu opinión
@@ -53,7 +57,6 @@ es:
Etiqueta esta idea. Puedes elegir entre nuestras propuestas o introducir las que desees.
Para ello solo tienes que escribir las etiquetas que desees separadas por "," y pulsar "intro".
Algunas recomendaciones:
accept_terms: Acepto la política de privacidad y el aviso legal
show:
back_link: Volver
comments_title: Comentarios
@@ -105,6 +108,7 @@ es:
simple_captcha:
placeholder: "Introduce el texto de la imagen"
label: "Introduce el texto en la caja"
refresh_button_text: "Refrescar"
message:
user: "el código secreto no coincide con la imagen"
debate: "el código secreto no coincide con la imagen"

View File

@@ -19,19 +19,6 @@ feature 'Account' do
expect(page).to have_selector(avatar('Manuela Colau'), count: 1)
end
scenario "Failed Edit" do
visit account_path
fill_in 'account_first_name', with: ''
fill_in 'account_last_name', with: ''
fill_in 'account_nickname', with: ''
click_button 'Save changes'
expect(page).to have_content "2 errors prohibited this debate from being saved"
expect(page).to have_content "First name can't be blank"
expect(page).to have_content "First name can't be blank"
end
scenario 'Edit' do
visit account_path
@@ -50,4 +37,22 @@ feature 'Account' do
expect(page).to have_selector("input[id='account_email_on_debate_comment'][value='1']")
expect(page).to have_selector("input[id='account_email_on_comment_reply'][value='1']")
end
scenario "Errors on edit" do
visit account_path
fill_in 'account_first_name', with: ''
click_button 'Save changes'
expect(page).to have_content error_message
end
scenario 'Errors editing credentials' do
visit account_path
click_link 'Change my credentials'
click_button 'Update'
expect(page).to have_content error_message
end
end

View File

@@ -10,14 +10,12 @@ feature 'Comments' do
visit debate_path(debate)
expect(page).to have_css('.comment', count: 3)
expect(page).to have_content '3 Comments'
comment = Comment.first
within first('.comment') do
expect(page).to have_content comment.user.name
expect(page).to have_content time_ago_in_words(comment.created_at)
expect(page).to have_content comment.body
expect(page).to have_selector(avatar(comment.user.name), count: 1)
end
end
@@ -51,6 +49,18 @@ feature 'Comments' do
end
end
scenario 'Errors on create', :js do
user = create(:user)
debate = create(:debate)
login_as(user)
visit debate_path(debate)
click_button 'Publish comment'
expect(page).to have_content "Can't be blank"
end
scenario 'Reply', :js do
citizen = create(:user, first_name: 'Ana')
manuela = create(:user, first_name: 'Manuela')
@@ -74,6 +84,23 @@ feature 'Comments' do
expect(page).to_not have_selector("#js-comment-form-comment_#{comment.id}", visible: true)
end
scenario 'Errors on reply', :js do
user = create(:user)
debate = create(:debate)
comment = create(:comment, commentable: debate, user: user)
login_as(user)
visit debate_path(debate)
click_link "Reply"
within "#js-comment-form-comment_#{comment.id}" do
click_button 'Publish reply'
expect(page).to have_content "Can't be blank"
end
end
scenario "N replies", :js do
debate = create(:debate)
parent = create(:comment, commentable: debate)
@@ -86,11 +113,6 @@ feature 'Comments' do
visit debate_path(debate)
expect(page).to have_css(".comment.comment.comment.comment.comment.comment.comment.comment")
expect(page).to have_content '8 Comments'
within first('.comment') do
expect(page).to have_content '1 Response'
end
end
end

View File

@@ -25,7 +25,7 @@ feature 'Debates' do
expect(page).to have_content "Debate description"
expect(page).to have_content debate.author.name
expect(page).to have_content I18n.l(debate.created_at.to_date)
expect(page).to have_selector(avatar(debate.author.name), count: 1)
expect(page).to have_selector(avatar(debate.author.name))
within('.social-share-button') do
expect(page.all('a').count).to be(3) # Twitter, Facebook, Google+
@@ -92,6 +92,15 @@ feature 'Debates' do
end
end
scenario 'Errors on create' do
author = create(:user)
login_as(author)
visit new_debate_path
click_button 'Create Debate'
expect(page).to have_content /error/
end
scenario 'JS injection is prevented but safe html is respected' do
author = create(:user)
login_as(author)
@@ -202,6 +211,17 @@ feature 'Debates' do
expect(page).to have_content "Let's..."
end
scenario 'Errors on update' do
debate = create(:debate)
login_as(debate.author)
visit edit_debate_path(debate)
fill_in 'debate_title', with: ""
click_button 'Update Debate'
expect(page).to have_content error_message
end
scenario 'Captcha is required to update a debate' do
debate = create(:debate)
login_as(debate.author)
@@ -278,15 +298,6 @@ feature 'Debates' do
expect(page).not_to have_content '+'
end
end
scenario 'Debate#show shows the full tag list' do
visit debate_path(debate)
within("#debate-#{debate.id}") do
all_tags.each do |tag|
expect(page).to have_content tag
end
end
end
end
end

View File

@@ -23,6 +23,14 @@ feature 'Users' do
expect(page).to have_content "Your email address has been successfully confirmed"
end
scenario 'Errors on sign up' do
visit '/'
click_link 'Sign up'
click_button 'Sign up'
expect(page).to have_content error_message
end
scenario 'Sign in' do
user = create(:user, email: 'manuela@madrid.es', password: 'judgementday')

View File

@@ -74,4 +74,8 @@ module CommonActions
SCRIPT
end
def error_message
/\d errors? prohibited this (.*) from being saved:/
end
end