Welcome to the Treehouse Community

The Treehouse Community is a meeting place for developers, designers, and programmers of all backgrounds and skill levels to get support. Collaborate here on code errors or bugs that you need feedback on, or asking for an extra set of eyes on your latest project. Join thousands of Treehouse students and alumni in the community today. (Note: Only Treehouse students can comment or ask questions, but non-students are welcome to browse our conversations.)

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and a supportive community. Start your free trial today.

Ruby

Stuck! bin/rake won't pass Authenticating Rails ODOT

These are my 4 errors:

Failures:

  1) Adding todo items is successful with valid content
     Failure/Error: within("ul.todo_items") do
     Capybara::ElementNotFound:
       Unable to find css "ul.todo_items"
     # ./spec/features/todo_items/create_spec.rb:14:in `block (2 levels) in <top (required)>'

  2) todo_lists/index renders a list of todo_lists
     Failure/Error: assert_select "tr>td", :text => "Title".to_s, :count => 2
     Minitest::Assertion:
        Expected exactly 2 elements matching "tr > td", found 0..
        Expected: 2
       Actual: 0
      # ./spec/views/todo_lists/index.html.erb_spec.rb:20:in `block (2 levels) in <top (required)>'

  3) Viewing todo items displays item content when a todo list has items
      Failure/Error: expect(page.all("ul.todo_items li").size).to eq(2)

       expected: 2
            got: 0

       (compared using ==)
     # ./spec/features/todo_items/index_spec.rb:25:in `block (2 levels) in <top (required)>'

  4) Viewing todo items displays the title of the todo list
      Failure/Error: within("h1") do
      Capybara::Ambiguous:
        Ambiguous match, found 2 elements matching css "h1"
       # ./spec/features/todo_items/index_spec.rb:9:in `block (2 levels) in <top (required)>'

Here is my: app/views/todo_lists/index.html.erb

<h1>Todo Lists</h1>


<% @todo_lists.each do |todo_list| %>
<div class="todo_list" id="<%= dom_id(todo_list) %>">
    <h2><%= todo_list.title %></h2>
    <p><%= todo_list.description %></p>
     <ul class="functions">
        <li><%= link_to "List Items", todo_list_todo_items_path(todo_list) %></li>
        <li><%= link_to 'Show', todo_list %></li>
        <li><%= link_to 'Edit', edit_todo_list_path(todo_list) %></li>
        <li><%= link_to 'Destroy', todo_list, method: :delete, data: { confirm: 'Are you sure?' } %></li>
    </ul>
        <br class="clear" />

 </div>
 <% end %>

 <br>

  <%= link_to 'New Todo list', new_todo_list_path %>

Here is my: spec/features/todo_items/index_spec.rb

require 'spec_helper'

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


    it "displays the title of the todo list" do
            visit_todo_list(todo_list)
        within("h1") do
            expect(page).to have_content(todo_list.title)
        end
    end

     it "displays no items when a todo list is empty" do    
         visit_todo_list(todo_list)
         expect(page.all("ul.todo_items li").size).to eq(0)
     end

     it "displays item content when a todo list has items" do
        todo_list.todo_items.create(content: "Milk")
        todo_list.todo_items.create(content: "Eggs")

         visit_todo_list(todo_list)

         expect(page.all("ul.todo_items li").size).to eq(2)

         within "ul.todo_items" do
             expect(page).to have_content("Milk")
             expect(page).to have_content("Eggs")
         end
        end
      end

Here is my: /spec/features/todo_items/create_spec

require 'spec_helper'

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



     it "is successful with valid content" 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 no content" 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 can't be blank")
    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: "1"
        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

Here's my spec/views/todo_lists/index.html.erb_spec.rb

require 'spec_helper'

describe "todo_lists/index" do
  before(:each) do
    assign(:todo_lists, [
      stub_model(TodoList,
        :title => "Title",
        :description => "MyText"
      ),
      stub_model(TodoList,
        :title => "Title",
        :description => "MyText"
      )
    ])
  end

  it "renders a list of todo_lists" do
    render
    # Run the generator again with the --webrat flag if you want to use webrat matchers
    assert_select "tr>td", :text => "Title".to_s, :count => 2
    assert_select "tr>td", :text => "MyText".to_s, :count => 2
  end
end

Can anyone decipher this for me? Thank you!

5 Answers

Maciej Czuchnowski
Maciej Czuchnowski
36,440 Points

This is how the spec/features/todo_items/create_spec.rb file should look like (you had wrong visit paths and tags in "within"):

