First encounter with RSpec, please help

Hello, I’m working on a feature of insoshi to limit daily connection
requests, using a boolean and integer value set by the admin. The
feature works fine, but causes 11 failures in `rake spec’, not to
mention the two or three tests for the new variables yet to be written.

Here is the existing connection_spec, followed by
connections_controller_spec

require File.dirname(FILE) + ‘/…/spec_helper’

describe Connection do

before(:each) do
@emails = ActionMailer::Base.deliveries
@emails.clear
@global_prefs = Preference.find(:first)

@person = people(:quentin)
@contact = people(:aaron)

end

describe “class methods” do

it "should create a request" do
  Connection.request(@person, @contact)
  status(@person, @contact).should == Connection::PENDING
  status(@contact, @person).should == Connection::REQUESTED
end

abridged

connections_controller_spec

require File.dirname(FILE) + ‘/…/spec_helper’

describe ConnectionsController do
integrate_views

before(:each) do
@person = login_as(:quentin)
@contact = people(:aaron)
end

it “should protect the create page” do
logout
post :create
response.should redirect_to(login_url)
end

it “should create a new connection request” do
Connection.should_receive(:request).with(@person, @contact).
and_return(true)
post :create, :person_id => @contact
response.should redirect_to(home_url)
end

abridged

The two vars needed can be accessed in the connection_spec with
@global_prefs.limit_requests and @global_prefs.daily_request_limit

Please help me clear this problem.

The errors from `rake spec’ –

Spec::Mocks::MockExpectationError in ‘ConnectionsController should
create a new connection request’
Mock ‘Class’ expected :request with (I’m Quentin, I’m Aaron) once, but
received it 0 times
./spec/controllers/connections_controller_spec.rb:18:

