Ruby Build a Todo List Application with Rails 4 Build a Todo List Application with Rails 4 Adding Validations to Todo Items

Richard McGrath
Richard McGrath
5,597 Points

I have not been able to solve the following error:

1) Adding todo items displays an error with content less than 2 characters long
     Failure/Error: expect(page).to have_content('There was a problem adding that todo list item')
       expected to find text "There was a problem adding that todo list item" in "2 errors Prohibited this todo item from being saved: Content can't be blank Content is too short (minimum is 3 characters)"

# ./spec/features/todo_items/create_spec.rb:30:in `block (3 levels) in <top (required)>'
# ./spec/features/todo_items/create_spec.rb:29:in `block (2 levels) in <top (required)>'

Here is my code below.

create_spec.rb

require 'rails_helper'

describe 'Adding todo items' do
  let!(:todo_list) {TodoList.create(title: 'Grocery list', description: 'Grocery' ) }

  def visit_todo_list(list)
    visit '/todo_lists'
    within "#todo_list_#{list.id}" do
      click_link 'List Items'
    end
  end

  it 'Is successful with valid contnt' do
    visit_todo_list(todo_list)
    click_link 'New Todo Item'
    fill_in 'Content', with: 'Milk'
    click_button 'Save'
    expect(page).to have_content('Added todo list item')
    within('ul.todo_items') do
      expect(page).to have_content('Milk')
    end
  end

  it 'displays an error with content less than 2 characters long' do
    visit_todo_list(todo_list)
    click_link 'New Todo Item'
    fill_in 'Content', with: ''
    click_button 'Save'
    within('div.flash') do
      expect(page).to have_content('There was a problem adding that todo list item')
    end
    expect(page).to have_content('Content is too short')
  end
end

todo_items_controller.rb

class TodoItemsController < ApplicationController
  def index
    @todo_list = TodoList.find(params[:todo_list_id])
  end

  def new
    @todo_list = TodoList.find(params[:todo_list_id])
    @todo_item = @todo_list.todo_items.new
  end

  def create
    @todo_list = TodoList.find(params[:todo_list_id])
    @todo_item = @todo_list.todo_items.new(todo_item_params)
    if @todo_item.save
      flash[:success] = 'Added todo list item'
      redirect_to todo_list_todo_items_path
    else
      flash[:error] = 'There was a problem adding that todo list item'
      render action: :new
    end
  end

  private

  def todo_item_params
    params[:todo_item].permit(:content)
  end
end

new.html.erb

<%= form_for [@todo_list, @todo_item] do |form| %>
  <% if @todo_item.errors.any? %>
    <div id="error_explanation" class="flash">
      <h2><%= pluralize(@todo_item.errors.count, 'error') %> Prohibited this todo item from being saved:</h2>
    <ul>
      <% @todo_item.errors.full_messages.each do |msg| %>
      <li><%= msg %></li>
      <% end %>
    </ul>
  </div>
 <% end %>

  <%= form.label :content %>
  <%= form.text_field :content %>

  <%= form.submit 'Save' %>
<% end %>

todo_item.rb

class TodoItem < ActiveRecord::Base
  belongs_to :todo_list

  validates :content, presence: true, length: { minimum: 3 }
end

application.html.erb

<!DOCTYPE html>
<html>
<head>
  <title>Odot</title>
  <%= stylesheet_link_tag    'application', media: 'all', 'data-turbolinks-track' => true %>
  <%= javascript_include_tag 'application', 'data-turbolinks-track' => true %>
  <%= csrf_meta_tags %>
</head>
<body>

<% flash.each do |type, message| %>
<div class="alert flash<%= type %>">
  <%= message %>
</div>
<% end %>

<%= yield %>

</body>
</html>

1 Answer

Richard McGrath
Richard McGrath
5,597 Points

In create_spect.rb

changing

within('div.flash') do

to

within('div.flasherror') do

Is not allowing the test to pass.