require 'spec_helper'

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

    it "is successful with valid content" do
        visit(todo_list_todo_items_path(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("table.todo_items") do
            expect(page).to have_content("Milk")
        end
    end

    it "displays an error with no content" do
        visit(todo_list_todo_items_path(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 can't be blank")
    end

    it "displays an error with content les than 2 characters long" do
        visit(todo_list_todo_items_path(todo_list))
        click_link "New Todo Item"
        fill_in "Content", with: "1"
        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

Remove one of these duplicate lines from your views/todo_items/index.erb:

<table class="todo_items">
    <table class="todo_items">

I would also downgrade rspec to 2.99 (version 3 has some syntax changes):

1) modyfy your gemfile:

group :development, :test do
    gem 'rspec-rails', '2.99'
end

2) run bundle update

This all applies to your first error and worked on my computer. I'm not yet sure how to tackle the remaining errors you are quoting.

Thanks so much for your help!!! It worked. Still stuck on the ambiguous match css h1 file, but other than that I'm trucking along. Cheers!

Failure #1: Unable to find css "ul.todo_items"

This is your current mark up:

<% @todo_lists.each do |todo_list| %>
<div class="todo_list" id="<%= dom_id(todo_list) %>">
    <h2><%= todo_list.title %></h2>
    <p><%= todo_list.description %></p>
     <ul class="functions">
        <li><%= link_to "List Items", todo_list_todo_items_path(todo_list) %></li>
        <li><%= link_to 'Show', todo_list %></li>
        <li><%= link_to 'Edit', edit_todo_list_path(todo_list) %></li>
        <li><%= link_to 'Destroy', todo_list, method: :delete, data: { confirm: 'Are you sure?' } %></li>
    </ul>
        <br class="clear" />

 </div>
 <% end %>

You don't currently have a ul with the class of todo_items - in fact you haven't displayed any todo items in this code. This is why the test is failing. I'm sure they cover this on the video.. but something along these lines - but not exactly - will fix this particular test as it is now. This should point you in the right direction..

<% @todo_lists.each do |todo_list| %>
<div class="todo_list" id="<%= dom_id(todo_list) %>">
    <h2><%= todo_list.title %></h2>
    <p><%= todo_list.description %></p>

    <ul class="todo_items">
    <% @todo_items.each do |todo_item| %>
      <li><%= todo_item.content %></li>
    <% end %>
    </ul>

     <ul class="functions">
        <li><%= link_to "List Items", todo_list_todo_items_path(todo_list) %></li>
        <li><%= link_to 'Show', todo_list %></li>
        <li><%= link_to 'Edit', edit_todo_list_path(todo_list) %></li>
        <li><%= link_to 'Destroy', todo_list, method: :delete, data: { confirm: 'Are you sure?' } %></li>
    </ul>
        <br class="clear" />

 </div>
 <% end %>

Thank you guys so much for your help. Unfortunately, this didn't work or anything like it that I tried. If any of either of you get a free second, would you mind running it yourself and see what's actually going on? It would mean a lot. Thanks again.

https://github.com/lamagnotti/odot

Maciej Czuchnowski
Maciej Czuchnowski
36,440 Points

I was going to ask you for it :). I'll take a look.

Thanks!!! Just FYI, in the one that's up now,

Looks like this:

<div class="todo_list" id"<%= dom_id(todo_list) %>">

When it should be like this: (including the = sign after id)

<div class="todo_list" id="<%= dom_id(todo_list) %>">

Sorry about that! Thanks so much for your help, really; this is has been driving me up a wall the past 2 days.

Maciej Czuchnowski
Maciej Czuchnowski
36,440 Points

OK...you showed us the wrong index file :)

Joel Brennan
Joel Brennan
18,300 Points
require 'spec_helper'

describe "Viewing todo items" do
    let!(:todo_list) {TodoList.create(title: "Grocery list", description: "Groceries")}
    let(:user) { create(:user)}
    before {sign_in user, password: 'treehouse1'}

    it "displays the title of the todo list" do
        visit_todo_list(todo_list)
        within("div.wrapper h1") do
            expect(page).to have_content(todo_list.title)
        end
    end

    it "displays no items when a todo list is empty" do
        visit_todo_list(todo_list)
            expect(page.all("table.todo_items tbody tr").size).to eq(0)
    end
    it "displays item content when a todo list has items" do
        todo_list.todo_items.create(content: "Milk")
        todo_list.todo_items.create(content: "Eggs")

        visit_todo_list(todo_list)

        expect(page.all("table.todo_items tbody tr").size).to eq(2)

        within "table.todo_items" do
            expect(page).to have_content("Milk")
            expect(page).to have_content("Eggs")
        end

    end
end

This is how it looks later.

*I have used .wrapper class instead. But if you followed Mr Seifer yours will be: within("div.content h1")

Otherwise you have 2No. h1 as your header contains a h1 element (I think).

Maciej Czuchnowski
Maciej Czuchnowski
36,440 Points

In your index.html.erb I can't see any code that gives the UL element the .todo_items class. Please remember that ul.todo_items means "unordered list with class todo_items" - if you put a space there - ul .todo_items - this will mean "any element with .todo_items class within the unordered list", which is better, but I still don't see this class assigned to anything in your erb file...

So what's your advice or solution here though? How should I write the class for this? Thanks for the quick reply.

The test is failing because you've told it to look for an html element in your view which doesn't exist.

You can either present the information in the way that you're testing or change the test so it's looking for the correct markup on you page.

Maciej Czuchnowski
Maciej Czuchnowski
36,440 Points

Try assigning class todo_items to the ul (instead of functions) and put a space in your specs: ul .todo_items. I can't guarantee this will work, I'd have to experiment directly on the whole code, but this should do something...

Hey Maciej, I tried that but it didn't work =/ It had no effect on the test at all.

Tom, if that's the case, how can I present the info in that way? Thanks for your help guys!

Maciej Czuchnowski
Maciej Czuchnowski
36,440 Points

OK, try without that space I mentioned ;)

Joel Brennan
Joel Brennan
18,300 Points

*EDIT

This all gets explained later in: Adding User Support to Our Application

Fixing Our Tests.