‘SearchesController Forum post searches should render with a topic link’
FAILED
Expected at least 1 element matching
“a[href=’/forums/953125641/topics/953125641#post_119261968’]”, found 0.
is not true.
./spec/controllers/searches_controller_spec.rb:174:

‘SearchesController Forum post searches should render with a post div’
FAILED
Expected at least 1 element matching “div[class=‘forum’]”, found 0.
is not true.
./spec/controllers/searches_controller_spec.rb:167:

‘SearchesController Forum post searches should search by topic name’
FAILED
Expected array to include #ForumPost:0xb74944c4
./spec/controllers/searches_controller_spec.rb:162:

‘SearchesController Forum post searches should search by post body’
FAILED
Expected array to include #ForumPost:0xb6670e74
./spec/controllers/searches_controller_spec.rb:148:

‘SearchesController Message searches should search by content’ FAILED
Expected array to include #Message:0xb65cf240
./spec/controllers/searches_controller_spec.rb:123:

‘SearchesController Message searches should search by subject’ FAILED
Expected array to include #Message:0xb65a6f84
./spec/controllers/searches_controller_spec.rb:118:

‘SearchesController Person searches as an admin should return email
unverified users’ FAILED
Expected array to include #Person:0xb653918c
./spec/controllers/searches_controller_spec.rb:104:

‘SearchesController Person searches as an admin should return
deactivated users’ FAILED
Expected array to include #Person:0xb652f0d8
./spec/controllers/searches_controller_spec.rb:96:

‘SearchesController Person searches should search by description’ FAILED
expected: [#<Person id: 745185059, email: “[email protected]”, name:
“Quentin”, remember_token: nil, crypted_password:
“tiM81jP/bSzxdKEpRXyd0osc/N9hXVDPQutJ7ZxsJCyKoXIRuBa…”, description:
“I’m Quentin”, remember_token_expires_at: nil, last_contacted_at: nil,
last_logged_in_at: “2008-08-10 10:19:06”, forum_posts_count: 0,
blog_post_comments_count: 0, wall_comments_count: 0, created_at:
“2008-08-05 10:19:00”, updated_at: “2008-08-10 10:19:06”, admin: false,
deactivated: false, connection_notifications: true,
message_notifications: true, wall_comment_notifications: true,
blog_comment_notifications: true, email_verified: true>],
got: [] (using ==)
./spec/controllers/searches_controller_spec.rb:64:

‘SearchesController Person searches should search by name’ FAILED
expected: [#<Person id: 745185059, email: “[email protected]”, name:
“Quentin”, remember_token: nil, crypted_password:
“tiM81jP/bSzxdKEpRXyd0osc/N9hXVDPQutJ7ZxsJCyKoXIRuBa…”, description:
“I’m Quentin”, remember_token_expires_at: nil, last_contacted_at: nil,
last_logged_in_at: “2008-08-10 10:19:06”, forum_posts_count: 0,
blog_post_comments_count: 0, wall_comments_count: 0, created_at:
“2008-08-05 10:19:00”, updated_at: “2008-08-10 10:19:06”, admin: false,
deactivated: false, connection_notifications: true,
message_notifications: true, wall_comment_notifications: true,
blog_comment_notifications: true, email_verified: true>],
got: [] (using ==)
./spec/controllers/searches_controller_spec.rb:59:

Finished in 11.488971 seconds

366 examples, 11 failures

On Sun, Aug 10, 2008 at 11:03 AM, Jesse C. [email protected]
wrote:

require File.dirname(FILE) + ‘/…/spec_helper’
end

@contact = people(:aaron)
and_return(true)
post :create, :person_id => @contact
response.should redirect_to(home_url)
end

abridged

The two vars needed can be accessed in the connection_spec with
@global_prefs.limit_requests and @global_prefs.daily_request_limit

Please help me clear this problem.

Please post the code for Connection and Controller as well.

Connection

== Schema Information

Schema version: 26

Table name: connections

id :integer(11) not null, primary key

person_id :integer(11)

contact_id :integer(11)

status :integer(11)

accepted_at :datetime

created_at :datetime

updated_at :datetime

class Connection < ActiveRecord::Base
extend ActivityLogger
extend PreferencesHelper

belongs_to :person
belongs_to :contact, :class_name => “Person”, :foreign_key =>
“contact_id”
has_many :activities, :foreign_key => “item_id”, :dependent =>
:destroy
validates_presence_of :person_id, :contact_id

Status codes.

ACCEPTED = 0
REQUESTED = 1
PENDING = 2

Accept a connection request (instance method).

Each connection is really two rows, so delegate this method

to Connection.accept to wrap the whole thing in a transaction.

def accept
Connection.accept(person_id, contact_id)
end

def breakup
Connection.breakup(person_id, contact_id)
end

class << self

# Return true if the persons are (possibly pending) connections.
def exists?(person, contact)
  not conn(person, contact).nil?
end

alias exist? exists?

# Make a pending connection request.
def request(person, contact, send_mail = nil)
  if send_mail.nil?
    send_mail = global_prefs.email_notifications? &&
                contact.connection_notifications?
  end
  if person == contact or Connection.exists?(person, contact)
    nil
  else
    transaction do
      create(:person => person, :contact => contact, :status => 

PENDING)
create(:person => contact, :contact => person, :status =>
REQUESTED)
end
if send_mail
# The order here is important: the mail is sent to the
contact,
# so the connection should be from the contact’s point of
view.
connection = conn(contact, person)
PersonMailer.deliver_connection_request(connection)
end
true
end
end

# Accept a connection request.
def accept(person, contact)
  transaction do
    accepted_at = Time.now
    accept_one_side(person, contact, accepted_at)
    accept_one_side(contact, person, accepted_at)
  end
  log_activity(conn(person, contact))
end

def connect(person, contact, send_mail = nil)
  transaction do
    request(person, contact, send_mail)
    accept(person, contact)
  end
  conn(person, contact)
end

# Delete a connection or cancel a pending request.
def breakup(person, contact)
  transaction do
    destroy(conn(person, contact))
    destroy(conn(contact, person))
  end
end

# Return a connection based on the person and contact.
def conn(person, contact)
  find_by_person_id_and_contact_id(person, contact)
end

def accepted?(person, contact)
  conn(person, contact).status == ACCEPTED
end

def connected?(person, contact)
  exist?(person, contact) and accepted?(person, contact)
end

end

private

class << self
# Update the db with one side of an accepted connection request.
def accept_one_side(person, contact, accepted_at)
conn = conn(person, contact)
conn.update_attributes!(:status => ACCEPTED,
:accepted_at => accepted_at)
end

def log_activity(conn)
  activity = Activity.create!(:item => conn, :person => conn.person)
  add_activities(:activity => activity, :person => conn.person)
  add_activities(:activity => activity, :person => conn.contact)
end

end
end

Controller

class ConnectionsController < ApplicationController

before_filter :login_required, :setup
before_filter :authorize_view, :only => :index
before_filter :authorize_person, :only => [:edit, :update, :destroy]
before_filter :redirect_for_inactive, :only => [:edit, :update]

Show all the contacts for a person.

def index
@contacts = @person.contacts.paginate(:page => params[:page],
:per_page => RASTER_PER_PAGE)
end

def edit
@contact = @connection.contact
end

def create
@contact = Person.find(params[:person_id])

respond_to do |format|
  if can_request? and Connection.request(current_person, @contact)
    flash[:notice] = 'Connection request sent!'
    format.html { redirect_to(home_url) }
  else
    # This should only happen when people exceed daily request limit
    # or something funky like friending themselves.
    flash[:notice] = "Invalid connection or exceeds daily \
          request limit 

(#{Preference.find(:first).daily_request_limit})."
format.html { redirect_to(home_url) }
end
end
end

validate against admin daily connection request limit

def can_request?
@requests_limited = Preference.find(:first).limit_requests
@limit = Preference.find(:first).daily_request_limit
if @requests_limited
@list =
Connection.find_all_by_person_id_and_status(current_person,
Connection::PENDING, :order => ‘created_at
desc’)
if @limit == 0
false
elsif not @list[@limit - 1].nil?
@list[@limit - 1].created_at < 1.day.ago
else
true
end
end
end

def update

respond_to do |format|
  contact = @connection.contact
  name = contact.name
  case params[:commit]
  when "Accept"
    @connection.accept
    flash[:notice] = %(Accepted connection with
                       <a href="#{person_url(contact)}">#{name}</a>)
  when "Decline"
    @connection.breakup
    flash[:notice] = "Declined connection with #{name}"
  end
  format.html { redirect_to(home_url) }
end

end

def destroy
@connection.breakup

respond_to do |format|
  flash[:success] = "Ended connection with 

#{@connection.contact.name}"
format.html { redirect_to( person_connections_url(current_person))
}
end
end

private

def setup
  # Connections have same body class as profiles.
  @body = "profile"
end

def authorize_view
  @person = Person.find(params[:person_id])
  unless (current_person?(@person) or
          Connection.connected?(@person, current_person))
    redirect_to home_url
  end
end

# Make sure the current person is correct for this connection.
def authorize_person
  @connection = Connection.find(params[:id],
                                :include => [:person, :contact])
  unless current_person?(@connection.person)
    flash[:error] = "Invalid connection."
    redirect_to home_url
  end
rescue ActiveRecord::RecordNotFound
  flash[:error] = "Invalid or expired connection request"
  redirect_to home_url
end

# Redirect if the target person is inactive.
# Suppose Alice sends Bob a connection request, but then the admin
# deactivates Alice.  We don't want Bob to be able to make the 

connection.
def redirect_for_inactive
if @connection.contact.deactivated?
flash[:error] = “Invalid connection request: person deactivated”
redirect_to home_url
end
end

end

Error

Spec::Mocks::MockExpectationError in ‘ConnectionsController should
create a new connection request’
Mock ‘Class’ expected :request with (I’m Quentin, I’m Aaron) once, but
received it 0 times
./spec/controllers/connections_controller_spec.rb:18:

Finished in 10.707133 seconds

David C. wrote:

On Sun, Aug 10, 2008 at 11:03 AM, Jesse C. [email protected]
wrote:

require File.dirname(FILE) + ‘/…/spec_helper’
end

@contact = people(:aaron)
and_return(true)
post :create, :person_id => @contact
response.should redirect_to(home_url)
end

abridged

The two vars needed can be accessed in the connection_spec with
@global_prefs.limit_requests and @global_prefs.daily_request_limit

Please help me clear this problem.

Please post the code for Connection and Controller as well.