Нужна помощь в определении причин, по которым приложение rails 3 отправляет 2 электронных письма вместо 1 - PullRequest
1 голос
/ 03 апреля 2012

Я пытаюсь протестировать отправку электронной почты в моем приложении rails 3, и я тестирую с помощью cucumber / rspec. В моем тесте я хочу, чтобы пользователь мог получать электронную почту, но вместо того, чтобы отправлять одно, он отправляет два. Вот моя особенность:

функция / 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"

Когда я запускаю это, я получаю эту ошибку:

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'

По какой-то причине он получает два электронных письма вместо одного, как показано в этой строке ожидается: 1 получил: 2

Вот еще немного кода:

Приложение / наблюдатели / 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

приложение / модели / 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

приложение / Config / application.rb

 config.active_record.observers = :comment_observer

приложение / отправители / 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

Итак, кто-нибудь может помочь мне понять, почему rspec сообщает о двух электронных письмах вместо одного?

Редактировать: код для ошибочного шага:

функции / 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

Редактировать 2: Вот код из файла журнала

https://gist.github.com/2294406

Ответы [ 2 ]

2 голосов
/ 02 июля 2012

Судя по всему, у нас та же проблема. Я следую той же книге (Rails 3 в действии) и застрял в том же месте. Я не мог определить, где именно проблема, но когда я поставил:

class CommentObserver < ActiveRecord::Observer
  def after_create(comment)
    p comment.ticket.watchers
    (comment.ticket.watchers - [comment.user]).each do |user|
      Notifier.comment_updated(comment, user).deliver
    end
  end
end

Я увидел, что массив наблюдателей объекта комментария содержит дубликат того же пользователя:

[#<User id: 1, email: "alice@ticketee.com", encrypted_password: "$2a$04$D27BhCTxcOqsidMSDhp0FebonA82npQ01iFib3zwYCfT...", reset_password_token: nil, reset_password_sent_at: nil, remember_created_at: nil, sign_in_count: 0, current_sign_in_at: nil, last_sign_in_at: nil, current_sign_in_ip: nil, last_sign_in_ip: nil, created_at: "2012-07-02 15:32:42", updated_at: "2012-07-02 15:32:42", confirmation_token: nil, confirmed_at: "2012-07-02 15:32:42", confirmation_sent_at: "2012-07-02 15:32:42", admin: false>, #<User id: 1, email: "alice@ticketee.com", encrypted_password: "$2a$04$D27BhCTxcOqsidMSDhp0FebonA82npQ01iFib3zwYCfT...", reset_password_token: nil, reset_password_sent_at: nil, remember_created_at: nil, sign_in_count: 0, current_sign_in_at: nil, last_sign_in_at: nil, current_sign_in_ip: nil, last_sign_in_ip: nil, created_at: "2012-07-02 15:32:42", updated_at: "2012-07-02 15:32:42", confirmation_token: nil, confirmed_at: "2012-07-02 15:32:42", confirmation_sent_at: "2012-07-02 15:32:42", admin: false>]

Я не знаю, почему, но я только что обошел это, поместив массив идентификаторов пользователей в цикл отправки:

class CommentObserver < ActiveRecord::Observer
  def after_create(comment)
    sent = []
    (comment.ticket.watchers - [comment.user]).each do |user|
      Notifier.comment_updated(comment, user).deliver unless sent.include?(user.id)
      sent << user.id
    end
  end
end

Грязно, но это сработало. Я надеюсь, что кто-то сможет выяснить, что здесь произошло.

1 голос
/ 03 апреля 2012

Возможно, у вас есть другой наблюдатель / обратный вызов, который запускается в данном примере. Попробуйте очистить почтовую очередь перед шагом And I press "Create Comment". Для отладки отправки электронной почты вы можете использовать отличный https://github.com/sj26/mailcatcher гем или просто проверить журналы приложений.

...