I am trying to testing sending email in my rails 3 app, and am testing with cucumber/rspec. In my test, I want the user to be able to receive an email, but instead of sending one, it is sending two. Here is my feature:
features/ticket_notications.feature
Feature: Ticket Notifications
Background:
Given there are the following users:
| email | password |
| alice@ticketee.com | password |
| bob@ticketee.com | password |
Given a clear email queue
Given there is a project called "TextMate 2"
And "alice@ticketee.com" can view the "TextMate 2" project
And "bob@ticketee.com" can view the "TextMate 2" project
And "alice@ticketee.com" has created a ticket for this project:
| title | description |
| Release date | TBA very shortly. |
Given I am signed in as "bob@ticketee.com"
Given I am on the homepage
Scenario: Ticket owner is automatically subscribed to a ticket
When I follow "TextMate 2"
And I follow "Release date"
And I fill in "Text" with "Is it out yet?"
And I press "Create Comment"
Then "alice@ticketee.com" should receive an email
When "alice@ticketee.com" opens the email
Then they should see "updated the Release date ticket" in the email body
And they should see "[ticketee] TextMate 2 - Release date" in the email subject
Then they click the first link in the email
Then I should see "Release date" within "#ticket h2"
When I run this I get this error:
Then "alice@ticketee.com" should receive an email
# features/step_definitions/email_steps.rb:5
expected: 1
got: 2 (using ==)* (RSpec::Expectations::ExpectationNotMetError)
./features/step_definitions/email_steps.rb:52:in `/^(?:I|they|"([^"]*?)") should receive (an|no|\d+) emails?$/'
features\ticket_notifications.feature:26:in `Then "alice@ticketee.com" should receive an email'
So for some reason it’ receiving two emails instead of one, as seen in this line
expected: 1
got: 2
Here is some more code:
app/observers/comment_observer
class CommentObserver < ActiveRecord::Observer
def after_create(comment)
(comment.ticket.watchers - [comment.user]).each do |user|
Notifier.comment_updated(comment, user).deliver
end
end
end
app/models/ticket.rb
has_and_belongs_to_many :watchers, :join_table => "ticket_watchers",
:class_name => "User"
after_create :creator_watches_me
private
def creator_watches_me
self.watchers << user
end
app/config/application.rb
config.active_record.observers = :comment_observer
app/mailers/notifier.rb
class Notifier < ActionMailer::Base
default from: "ticketee@gmail.com"
def comment_updated(comment, user)
@comment = comment
@user = user
mail(:to => user.email,
:subject => "[ticketee] #{comment.ticket.project.name} - #{comment.ticket.title}")
end
end
So, can anyone help me figure out why rspec reporting two emails instead of only one?
Edit: The code for the failing step:
features/step_definitions/email_steps.rb
Then /^(?:I|they|"([^"]*?)") should receive (an|no|\d+) emails?$/ do |address, amount|
unread_emails_for(address).size.should == parse_email_count(amount)
end
Edit 2:
Here is the code from the log file
From the look of it, I think we have the same problem. I’m following the same book (Rails 3 in Action) and got stuck in the same place. I couldn’t detect where exactly the problem is, but when I put :
I saw that the watchers array of comment object contains duplicate of the same user:
I dunno why, but I just created a workaround on this by putting an array of user id inside the sending loop :
Dirty, but it worked. I’m hoping someone can figure out what happened here.