ActionMailer sending real emails in test mode! - How to turn off? - ruby-on-rails-3

Newly signed up users to my little app must be approved by the admin (me) before they can gain access to the site. I've succeeded in generating such emails in development with an after_create :send_admin_email in my user model which works great. My problem is that I'm generating multiple users during my tests (using FactoryGirl) and each test user created sends off a real email. Running my tests is like pouring molasses in January and I've got to delete hundreds of emails sent to my inbox. How do I turn that off?
Action Mailer Basics in the Rails Guides tells me that "By default Action Mailer does not send emails in the test environment. They are just added to the ActionMailer::Base.deliveries array."
Moreover, in config/environments/test.rb I've got:
config.action_mailer.delivery_method = :test
That's in addition to in config/environment.rb having:
# Configuration for using SendGrid on Heroku
ActionMailer::Base.smtp_settings = {
:address => 'smtp.sendgrid.net',
:port => '587',
:authentication => :plain,
:user_name => 'app[my app number]#heroku.com',
:password => '[something super secret]',
:domain => '[let's get this party started!.com]',
:enable_starttls_auto => true
}
ActionMailer::Base.delivery_method = :smtp
I'm sure that I'm missing something simple and basic. I've searched around and related questions and posts deal with how to test that ActionMailer actually sent email.
Humble gratitude in advance for any thoughts or help.
Addendum: Following answer to similar question found at Is it possible to turn off ActionMailer emails when cucumber testing is happening on development? I was able to stop the email sending madness. Still, I had to add ActionMailer::Base.delivery_method = :test to several rspec files. Is there a way I can shut this down globally? Anyone have any thoughts on what's going on?

So I've figured it out. Having the line ActionMailer::Base.delivery_method = :smtp in config/environment.rb overrides ActionMailer::Base.delivery_method = :test in config/environments/test.rb.
So, delete that line, ActionMailer::Base.delivery_method = :smtp'
from config/environment.rb and place it in config/environments/production.rb.
That allows you to place ActionMailer::Base.delivery_method = :test in config/environments/test.rb and the version you want in config/environments/development.rb. I made development.rb :test as I populated my database using Faker and changed it to smtp so I was sure that real emails were sent as an additional check.
Note: You must restart your server for these changes to take effect.
Another note: Heroku's current SendGrid Instructions put the SendGrid Heroku configuration code in a new config/initializers/mail.rb file which will likely require removing its last line and placing the desired version in each config/environments/[production.rb, development.rb, test.rb]

Perhaps useful...
My config/environment.rb did not contain ActionMailer::Base.delivery_method = :smtp and my config/environments/test.rb did contain ActionMailer::Base.delivery_method = :test but Rails still delivered mailers while testing.
I simply added the following to config/environments/test.rb to fix:
config.action_mailer.perform_deliveries = false

I faced the similar situation in Rails4.2 (ActiveJob integration with ActionMailer) even if I didn't write delivery_method = :smtp in config/environment.rb.
In my case, The issue here happened after using "resque" as background worker. Finally, I found out that the following config was WRONG:
config/initializers/active_job.rb:
Rails.application.config.active_job.queue_adapter = :resque # here is WRONG
...because it effected to test mode as well.
So, I set "queue_adapter = :resque" only in config/environments/{development,production.rb}. Now, that works as I expect.

Related

Mailcatcher not working in Rails

I am trying get mailcatcher working with my Rails 3.2.x app. Added mailcatcher gem and bundled, and...
development.rb
config.action_mailer.delivery_method = :smtp
config.action_mailer.smtp_settings = {
address: "localhost",
port: 1025,
}
I get the mailcatcher console at localhost:1080, but I get nothing when mails is sent. I am using delayed job, and can see delayed jobs being created and run, so I know the mails are being triggered in dev. What is my next step in troubleshooting this?
I ended up using https://github.com/ryanb/letter_opener. This worked out of the box for me.

Ruby on Rails: Active Admin and Heroku - dashboard error

