I am implementing griddler(using Mandrill) to fetch e-mail in my app.
This is my class to receive mail
#app/email_receivers/incoming.rb
class EmailReceiver < Incoming::Strategies::Mandrill
def receive(mail)
%(Got message from #{mail.to.first} with subject "#{mail.subject}")
end
end
req = Rack::Request.new(Rails.env)
result = EmailReceiver.receive(req)
This is my rails controller that calls receive method of EmailReceiver class.
#emails_controller.rb
class EmailsController < ActionController::Base
def create
if EmailReceiver.receive(request)
render :json => { :status => 'ok' }
else
render :json => { :status => 'rejected' }, :status => 403
end
end
end
Routes for calling create method of EmailsController
#routes.rb
Rails.application.routes.draw do
post '/emails' => 'emails#create'
end
Note:- After running server in production environment
rails s -e production
I got this error
/home/bvc-2/.rvm/gems/ruby-2.2.1/gems/rack-1.6.4/lib/rack/request.rb:192:in `[]=': string not matched (IndexError)
Where "puts req" in
req = Rack::Request.new(Rails.env)
turns out to be:
#<Rack::Request:0xc3bace8 #env="production">
And my config/application.rb file is:-
require File.expand_path('../boot', __FILE__)
require 'rails/all'
# Require the gems listed in Gemfile, including any gems
# you've limited to :test, :development, or :production.
Bundler.require(*Rails.groups)
ActionMailer::Base.smtp_settings = {
:address =>"smtp.gmail.com",
:port => 587,
:domain => "gmail.com",
:user_name => "***#gmail.com",
:password => "pass*******",
:authentication => 'plain',
:enable_starttls_auto => true
}
module ComplaintSystem
class Application < Rails::Application
# Settings in config/environments/* take precedence over those specified here.
# Application configuration should go into files in config/initializers
# -- all .rb files in that directory are automatically loaded.
# Set Time.zone default to the specified zone and make Active Record auto-convert to this zone.
# Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC.
# config.time_zone = 'Central Time (US & Canada)'
config.active_job.queue_adapter = :delayed_job
config.time_zone = 'Mumbai'
config.active_record.default_timezone = :local
# The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded.
# config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s]
# config.i18n.default_locale = :de
# Do not swallow errors in after_commit/after_rollback callbacks.
config.active_record.raise_in_transactional_callbacks = true
end
end
This type of error happens when you try to access a string variable as a Hash by mistake.
s = "hello world"
s["position"] = "programming is fun"
# > IndexError: string not matched
# > from (irb):5:in `[]='
# > from (irb):5
Look at your full stack trace and see where you are trying to do such operation.
Related
I need to include res-client into my module in order to use RestClient::Resource.
I use the method in the module in a Chef recipe (ruby_block resource).
When my ruby_block resource tries to run the method in the module it output this error:
ERROR: cannot load such file -- rest-client
The following is my module residing in libraries folder:
module SecretServer
def fetch_token
payload = { :username => "***", :password => "***", :grant_type => "****"}
uri = ***
request = RestClient::Resource.new(uri, :verify_ssl => false)
post_request = request.post payload, :content_type => 'application/x-www-form-urlencoded'
token = JSON.parse(post_request)["access_token"]
return token
end
end
require 'rest-client'
Chef::Recipe.include(SecretServer)
Chef::Resource.include(SecretServer)
The following is the resource that calls the function in module:
ruby_block 'parse data' do
block do
res = fetch_token
puts res
end
end
This is just one of the several recipes in my cookbook. This recipe runs after the target node is almost ready and 'bundle install' has been run on the target node.
I also install rest-client in the target node. I tried each of following resource before my ruby_block resource:
chef_gem 'rest-client' do
action :install
end
gem_package 'rest-client' do
action :install
end
My question is how to include 'rest-client' and utilize it in Chef recipes?
Long ago, the HTTP clients lived together in harmony. Then everything changed when the JSON gem attacked. Only the Chef::HTTP was still to be included with Chef as all the other clients were under too much flux to include.
We don't include that gem anymore, so to use it, you would have to install it yourself either via a cookbook gem dependency or a chef_gem resource. But for simple stuff you can just use our Chef::HTTP::SimpleJSON client instead:
Chef::HTTP::SimpleJson.new(uri).post("", args)["access_token"]
Or something like that (specifics depend on if you must use form encoding or if the server also speaks JSON).
I am trying to make some tests with Rspec/Capybara/Poltergeist on my Rails 4 application, Phantomjs is installed (version 2.2.1), but I always get this error :
Failure/Error: visit(perfect_landing_page_path)
Capybara::Poltergeist::StatusFailError:
Request to 'http://127.0.0.1:49623/path' failed to reach server, check DNS
and/or server status
The test i'm working on :
require 'rails_helper'
RSpec.feature 'Subscription', :type => :feature do
let!(:plan) { create(:plan) }
let!(:landing_page) { create(:landing_page) }
before(:each) { landing_page.default_plan = plan }
describe 'landing_page#perfect_show' do
scenario 'form display', js: true do
plan_2 = create(:plan)
plan_3 = create(:plan)
landing_page.plans << plan_2
landing_page.plans << plan_3
visit(perfect_landing_page_path)
expect(page).to have_css(".start-now", count: 3)
first(".start-now").click
expect(page).to have_css("#new_user")
end
end
end
My Gemfile looks like this :
gem 'rspec-rails', '~> 3.0'
gem 'factory_girl_rails'
gem 'guard-rspec'
group :test do
gem 'database_cleaner'
gem 'capybara'
gem 'capybara-screenshot'
gem 'poltergeist'
gem 'selenium-webdriver'
gem 'shoulda-matchers', require: false
gem 'show_me_the_cookies'
end
My spec/support/capybara.rb file :
require 'capybara/rails'
require 'capybara/rspec'
require 'capybara-screenshot/rspec'
require "capybara/poltergeist" # Add this line to require poltergeist
require 'selenium-webdriver'
Capybara.register_driver :poltergeist do |app|
Capybara::Poltergeist::Driver.new(app, {:js_errors => false, :default_max_wait_time => 30, :timeout => 30, phantomjs_options: [
'--load-images=no',
'--ignore-ssl-errors=true',
'--ssl-protocol=any']})
end
Capybara.register_driver :poltergeist_debug do |app|
Capybara::Poltergeist::Driver.new(app, :inspector => true)
end
Capybara.configure do |config|
config.javascript_driver = :poltergeist
config.ignore_hidden_elements = true
config.default_max_wait_time = 30
end
My spec_helper.rb file :
require 'capybara/rspec'
RSpec.configure do |config|
config.expect_with :rspec do |expectations|
expectations.include_chain_clauses_in_custom_matcher_descriptions = true
end
config.mock_with :rspec do |mocks|
mocks.verify_partial_doubles = true
end
config.filter_run :focus
config.run_all_when_everything_filtered = true
Did someone encounter this problem before ? Does anyone have a solution for this ? I have been banging my head for days looking on the web...
Thank you very much.
PS : it works fine on my friend's mac (Yosemite or El Capitan), just not on mine.
I was having this problem in CI (CodeShip).
Adding a call to bundle exec rake assets:precompile at the end of the setup commands seemed to fix it:
CodeShip CI Setup Commands:
rvm use 2.3.4 --install
bundle install
export RAILS_ENV=test
bundle exec rake db:schema:load
bundle exec rake assets:precompile
Also had a whitelist per #agbodike but in the rails_helper.rb
config.before(:each, js: true) do
page.driver.browser.url_whitelist = ["127.0.0.1"]
end
I had the same issue and it was due to a 3rd party script timing out. You can prevent loading of 3rd party scripts with a blacklist. For example:
config.before(:each, js: true) do
page.driver.browser.url_blacklist = ["http://use.typekit.net"]
end
would prevent any URL starting with http://use.typekit.net from being called for each test that uses the js driver. More information can be found at:
https://robots.thoughtbot.com/speed-up-javascript-capybara-specs-by-blacklisting-urls
Alternatively you can use a whitelist:
config.before(:each, js: true) do
page.driver.browser.url_whitelist = ["127.0.0.1"]
end
which will block all requests not to 127.0.0.1
I placed the configuration in spec/feature_helper.rb to ensure it was only set for feature specs.
You can avoid these by precompile the assets before tests.
And the code is:
RSpec.configure do |config|
config.before :all do
ENV['PRECOMPILE_ASSETS'] ||= begin
case self.class.metadata[:type]
when :feature, :view
STDOUT.write "Precompiling assets..."
require 'rake'
Rails.application.load_tasks
Rake::Task['assets:precompile'].invoke
STDOUT.puts " done."
Time.now.to_s
end
end
end
end
more info
I want to extract sign_in out of my feature tests into a Ruby module, consistent with this Thoughtbot article. Feature is not seeing sign_in. What am I doing wrong?
Failures:
1) User signs in with valid email and password
Failure/Error: sign_in
NameError:
undefined local variable or method `sign_in' for #<RSpec::ExampleGroups::UserSignsIn:0x0000000238a958>
# ./spec/features/sign_in_spec.rb:16:in `block (2 levels) in <top (required)>'
# .bundle/binstubs/rspec:16:in `load'
# .bundle/binstubs/rspec:16:in `<main>'
Finished in 0.17549 seconds (files took 2.77 seconds to load)
1 example, 1 failure
spec/features/sign_in_spec.rb
require 'rails_helper'
feature 'User signs in' do
scenario 'with valid email and password' do
sign_in
expect(page).to have_content 'Signed in successfully'
end
end
spec/support/features/session_helpers.rb
module Features
module SessionHelpers
def sign_in
user = create(:user)
visit '/'
find(:xpath, "//a[#href='/users/sign_in']").click
fill_in 'Email', with: user.email
fill_in 'Password', with: user.password
click_button 'Sign in'
end
end
end
spec/support/features.rb
RSpec.configure do |config|
config.include Features::SessionHelpers, type: :feature
end
rails_helper.rb
ENV['RAILS_ENV'] ||= 'test'
require File.expand_path('../../config/environment', __FILE__)
abort("The Rails environment is running in production mode!") if Rails.env.production?
require 'spec_helper'
require 'rspec/rails'
require 'pry'
require 'faker'
require 'devise'
require 'email_spec'
ActiveRecord::Migration.maintain_test_schema!
RSpec.configure do |config|
config.include FactoryGirl::Syntax::Methods # Include Factory Girl syntax to simplify calls to factories
config.use_transactional_fixtures = true
config.include Devise::TestHelpers, type: :controller
config.infer_spec_type_from_file_location!
config.include(EmailSpec::Helpers)
config.include(EmailSpec::Matchers)
end
spec_helper.rb
require 'codeclimate-test-reporter'
CodeClimate::TestReporter.start
require 'capybara/rspec'
require 'capybara/email/rspec'
RSpec.configure do |config|
config.before(:each) { ActionMailer::Base.deliveries.clear } # uses email_spec gem to clear mail delivereies
config.expect_with :rspec do |expectations|
expectations.include_chain_clauses_in_custom_matcher_descriptions = true
end
config.mock_with :rspec do |mocks|
mocks.verify_partial_doubles = true
end
end
Do you have something in your rails_helper.rb or spec_helper.rb that will cause your helper to be loaded?
Change your rails_helper.rb to start with:
ENV['RAILS_ENV'] ||= 'test'
require File.expand_path('../../config/environment', __FILE__)
abort("The Rails environment is running in production mode!") if Rails.env.production?
require 'spec_helper'
require 'rspec/rails'
require 'pry'
require 'faker'
require 'devise'
require 'email_spec'
Dir[Rails.root.join("spec/support/**/*.rb")].each { |f| require f }
ActiveRecord::Migration.maintain_test_schema!
RSpec.configure do |config|
config.include Features::SessionHelpers, type: :feature
...
And delete spec/support/features.rb. This will ensure that the order of execution is correct, creating your Helper module (and anything else in your support folder) and then including the helper in RSpec's namespace.
I am trying to get my ENV variables in production mode ...
but now way .. cannot reach the server ... the SECRET_KEY_BASE is not found ... if I hardcode it , then go trouble w the database creds, and if I hardcode them, got trouble w the SMTP creds...
this means that no ENV[] variables cannot be reached ...
I added the gemfile to get it in :production environment, and bundled it
gem 'dotenv-rails', :groups => [:development, :test, :staging, :production]
my .env file is present in my remote server ( Ubuntu 14 - w .rbenv Ruby 2.0 , Rais 4.2 )
cat /var/www/workshop/shared/.env
SECRET_KEY_BASE=106063d5146566142b6aa4782b874115c73a61ac2505f11f8e
DATABASE_USER_NAME=myself
DATABASE_PASSWORD=mydbpwd
MAILGUN_SMTP_SERVER=smtp.mailgun.org
MAILGUN_SMTP_USER_NAME=postmaster#mydomain.com
MAILGUN_SMTP_PASSWORD=2fc998a7399999999a264b88c
MAILGUN_SMTP_DOMAIN=mydomain.com
I set my secrets.yml file on the remote server
cat secrets.yml
production:
secret_key_base: <%= ENV["SECRET_KEY_BASE"] %>
I set my database.yml
cat database.yml
production:
adapter: postgresql
database: workshop
encoding: unicode
pool: 5
username: <%= ENV['DATABASE_USER_NAME'] %>
password: <%= ENV['DATABASE_PASSWORD'] %>
and I updated my config/environments/production.rb w smtp creds
cat production.rb
.....
# SMTP settings for mailgun
config.action_mailer.smtp_settings = {
:port => 587,
:address => ENV['MAILGUN_SMTP_SERVER'],
:user_name => ENV['MAILGUN_SMTP_USER_NAME'],
:password => ENV['MAILGUN_SMTP_PASSWORD'],
:domain => ENV['MAILGUN_SMTP_DOMAIN'],
:authentication => :plain,
:enable_starttls_auto => true
}
...
Finally I gave up w .dotenv in production...
I resolved using Rails 4.1 secrets.yml...
as I am deploying w capistrano 3 ,
- I use the gem capistrano-upload-config
- I created : secrets.production.yml , database.production.yml, configuration.production.yml
- I added in my capistrano deploy.rb
set :config_files, %w{config/database.yml config/secrets.yml config/application.yml}
set :linked_files, %w{config/database.yml config/secrets.yml config/application.yml}
capistrano uploads these productions files from the local .production files and link them... so
the server database.yml is loaded/linked (from local database.production.yml)
the server secrets.yml is loaded/linked (from local secrets.production.yml)
the server application.yml is loaded/linked (from local application.production.yml)
regarding the production.rb SMTP settings , I use the secrets file :
:address => Rails.application.secrets.mailgun_smtp_server,
...
all these files are in .gitignore
My ruby on rails action mailer runs all good in development environment, but in production environment, it keeps throw:
ActionView::Template::Error: Missing host to link to! Please provide the :host parameter, set default_url_options[:host], or set :only_path to true
My development config is
config.action_mailer.delivery_method = :smtp
config.action_mailer.smtp_settings = {
:port => xxx,
:address => 'smtp.example.org',
:user_name => 'xxx#example.com',
:password => 'xxxxxxxx',
:domain => 'xxxxxx.example',
:authentication => :plain,
}
config.action_mailer.default_url_options = { :host => 'localhost:3000' }
My production config is
config.action_mailer.delivery_method = :smtp
config.action_mailer.smtp_settings = {
:port => 587,
:address => 'smtp.example.org',
:user_name => 'xxx#example.com',
:password => 'xxxxxx',
:domain => 'example.com',
:authentication => :plain,
}
config.action_mailer.default_url_options = { :host => 'example.com' }
My other environments are:
ruby 2.1.1
rails 4.0.3
sidekiq
devise
devise-async
I have tried:
Add the following in a initializer file
ActionMailer::Base.default_url_options[:host] = "example.com"
This answer here
Neither of them works.
In the end I added the following with the correct value to each environment file:
test.rb / development.rb / production.rb
Devise 3.2.x - 4.x.x
Rails 4.1.x && Rails 4.2.x && Rails 5.x.x
Thanks to maudulus
# Default Mailer Host
Rails.application.routes.default_url_options[:host] = 'domain.example'
Try restarting the server. Even in Rails 4.1 the config is not reparsed without a restart.