I have a list of stories assigned to me in Cucumber, one of them being "Then the user should receive a confirmation email". I think testing that the user receives it is beyond the power of the application, but how can I test that an email had just been sent?
You can use this step definition :
Then "the user should receive a confirmation email" do
# this will get the first email, so we can check the email headers and body.
email = ActionMailer::Base.deliveries.first
email.from.should == "admin#example.com"
email.to.should == #user.email
email.body.should include("some key word or something....")
end
Tested with Rails 3.2
Source
email_spec + action_mailer_cache_delivery gems are your friends for doing this
I would suggest you to verify the last_response after some action ocurrs, like, a user click on a button, or something like that.
Or if you are updating a record after doing something, check for the updated_at attribute to see if it was changed or not.
Check dockyard/capybara-email gem:
feature 'Emailer' do
background do
# will clear the message queue
clear_emails
visit email_trigger_path
# Will find an email sent to test#example.com
# and set `current_email`
open_email('test#example.com')
end
scenario 'following a link' do
current_email.click_link 'your profile'
expect(page).to have_content 'Profile page'
end
scenario 'testing for content' do
expect(current_email).to have_content 'Hello Joe!'
end
scenario 'testing for a custom header' do
expect(current_email.headers).to include 'header-key'
end
scenario 'testing for a custom header value' do
expect(current_email.header('header-key')).to eq 'header_value'
end
scenario 'view the email body in your browser' do
# the `launchy` gem is required
current_email.save_and_open
end
end
Another option is PutsBox. You can send an email to whatever-you-want#putsbox.com, wait for a few seconds (SMTP stuff ins't instantaneous) then check your email via http://preview.putsbox.com/p/whatever-you-want/last.
This post tutorial has some examples.
Related
I am working with a Rails 3 App and am needing to adjust the error message on the password resent view. If a user types in an email address and submits it, currently, the app will display this error message:
Email not found
I am needing to change this error message to this:
We don't have an account with that e-mail address. Maybe you used another address?
I know that you can adjust this in the Devise YML file, but am not sure how to do this... any suggestions?
Working Code
class PasswordsController < Devise::PasswordsController
def create
user = User.find_by_email(params[:user][:email])
if user.nil?
flash.now[:notice] = "We don't have an account with that e-mail address. Maybe you used another address?"
end
super
end
end
You could try using a before_filter that checks if the email exists in the datbase and if not the it redirects you to the password reset form with a flash notice
I am new to Rails and Twilio, and am trying to run the Twilio Appointment Reminder sample code. I am able to place the call, but am unable to get any feedback from Twilio about the number keys pressed by the caller.
After the call is made, the reminder TwiML is run: here the Gather command should prompt Twilio to record a single digit input from the caller:
xml.instruct!
xml.Response do
xml.Gather(:action => #post_to, :numDigits => 1) do
xml.Say "Hello this is a call"
xml.Say "Please press 1 to repeat this menu. Press 2 for directions. Or press 3 if you are done."
end
end
After a digit is pushed, the Twilio should POST to my directions command in the controller :
def directions
if params['Digits'] == '3'
redirect_to :action => 'goodbye'
return
end
if !params['Digits'] or params['Digits'] != '2'
redirect_to :action => 'reminder'
return
end
#redirect_to = BASE_URL + '/reminder'
render :action => "directions.xml.builder", :layout => false
end
However, every time i call myself and enter a number, the call keeps looping back to the original message. I then checked my logs and apparently there is no 'Digits' parameter being sent from Twilio.
Anyone encounter this problem?
Usually what's happening in a case like this is that the URL being posted to immediately issues a redirect because of something like URL rewriting or HTTPS redirection or the like. Twilio follows the redirect and on the subsequent GET request sends along the standard set of parameters which doesn't include the Digits parameter that is only sent on the initial POST to the <Gather> action URL.
am developing ruby on rails3 application where i am sending an email to user and if user replies that email then that reply content, date should be updated to the database. For this i have ProductComment model. when admin sends comment to the user it will be stored in the database. if user replies to that then database should be updated accordingly. I am trying to use mailman. I have installed the gem. But am not getting how to get the comment id, what should i write in replyto address, where to write the mailman code and from which mail i should read.
Am sending email like this:
mail(:to => #user.email, :subject => "Edit Your Product", :reply_to=>"abc#syz.com)
I am handling it in products controller like this:
require 'mailman'
Mailman::Application.run do
to 'abc#xyz.com' do
ProductComment.create(message)
end
end
Please help me to come out from this problem
Please tell me how to use mailman gem in ruby on rails3 application
there is a recent pro-episode on receiving emails with mailman on railscasts: http://railscasts.com/episodes/313-receiving-email-with-mailman
chmod +x script/mailman_server
cat mailman_test.eml | script/mailman_server
script/mailman_server
-
# script/mailman_server
#!/usr/bin/env ruby
require "rubygems"
require "bundler/setup"
require "mailman"
Mailman.config.logger = Logger.new("log/mailman.log")
Mailman.config.pop3 = {
server: 'pop.gmail.com', port: 995, ssl: true,
username: ENV["GMAIL_USERNAME"],
password: ENV["GMAIL_PASSWORD"]
}
Mailman::Application.run do
default do
begin
Ticket.receive_mail(message)
rescue Exception => e
Mailman.logger.error "Exception occurred while receiving message:\n#{message}"
Mailman.logger.error [e, *e.backtrace].join("\n")
end
end
end
-
def self.receive_mail(message)
ticket_id = message.subject[/^Update (\d+)$/, 1]
if ticket_id.present? && Ticket.exists?(ticket_id)
Ticket.update(ticket_id, body: message.body.decoded)
else
Ticket.create subject: message.subject, body: message.body.decoded, from: message.from.first
end
end
Postmark Inbound is a good choice. Setup like so:
Sign up for Postmark, they will give you an email which Postmark will assign to your account.
Sign up for Google Apps branded Gmail for your domain. Set up forwarding from an account to the Postmark email address. People can now email reply#yourdamin.com, and it will be forwarded to Postmark.
Create a callback URL. When Postmark receives an email it will package it up and post it to your callback. You can then access the email attributes via the params hash.
To implement replying to messages, simply add a reply to field to your outgoing message which contains a unique hash for the message, e.g.
reply+uniquehash#yourdomain.com.
This is a legal email address, and will be sent to reply#yourdomain.com. You can then parse out the hash in your callback and use it to match the reply to the original message.
Simple :)
I'm trying to set up my RoR 3 application to receive emails and then process those emails and update them into the database table called product_comments.
In my application, I have products_controller. Admin can approve or disapprove the products. when the admin disapproves the product, admin adds a comment and that comment will be mailed to the artist, if artist replied to that mail, the product_comments table should be updated to store the replied comment and replied date.
Here is (part of) what I have in my products controller:
if #productcomment.save
ArtistProduct.where(:id=>params[:id]).update_all(:astatus=>'disapproved', :status=>'disapproved')
UserMailer.comment_email( #productcomment).deliver
end
When users add a comment, the admin receives an email. When admins add a comment, users receive an email. (This is already functioning.)
I'm using Cloudmailin to help me receive incoming mail. I've set up the Cloudmailin address to point to http://myapp.com/incoming.
I am not getting how to integrate Cloudmailin to my application. Please help me.
UPDATE
I have just created incoming controller and my incoming controller looks like:
require 'mail'
def create
#comment = ProductComment.find_by_token(params[:to].split('#')[0])
ProductComment.update(:id=>#comment.id,{:reply => params[:plain], :rfrom=>params[:from], :replieddate=>params[:date]})
render :text => 'success', :status => 200
end
My question is how i will get the comment id? While sending an email i want specify comment id or not? if want to specify that id where i want to specify. I have created one account in Cloudmailin is that enough for process the incoming mail or i need to follow any other steps to receive the mail to my application? that is any server setting should be done or what. I am getting any thing. Please help.
Now am sending an email like:
mail(:to => #user.email, :subject => "Edit Your Product")
and i Have set the from as default and it looks like:
default from: "abc#xyz.com"
This is the admin email address.
Please help me.
You can use mailman.
The user guide has an example that does just what you are asking for.
I'd like to test if an email is delivered if I call a controller method with :post. I'll use email_spec so I tried this snipped here: http://rubydoc.info/gems/email_spec/1.2.1/file/README.rdoc#Testing_In_Isolation
But it doesn't work, because I pass an instance of the model-object to the delivery-method and the instance is saved before the delivery.
I tried to create an other instance of the model-object, but then the id isn't the same.
My controller-method looks like this:
def create
#params = params[:reservation]
#reservation = Reservation.new(#params)
if #reservation.save
ReservationMailer.confirm_email(#reservation).deliver
redirect_to success_path
else
#title = "Reservation"
render 'new'
end
end
Do you have any idea to solve this?
Assuming your test environment is set up in the usual fashion (that is, you have config.action_mailer.delivery_method = :test), then delivered emails are inserted into the global array ActionMailer::Base.deliveries as Mail::Message instances. You can read that from your test case and ensure the email is as expected. See here.
Configure your test environment to accumulate sent mails in ActionMailer::Base.deliveries.
# config/environments/test.rb
config.action_mailer.delivery_method = :test
Then something like this should allow you to test that the mail was sent.
# Sample parameters you would expect for POST #create.
def reservation_params
{ "reservation" => "Drinks for two at 8pm" }
end
describe MyController do
describe "#create" do
context "when a reservation is saved" do
it "sends a confirmation email" do
expect { post :create, reservation_params }.to change { ActionMailer::Base.deliveries.count }.by(1)
end
end
end
end
Note that my example uses RSpec 3 syntax.
I know I'm late to the party with this one, but for future Googlers...
I think a better solution to this problem is answered here
The previously accepted answer is testing the Mailer itself (inside the controller spec). All you should be testing for here is that the Mailer gets told to deliver something with the right parameters.
You can then test the Mailer elsewhere to make sure it responds to those parameters correctly.
ReservationMailer.should_receive(:confirm_email).with(an_instance_of(Reservation))
This is way how to test that Mailer is called with right arguments. You can use this code in feature, controller or mailer spec:
delivery = double
expect(delivery).to receive(:deliver_now).with(no_args)
expect(ReservationMailer).to receive(:confirm_email)
.with('reservation')
.and_return(delivery)
Anyone using rspec +3.4 and ActiveJob to send async emails, try with:
expect {
post :create, params
}.to have_enqueued_job.on_queue('mailers')
To add a little more, make sure if you're going to stub out a call using should_receive that you have an integration test elsewhere testing that you're actually calling the method correctly.
I've been bit a few times by changing a method that was tested elsewhere with should_receive and having tests still pass when the method call was broken.
If you prefer to test the outcome rather than using should_receive, shoulda has a nice matcher that works like the following:
it { should have_sent_email.with_subject(/is spam$/) }
Shoulda documentation
More information on using Shoulda Matchers with rSpec
If you're using Capybara with Capybara Email and you sent an email to test#example.com, you can also use this method:
email = open_email('test#example.com')
And then you can test it like this:
expect(email.subject).to eq('SUBJECT')
expect(email.to).to eq(['test#example.com'])
Try email-spec
describe "POST /signup (#signup)" do
it "should deliver the signup email" do
# expect
expect(UserMailer).to(receive(:deliver_signup).with("email#example.com", "Jimmy Bean"))
# when
post :signup, "Email" => "email#example.com", "Name" => "Jimmy Bean"
end
end
more examples here: https://github.com/email-spec/email-spec#testing-in-isolation