I have some Ruby on Rails applications that are using Active Admin gem. Rails version is 3.2.6, Active Admin version is 0.4.4.
I am pushing these applications to Heroku, then doing migrations and everything is working fine. But after some time (when application restarts) i'm starting to get 404 error when trying to open admin page (like myapp/admin). In logs there is an error:
ActionController::RoutingError (uninitialized constant Admin::DashboardController)
Moreover, if i'm trying to open some other admin page (like myapp/admin/videos - to administer videos) everything is still working fine, but error 404 persists when opening Dashboard page.
I have tried to put
config.cache_classes = true
config.assets.compile = true
to my config files, but all the same.
Basically the scheme is as follows:
I make some changes to the app, commit the changes with "git add .", "git commit" and push it to Heroku
I open the /admin page on Heroku and it works fine
After application restarts i get 404 error when visiting /admin, but everything still works when accessing other admin pages, not dashboard
GoTo 1
I'm still unsure if the error appears when the app is restarted by itself (not by "heroku restart").
Any ideas why this is happening? Maybe someone can advice how to switch off this Dashboard and use my myapp/admin/videos as the default admin page?
I had this very same problem, and since it complaints about the ActiveAdmin Dashboard, and it is now deprecated I proceeded to update my dashboard.rb file to the new Dashboard style and that solved the problem.
(I got that file from here).
Hope it helps.
I got the same issue.
Check whether you have to upgrade ActiveAdmin to new version
When upgrading to a new version of ActiveAdmin you may need to run
rails generate active_admin:assets
If you get:
uninitialized constant Admin::DashboardController
Use the New default page for admin/dashboard.rb
which is like following,
ActiveAdmin.register_page "Dashboard" do
menu :priority => 1, :label => proc{ I18n.t("active_admin.dashboard") }
content :title => proc{ I18n.t("active_admin.dashboard") } do
div :class => "blank_slate_container", :id => "dashboard_default_message" do
span :class => "blank_slate" do
span I18n.t("active_admin.dashboard_welcome.welcome")
small I18n.t("active_admin.dashboard_welcome.call_to_action")
end
end
# Here is an example of a simple dashboard with columns and panels.
#
# columns do
# column do
# panel "Recent Posts" do
# ul do
# Post.recent(5).map do |post|
# li link_to(post.title, admin_post_path(post))
# end
# end
# end
# end
# column do
# panel "Info" do
# para "Welcome to ActiveAdmin."
# end
# end
# end
end # content
end

Heroku Cedar: How to scale WEB dynos based on time of day

