Test-Driven Development (TDD) with Rails 3 and rspec :part 3

Please find the previous two part . Part one and part two.

Let’s create out edit test.

To add edit test  you have to modify your spec file.

require 'spec_helper'

describe "Tasks" do
  before do
    @task = Task.create :task => 'go to bed'
  end

  describe "GET /tasks" do

    it "display some tasks" do
      visit tasks_path
      page.should have_content "go to bed"
    end

    it "creates a new page" do
      visit tasks_path
      fill_in 'Task', :with => 'go to work'
      click_button "Create Task"

      current_path.should == tasks_path
      page.should have_content 'go to work'

      save_and_open_page
    end

  end

  describe "PUT /tasks" do
    it "edits a task" do
      visit tasks_path
      click_link 'Edit'

      current_path.should == edit_task_path(@task)
      #save_and_open_page

      #page.should have_content 'go to bed'
      find_field('Task').value.should == 'go to bed'
      fill_in 'Task', :with => 'updated task'
      click_button "Update Task"

      current_path.should  == tasks_path

      page.should have_content 'updated task'
    end

 end
end

So, if we click on edit link a form should come and we should update the data.

Obviously this test fails because we didn’t modify our view file to add edit link and also din’t create our edit and update method for edit.

So, lets modify those files.

Modify the view file.

<h1>Tasks</h1>
<%= form_for Task.new do |f| %>
    <%= f.label :task %>
    <%= f.text_field :task %>
    <%= f.submit %>
<% end %>
<ul>
  <% for task in @tasks %>
      <li id="task_<%= task.id %>">
        <%= task.task %>
        | <%= link_to 'Edit', edit_task_path(task) %>
        </li>
  <% end %>
</ul>

Now create our edit method. Modify your Tasks controller to modify this.

 
  def edit
    @task = Task.find params[:id]
  end

Now create a view for edit.

Create a new view called edit.html.erb in your views folder. And add this form code here for edit.

<%= form_for @task do |f| %>
    <%= f.label :task %>
    <%= f.text_field :task %>
    <%= f.submit %>
<% end %>

Create Partial:

We have created some duplicate code for create form. But Rails always encourage DRY or Don’t repeat yourself philosophy .

So we now modify our create and edit form and lets create one form call partial. To create partial you have name you’r file name like this _form.html.erb

So, lets create our partial for this project.

<%= form_for @task do |f| %>
    <%= f.label :task %>
    <%= f.text_field :task %>
    <%= f.submit %>
<% end %>

And remove the form part from index view and edit view and this line to show your form.

<%= render 'form' %>

Now we add our update method. Add this method to your Tasks Controller.

def update
    task = Task.find params[:id]
    if task.update_attributes params[:task]
      redirect_to tasks_path,  :notice => 'Your tasks successfully been updated'
    else
      redirect_to :back, :notice => 'There was an error updating your task.'
    end
  end

Add Flash Message:

To add flash message you should add this code to your layout file.
Go to views/layouts/application.html.erb . Add this code above your  <%= yield %>

<% flash.each do |name, message| %>
    <%= content_tag :div, message, :id => "flash_#{name}" %>
<% end %>

Now test will run successfully.

Add Validates:

We didn’t add any validation in this project yet. So let’s add empty validation.

First write test for validation. So, modify your spec file again.

require 'spec_helper'

describe "Tasks" do
  before do
    @task = Task.create :task => 'go to bed'
  end

  describe "GET /tasks" do

    it "display some tasks" do
      visit tasks_path
      page.should have_content "go to bed"
    end

    it "creates a new page" do
      visit tasks_path
      fill_in 'Task', :with => 'go to work'
      click_button "Create Task"

      current_path.should == tasks_path
      page.should have_content 'go to work'

      save_and_open_page
    end

  end

  describe "PUT /tasks" do
    it "edits a task" do
      visit tasks_path
      click_link 'Edit'

      current_path.should == edit_task_path(@task)
      #save_and_open_page

      #page.should have_content 'go to bed'
      find_field('Task').value.should == 'go to bed'
      fill_in 'Task', :with => 'updated task'
      click_button "Update Task"

      current_path.should  == tasks_path

      page.should have_content 'updated task'
    end

    it "should not update an empty task" do
      visit tasks_path
      click_link 'Edit'

      fill_in 'Task', :with => ''
      click_button 'Update Task'

      current_path.should == edit_task_path(@task)
      page.should have_content 'There was an error updating your task.'
    end

  end
end

Now if we add empty data when update error will occurred.

Now we add our last test. Test for delete.

First create our test code. Modify your spec file again.

require 'spec_helper'

describe "Tasks" do
  before do
    @task = Task.create :task => 'go to bed'
  end

  describe "GET /tasks" do

    it "display some tasks" do
      visit tasks_path
      page.should have_content "go to bed"
    end

    it "creates a new page" do
      visit tasks_path
      fill_in 'Task', :with => 'go to work'
      click_button "Create Task"

      current_path.should == tasks_path
      page.should have_content 'go to work'

      save_and_open_page
    end

  end

  describe "PUT /tasks" do
    it "edits a task" do
      visit tasks_path
      click_link 'Edit'

      current_path.should == edit_task_path(@task)
      #save_and_open_page

      #page.should have_content 'go to bed'
      find_field('Task').value.should == 'go to bed'
      fill_in 'Task', :with => 'updated task'
      click_button "Update Task"

      current_path.should  == tasks_path

      page.should have_content 'updated task'
    end

    it "should not update an empty task" do
      visit tasks_path
      click_link 'Edit'

      fill_in 'Task', :with => ''
      click_button 'Update Task'

      current_path.should == edit_task_path(@task)
      page.should have_content 'There was an error updating your task.'
    end

  end

  describe "DELETE /tasks" do
    it "should delete a task" do
      visit tasks_path
      find("#task_#{@task.id}").click_link 'Delete'
      page.should have_content 'Task has been deleted'
      page.should have_no_content 'go to bed'
    end
  end

end

Test will show error because we didn’t add the delete button and destroy method yet.

Let’s add our delete link first in index.html.erb

<%= link_to 'Delete', task, :method => 'delete' %>

And destroy method.

def destroy
     Task.destroy params[:id]
     redirect_to :back, :notice => 'Task has been deleted'
end

If we run test everything will be fine.

Now just modify our flash message view to add the css code.

Add this code to app/assets/stylesheets/tasks.css.scss

#flash_notice {
   background: green;
   border: 1px solid darken(green, 20%);
   text-align: center;
   padding: 5px;
   color: white;
}

That’s it. you can write basic test for your application with rspec.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s