I want my Rails 3.1 app to scale up to 1 web dyno at 8am, then down to 0 web dynos at 5pm.
BUT, I do not want to sign up for a paid service, and I cannot count on my home computer being connected to the internet.
It seems like the Heroku Scheduler should make this trivial. Any quick solutions or links?
The answer is 'yes' you can do this from scheduler and it's trivial once you know the answer:
Add a heroku config var with your app name: heroku config:add APP_NAME:blah
Add gem 'heroku' to your Gemfile
In order to verify, manually scale up/down your app: heroku ps:scale web=2
Add a rake task to lib/tasks/scheduler.rake:
desc "Scale up dynos"
task :spin_up => :environment do
heroku = Heroku::Client.new('USERNAME', 'PASSWORD')
heroku.ps_scale(ENV['APP_NAME'], :type=>'web', :qty=>2)
end
# Add a similar task to Spin down
Add the Scheduler addon: heroku addons:add scheduler:standard
Use the Scheduler web interface to add "rake spin_up" at whatever time you like
Add a rake spin_down task and schedule it for whenever.
Notes:
Step 1 is needed because I couldn't find any other way to be certain of the App name (and I use 'staging' and 'production' environments for my apps.
Step 3 is required because otherwise the ruby command errors out as it requires that you first agree (via Yes/No response) that you will be charged money as a result of this action.
In step 4, I couldn't find any docs about how to do this with an API key via the heroku gem, so it looks like user/pass is required.
Hope this helps someone else!
Just implemented this approach (good answer above #dnszero), thought I would update the answer with Heroku's new API.
Add your app name as a heroku config variable
require 'heroku-api'
desc "Scale UP dynos"
task :spin_up => :environment do
heroku = Heroku::API.new(:api_key => 'YOUR_ACCOUNT_API_KEY')
heroku.post_ps_scale(ENV['APP_NAME'], 'web', 2)
end
This is with heroku (2.31.2), heroku-api (0.3.5)
You can scale your web process to zero by
heroku ps:scale web=0
or back to 1 via
heroku ps:scale web=1
you'd then have to have a task set to run at 8 that scales it up and one that runs at 17 that scales it down. Heroku may require you to verify your account (ie enter credit card details) to use the Heroku Scheduler plus then you'd have to have the Heroku gem inside your app and your Heroku credentials too so it can turn your app on or off.
But like Neil says - you get 750hrs a month free which can't roll over into the next month so why not just leave it running all the time?
See also this complete gist, which also deals with the right command to use from the Heroku scheduler: https://gist.github.com/maggix/8676595
So I decided to implement this in 2017 and saw that the Heroku gem used by the accepted answer has been deprecated in favor of the 'platform-api' gem. I just thought I'd post what worked for me, since i haven't seen any other posts with a more up-to-date answer.
Here is my rake file that scales my web dynos to a count of 2. I used 'httparty' gem to make a PATCH request with appropriate headers to the Platform API, as per their docs, in the "Formation" section.
require 'platform-api'
require 'httparty'
desc "Scale UP dynos"
task :scale_up => :environment do
headers = {
"Authorization" => "Bearer #{ENV['HEROKU_API_KEY']}",
"Content-Type" => "application/json",
"Accept" => "application/vnd.heroku+json; version=3"
}
params = {
:quantity => 2,
:size => "standard-1X"
}
response = HTTParty.patch("https://api.heroku.com/apps/#{ENV['APP_NAME']}/formation/web", body: params.to_json, headers: headers)
puts response
end
As an update to #Ren's answer, Heroku's Platform API gem makes this really easy.
heroku = PlatformAPI.connect_oauth(<HEROKU PLATFORM API KEY>)
heroku.formation.batch_update(<HEROKU APP NAME>, {"updates" =>
[{"process" => <PROCESS NAME>,
"quantity" => <QUANTITY AS INTEGER>,
"size" => <DYNO SIZE>}]
})
If you're running on the cedar stack, you won't be able to scale to zero web dynos without changing the procfile and deploying.
Also, why bother if you get one free dyno a month (750 dyno hours, a little over a month in fact)?

Turning off ip spoofing check in Rails 3 application

The problem
I'm getting the error:
ActionDispatch::RemoteIp::IpSpoofAttackError (IP spoofing attack?!HTTP_CLIENT_IP="203.29.78.157"HTTP_X_FORWARDED_FOR="172.20.19.214, 116.50.58.180"):
when some people visit my Rails 3.0.10 application and log in or confirm their email address. I'm using Devise.
What I've tried
http://pivotallabs.com/users/jay/blog/articles/1216-standup-4-7-2010-disabling-rails-ip-spoofing-safeguard
So within production.rb I've added:
config.action_controller.ip_spoofing_check = false
I've also tried adding it to environment.rb:
Things3::Application.configure do
config.action_mailer.delivery_method = :smtp
config.action_controller.ip_spoofing_check = false
end
I still get the error. What am I missing?
Note that the method "config.action_controller.ip_spoofing_check=" has deprecation warnings starting 3.0, and now won't work on 3.2. Use the following method call instead:
config.action_dispatch.ip_spoofing_check = false
This blog post might help: it explains why this error occur and how to disable ip spoofing while retaining the security check https://github.com/phinze/writeheavy.com/blob/master/_posts/2011-07-31-when-its-ok-to-turn-of-rails-ip-spoof-checking.markdown
This started working for me right after I posted this. I made a mistake testing it when I'd added it to environment.rb.

using webmock with cucumber

I am using webmock and it is not working for cucumber tests
In my Gemfile
gem 'vcr'
gem 'webmock'
And in my features/support.env.rb, I have
require 'webmock/cucumber'
WebMock.allow_net_connect!
When I run my cucumber tests I am getting this error.
Real HTTP connections are disabled. Unregistered request:
GET http://127.0.0.1:9887/__identify__ with headers
{'Accept'=>'*/*', 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'User-Agent'=>'Ruby'}
Am I doing anything wrong or is sth missing?
First off, if you're using VCR, you don't need to configure webmock with the require 'webmock/cucumber' line and the WebMock.allow_net_connect! line. VCR takes care of any necessary WebMock configuration for you.
The request that is triggering the error looks like it's coming from Capybara. When you use one of the javascript drivers, capybara boots your app using a simple rack server, and then polls the special __identify__ path so it knows when it has finished booting.
VCR includes support for ignoring localhost requests so that it won't interfere with this. The relish docs have the full story but the short version is that you need to add VCR configuration like this:
VCR.config do |c|
c.ignore_localhost = true
end
I had the same error though do not use VCR. I was able to resolve this by adding:
require 'webmock/cucumber'
WebMock.disable_net_connect!(:allow_localhost => true)
to my env.rb file.
Expanding on Myron Marston's answer. If you need to keep localhost for something else, such as a Rack App, that you might want VCR to capture request for, you will need to create a custom matcher rather than ignore all localhost requests.
require 'vcr'
VCR.configure do |c|
c.hook_into :webmock
c.ignore_localhost = false
c.ignore_request do |request|
localhost_has_identify?(request)
end
end
private
def localhost_has_identify?(request)
if(request.uri =~ /127.0.0.1:\d{5}\/__identify__/)
true
else
false
end
end
If you use both RSpec and Cucumber, you might need to create two config files for WebMock (when using with VCR):
# spec/support/webmock.rb
# Config for RSpec
require 'webmock/rspec'
WebMock.disable_net_connect!(allow_localhost: true)
# features/support/webmock.rb
# Config for Cucumber
require 'webmock/cucumber'
WebMock.disable_net_connect!(allow_localhost: true)
Documenting this here for people to find when googling for __identify__. Errors look like...
Real HTTP connections are disabled.
Unregistered request: GET http://127.0.0.1:59005/__identify__