pax_global_header 0000666 0000000 0000000 00000000064 12667400506 0014520 g ustar 00root root 0000000 0000000 52 comment=a0e0b67b5afbb02d9ea9e48d71ae80b3efb8c0ac
rails-4.2.6/ 0000775 0000000 0000000 00000000000 12667400506 0012643 5 ustar 00root root 0000000 0000000 rails-4.2.6/.gitignore 0000664 0000000 0000000 00000000756 12667400506 0014643 0 ustar 00root root 0000000 0000000 # Don't put *.swp, *.bak, etc here; those belong in a global ~/.gitignore.
# Check out https://help.github.com/articles/ignoring-files for how to set that up.
debug.log
.Gemfile
/.bundle
/.ruby-version
pkg
/dist
/doc/rdoc
/*/doc
/*/test/tmp
/activerecord/sqlnet.log
/activemodel/test/fixtures/fixture_database.sqlite3
/activesupport/test/fixtures/isolation_test
/railties/test/500.html
/railties/test/fixtures/tmp
/railties/test/initializer/root/log
/railties/doc
/railties/tmp
/guides/output
rails-4.2.6/.travis.yml 0000664 0000000 0000000 00000002371 12667400506 0014757 0 ustar 00root root 0000000 0000000 language: ruby
sudo: false
script: 'ci/travis.rb'
before_install:
- "rvm current | grep 'jruby' && export AR_JDBC=true || echo"
- "rm ${BUNDLE_GEMFILE}.lock"
before_script:
- bundle update
cache: bundler
env:
global:
- JRUBY_OPTS='-J-Xmx1024M'
matrix:
- "GEM=railties"
- "GEM=ap"
- "GEM=am,amo,as,av,aj"
- "GEM=ar:mysql"
- "GEM=ar:mysql2"
- "GEM=ar:sqlite3"
- "GEM=ar:postgresql"
- "GEM=aj:integration"
rvm:
- 1.9.3
- 2.0.0
- 2.1
- 2.2.4
- 2.3.0
- ruby-head
matrix:
allow_failures:
- rvm: ruby-head
- rvm: 1.9.3
env: "GEM=ar:mysql"
- rvm: 2.0.0
env: "GEM=ar:mysql"
- rvm: ruby-head
env: "GEM=ar:mysql"
- env: "GEM=aj:integration"
fast_finish: true
notifications:
email: false
irc:
on_success: change
on_failure: always
channels:
- "irc.freenode.org#rails-contrib"
campfire:
on_success: change
on_failure: always
rooms:
- secure: "YA1alef1ESHWGFNVwvmVGCkMe4cUy4j+UcNvMUESraceiAfVyRMAovlQBGs6\n9kBRm7DHYBUXYC2ABQoJbQRLDr/1B5JPf/M8+Qd7BKu8tcDC03U01SMHFLpO\naOs/HLXcDxtnnpL07tGVsm0zhMc5N8tq4/L3SHxK7Vi+TacwQzI="
bundler_args: --without test --jobs 3 --retry 3
services:
- memcached
- redis
- rabbitmq
addons:
postgresql: "9.3"
rails-4.2.6/.yardopts 0000664 0000000 0000000 00000000104 12667400506 0014504 0 ustar 00root root 0000000 0000000 --exclude /templates/
--quiet
act*/lib/**/*.rb
railties/lib/**/*.rb
rails-4.2.6/CONTRIBUTING.md 0000664 0000000 0000000 00000002255 12667400506 0015100 0 ustar 00root root 0000000 0000000 Ruby on Rails is a volunteer effort. We encourage you to pitch in. [Join the team](http://contributors.rubyonrails.org)!
* If you want to submit a bug report please make sure to follow our [reporting guidelines](http://edgeguides.rubyonrails.org/contributing_to_ruby_on_rails.html#reporting-an-issue).
* If you want to submit a patch, please read the [Contributing to Ruby on Rails](http://edgeguides.rubyonrails.org/contributing_to_ruby_on_rails.html) guide.
* If you want to contribute to Rails documentation, please read the [Contributing to the Rails Documentation](http://edgeguides.rubyonrails.org/contributing_to_ruby_on_rails.html#contributing-to-the-rails-documentation) section of the aforementioned guide.
*We only accept bug reports and pull requests in GitHub*.
* If you have a question about how to use Ruby on Rails, please [ask the rubyonrails-talk mailing list](https://groups.google.com/forum/?fromgroups#!forum/rubyonrails-talk).
* If you have a change or new feature in mind, please [suggest it on the rubyonrails-core mailing list](https://groups.google.com/forum/?fromgroups#!forum/rubyonrails-core) and start writing code.
Thanks! :heart: :heart: :heart:
Rails Team
rails-4.2.6/Gemfile 0000664 0000000 0000000 00000006663 12667400506 0014151 0 ustar 00root root 0000000 0000000 source 'https://rubygems.org'
gemspec
# We need a newish Rake since Active Job sets its test tasks' descriptions.
gem 'rake', '>= 10.3'
# This needs to be with require false as it is
# loaded after loading the test library to
# ensure correct loading order
gem 'mocha', '~> 0.14', require: false
gem 'rack-cache', '~> 1.2'
gem 'jquery-rails', '~> 4.0'
gem 'coffee-rails', '~> 4.1.0'
gem 'turbolinks'
gem 'sprockets', '~> 3.0.0.rc.1'
gem 'execjs', '< 2.5'
# require: false so bcrypt is loaded only when has_secure_password is used.
# This is to avoid ActiveModel (and by extension the entire framework)
# being dependent on a binary library.
gem 'bcrypt', '~> 3.1.10', require: false
# This needs to be with require false to avoid
# it being automatically loaded by sprockets
gem 'uglifier', '>= 1.3.0', require: false
group :doc do
gem 'sdoc', '~> 0.4.0'
gem 'redcarpet', '~> 3.1.2', platforms: :ruby
gem 'w3c_validators'
gem 'kindlerb', '0.1.1'
gem 'mustache', '~> 0.99.8'
end
# AS
gem 'dalli', '>= 2.2.1'
# ActiveJob
group :job do
gem 'resque', require: false
gem 'resque-scheduler', require: false
gem 'sidekiq', require: false
gem 'sucker_punch', '< 2.0', require: false
gem 'delayed_job', require: false
gem 'queue_classic', require: false, platforms: :ruby
gem 'sneakers', '0.1.1.pre', require: false
gem 'que', require: false
gem 'backburner', require: false
gem 'qu-rails', github: "bkeepers/qu", branch: "master", require: false
gem 'qu-redis', require: false
gem 'delayed_job_active_record', require: false
gem 'sequel', require: false
gem 'amq-protocol', '< 2.0.0', require: false
end
# Add your own local bundler stuff
local_gemfile = File.dirname(__FILE__) + "/.Gemfile"
instance_eval File.read local_gemfile if File.exist? local_gemfile
group :test do
# FIX: Our test suite isn't ready to run in random order yet
gem 'minitest', '< 5.3.4'
platforms :mri_19 do
gem 'ruby-prof', '~> 0.11.2'
end
# platforms :mri_19, :mri_20 do
# gem 'debugger'
# end
platforms :mri do
gem 'stackprof'
end
gem 'benchmark-ips'
end
platforms :ruby do
gem 'nokogiri', '>= 1.4.5'
# Needed for compiling the ActionDispatch::Journey parser
gem 'racc', '>=1.4.6', require: false
# AR
gem 'sqlite3', '~> 1.3.6'
group :db do
gem 'pg', '>= 0.15.0'
gem 'mysql', '>= 2.9.0'
gem 'mysql2', '>= 0.4.0'
end
end
platforms :jruby do
gem 'json'
if ENV['AR_JDBC']
gem 'activerecord-jdbcsqlite3-adapter', github: 'jruby/activerecord-jdbc-adapter', branch: 'master'
group :db do
gem 'activerecord-jdbcmysql-adapter', github: 'jruby/activerecord-jdbc-adapter', branch: 'master'
gem 'activerecord-jdbcpostgresql-adapter', github: 'jruby/activerecord-jdbc-adapter', branch: 'master'
end
else
gem 'activerecord-jdbcsqlite3-adapter', '>= 1.3.0'
group :db do
gem 'activerecord-jdbcmysql-adapter', '>= 1.3.0'
gem 'activerecord-jdbcpostgresql-adapter', '>= 1.3.0'
end
end
end
platforms :rbx do
# The rubysl-yaml gem doesn't ship with Psych by default
# as it needs libyaml that isn't always available.
gem 'psych', '~> 2.0'
end
# gems that are necessary for ActiveRecord tests with Oracle database
if ENV['ORACLE_ENHANCED']
platforms :ruby do
gem 'ruby-oci8', '~> 2.1'
end
gem 'activerecord-oracle_enhanced-adapter', github: 'rsim/oracle-enhanced', branch: 'master'
end
# A gem necessary for ActiveRecord tests with IBM DB
gem 'ibm_db' if ENV['IBM_DB']
rails-4.2.6/Gemfile.lock 0000664 0000000 0000000 00000014544 12667400506 0015075 0 ustar 00root root 0000000 0000000 GIT
remote: git://github.com/bkeepers/qu.git
revision: d098e2657c92e89a6413bebd9c033930759c061f
branch: master
specs:
qu (0.2.0)
qu-rails (0.2.0)
qu (= 0.2.0)
railties (>= 3.2, < 5)
qu-redis (0.2.0)
qu (= 0.2.0)
redis-namespace
PATH
remote: .
specs:
actionmailer (4.2.6)
actionpack (= 4.2.6)
actionview (= 4.2.6)
activejob (= 4.2.6)
mail (~> 2.5, >= 2.5.4)
rails-dom-testing (~> 1.0, >= 1.0.5)
actionpack (4.2.6)
actionview (= 4.2.6)
activesupport (= 4.2.6)
rack (~> 1.6)
rack-test (~> 0.6.2)
rails-dom-testing (~> 1.0, >= 1.0.5)
rails-html-sanitizer (~> 1.0, >= 1.0.2)
actionview (4.2.6)
activesupport (= 4.2.6)
builder (~> 3.1)
erubis (~> 2.7.0)
rails-dom-testing (~> 1.0, >= 1.0.5)
rails-html-sanitizer (~> 1.0, >= 1.0.2)
activejob (4.2.6)
activesupport (= 4.2.6)
globalid (>= 0.3.0)
activemodel (4.2.6)
activesupport (= 4.2.6)
builder (~> 3.1)
activerecord (4.2.6)
activemodel (= 4.2.6)
activesupport (= 4.2.6)
arel (~> 6.0)
activesupport (4.2.6)
i18n (~> 0.7)
json (~> 1.7, >= 1.7.7)
minitest (~> 5.1)
thread_safe (~> 0.3, >= 0.3.4)
tzinfo (~> 1.1)
rails (4.2.6)
actionmailer (= 4.2.6)
actionpack (= 4.2.6)
actionview (= 4.2.6)
activejob (= 4.2.6)
activemodel (= 4.2.6)
activerecord (= 4.2.6)
activesupport (= 4.2.6)
bundler (>= 1.3.0, < 2.0)
railties (= 4.2.6)
sprockets-rails
railties (4.2.6)
actionpack (= 4.2.6)
activesupport (= 4.2.6)
rake (>= 0.8.7)
thor (>= 0.18.1, < 2.0)
GEM
remote: https://rubygems.org/
specs:
amq-protocol (1.9.2)
arel (6.0.3)
backburner (1.2.0)
beaneater (~> 1.0)
dante (> 0.1.5)
bcrypt (3.1.10)
bcrypt (3.1.10-x64-mingw32)
bcrypt (3.1.10-x86-mingw32)
beaneater (1.0.0)
benchmark-ips (2.3.0)
builder (3.2.2)
bunny (1.1.9)
amq-protocol (>= 1.9.2)
celluloid (0.15.2)
timers (~> 1.1.0)
coffee-rails (4.1.1)
coffee-script (>= 2.2.0)
railties (>= 4.0.0, < 5.1.x)
coffee-script (2.4.1)
coffee-script-source
execjs
coffee-script-source (1.10.0)
concurrent-ruby (1.0.0)
connection_pool (2.2.0)
dalli (2.7.5)
dante (0.2.0)
delayed_job (4.1.1)
activesupport (>= 3.0, < 5.0)
delayed_job_active_record (4.1.0)
activerecord (>= 3.0, < 5)
delayed_job (>= 3.0, < 5)
erubis (2.7.0)
execjs (2.4.0)
globalid (0.3.6)
activesupport (>= 4.1.0)
i18n (0.7.0)
jquery-rails (4.0.5)
rails-dom-testing (~> 1.0)
railties (>= 4.2.0)
thor (>= 0.14, < 2.0)
json (1.8.3)
kindlerb (0.1.1)
mustache
nokogiri
loofah (2.0.3)
nokogiri (>= 1.5.9)
mail (2.6.3)
mime-types (>= 1.16, < 3)
metaclass (0.0.4)
mime-types (2.99.1)
mini_portile2 (2.0.0)
minitest (5.3.3)
mocha (0.14.0)
metaclass (~> 0.0.1)
mono_logger (1.1.0)
multi_json (1.11.2)
mustache (0.99.8)
mysql (2.9.1)
mysql2 (0.4.2)
nokogiri (1.6.7.1)
mini_portile2 (~> 2.0.0.rc2)
nokogiri (1.6.7.1-x64-mingw32)
mini_portile2 (~> 2.0.0.rc2)
nokogiri (1.6.7.1-x86-mingw32)
mini_portile2 (~> 2.0.0.rc2)
pg (0.18.4)
psych (2.0.17)
que (0.11.2)
queue_classic (3.1.0)
pg (>= 0.17, < 0.19)
racc (1.4.14)
rack (1.6.4)
rack-cache (1.5.1)
rack (>= 0.4)
rack-protection (1.5.3)
rack
rack-test (0.6.3)
rack (>= 1.0)
rails-deprecated_sanitizer (1.0.3)
activesupport (>= 4.2.0.alpha)
rails-dom-testing (1.0.7)
activesupport (>= 4.2.0.beta, < 5.0)
nokogiri (~> 1.6.0)
rails-deprecated_sanitizer (>= 1.0.1)
rails-html-sanitizer (1.0.3)
loofah (~> 2.0)
rake (10.4.2)
rdoc (4.2.1)
json (~> 1.4)
redcarpet (3.1.2)
redis (3.2.2)
redis-namespace (1.5.2)
redis (~> 3.0, >= 3.0.4)
resque (1.25.2)
mono_logger (~> 1.0)
multi_json (~> 1.0)
redis-namespace (~> 1.3)
sinatra (>= 0.9.2)
vegas (~> 0.1.2)
resque-scheduler (4.0.0)
mono_logger (~> 1.0)
redis (~> 3.0)
resque (~> 1.25)
rufus-scheduler (~> 3.0)
ruby-prof (0.11.3)
rufus-scheduler (3.1.10)
sdoc (0.4.1)
json (~> 1.7, >= 1.7.7)
rdoc (~> 4.0)
sequel (4.29.0)
serverengine (1.5.11)
sigdump (~> 0.2.2)
sidekiq (4.0.1)
concurrent-ruby (~> 1.0)
connection_pool (~> 2.2, >= 2.2.0)
json (~> 1.0)
redis (~> 3.2, >= 3.2.1)
sigdump (0.2.3)
sinatra (1.4.6)
rack (~> 1.4)
rack-protection (~> 1.4)
tilt (>= 1.3, < 3)
sneakers (0.1.1.pre)
bunny (~> 1.1.3)
serverengine
thor
thread
sprockets (3.0.3)
rack (~> 1.0)
sprockets-rails (3.0.4)
actionpack (>= 4.0)
activesupport (>= 4.0)
sprockets (>= 3.0.0)
sqlite3 (1.3.11)
stackprof (0.2.7)
sucker_punch (1.0.5)
celluloid (~> 0.15.2)
thor (0.19.1)
thread (0.2.2)
thread_safe (0.3.5)
tilt (2.0.1)
timers (1.1.0)
turbolinks (2.5.3)
coffee-rails
tzinfo (1.2.2)
thread_safe (~> 0.1)
uglifier (2.7.2)
execjs (>= 0.3.0)
json (>= 1.8.0)
vegas (0.1.11)
rack (>= 1.0.0)
w3c_validators (1.2)
json
nokogiri
PLATFORMS
ruby
x64-mingw32
x86-mingw32
DEPENDENCIES
activerecord-jdbcmysql-adapter (>= 1.3.0)
activerecord-jdbcpostgresql-adapter (>= 1.3.0)
activerecord-jdbcsqlite3-adapter (>= 1.3.0)
amq-protocol (< 2.0.0)
backburner
bcrypt (~> 3.1.10)
benchmark-ips
coffee-rails (~> 4.1.0)
dalli (>= 2.2.1)
delayed_job
delayed_job_active_record
execjs (< 2.5)
jquery-rails (~> 4.0)
json
kindlerb (= 0.1.1)
minitest (< 5.3.4)
mocha (~> 0.14)
mustache (~> 0.99.8)
mysql (>= 2.9.0)
mysql2 (>= 0.4.0)
nokogiri (>= 1.4.5)
pg (>= 0.15.0)
psych (~> 2.0)
qu-rails!
qu-redis
que
queue_classic
racc (>= 1.4.6)
rack-cache (~> 1.2)
rails!
rake (>= 10.3)
redcarpet (~> 3.1.2)
resque
resque-scheduler
ruby-prof (~> 0.11.2)
sdoc (~> 0.4.0)
sequel
sidekiq
sneakers (= 0.1.1.pre)
sprockets (~> 3.0.0.rc.1)
sqlite3 (~> 1.3.6)
stackprof
sucker_punch (< 2.0)
turbolinks
uglifier (>= 1.3.0)
w3c_validators
BUNDLED WITH
1.11.2
rails-4.2.6/RAILS_VERSION 0000664 0000000 0000000 00000000006 12667400506 0014641 0 ustar 00root root 0000000 0000000 4.2.6
rails-4.2.6/README.md 0000664 0000000 0000000 00000010152 12667400506 0014121 0 ustar 00root root 0000000 0000000 ## Welcome to Rails
Rails is a web-application framework that includes everything needed to
create database-backed web applications according to the
[Model-View-Controller (MVC)](http://en.wikipedia.org/wiki/Model-view-controller)
pattern.
Understanding the MVC pattern is key to understanding Rails. MVC divides your
application into three layers, each with a specific responsibility.
The _Model layer_ represents your domain model (such as Account, Product,
Person, Post, etc.) and encapsulates the business logic that is specific to
your application. In Rails, database-backed model classes are derived from
`ActiveRecord::Base`. Active Record allows you to present the data from
database rows as objects and embellish these data objects with business logic
methods. You can read more about Active Record in its [README](activerecord/README.rdoc).
Although most Rails models are backed by a database, models can also be ordinary
Ruby classes, or Ruby classes that implement a set of interfaces as provided by
the Active Model module. You can read more about Active Model in its [README](activemodel/README.rdoc).
The _Controller layer_ is responsible for handling incoming HTTP requests and
providing a suitable response. Usually this means returning HTML, but Rails controllers
can also generate XML, JSON, PDFs, mobile-specific views, and more. Controllers load and
manipulate models, and render view templates in order to generate the appropriate HTTP response.
In Rails, incoming requests are routed by Action Dispatch to an appropriate controller, and
controller classes are derived from `ActionController::Base`. Action Dispatch and Action Controller
are bundled together in Action Pack. You can read more about Action Pack in its
[README](actionpack/README.rdoc).
The _View layer_ is composed of "templates" that are responsible for providing
appropriate representations of your application's resources. Templates can
come in a variety of formats, but most view templates are HTML with embedded
Ruby code (ERB files). Views are typically rendered to generate a controller response,
or to generate the body of an email. In Rails, View generation is handled by Action View.
You can read more about Action View in its [README](actionview/README.rdoc).
Active Record, Action Pack, and Action View can each be used independently outside Rails.
In addition to them, Rails also comes with Action Mailer ([README](actionmailer/README.rdoc)), a library
to generate and send emails; Active Job ([README](activejob/README.md)), a
framework for declaring jobs and making them run on a variety of queueing
backends; and Active Support ([README](activesupport/README.rdoc)), a collection
of utility classes and standard library extensions that are useful for Rails,
and may also be used independently outside Rails.
## Getting Started
1. Install Rails at the command prompt if you haven't yet:
gem install rails
2. At the command prompt, create a new Rails application:
rails new myapp
where "myapp" is the application name.
3. Change directory to `myapp` and start the web server:
cd myapp
rails server
Run with `--help` or `-h` for options.
4. Using a browser, go to `http://localhost:3000` and you'll see:
"Welcome aboard: You're riding Ruby on Rails!"
5. Follow the guidelines to start developing your application. You may find
the following resources handy:
* [Getting Started with Rails](http://guides.rubyonrails.org/getting_started.html)
* [Ruby on Rails Guides](http://guides.rubyonrails.org)
* [The API Documentation](http://api.rubyonrails.org)
* [Ruby on Rails Tutorial](http://www.railstutorial.org/book)
## Contributing
We encourage you to contribute to Ruby on Rails! Please check out the
[Contributing to Ruby on Rails guide](http://edgeguides.rubyonrails.org/contributing_to_ruby_on_rails.html) for guidelines about how to proceed. [Join us!](http://contributors.rubyonrails.org)
## Code Status
* [](https://travis-ci.org/rails/rails)
## License
Ruby on Rails is released under the [MIT License](http://www.opensource.org/licenses/MIT).
rails-4.2.6/RELEASING_RAILS.rdoc 0000664 0000000 0000000 00000016031 12667400506 0015760 0 ustar 00root root 0000000 0000000 = Releasing Rails
In this document, we'll cover the steps necessary to release Rails. Each
section contains steps to take during that time before the release. The times
suggested in each header are just that: suggestions. However, they should
really be considered as minimums.
== 10 Days before release
Today is mostly coordination tasks. Here are the things you must do today:
=== Is the CI green? If not, make it green. (See "Fixing the CI")
Do not release with a Red CI. You can find the CI status here:
http://travis-ci.org/rails/rails
=== Is Sam Ruby happy? If not, make him happy.
Sam Ruby keeps a test suite that makes sure the code samples in his book (Agile
Web Development with Rails) all work. These are valuable integration tests
for Rails. You can check the status of his tests here:
http://intertwingly.net/projects/dashboard.html
Do not release with Red AWDwR tests.
=== Are the supported plugins working? If not, make it work.
Some Rails plugins are important and need to be supported until Rails 5.
As these plugins are outside the Rails repository it is easy to break them without knowing
after some refactoring or bug fix, so it is important to check if the following plugins
are working with the versions that will be released:
* https://github.com/rails/protected_attributes
* https://github.com/rails/activerecord-deprecated_finders
Do not release red plugins tests.
=== Do we have any Git dependencies? If so, contact those authors.
Having Git dependencies indicates that we depend on unreleased code.
Obviously Rails cannot be released when it depends on unreleased code.
Contact the authors of those particular gems and work out a release date that
suits them.
=== Contact the security team (either Koz or tenderlove)
Let them know of your plans to release. There may be security issues to be
addressed, and that can impact your release date.
=== Notify implementors.
Ruby implementors have high stakes in making sure Rails works. Be kind and
give them a heads up that Rails will be released soonish.
This only need to be done for major and minor releases, bugfix releases aren't a
big enough deal, and are supposed to be backwards compatible.
Send an email just giving a heads up about the upcoming release to these
lists:
* team@jruby.org
* community@rubini.us
* rubyonrails-core@googlegroups.com
Implementors will love you and help you.
== 3 Days before release
This is when you should release the release candidate. Here are your tasks
for today:
=== Is the CI green? If not, make it green.
=== Is Sam Ruby happy? If not, make him happy.
=== Contact the security team. CVE emails must be sent on this day.
=== Create a release branch.
From the stable branch, create a release branch. For example, if you're
releasing Rails 3.0.10, do this:
[aaron@higgins rails (3-0-stable)]$ git checkout -b 3-0-10
Switched to a new branch '3-0-10'
[aaron@higgins rails (3-0-10)]$
=== Update each CHANGELOG.
Many times commits are made without the CHANGELOG being updated. You should
review the commits since the last release, and fill in any missing information
for each CHANGELOG.
You can review the commits for the 3.0.10 release like this:
[aaron@higgins rails (3-0-10)]$ git log v3.0.9..
If you're doing a stable branch release, you should also ensure that all of
the CHANGELOG entries in the stable branch are also synced to the master
branch.
=== Update the RAILS_VERSION file to include the RC.
=== Build and test the gem.
Run `rake install` to generate the gems and install them locally. Then try
generating a new app and ensure that nothing explodes.
This will stop you from looking silly when you push an RC to rubygems.org and
then realise it is broken.
=== Release the gem.
IMPORTANT: Due to YAML parse problems on the rubygems.org server, it is safest
to use Ruby 1.8 when releasing.
Run `rake release`. This will populate the gemspecs with data from
RAILS_VERSION, commit the changes, tag it, and push the gems to rubygems.org.
Here are the commands that `rake release` should use, so you can understand
what to do in case anything goes wrong:
$ rake all:build
$ git commit -am'updating RAILS_VERSION'
$ git tag -m 'v3.0.10.rc1 release' v3.0.10.rc1
$ git push
$ git push --tags
$ for i in $(ls pkg); do gem push $i; done
=== Send Rails release announcements
Write a release announcement that includes the version, changes, and links to
GitHub where people can find the specific commit list. Here are the mailing
lists where you should announce:
* rubyonrails-core@googlegroups.com
* rubyonrails-talk@googlegroups.com
* ruby-talk@ruby-lang.org
Use Markdown format for your announcement. Remember to ask people to report
issues with the release candidate to the rails-core mailing list.
IMPORTANT: If any users experience regressions when using the release
candidate, you *must* postpone the release. Bugfix releases *should not*
break existing applications.
=== Post the announcement to the Rails blog.
If you used Markdown format for your email, you can just paste it in to the
blog.
* http://weblog.rubyonrails.org
=== Post the announcement to the Rails Twitter account.
== Time between release candidate and actual release
Check the rails-core mailing list and the GitHub issue list for regressions in
the RC.
If any regressions are found, fix the regressions and repeat the release
candidate process. We will not release the final until 72 hours after the
last release candidate has been pushed. This means that if users find
regressions, the scheduled release date must be postponed.
When you fix the regressions, do not create a new branch. Fix them on the
stable branch, then cherry pick the commit to your release branch. No other
commits should be added to the release branch besides regression fixing commits.
== Day of release
Many of these steps are the same as for the release candidate, so if you need
more explanation on a particular step, see the RC steps.
Today, do this stuff in this order:
* Apply security patches to the release branch
* Update CHANGELOG with security fixes.
* Update RAILS_VERSION to remove the rc
* Build and test the gem
* Release the gems
* If releasing a new stable version:
- Trigger stable docs generation (see below)
- Update the version in the home page
* Email security lists
* Email general announcement lists
=== Emailing the Rails security announce list
Email the security announce list once for each vulnerability fixed.
You can do this, or ask the security team to do it.
Email the security reports to:
* rubyonrails-security@googlegroups.com
* oss-security@lists.openwall.com
Be sure to note the security fixes in your announcement along with CVE numbers
and links to each patch. Some people may not be able to upgrade right away,
so we need to give them the security fixes in patch form.
* Blog announcements
* Twitter announcements
* Merge the release branch to the stable branch.
* Drink beer (or other cocktail)
== Misc
=== Fixing the CI
There are two simple steps for fixing the CI:
1. Identify the problem
2. Fix it
Repeat these steps until the CI is green.
rails-4.2.6/Rakefile 0000664 0000000 0000000 00000003704 12667400506 0014314 0 ustar 00root root 0000000 0000000 require 'sdoc'
require 'net/http'
$:.unshift File.expand_path('..', __FILE__)
require "tasks/release"
require 'railties/lib/rails/api/task'
desc "Build gem files for all projects"
task :build => "all:build"
desc "Release all gems to rubygems and create a tag"
task :release => "all:release"
PROJECTS = %w(activesupport activemodel actionpack actionview actionmailer activerecord railties activejob)
desc 'Run all tests by default'
task :default => %w(test test:isolated)
%w(test test:isolated package gem).each do |task_name|
desc "Run #{task_name} task for all projects"
task task_name do
errors = []
PROJECTS.each do |project|
system(%(cd #{project} && #{$0} #{task_name})) || errors << project
end
fail("Errors in #{errors.join(', ')}") unless errors.empty?
end
end
desc "Smoke-test all projects"
task :smoke do
(PROJECTS - %w(activerecord)).each do |project|
system %(cd #{project} && #{$0} test:isolated)
end
system %(cd activerecord && #{$0} sqlite3:isolated_test)
end
desc "Install gems for all projects."
task :install => "all:install"
desc "Generate documentation for the Rails framework"
if ENV['EDGE']
Rails::API::EdgeTask.new('rdoc')
else
Rails::API::StableTask.new('rdoc')
end
desc 'Bump all versions to match RAILS_VERSION'
task :update_versions => "all:update_versions"
# We have a webhook configured in GitHub that gets invoked after pushes.
# This hook triggers the following tasks:
#
# * updates the local checkout
# * updates Rails Contributors
# * generates and publishes edge docs
# * if there's a new stable tag, generates and publishes stable docs
#
# Everything is automated and you do NOT need to run this task normally.
desc 'Publishes docs, run this AFTER a new stable tag has been pushed'
task :publish_docs do
Net::HTTP.new('api.rubyonrails.org', 8080).start do |http|
request = Net::HTTP::Post.new('/rails-master-hook')
response = http.request(request)
puts response.body
end
end
rails-4.2.6/actionmailer/ 0000775 0000000 0000000 00000000000 12667400506 0015312 5 ustar 00root root 0000000 0000000 rails-4.2.6/actionmailer/CHANGELOG.md 0000664 0000000 0000000 00000005626 12667400506 0017134 0 ustar 00root root 0000000 0000000 ## Rails 4.2.6 (March 07, 2016) ##
* No changes.
## Rails 4.2.5.2 (February 26, 2016) ##
* No changes.
## Rails 4.2.5.1 (January 25, 2015) ##
* No changes.
## Rails 4.2.5 (November 12, 2015) ##
* No changes.
## Rails 4.2.4 (August 24, 2015) ##
* No Changes *
## Rails 4.2.3 (June 25, 2015) ##
* `assert_emails` in block form use the given number as expected value.
This makes the error message much easier to understand.
*Yuji Yaginuma*
* Mailer preview now uses `url_for` to fix links to emails for apps running on
a subdirectory.
*Remo Mueller*
* Mailer previews no longer crash when the `mail` method wasn't called
(`NullMail`).
Fixes #19849.
*Yves Senn*
* Make sure labels and values line up in mailer previews.
*Yves Senn*
## Rails 4.2.2 (June 16, 2015) ##
* No Changes *
## Rails 4.2.1 (March 19, 2015) ##
* No Changes *
## Rails 4.2.0 (December 20, 2014) ##
* `MailerGenerator` now generates layouts by default. The HTML mailer layout
now includes `` and `
` tags which improve the spam rating in
some spam detection engines. Mailers now inherit from `ApplicationMailer`
which sets the default layout.
*Andy Jeffries*
* `link_to` and `url_for` now generate URLs by default in templates.
Passing `only_path: false` is no longer needed.
Fixes #16497 and #16589.
*Xavier Noria*, *Richard Schneeman*
* Attachments can now be added while rendering the mail template.
Fixes #16974.
*Christian Felder*
* Add `#deliver_later` and `#deliver_now` methods and deprecate `#deliver` in
favor of `#deliver_now`. `#deliver_later` will enqueue a job to render and
deliver the mail instead of delivering it immediately. The job is enqueued
using the new Active Job framework in Rails and will use the queue that you
have configured in Rails.
*DHH*, *Abdelkader Boudih*, *Cristian Bica*
* `ActionMailer::Previews` are now class methods instead of instance methods.
*Cristian Bica*
* Deprecate `*_path` helpers in email views. They generated broken links in
email views and were not the intention of most developers. The `*_url`
helper is recommended instead.
*Richard Schneeman*
* Raise an exception when attachments are added after `mail` is called.
This is a safeguard to prevent invalid emails.
Fixes #16163.
*Yves Senn*
* Add `config.action_mailer.show_previews` configuration option.
This configuration option can be used to enable the mail preview in
environments other than development (such as staging).
Defaults to `true` in development and `false` elsewhere.
*Leonard Garvey*
* Allow preview interceptors to be registered through
`config.action_mailer.preview_interceptors`.
See #15739.
*Yves Senn*
Please check [4-1-stable](https://github.com/rails/rails/blob/4-1-stable/actionmailer/CHANGELOG.md)
for previous changes.
rails-4.2.6/actionmailer/MIT-LICENSE 0000664 0000000 0000000 00000002062 12667400506 0016746 0 ustar 00root root 0000000 0000000 Copyright (c) 2004-2014 David Heinemeier Hansson
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
rails-4.2.6/actionmailer/README.rdoc 0000664 0000000 0000000 00000013050 12667400506 0017117 0 ustar 00root root 0000000 0000000 = Action Mailer -- Easy email delivery and testing
Action Mailer is a framework for designing email service layers. These layers
are used to consolidate code for sending out forgotten passwords, welcome
wishes on signup, invoices for billing, and any other use case that requires
a written notification to either a person or another system.
Action Mailer is in essence a wrapper around Action Controller and the
Mail gem. It provides a way to make emails using templates in the same
way that Action Controller renders views using templates.
Additionally, an Action Mailer class can be used to process incoming email,
such as allowing a blog to accept new posts from an email (which could even
have been sent from a phone).
== Sending emails
The framework works by initializing any instance variables you want to be
available in the email template, followed by a call to +mail+ to deliver
the email.
This can be as simple as:
class Notifier < ActionMailer::Base
default from: 'system@loudthinking.com'
def welcome(recipient)
@recipient = recipient
mail(to: recipient,
subject: "[Signed up] Welcome #{recipient}")
end
end
The body of the email is created by using an Action View template (regular
ERB) that has the instance variables that are declared in the mailer action.
So the corresponding body template for the method above could look like this:
Hello there,
Mr. <%= @recipient %>
Thank you for signing up!
If the recipient was given as "david@loudthinking.com", the email
generated would look like this:
Date: Mon, 25 Jan 2010 22:48:09 +1100
From: system@loudthinking.com
To: david@loudthinking.com
Message-ID: <4b5d84f9dd6a5_7380800b81ac29578@void.loudthinking.com.mail>
Subject: [Signed up] Welcome david@loudthinking.com
Mime-Version: 1.0
Content-Type: text/plain;
charset="US-ASCII";
Content-Transfer-Encoding: 7bit
Hello there,
Mr. david@loudthinking.com
Thank you for signing up!
In order to send mails, you simply call the method and then call +deliver_now+ on the return value.
Calling the method returns a Mail Message object:
message = Notifier.welcome("david@loudthinking.com") # => Returns a Mail::Message object
message.deliver_now # => delivers the email
Or you can just chain the methods together like:
Notifier.welcome("david@loudthinking.com").deliver_now # Creates the email and sends it immediately
== Setting defaults
It is possible to set default values that will be used in every method in your
Action Mailer class. To implement this functionality, you just call the public
class method +default+ which you get for free from ActionMailer::Base.
This method accepts a Hash as the parameter. You can use any of the headers,
email messages have, like +:from+ as the key. You can also pass in a string as
the key, like "Content-Type", but Action Mailer does this out of the box for you,
so you won't need to worry about that. Finally, it is also possible to pass in a
Proc that will get evaluated when it is needed.
Note that every value you set with this method will get overwritten if you use the
same key in your mailer method.
Example:
class AuthenticationMailer < ActionMailer::Base
default from: "awesome@application.com", subject: Proc.new { "E-mail was generated at #{Time.now}" }
.....
end
== Receiving emails
To receive emails, you need to implement a public instance method called
+receive+ that takes an email object as its single parameter. The Action Mailer
framework has a corresponding class method, which is also called +receive+, that
accepts a raw, unprocessed email as a string, which it then turns into the email
object and calls the receive instance method.
Example:
class Mailman < ActionMailer::Base
def receive(email)
page = Page.find_by(address: email.to.first)
page.emails.create(
subject: email.subject, body: email.body
)
if email.has_attachments?
email.attachments.each do |attachment|
page.attachments.create({
file: attachment, description: email.subject
})
end
end
end
end
This Mailman can be the target for Postfix or other MTAs. In Rails, you would use
the runner in the trivial case like this:
rails runner 'Mailman.receive(STDIN.read)'
However, invoking Rails in the runner for each mail to be received is very
resource intensive. A single instance of Rails should be run within a daemon, if
it is going to process more than just a limited amount of email.
== Configuration
The Base class has the full list of configuration options. Here's an example:
ActionMailer::Base.smtp_settings = {
address: 'smtp.yourserver.com', # default: localhost
port: '25', # default: 25
user_name: 'user',
password: 'pass',
authentication: :plain # :plain, :login or :cram_md5
}
== Download and installation
The latest version of Action Mailer can be installed with RubyGems:
% [sudo] gem install actionmailer
Source code can be downloaded as part of the Rails project on GitHub
* https://github.com/rails/rails/tree/4-2-stable/actionmailer
== License
Action Mailer is released under the MIT license:
* http://www.opensource.org/licenses/MIT
== Support
API documentation is at
* http://api.rubyonrails.org
Bug reports can be filed for the Ruby on Rails project here:
* https://github.com/rails/rails/issues
Feature requests should be discussed on the rails-core mailing list here:
* https://groups.google.com/forum/?fromgroups#!forum/rubyonrails-core
rails-4.2.6/actionmailer/Rakefile 0000664 0000000 0000000 00000001334 12667400506 0016760 0 ustar 00root root 0000000 0000000 require 'rake/testtask'
require 'rubygems/package_task'
desc "Default Task"
task default: [ :test ]
# Run the unit tests
Rake::TestTask.new { |t|
t.libs << "test"
t.pattern = 'test/**/*_test.rb'
t.warning = true
t.verbose = true
t.ruby_opts = ["--dev"] if defined?(JRUBY_VERSION)
}
namespace :test do
task :isolated do
Dir.glob("test/**/*_test.rb").all? do |file|
sh(Gem.ruby, '-w', '-Ilib:test', file)
end or raise "Failures"
end
end
spec = eval(File.read('actionmailer.gemspec'))
Gem::PackageTask.new(spec) do |p|
p.gem_spec = spec
end
desc "Release to rubygems"
task release: :package do
require 'rake/gemcutter'
Rake::Gemcutter::Tasks.new(spec).define
Rake::Task['gem:push'].invoke
end
rails-4.2.6/actionmailer/actionmailer.gemspec 0000664 0000000 0000000 00000002014 12667400506 0021323 0 ustar 00root root 0000000 0000000 version = File.read(File.expand_path('../../RAILS_VERSION', __FILE__)).strip
Gem::Specification.new do |s|
s.platform = Gem::Platform::RUBY
s.name = 'actionmailer'
s.version = version
s.summary = 'Email composition, delivery, and receiving framework (part of Rails).'
s.description = 'Email on Rails. Compose, deliver, receive, and test emails using the familiar controller/view pattern. First-class support for multipart email and attachments.'
s.required_ruby_version = '>= 1.9.3'
s.license = 'MIT'
s.author = 'David Heinemeier Hansson'
s.email = 'david@loudthinking.com'
s.homepage = 'http://www.rubyonrails.org'
s.files = Dir['CHANGELOG.md', 'README.rdoc', 'MIT-LICENSE', 'lib/**/*']
s.require_path = 'lib'
s.requirements << 'none'
s.add_dependency 'actionpack', version
s.add_dependency 'actionview', version
s.add_dependency 'activejob', version
s.add_dependency 'mail', ['~> 2.5', '>= 2.5.4']
s.add_dependency 'rails-dom-testing', '~> 1.0', '>= 1.0.5'
end
rails-4.2.6/actionmailer/lib/ 0000775 0000000 0000000 00000000000 12667400506 0016060 5 ustar 00root root 0000000 0000000 rails-4.2.6/actionmailer/lib/action_mailer.rb 0000664 0000000 0000000 00000003752 12667400506 0021222 0 ustar 00root root 0000000 0000000 #--
# Copyright (c) 2004-2014 David Heinemeier Hansson
#
# Permission is hereby granted, free of charge, to any person obtaining
# a copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish,
# distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so, subject to
# the following conditions:
#
# The above copyright notice and this permission notice shall be
# included in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#++
require 'abstract_controller'
require 'action_mailer/version'
# Common Active Support usage in Action Mailer
require 'active_support/rails'
require 'active_support/core_ext/class'
require 'active_support/core_ext/module/attr_internal'
require 'active_support/core_ext/string/inflections'
require 'active_support/lazy_load_hooks'
module ActionMailer
extend ::ActiveSupport::Autoload
eager_autoload do
autoload :Collector
end
autoload :Base
autoload :DeliveryMethods
autoload :InlinePreviewInterceptor
autoload :MailHelper
autoload :Preview
autoload :Previews, 'action_mailer/preview'
autoload :TestCase
autoload :TestHelper
autoload :MessageDelivery
autoload :DeliveryJob
end
autoload :Mime, 'action_dispatch/http/mime_type'
ActiveSupport.on_load(:action_view) do
ActionView::Base.default_formats ||= Mime::SET.symbols
ActionView::Template::Types.delegate_to Mime
end
rails-4.2.6/actionmailer/lib/action_mailer/ 0000775 0000000 0000000 00000000000 12667400506 0020666 5 ustar 00root root 0000000 0000000 rails-4.2.6/actionmailer/lib/action_mailer/base.rb 0000664 0000000 0000000 00000113670 12667400506 0022135 0 ustar 00root root 0000000 0000000 require 'mail'
require 'action_mailer/collector'
require 'active_support/core_ext/string/inflections'
require 'active_support/core_ext/hash/except'
require 'active_support/core_ext/module/anonymous'
require 'action_mailer/log_subscriber'
module ActionMailer
# Action Mailer allows you to send email from your application using a mailer model and views.
#
# = Mailer Models
#
# To use Action Mailer, you need to create a mailer model.
#
# $ rails generate mailer Notifier
#
# The generated model inherits from ApplicationMailer which in turn
# inherits from ActionMailer::Base. A mailer model defines methods
# used to generate an email message. In these methods, you can setup variables to be used in
# the mailer views, options on the mail itself such as the :from address, and attachments.
#
# class ApplicationMailer < ActionMailer::Base
# default from: 'from@exmaple.com'
# layout 'mailer'
# end
#
# class Notifier < ApplicationMailer
# default from: 'no-reply@example.com',
# return_path: 'system@example.com'
#
# def welcome(recipient)
# @account = recipient
# mail(to: recipient.email_address_with_name,
# bcc: ["bcc@example.com", "Order Watcher "])
# end
# end
#
# Within the mailer method, you have access to the following methods:
#
# * attachments[]= - Allows you to add attachments to your email in an intuitive
# manner; attachments['filename.png'] = File.read('path/to/filename.png')
#
# * attachments.inline[]= - Allows you to add an inline attachment to your email
# in the same manner as attachments[]=
#
# * headers[]= - Allows you to specify any header field in your email such
# as headers['X-No-Spam'] = 'True'. Note that declaring a header multiple times
# will add many fields of the same name. Read #headers doc for more information.
#
# * headers(hash) - Allows you to specify multiple headers in your email such
# as headers({'X-No-Spam' => 'True', 'In-Reply-To' => '1234@message.id'})
#
# * mail - Allows you to specify email to be sent.
#
# The hash passed to the mail method allows you to specify any header that a Mail::Message
# will accept (any valid email header including optional fields).
#
# The mail method, if not passed a block, will inspect your views and send all the views with
# the same name as the method, so the above action would send the +welcome.text.erb+ view
# file as well as the +welcome.html.erb+ view file in a +multipart/alternative+ email.
#
# If you want to explicitly render only certain templates, pass a block:
#
# mail(to: user.email) do |format|
# format.text
# format.html
# end
#
# The block syntax is also useful in providing information specific to a part:
#
# mail(to: user.email) do |format|
# format.text(content_transfer_encoding: "base64")
# format.html
# end
#
# Or even to render a special view:
#
# mail(to: user.email) do |format|
# format.text
# format.html { render "some_other_template" }
# end
#
# = Mailer views
#
# Like Action Controller, each mailer class has a corresponding view directory in which each
# method of the class looks for a template with its name.
#
# To define a template to be used with a mailing, create an .erb file with the same
# name as the method in your mailer model. For example, in the mailer defined above, the template at
# app/views/notifier/welcome.text.erb would be used to generate the email.
#
# Variables defined in the methods of your mailer model are accessible as instance variables in their
# corresponding view.
#
# Emails by default are sent in plain text, so a sample view for our model example might look like this:
#
# Hi <%= @account.name %>,
# Thanks for joining our service! Please check back often.
#
# You can even use Action View helpers in these views. For example:
#
# You got a new note!
# <%= truncate(@note.body, length: 25) %>
#
# If you need to access the subject, from or the recipients in the view, you can do that through message object:
#
# You got a new note from <%= message.from %>!
# <%= truncate(@note.body, length: 25) %>
#
#
# = Generating URLs
#
# URLs can be generated in mailer views using url_for or named routes. Unlike controllers from
# Action Pack, the mailer instance doesn't have any context about the incoming request, so you'll need
# to provide all of the details needed to generate a URL.
#
# When using url_for you'll need to provide the :host, :controller, and :action:
#
# <%= url_for(host: "example.com", controller: "welcome", action: "greeting") %>
#
# When using named routes you only need to supply the :host:
#
# <%= users_url(host: "example.com") %>
#
# You should use the named_route_url style (which generates absolute URLs) and avoid using the
# named_route_path style (which generates relative URLs), since clients reading the mail will
# have no concept of a current URL from which to determine a relative path.
#
# It is also possible to set a default host that will be used in all mailers by setting the :host
# option as a configuration option in config/application.rb:
#
# config.action_mailer.default_url_options = { host: "example.com" }
#
# When you decide to set a default :host for your mailers, then you need to make sure to use the
# only_path: false option when using url_for. Since the url_for view helper
# will generate relative URLs by default when a :host option isn't explicitly provided, passing
# only_path: false will ensure that absolute URLs are generated.
#
# = Sending mail
#
# Once a mailer action and template are defined, you can deliver your message or create it and save it
# for delivery later:
#
# Notifier.welcome(User.first).deliver_now # sends the email
# mail = Notifier.welcome(User.first) # => an ActionMailer::MessageDelivery object
# mail.deliver_now # sends the email
#
# The ActionMailer::MessageDelivery class is a wrapper around a Mail::Message object. If
# you want direct access to the Mail::Message object you can call the message method on
# the ActionMailer::MessageDelivery object.
#
# Notifier.welcome(User.first).message # => a Mail::Message object
#
# Action Mailer is nicely integrated with Active Job so you can send emails in the background (example: outside
# of the request-response cycle, so the user doesn't have to wait on it):
#
# Notifier.welcome(User.first).deliver_later # enqueue the email sending to Active Job
#
# You never instantiate your mailer class. Rather, you just call the method you defined on the class itself.
#
# = Multipart Emails
#
# Multipart messages can also be used implicitly because Action Mailer will automatically detect and use
# multipart templates, where each template is named after the name of the action, followed by the content
# type. Each such detected template will be added as a separate part to the message.
#
# For example, if the following templates exist:
# * signup_notification.text.erb
# * signup_notification.html.erb
# * signup_notification.xml.builder
# * signup_notification.yml.erb
#
# Each would be rendered and added as a separate part to the message, with the corresponding content
# type. The content type for the entire message is automatically set to multipart/alternative,
# which indicates that the email contains multiple different representations of the same email
# body. The same instance variables defined in the action are passed to all email templates.
#
# Implicit template rendering is not performed if any attachments or parts have been added to the email.
# This means that you'll have to manually add each part to the email and set the content type of the email
# to multipart/alternative.
#
# = Attachments
#
# Sending attachment in emails is easy:
#
# class Notifier < ApplicationMailer
# def welcome(recipient)
# attachments['free_book.pdf'] = File.read('path/to/file.pdf')
# mail(to: recipient, subject: "New account information")
# end
# end
#
# Which will (if it had both a welcome.text.erb and welcome.html.erb
# template in the view directory), send a complete multipart/mixed email with two parts,
# the first part being a multipart/alternative with the text and HTML email parts inside,
# and the second being a application/pdf with a Base64 encoded copy of the file.pdf book
# with the filename +free_book.pdf+.
#
# If you need to send attachments with no content, you need to create an empty view for it,
# or add an empty body parameter like this:
#
# class Notifier < ApplicationMailer
# def welcome(recipient)
# attachments['free_book.pdf'] = File.read('path/to/file.pdf')
# mail(to: recipient, subject: "New account information", body: "")
# end
# end
#
# = Inline Attachments
#
# You can also specify that a file should be displayed inline with other HTML. This is useful
# if you want to display a corporate logo or a photo.
#
# class Notifier < ApplicationMailer
# def welcome(recipient)
# attachments.inline['photo.png'] = File.read('path/to/photo.png')
# mail(to: recipient, subject: "Here is what we look like")
# end
# end
#
# And then to reference the image in the view, you create a welcome.html.erb file and
# make a call to +image_tag+ passing in the attachment you want to display and then call
# +url+ on the attachment to get the relative content id path for the image source:
#
# Please Don't Cringe
#
# <%= image_tag attachments['photo.png'].url -%>
#
# As we are using Action View's +image_tag+ method, you can pass in any other options you want:
#
# Please Don't Cringe
#
# <%= image_tag attachments['photo.png'].url, alt: 'Our Photo', class: 'photo' -%>
#
# = Observing and Intercepting Mails
#
# Action Mailer provides hooks into the Mail observer and interceptor methods. These allow you to
# register classes that are called during the mail delivery life cycle.
#
# An observer class must implement the :delivered_email(message) method which will be
# called once for every email sent after the email has been sent.
#
# An interceptor class must implement the :delivering_email(message) method which will be
# called before the email is sent, allowing you to make modifications to the email before it hits
# the delivery agents. Your class should make any needed modifications directly to the passed
# in Mail::Message instance.
#
# = Default Hash
#
# Action Mailer provides some intelligent defaults for your emails, these are usually specified in a
# default method inside the class definition:
#
# class Notifier < ApplicationMailer
# default sender: 'system@example.com'
# end
#
# You can pass in any header value that a Mail::Message accepts. Out of the box,
# ActionMailer::Base sets the following:
#
# * mime_version: "1.0"
# * charset: "UTF-8",
# * content_type: "text/plain",
# * parts_order: [ "text/plain", "text/enriched", "text/html" ]
#
# parts_order and charset are not actually valid Mail::Message header fields,
# but Action Mailer translates them appropriately and sets the correct values.
#
# As you can pass in any header, you need to either quote the header as a string, or pass it in as
# an underscored symbol, so the following will work:
#
# class Notifier < ApplicationMailer
# default 'Content-Transfer-Encoding' => '7bit',
# content_description: 'This is a description'
# end
#
# Finally, Action Mailer also supports passing Proc objects into the default hash, so you
# can define methods that evaluate as the message is being generated:
#
# class Notifier < ApplicationMailer
# default 'X-Special-Header' => Proc.new { my_method }
#
# private
#
# def my_method
# 'some complex call'
# end
# end
#
# Note that the proc is evaluated right at the start of the mail message generation, so if you
# set something in the defaults using a proc, and then set the same thing inside of your
# mailer method, it will get over written by the mailer method.
#
# It is also possible to set these default options that will be used in all mailers through
# the default_options= configuration in config/application.rb:
#
# config.action_mailer.default_options = { from: "no-reply@example.org" }
#
# = Callbacks
#
# You can specify callbacks using before_action and after_action for configuring your messages.
# This may be useful, for example, when you want to add default inline attachments for all
# messages sent out by a certain mailer class:
#
# class Notifier < ApplicationMailer
# before_action :add_inline_attachment!
#
# def welcome
# mail
# end
#
# private
#
# def add_inline_attachment!
# attachments.inline["footer.jpg"] = File.read('/path/to/filename.jpg')
# end
# end
#
# Callbacks in Action Mailer are implemented using
# AbstractController::Callbacks, so you can define and configure
# callbacks in the same manner that you would use callbacks in classes that
# inherit from ActionController::Base.
#
# Note that unless you have a specific reason to do so, you should prefer using before_action
# rather than after_action in your Action Mailer classes so that headers are parsed properly.
#
# = Previewing emails
#
# You can preview your email templates visually by adding a mailer preview file to the
# ActionMailer::Base.preview_path. Since most emails do something interesting
# with database data, you'll need to write some scenarios to load messages with fake data:
#
# class NotifierPreview < ActionMailer::Preview
# def welcome
# Notifier.welcome(User.first)
# end
# end
#
# Methods must return a Mail::Message object which can be generated by calling the mailer
# method without the additional deliver_now / deliver_later. The location of the
# mailer previews directory can be configured using the preview_path option which has a default
# of test/mailers/previews:
#
# config.action_mailer.preview_path = "#{Rails.root}/lib/mailer_previews"
#
# An overview of all previews is accessible at http://localhost:3000/rails/mailers
# on a running development server instance.
#
# Previews can also be intercepted in a similar manner as deliveries can be by registering
# a preview interceptor that has a previewing_email method:
#
# class CssInlineStyler
# def self.previewing_email(message)
# # inline CSS styles
# end
# end
#
# config.action_mailer.preview_interceptors :css_inline_styler
#
# Note that interceptors need to be registered both with register_interceptor
# and register_preview_interceptor if they should operate on both sending and
# previewing emails.
#
# = Configuration options
#
# These options are specified on the class level, like
# ActionMailer::Base.raise_delivery_errors = true
#
# * default_options - You can pass this in at a class level as well as within the class itself as
# per the above section.
#
# * logger - the logger is used for generating information on the mailing run if available.
# Can be set to +nil+ for no logging. Compatible with both Ruby's own +Logger+ and Log4r loggers.
#
# * smtp_settings - Allows detailed configuration for :smtp delivery method:
# * :address - Allows you to use a remote mail server. Just change it from its default
# "localhost" setting.
# * :port - On the off chance that your mail server doesn't run on port 25, you can change it.
# * :domain - If you need to specify a HELO domain, you can do it here.
# * :user_name - If your mail server requires authentication, set the username in this setting.
# * :password - If your mail server requires authentication, set the password in this setting.
# * :authentication - If your mail server requires authentication, you need to specify the
# authentication type here.
# This is a symbol and one of :plain (will send the password Base64 encoded), :login (will
# send the password Base64 encoded) or :cram_md5 (combines a Challenge/Response mechanism to exchange
# information and a cryptographic Message Digest 5 algorithm to hash important information)
# * :enable_starttls_auto - Detects if STARTTLS is enabled in your SMTP server and starts
# to use it. Defaults to true.
# * :openssl_verify_mode - When using TLS, you can set how OpenSSL checks the certificate. This is
# really useful if you need to validate a self-signed and/or a wildcard certificate. You can use the name
# of an OpenSSL verify constant ('none', 'peer', 'client_once',
# 'fail_if_no_peer_cert') or directly the constant (OpenSSL::SSL::VERIFY_NONE,
# OpenSSL::SSL::VERIFY_PEER, ...).
#
# * sendmail_settings - Allows you to override options for the :sendmail delivery method.
# * :location - The location of the sendmail executable. Defaults to /usr/sbin/sendmail.
# * :arguments - The command line arguments. Defaults to -i -t with -f sender@address
# added automatically before the message is sent.
#
# * file_settings - Allows you to override options for the :file delivery method.
# * :location - The directory into which emails will be written. Defaults to the application
# tmp/mails.
#
# * raise_delivery_errors - Whether or not errors should be raised if the email fails to be delivered.
#
# * delivery_method - Defines a delivery method. Possible values are :smtp (default),
# :sendmail, :test, and :file. Or you may provide a custom delivery method
# object e.g. +MyOwnDeliveryMethodClass+. See the Mail gem documentation on the interface you need to
# implement for a custom delivery agent.
#
# * perform_deliveries - Determines whether emails are actually sent from Action Mailer when you
# call .deliver on an email message or on an Action Mailer method. This is on by default but can
# be turned off to aid in functional testing.
#
# * deliveries - Keeps an array of all the emails sent out through the Action Mailer with
# delivery_method :test. Most useful for unit and functional testing.
class Base < AbstractController::Base
include DeliveryMethods
include Previews
abstract!
include AbstractController::Rendering
include AbstractController::Logger
include AbstractController::Helpers
include AbstractController::Translation
include AbstractController::AssetPaths
include AbstractController::Callbacks
include ActionView::Layouts
PROTECTED_IVARS = AbstractController::Rendering::DEFAULT_PROTECTED_INSTANCE_VARIABLES + [:@_action_has_layout]
def _protected_ivars # :nodoc:
PROTECTED_IVARS
end
helper ActionMailer::MailHelper
private_class_method :new #:nodoc:
class_attribute :default_params
self.default_params = {
mime_version: "1.0",
charset: "UTF-8",
content_type: "text/plain",
parts_order: [ "text/plain", "text/enriched", "text/html" ]
}.freeze
class << self
# Register one or more Observers which will be notified when mail is delivered.
def register_observers(*observers)
observers.flatten.compact.each { |observer| register_observer(observer) }
end
# Register one or more Interceptors which will be called before mail is sent.
def register_interceptors(*interceptors)
interceptors.flatten.compact.each { |interceptor| register_interceptor(interceptor) }
end
# Register an Observer which will be notified when mail is delivered.
# Either a class, string or symbol can be passed in as the Observer.
# If a string or symbol is passed in it will be camelized and constantized.
def register_observer(observer)
delivery_observer = case observer
when String, Symbol
observer.to_s.camelize.constantize
else
observer
end
Mail.register_observer(delivery_observer)
end
# Register an Interceptor which will be called before mail is sent.
# Either a class, string or symbol can be passed in as the Interceptor.
# If a string or symbol is passed in it will be camelized and constantized.
def register_interceptor(interceptor)
delivery_interceptor = case interceptor
when String, Symbol
interceptor.to_s.camelize.constantize
else
interceptor
end
Mail.register_interceptor(delivery_interceptor)
end
# Returns the name of current mailer. This method is also being used as a path for a view lookup.
# If this is an anonymous mailer, this method will return +anonymous+ instead.
def mailer_name
@mailer_name ||= anonymous? ? "anonymous" : name.underscore
end
# Allows to set the name of current mailer.
attr_writer :mailer_name
alias :controller_path :mailer_name
# Sets the defaults through app configuration:
#
# config.action_mailer.default(from: "no-reply@example.org")
#
# Aliased by ::default_options=
def default(value = nil)
self.default_params = default_params.merge(value).freeze if value
default_params
end
# Allows to set defaults through app configuration:
#
# config.action_mailer.default_options = { from: "no-reply@example.org" }
alias :default_options= :default
# Receives a raw email, parses it into an email object, decodes it,
# instantiates a new mailer, and passes the email object to the mailer
# object's +receive+ method.
#
# If you want your mailer to be able to process incoming messages, you'll
# need to implement a +receive+ method that accepts the raw email string
# as a parameter:
#
# class MyMailer < ActionMailer::Base
# def receive(mail)
# # ...
# end
# end
def receive(raw_mail)
ActiveSupport::Notifications.instrument("receive.action_mailer") do |payload|
mail = Mail.new(raw_mail)
set_payload_for_mail(payload, mail)
new.receive(mail)
end
end
# Wraps an email delivery inside of ActiveSupport::Notifications instrumentation.
#
# This method is actually called by the Mail::Message object itself
# through a callback when you call :deliver on the Mail::Message,
# calling +deliver_mail+ directly and passing a Mail::Message will do
# nothing except tell the logger you sent the email.
def deliver_mail(mail) #:nodoc:
ActiveSupport::Notifications.instrument("deliver.action_mailer") do |payload|
set_payload_for_mail(payload, mail)
yield # Let Mail do the delivery actions
end
end
def respond_to?(method, include_private = false) #:nodoc:
super || action_methods.include?(method.to_s)
end
protected
def set_payload_for_mail(payload, mail) #:nodoc:
payload[:mailer] = name
payload[:message_id] = mail.message_id
payload[:subject] = mail.subject
payload[:to] = mail.to
payload[:from] = mail.from
payload[:bcc] = mail.bcc if mail.bcc.present?
payload[:cc] = mail.cc if mail.cc.present?
payload[:date] = mail.date
payload[:mail] = mail.encoded
end
def method_missing(method_name, *args) # :nodoc:
if action_methods.include?(method_name.to_s)
MessageDelivery.new(self, method_name, *args)
else
super
end
end
end
attr_internal :message
# Instantiate a new mailer object. If +method_name+ is not +nil+, the mailer
# will be initialized according to the named method. If not, the mailer will
# remain uninitialized (useful when you only need to invoke the "receive"
# method, for instance).
def initialize(method_name=nil, *args)
super()
@_mail_was_called = false
@_message = Mail.new
process(method_name, *args) if method_name
end
def process(method_name, *args) #:nodoc:
payload = {
mailer: self.class.name,
action: method_name
}
ActiveSupport::Notifications.instrument("process.action_mailer", payload) do
lookup_context.skip_default_locale!
super
@_message = NullMail.new unless @_mail_was_called
end
end
class NullMail #:nodoc:
def body; '' end
def header; {} end
def respond_to?(string, include_all=false)
true
end
def method_missing(*args)
nil
end
end
# Returns the name of the mailer object.
def mailer_name
self.class.mailer_name
end
# Allows you to pass random and unusual headers to the new Mail::Message
# object which will add them to itself.
#
# headers['X-Special-Domain-Specific-Header'] = "SecretValue"
#
# You can also pass a hash into headers of header field names and values,
# which will then be set on the Mail::Message object:
#
# headers 'X-Special-Domain-Specific-Header' => "SecretValue",
# 'In-Reply-To' => incoming.message_id
#
# The resulting Mail::Message will have the following in its header:
#
# X-Special-Domain-Specific-Header: SecretValue
#
# Note about replacing already defined headers:
#
# * +subject+
# * +sender+
# * +from+
# * +to+
# * +cc+
# * +bcc+
# * +reply-to+
# * +orig-date+
# * +message-id+
# * +references+
#
# Fields can only appear once in email headers while other fields such as
# X-Anything can appear multiple times.
#
# If you want to replace any header which already exists, first set it to
# +nil+ in order to reset the value otherwise another field will be added
# for the same header.
def headers(args = nil)
if args
@_message.headers(args)
else
@_message
end
end
# Allows you to add attachments to an email, like so:
#
# mail.attachments['filename.jpg'] = File.read('/path/to/filename.jpg')
#
# If you do this, then Mail will take the file name and work out the mime type
# set the Content-Type, Content-Disposition, Content-Transfer-Encoding and
# base64 encode the contents of the attachment all for you.
#
# You can also specify overrides if you want by passing a hash instead of a string:
#
# mail.attachments['filename.jpg'] = {mime_type: 'application/x-gzip',
# content: File.read('/path/to/filename.jpg')}
#
# If you want to use a different encoding than Base64, you can pass an encoding in,
# but then it is up to you to pass in the content pre-encoded, and don't expect
# Mail to know how to decode this data:
#
# file_content = SpecialEncode(File.read('/path/to/filename.jpg'))
# mail.attachments['filename.jpg'] = {mime_type: 'application/x-gzip',
# encoding: 'SpecialEncoding',
# content: file_content }
#
# You can also search for specific attachments:
#
# # By Filename
# mail.attachments['filename.jpg'] # => Mail::Part object or nil
#
# # or by index
# mail.attachments[0] # => Mail::Part (first attachment)
#
def attachments
if @_mail_was_called
LateAttachmentsProxy.new(@_message.attachments)
else
@_message.attachments
end
end
class LateAttachmentsProxy < SimpleDelegator
def inline; _raise_error end
def []=(_name, _content); _raise_error end
private
def _raise_error
raise RuntimeError, "Can't add attachments after `mail` was called.\n" \
"Make sure to use `attachments[]=` before calling `mail`."
end
end
# The main method that creates the message and renders the email templates. There are
# two ways to call this method, with a block, or without a block.
#
# It accepts a headers hash. This hash allows you to specify
# the most used headers in an email message, these are:
#
# * +:subject+ - The subject of the message, if this is omitted, Action Mailer will
# ask the Rails I18n class for a translated +:subject+ in the scope of
# [mailer_scope, action_name] or if this is missing, will translate the
# humanized version of the +action_name+
# * +:to+ - Who the message is destined for, can be a string of addresses, or an array
# of addresses.
# * +:from+ - Who the message is from
# * +:cc+ - Who you would like to Carbon-Copy on this email, can be a string of addresses,
# or an array of addresses.
# * +:bcc+ - Who you would like to Blind-Carbon-Copy on this email, can be a string of
# addresses, or an array of addresses.
# * +:reply_to+ - Who to set the Reply-To header of the email to.
# * +:date+ - The date to say the email was sent on.
#
# You can set default values for any of the above headers (except +:date+)
# by using the ::default class method:
#
# class Notifier < ActionMailer::Base
# default from: 'no-reply@test.lindsaar.net',
# bcc: 'email_logger@test.lindsaar.net',
# reply_to: 'bounces@test.lindsaar.net'
# end
#
# If you need other headers not listed above, you can either pass them in
# as part of the headers hash or use the headers['name'] = value
# method.
#
# When a +:return_path+ is specified as header, that value will be used as
# the 'envelope from' address for the Mail message. Setting this is useful
# when you want delivery notifications sent to a different address than the
# one in +:from+. Mail will actually use the +:return_path+ in preference
# to the +:sender+ in preference to the +:from+ field for the 'envelope
# from' value.
#
# If you do not pass a block to the +mail+ method, it will find all
# templates in the view paths using by default the mailer name and the
# method name that it is being called from, it will then create parts for
# each of these templates intelligently, making educated guesses on correct
# content type and sequence, and return a fully prepared Mail::Message
# ready to call :deliver on to send.
#
# For example:
#
# class Notifier < ActionMailer::Base
# default from: 'no-reply@test.lindsaar.net'
#
# def welcome
# mail(to: 'mikel@test.lindsaar.net')
# end
# end
#
# Will look for all templates at "app/views/notifier" with name "welcome".
# If no welcome template exists, it will raise an ActionView::MissingTemplate error.
#
# However, those can be customized:
#
# mail(template_path: 'notifications', template_name: 'another')
#
# And now it will look for all templates at "app/views/notifications" with name "another".
#
# If you do pass a block, you can render specific templates of your choice:
#
# mail(to: 'mikel@test.lindsaar.net') do |format|
# format.text
# format.html
# end
#
# You can even render plain text directly without using a template:
#
# mail(to: 'mikel@test.lindsaar.net') do |format|
# format.text { render plain: "Hello Mikel!" }
# format.html { render html: "Hello Mikel!
".html_safe }
# end
#
# Which will render a +multipart/alternative+ email with +text/plain+ and
# +text/html+ parts.
#
# The block syntax also allows you to customize the part headers if desired:
#
# mail(to: 'mikel@test.lindsaar.net') do |format|
# format.text(content_transfer_encoding: "base64")
# format.html
# end
#
def mail(headers = {}, &block)
return @_message if @_mail_was_called && headers.blank? && !block
m = @_message
# At the beginning, do not consider class default for content_type
content_type = headers[:content_type]
# Call all the procs (if any)
default_values = {}
self.class.default.each do |k,v|
default_values[k] = v.is_a?(Proc) ? instance_eval(&v) : v
end
# Handle defaults
headers = headers.reverse_merge(default_values)
headers[:subject] ||= default_i18n_subject
# Apply charset at the beginning so all fields are properly quoted
m.charset = charset = headers[:charset]
# Set configure delivery behavior
wrap_delivery_behavior!(headers.delete(:delivery_method), headers.delete(:delivery_method_options))
# Assign all headers except parts_order, content_type and body
assignable = headers.except(:parts_order, :content_type, :body, :template_name, :template_path)
assignable.each { |k, v| m[k] = v }
# Render the templates and blocks
responses = collect_responses(headers, &block)
@_mail_was_called = true
create_parts_from_responses(m, responses)
# Setup content type, reapply charset and handle parts order
m.content_type = set_content_type(m, content_type, headers[:content_type])
m.charset = charset
if m.multipart?
m.body.set_sort_order(headers[:parts_order])
m.body.sort_parts!
end
m
end
protected
# Used by #mail to set the content type of the message.
#
# It will use the given +user_content_type+, or multipart if the mail
# message has any attachments. If the attachments are inline, the content
# type will be "multipart/related", otherwise "multipart/mixed".
#
# If there is no content type passed in via headers, and there are no
# attachments, or the message is multipart, then the default content type is
# used.
def set_content_type(m, user_content_type, class_default)
params = m.content_type_parameters || {}
case
when user_content_type.present?
user_content_type
when m.has_attachments?
if m.attachments.detect { |a| a.inline? }
["multipart", "related", params]
else
["multipart", "mixed", params]
end
when m.multipart?
["multipart", "alternative", params]
else
m.content_type || class_default
end
end
# Translates the +subject+ using Rails I18n class under [mailer_scope, action_name] scope.
# If it does not find a translation for the +subject+ under the specified scope it will default to a
# humanized version of the action_name.
# If the subject has interpolations, you can pass them through the +interpolations+ parameter.
def default_i18n_subject(interpolations = {})
mailer_scope = self.class.mailer_name.tr('/', '.')
I18n.t(:subject, interpolations.merge(scope: [mailer_scope, action_name], default: action_name.humanize))
end
def collect_responses(headers) #:nodoc:
responses = []
if block_given?
collector = ActionMailer::Collector.new(lookup_context) { render(action_name) }
yield(collector)
responses = collector.responses
elsif headers[:body]
responses << {
body: headers.delete(:body),
content_type: self.class.default[:content_type] || "text/plain"
}
else
templates_path = headers.delete(:template_path) || self.class.mailer_name
templates_name = headers.delete(:template_name) || action_name
each_template(Array(templates_path), templates_name) do |template|
self.formats = template.formats
responses << {
body: render(template: template),
content_type: template.type.to_s
}
end
end
responses
end
def each_template(paths, name, &block) #:nodoc:
templates = lookup_context.find_all(name, paths)
if templates.empty?
raise ActionView::MissingTemplate.new(paths, name, paths, false, 'mailer')
else
templates.uniq { |t| t.formats }.each(&block)
end
end
def create_parts_from_responses(m, responses) #:nodoc:
if responses.size == 1 && !m.has_attachments?
responses[0].each { |k,v| m[k] = v }
elsif responses.size > 1 && m.has_attachments?
container = Mail::Part.new
container.content_type = "multipart/alternative"
responses.each { |r| insert_part(container, r, m.charset) }
m.add_part(container)
else
responses.each { |r| insert_part(m, r, m.charset) }
end
end
def insert_part(container, response, charset) #:nodoc:
response[:charset] ||= charset
part = Mail::Part.new(response)
container.add_part(part)
end
# Emails do not support relative path links.
def self.supports_path?
false
end
ActiveSupport.run_load_hooks(:action_mailer, self)
end
end
rails-4.2.6/actionmailer/lib/action_mailer/collector.rb 0000664 0000000 0000000 00000001531 12667400506 0023201 0 ustar 00root root 0000000 0000000 require 'abstract_controller/collector'
require 'active_support/core_ext/hash/reverse_merge'
require 'active_support/core_ext/array/extract_options'
module ActionMailer
class Collector
include AbstractController::Collector
attr_reader :responses
def initialize(context, &block)
@context = context
@responses = []
@default_render = block
end
def any(*args, &block)
options = args.extract_options!
raise ArgumentError, "You have to supply at least one format" if args.empty?
args.each { |type| send(type, options.dup, &block) }
end
alias :all :any
def custom(mime, options = {})
options.reverse_merge!(content_type: mime.to_s)
@context.formats = [mime.to_sym]
options[:body] = block_given? ? yield : @default_render.call
@responses << options
end
end
end
rails-4.2.6/actionmailer/lib/action_mailer/delivery_job.rb 0000664 0000000 0000000 00000000632 12667400506 0023671 0 ustar 00root root 0000000 0000000 require 'active_job'
module ActionMailer
# The ActionMailer::DeliveryJob class is used when you
# want to send emails outside of the request-response cycle.
class DeliveryJob < ActiveJob::Base # :nodoc:
queue_as :mailers
def perform(mailer, mail_method, delivery_method, *args) # :nodoc:
mailer.constantize.public_send(mail_method, *args).send(delivery_method)
end
end
end
rails-4.2.6/actionmailer/lib/action_mailer/delivery_methods.rb 0000664 0000000 0000000 00000005562 12667400506 0024571 0 ustar 00root root 0000000 0000000 require 'tmpdir'
module ActionMailer
# This module handles everything related to mail delivery, from registering
# new delivery methods to configuring the mail object to be sent.
module DeliveryMethods
extend ActiveSupport::Concern
included do
class_attribute :delivery_methods, :delivery_method
# Do not make this inheritable, because we always want it to propagate
cattr_accessor :raise_delivery_errors
self.raise_delivery_errors = true
cattr_accessor :perform_deliveries
self.perform_deliveries = true
self.delivery_methods = {}.freeze
self.delivery_method = :smtp
add_delivery_method :smtp, Mail::SMTP,
address: "localhost",
port: 25,
domain: 'localhost.localdomain',
user_name: nil,
password: nil,
authentication: nil,
enable_starttls_auto: true
add_delivery_method :file, Mail::FileDelivery,
location: defined?(Rails.root) ? "#{Rails.root}/tmp/mails" : "#{Dir.tmpdir}/mails"
add_delivery_method :sendmail, Mail::Sendmail,
location: '/usr/sbin/sendmail',
arguments: '-i -t'
add_delivery_method :test, Mail::TestMailer
end
# Helpers for creating and wrapping delivery behavior, used by DeliveryMethods.
module ClassMethods
# Provides a list of emails that have been delivered by Mail::TestMailer
delegate :deliveries, :deliveries=, to: Mail::TestMailer
# Adds a new delivery method through the given class using the given
# symbol as alias and the default options supplied.
#
# add_delivery_method :sendmail, Mail::Sendmail,
# location: '/usr/sbin/sendmail',
# arguments: '-i -t'
def add_delivery_method(symbol, klass, default_options={})
class_attribute(:"#{symbol}_settings") unless respond_to?(:"#{symbol}_settings")
send(:"#{symbol}_settings=", default_options)
self.delivery_methods = delivery_methods.merge(symbol.to_sym => klass).freeze
end
def wrap_delivery_behavior(mail, method=nil, options=nil) # :nodoc:
method ||= self.delivery_method
mail.delivery_handler = self
case method
when NilClass
raise "Delivery method cannot be nil"
when Symbol
if klass = delivery_methods[method]
mail.delivery_method(klass, (send(:"#{method}_settings") || {}).merge(options || {}))
else
raise "Invalid delivery method #{method.inspect}"
end
else
mail.delivery_method(method)
end
mail.perform_deliveries = perform_deliveries
mail.raise_delivery_errors = raise_delivery_errors
end
end
def wrap_delivery_behavior!(*args) # :nodoc:
self.class.wrap_delivery_behavior(message, *args)
end
end
end
rails-4.2.6/actionmailer/lib/action_mailer/gem_version.rb 0000664 0000000 0000000 00000000477 12667400506 0023540 0 ustar 00root root 0000000 0000000 module ActionMailer
# Returns the version of the currently loaded Action Mailer as a Gem::Version
def self.gem_version
Gem::Version.new VERSION::STRING
end
module VERSION
MAJOR = 4
MINOR = 2
TINY = 6
PRE = nil
STRING = [MAJOR, MINOR, TINY, PRE].compact.join(".")
end
end
rails-4.2.6/actionmailer/lib/action_mailer/inline_preview_interceptor.rb 0000664 0000000 0000000 00000002636 12667400506 0026657 0 ustar 00root root 0000000 0000000 require 'base64'
module ActionMailer
# Implements a mailer preview interceptor that converts image tag src attributes
# that use inline cid: style urls to data: style urls so that they are visible
# when previewing a HTML email in a web browser.
#
# This interceptor is not enabled by default, to use it just register it like any
# other mailer preview interceptor:
#
# ActionMailer::Base.register_preview_interceptor(ActionMailer::InlinePreviewInterceptor)
#
class InlinePreviewInterceptor
PATTERN = /src=(?:"cid:[^"]+"|'cid:[^']+')/i
include Base64
def self.previewing_email(message) #:nodoc:
new(message).transform!
end
def initialize(message) #:nodoc:
@message = message
end
def transform! #:nodoc:
return message if html_part.blank?
html_source.gsub!(PATTERN) do |match|
if part = find_part(match[9..-2])
%[src="#{data_url(part)}"]
else
match
end
end
message
end
private
def message
@message
end
def html_part
@html_part ||= message.html_part
end
def html_source
html_part.body.raw_source
end
def data_url(part)
"data:#{part.mime_type};base64,#{strict_encode64(part.body.raw_source)}"
end
def find_part(cid)
message.all_parts.find{ |p| p.attachment? && p.cid == cid }
end
end
end
rails-4.2.6/actionmailer/lib/action_mailer/log_subscriber.rb 0000664 0000000 0000000 00000002062 12667400506 0024217 0 ustar 00root root 0000000 0000000 require 'active_support/log_subscriber'
module ActionMailer
# Implements the ActiveSupport::LogSubscriber for logging notifications when
# email is delivered and received.
class LogSubscriber < ActiveSupport::LogSubscriber
# An email was delivered.
def deliver(event)
info do
recipients = Array(event.payload[:to]).join(', ')
"\nSent mail to #{recipients} (#{event.duration.round(1)}ms)"
end
debug { event.payload[:mail] }
end
# An email was received.
def receive(event)
info { "\nReceived mail (#{event.duration.round(1)}ms)" }
debug { event.payload[:mail] }
end
# An email was generated.
def process(event)
debug do
mailer = event.payload[:mailer]
action = event.payload[:action]
"\n#{mailer}##{action}: processed outbound mail in #{event.duration.round(1)}ms"
end
end
# Use the logger configured for ActionMailer::Base
def logger
ActionMailer::Base.logger
end
end
end
ActionMailer::LogSubscriber.attach_to :action_mailer
rails-4.2.6/actionmailer/lib/action_mailer/mail_helper.rb 0000664 0000000 0000000 00000003164 12667400506 0023500 0 ustar 00root root 0000000 0000000 module ActionMailer
# Provides helper methods for ActionMailer::Base that can be used for easily
# formatting messages, accessing mailer or message instances, and the
# attachments list.
module MailHelper
# Take the text and format it, indented two spaces for each line, and
# wrapped at 72 columns.
def block_format(text)
formatted = text.split(/\n\r?\n/).collect { |paragraph|
format_paragraph(paragraph)
}.join("\n\n")
# Make list points stand on their own line
formatted.gsub!(/[ ]*([*]+) ([^*]*)/) { " #{$1} #{$2.strip}\n" }
formatted.gsub!(/[ ]*([#]+) ([^#]*)/) { " #{$1} #{$2.strip}\n" }
formatted
end
# Access the mailer instance.
def mailer
@_controller
end
# Access the message instance.
def message
@_message
end
# Access the message attachments list.
def attachments
mailer.attachments
end
# Returns +text+ wrapped at +len+ columns and indented +indent+ spaces.
#
# my_text = 'Here is a sample text with more than 40 characters'
#
# format_paragraph(my_text, 25, 4)
# # => " Here is a sample text with\n more than 40 characters"
def format_paragraph(text, len = 72, indent = 2)
sentences = [[]]
text.split.each do |word|
if sentences.first.present? && (sentences.last + [word]).join(' ').length > len
sentences << [word]
else
sentences.last << word
end
end
indentation = " " * indent
sentences.map! { |sentence|
"#{indentation}#{sentence.join(' ')}"
}.join "\n"
end
end
end
rails-4.2.6/actionmailer/lib/action_mailer/message_delivery.rb 0000664 0000000 0000000 00000007532 12667400506 0024551 0 ustar 00root root 0000000 0000000 require 'delegate'
require 'active_support/core_ext/string/filters'
module ActionMailer
# The ActionMailer::MessageDelivery class is used by
# ActionMailer::Base when creating a new mailer.
# MessageDelivery is a wrapper (+Delegator+ subclass) around a lazy
# created Mail::Message. You can get direct access to the
# Mail::Message, deliver the email or schedule the email to be sent
# through Active Job.
#
# Notifier.welcome(User.first) # an ActionMailer::MessageDelivery object
# Notifier.welcome(User.first).deliver_now # sends the email
# Notifier.welcome(User.first).deliver_later # enqueue email delivery as a job through Active Job
# Notifier.welcome(User.first).message # a Mail::Message object
class MessageDelivery < Delegator
def initialize(mailer, mail_method, *args) #:nodoc:
@mailer = mailer
@mail_method = mail_method
@args = args
end
def __getobj__ #:nodoc:
@obj ||= @mailer.send(:new, @mail_method, *@args).message
end
def __setobj__(obj) #:nodoc:
@obj = obj
end
# Returns the Mail::Message object
def message
__getobj__
end
# Enqueues the email to be delivered through Active Job. When the
# job runs it will send the email using +deliver_now!+. That means
# that the message will be sent bypassing checking +perform_deliveries+
# and +raise_delivery_errors+, so use with caution.
#
# Notifier.welcome(User.first).deliver_later!
# Notifier.welcome(User.first).deliver_later!(wait: 1.hour)
# Notifier.welcome(User.first).deliver_later!(wait_until: 10.hours.from_now)
#
# Options:
#
# * :wait - Enqueue the email to be delivered with a delay
# * :wait_until - Enqueue the email to be delivered at (after) a specific date / time
# * :queue - Enqueue the email on the specified queue
def deliver_later!(options={})
enqueue_delivery :deliver_now!, options
end
# Enqueues the email to be delivered through Active Job. When the
# job runs it will send the email using +deliver_now+.
#
# Notifier.welcome(User.first).deliver_later
# Notifier.welcome(User.first).deliver_later(wait: 1.hour)
# Notifier.welcome(User.first).deliver_later(wait_until: 10.hours.from_now)
#
# Options:
#
# * :wait - Enqueue the email to be delivered with a delay
# * :wait_until - Enqueue the email to be delivered at (after) a specific date / time
# * :queue - Enqueue the email on the specified queue
def deliver_later(options={})
enqueue_delivery :deliver_now, options
end
# Delivers an email without checking +perform_deliveries+ and +raise_delivery_errors+,
# so use with caution.
#
# Notifier.welcome(User.first).deliver_now!
#
def deliver_now!
message.deliver!
end
# Delivers an email:
#
# Notifier.welcome(User.first).deliver_now
#
def deliver_now
message.deliver
end
def deliver! #:nodoc:
ActiveSupport::Deprecation.warn(<<-MSG.squish)
`#deliver!` is deprecated and will be removed in Rails 5. Use
`#deliver_now!` to deliver immediately or `#deliver_later!` to
deliver through Active Job.
MSG
deliver_now!
end
def deliver #:nodoc:
ActiveSupport::Deprecation.warn(<<-MSG.squish)
`#deliver` is deprecated and will be removed in Rails 5. Use
`#deliver_now` to deliver immediately or `#deliver_later` to
deliver through Active Job.
MSG
deliver_now
end
private
def enqueue_delivery(delivery_method, options={})
args = @mailer.name, @mail_method.to_s, delivery_method.to_s, *@args
ActionMailer::DeliveryJob.set(options).perform_later(*args)
end
end
end
rails-4.2.6/actionmailer/lib/action_mailer/preview.rb 0000664 0000000 0000000 00000006644 12667400506 0022706 0 ustar 00root root 0000000 0000000 require 'active_support/descendants_tracker'
module ActionMailer
module Previews #:nodoc:
extend ActiveSupport::Concern
included do
# Set the location of mailer previews through app configuration:
#
# config.action_mailer.preview_path = "#{Rails.root}/lib/mailer_previews"
#
mattr_accessor :preview_path, instance_writer: false
# Enable or disable mailer previews through app configuration:
#
# config.action_mailer.show_previews = true
#
# Defaults to true for development environment
#
mattr_accessor :show_previews, instance_writer: false
# :nodoc:
mattr_accessor :preview_interceptors, instance_writer: false
self.preview_interceptors = []
end
module ClassMethods
# Register one or more Interceptors which will be called before mail is previewed.
def register_preview_interceptors(*interceptors)
interceptors.flatten.compact.each { |interceptor| register_preview_interceptor(interceptor) }
end
# Register an Interceptor which will be called before mail is previewed.
# Either a class or a string can be passed in as the Interceptor. If a
# string is passed in it will be constantized.
def register_preview_interceptor(interceptor)
preview_interceptor = case interceptor
when String, Symbol
interceptor.to_s.camelize.constantize
else
interceptor
end
unless preview_interceptors.include?(preview_interceptor)
preview_interceptors << preview_interceptor
end
end
end
end
class Preview
extend ActiveSupport::DescendantsTracker
class << self
# Returns all mailer preview classes
def all
load_previews if descendants.empty?
descendants
end
# Returns the mail object for the given email name. The registered preview
# interceptors will be informed so that they can transform the message
# as they would if the mail was actually being delivered.
def call(email)
preview = self.new
message = preview.public_send(email)
inform_preview_interceptors(message)
message
end
# Returns all of the available email previews
def emails
public_instance_methods(false).map(&:to_s).sort
end
# Returns true if the email exists
def email_exists?(email)
emails.include?(email)
end
# Returns true if the preview exists
def exists?(preview)
all.any?{ |p| p.preview_name == preview }
end
# Find a mailer preview by its underscored class name
def find(preview)
all.find{ |p| p.preview_name == preview }
end
# Returns the underscored name of the mailer preview without the suffix
def preview_name
name.sub(/Preview$/, '').underscore
end
protected
def load_previews #:nodoc:
if preview_path
Dir["#{preview_path}/**/*_preview.rb"].each{ |file| require_dependency file }
end
end
def preview_path #:nodoc:
Base.preview_path
end
def show_previews #:nodoc:
Base.show_previews
end
def inform_preview_interceptors(message) #:nodoc:
Base.preview_interceptors.each do |interceptor|
interceptor.previewing_email(message)
end
end
end
end
end
rails-4.2.6/actionmailer/lib/action_mailer/railtie.rb 0000664 0000000 0000000 00000004274 12667400506 0022653 0 ustar 00root root 0000000 0000000 require 'active_job/railtie'
require "action_mailer"
require "rails"
require "abstract_controller/railties/routes_helpers"
module ActionMailer
class Railtie < Rails::Railtie # :nodoc:
config.action_mailer = ActiveSupport::OrderedOptions.new
config.eager_load_namespaces << ActionMailer
initializer "action_mailer.logger" do
ActiveSupport.on_load(:action_mailer) { self.logger ||= Rails.logger }
end
initializer "action_mailer.set_configs" do |app|
paths = app.config.paths
options = app.config.action_mailer
options.assets_dir ||= paths["public"].first
options.javascripts_dir ||= paths["public/javascripts"].first
options.stylesheets_dir ||= paths["public/stylesheets"].first
options.show_previews = Rails.env.development? if options.show_previews.nil?
if options.show_previews
options.preview_path ||= defined?(Rails.root) ? "#{Rails.root}/test/mailers/previews" : nil
end
# make sure readers methods get compiled
options.asset_host ||= app.config.asset_host
options.relative_url_root ||= app.config.relative_url_root
ActiveSupport.on_load(:action_mailer) do
include AbstractController::UrlFor
extend ::AbstractController::Railties::RoutesHelpers.with(app.routes, false)
include app.routes.mounted_helpers
register_interceptors(options.delete(:interceptors))
register_preview_interceptors(options.delete(:preview_interceptors))
register_observers(options.delete(:observers))
options.each { |k,v| send("#{k}=", v) }
if options.show_previews
app.routes.append do
get '/rails/mailers' => "rails/mailers#index"
get '/rails/mailers/*path' => "rails/mailers#preview"
end
end
end
end
initializer "action_mailer.compile_config_methods" do
ActiveSupport.on_load(:action_mailer) do
config.compile_methods! if config.respond_to?(:compile_methods!)
end
end
config.after_initialize do
if ActionMailer::Base.preview_path
ActiveSupport::Dependencies.autoload_paths << ActionMailer::Base.preview_path
end
end
end
end
rails-4.2.6/actionmailer/lib/action_mailer/test_case.rb 0000664 0000000 0000000 00000005561 12667400506 0023174 0 ustar 00root root 0000000 0000000 require 'active_support/test_case'
require 'rails-dom-testing'
module ActionMailer
class NonInferrableMailerError < ::StandardError
def initialize(name)
super "Unable to determine the mailer to test from #{name}. " +
"You'll need to specify it using tests YourMailer in your " +
"test case definition"
end
end
class TestCase < ActiveSupport::TestCase
module Behavior
extend ActiveSupport::Concern
include ActiveSupport::Testing::ConstantLookup
include TestHelper
include Rails::Dom::Testing::Assertions::SelectorAssertions
include Rails::Dom::Testing::Assertions::DomAssertions
included do
class_attribute :_mailer_class
setup :initialize_test_deliveries
setup :set_expected_mail
teardown :restore_test_deliveries
end
module ClassMethods
def tests(mailer)
case mailer
when String, Symbol
self._mailer_class = mailer.to_s.camelize.constantize
when Module
self._mailer_class = mailer
else
raise NonInferrableMailerError.new(mailer)
end
end
def mailer_class
if mailer = self._mailer_class
mailer
else
tests determine_default_mailer(name)
end
end
def determine_default_mailer(name)
mailer = determine_constant_from_test_name(name) do |constant|
Class === constant && constant < ActionMailer::Base
end
raise NonInferrableMailerError.new(name) if mailer.nil?
mailer
end
end
protected
def initialize_test_deliveries
set_delivery_method :test
@old_perform_deliveries = ActionMailer::Base.perform_deliveries
ActionMailer::Base.perform_deliveries = true
end
def restore_test_deliveries
restore_delivery_method
ActionMailer::Base.perform_deliveries = @old_perform_deliveries
ActionMailer::Base.deliveries.clear
end
def set_delivery_method(method)
@old_delivery_method = ActionMailer::Base.delivery_method
ActionMailer::Base.delivery_method = method
end
def restore_delivery_method
ActionMailer::Base.delivery_method = @old_delivery_method
end
def set_expected_mail
@expected = Mail.new
@expected.content_type ["text", "plain", { "charset" => charset }]
@expected.mime_version = '1.0'
end
private
def charset
"UTF-8"
end
def encode(subject)
Mail::Encodings.q_value_encode(subject, charset)
end
def read_fixture(action)
IO.readlines(File.join(Rails.root, 'test', 'fixtures', self.class.mailer_class.name.underscore, action))
end
end
include Behavior
end
end
rails-4.2.6/actionmailer/lib/action_mailer/test_helper.rb 0000664 0000000 0000000 00000003410 12667400506 0023527 0 ustar 00root root 0000000 0000000 module ActionMailer
# Provides helper methods for testing Action Mailer, including #assert_emails
# and #assert_no_emails
module TestHelper
# Asserts that the number of emails sent matches the given number.
#
# def test_emails
# assert_emails 0
# ContactMailer.welcome.deliver_now
# assert_emails 1
# ContactMailer.welcome.deliver_now
# assert_emails 2
# end
#
# If a block is passed, that block should cause the specified number of
# emails to be sent.
#
# def test_emails_again
# assert_emails 1 do
# ContactMailer.welcome.deliver_now
# end
#
# assert_emails 2 do
# ContactMailer.welcome.deliver_now
# ContactMailer.welcome.deliver_now
# end
# end
def assert_emails(number)
if block_given?
original_count = ActionMailer::Base.deliveries.size
yield
new_count = ActionMailer::Base.deliveries.size
assert_equal number, new_count - original_count, "#{number} emails expected, but #{new_count - original_count} were sent"
else
assert_equal number, ActionMailer::Base.deliveries.size
end
end
# Assert that no emails have been sent.
#
# def test_emails
# assert_no_emails
# ContactMailer.welcome.deliver_now
# assert_emails 1
# end
#
# If a block is passed, that block should not cause any emails to be sent.
#
# def test_emails_again
# assert_no_emails do
# # No emails should be sent from this block
# end
# end
#
# Note: This assertion is simply a shortcut for:
#
# assert_emails 0
def assert_no_emails(&block)
assert_emails 0, &block
end
end
end
rails-4.2.6/actionmailer/lib/action_mailer/version.rb 0000664 0000000 0000000 00000000277 12667400506 0022706 0 ustar 00root root 0000000 0000000 require_relative 'gem_version'
module ActionMailer
# Returns the version of the currently loaded Action Mailer as a
# Gem::Version.
def self.version
gem_version
end
end
rails-4.2.6/actionmailer/lib/rails/ 0000775 0000000 0000000 00000000000 12667400506 0017172 5 ustar 00root root 0000000 0000000 rails-4.2.6/actionmailer/lib/rails/generators/ 0000775 0000000 0000000 00000000000 12667400506 0021343 5 ustar 00root root 0000000 0000000 rails-4.2.6/actionmailer/lib/rails/generators/mailer/ 0000775 0000000 0000000 00000000000 12667400506 0022614 5 ustar 00root root 0000000 0000000 rails-4.2.6/actionmailer/lib/rails/generators/mailer/USAGE 0000664 0000000 0000000 00000001147 12667400506 0023406 0 ustar 00root root 0000000 0000000 Description:
============
Stubs out a new mailer and its views. Passes the mailer name, either
CamelCased or under_scored, and an optional list of emails as arguments.
This generates a mailer class in app/mailers and invokes your template
engine and test framework generators.
Example:
========
rails generate mailer Notifications signup forgot_password invoice
creates a Notifications mailer class, views, and test:
Mailer: app/mailers/notifications.rb
Views: app/views/notifications/signup.text.erb [...]
Test: test/mailers/notifications_test.rb
rails-4.2.6/actionmailer/lib/rails/generators/mailer/mailer_generator.rb 0000664 0000000 0000000 00000001057 12667400506 0026463 0 ustar 00root root 0000000 0000000 module Rails
module Generators
class MailerGenerator < NamedBase
source_root File.expand_path("../templates", __FILE__)
argument :actions, type: :array, default: [], banner: "method method"
check_class_collision
def create_mailer_file
template "mailer.rb", File.join('app/mailers', class_path, "#{file_name}.rb")
if self.behavior == :invoke
template "application_mailer.rb", 'app/mailers/application_mailer.rb'
end
end
hook_for :template_engine, :test_framework
end
end
end
rails-4.2.6/actionmailer/lib/rails/generators/mailer/templates/ 0000775 0000000 0000000 00000000000 12667400506 0024612 5 ustar 00root root 0000000 0000000 rails-4.2.6/actionmailer/lib/rails/generators/mailer/templates/application_mailer.rb 0000664 0000000 0000000 00000000146 12667400506 0030774 0 ustar 00root root 0000000 0000000 class ApplicationMailer < ActionMailer::Base
default from: "from@example.com"
layout 'mailer'
end
rails-4.2.6/actionmailer/lib/rails/generators/mailer/templates/mailer.rb 0000664 0000000 0000000 00000000567 12667400506 0026420 0 ustar 00root root 0000000 0000000 <% module_namespacing do -%>
class <%= class_name %> < ApplicationMailer
<% actions.each do |action| -%>
# Subject can be set in your I18n file at config/locales/en.yml
# with the following lookup:
#
# en.<%= file_path.tr("/",".") %>.<%= action %>.subject
#
def <%= action %>
@greeting = "Hi"
mail to: "to@example.org"
end
<% end -%>
end
<% end -%>
rails-4.2.6/actionmailer/test/ 0000775 0000000 0000000 00000000000 12667400506 0016271 5 ustar 00root root 0000000 0000000 rails-4.2.6/actionmailer/test/abstract_unit.rb 0000664 0000000 0000000 00000002741 12667400506 0021464 0 ustar 00root root 0000000 0000000 require File.expand_path('../../../load_paths', __FILE__)
require 'active_support/core_ext/kernel/reporting'
# These are the normal settings that will be set up by Railties
# TODO: Have these tests support other combinations of these values
silence_warnings do
Encoding.default_internal = "UTF-8"
Encoding.default_external = "UTF-8"
end
require 'active_support/testing/autorun'
require 'action_mailer'
require 'action_mailer/test_case'
require 'mail'
# Emulate AV railtie
require 'action_view'
ActionMailer::Base.send(:include, ActionView::Layouts)
# Show backtraces for deprecated behavior for quicker cleanup.
ActiveSupport::Deprecation.debug = true
# Disable available locale checks to avoid warnings running the test suite.
I18n.enforce_available_locales = false
FIXTURE_LOAD_PATH = File.expand_path('fixtures', File.dirname(__FILE__))
ActionMailer::Base.view_paths = FIXTURE_LOAD_PATH
module Rails
def self.root
File.expand_path('../', File.dirname(__FILE__))
end
end
# Skips the current run on Rubinius using Minitest::Assertions#skip
def rubinius_skip(message = '')
skip message if RUBY_ENGINE == 'rbx'
end
# Skips the current run on JRuby using Minitest::Assertions#skip
def jruby_skip(message = '')
skip message if defined?(JRUBY_VERSION)
end
require 'mocha/setup' # FIXME: stop using mocha
# FIXME: we have tests that depend on run order, we should fix that and
# remove this method call.
require 'active_support/test_case'
ActiveSupport::TestCase.test_order = :sorted
rails-4.2.6/actionmailer/test/assert_select_email_test.rb 0000664 0000000 0000000 00000002473 12667400506 0023672 0 ustar 00root root 0000000 0000000 require 'abstract_unit'
class AssertSelectEmailTest < ActionMailer::TestCase
class AssertSelectMailer < ActionMailer::Base
def test(html)
mail body: html, content_type: "text/html",
subject: "Test e-mail", from: "test@test.host", to: "test "
end
end
class AssertMultipartSelectMailer < ActionMailer::Base
def test(options)
mail subject: "Test e-mail", from: "test@test.host", to: "test " do |format|
format.text { render text: options[:text] }
format.html { render text: options[:html] }
end
end
end
#
# Test assert_select_email
#
def test_assert_select_email
assert_raise ActiveSupport::TestCase::Assertion do
assert_select_email {}
end
AssertSelectMailer.test("").deliver_now
assert_select_email do
assert_select "div:root" do
assert_select "p:first-child", "foo"
assert_select "p:last-child", "bar"
end
end
end
def test_assert_select_email_multipart
AssertMultipartSelectMailer.test(html: "", text: 'foo bar').deliver_now
assert_select_email do
assert_select "div:root" do
assert_select "p:first-child", "foo"
assert_select "p:last-child", "bar"
end
end
end
end
rails-4.2.6/actionmailer/test/asset_host_test.rb 0000664 0000000 0000000 00000002032 12667400506 0022026 0 ustar 00root root 0000000 0000000 require 'abstract_unit'
require 'action_controller'
class AssetHostMailer < ActionMailer::Base
def email_with_asset
mail to: 'test@localhost',
subject: 'testing email containing asset path while asset_host is set',
from: 'tester@example.com'
end
end
class AssetHostTest < ActionMailer::TestCase
def setup
AssetHostMailer.configure do |c|
c.asset_host = "http://www.example.com"
end
end
def teardown
restore_delivery_method
end
def test_asset_host_as_string
mail = AssetHostMailer.email_with_asset
assert_dom_equal %Q{
}, mail.body.to_s.strip
end
def test_asset_host_as_one_argument_proc
AssetHostMailer.config.asset_host = Proc.new { |source|
if source.starts_with?('/images')
'http://images.example.com'
end
}
mail = AssetHostMailer.email_with_asset
assert_dom_equal %Q{
}, mail.body.to_s.strip
end
end
rails-4.2.6/actionmailer/test/base_test.rb 0000664 0000000 0000000 00000100436 12667400506 0020573 0 ustar 00root root 0000000 0000000 # encoding: utf-8
require 'abstract_unit'
require 'set'
require 'action_dispatch'
require 'active_support/time'
require 'mailers/base_mailer'
require 'mailers/proc_mailer'
require 'mailers/asset_mailer'
class BaseTest < ActiveSupport::TestCase
include Rails::Dom::Testing::Assertions::DomAssertions
setup do
@original_delivery_method = ActionMailer::Base.delivery_method
ActionMailer::Base.delivery_method = :test
@original_asset_host = ActionMailer::Base.asset_host
@original_assets_dir = ActionMailer::Base.assets_dir
end
teardown do
ActionMailer::Base.asset_host = @original_asset_host
ActionMailer::Base.assets_dir = @original_assets_dir
BaseMailer.deliveries.clear
ActionMailer::Base.delivery_method = @original_delivery_method
end
test "method call to mail does not raise error" do
assert_nothing_raised { BaseMailer.welcome }
end
# Basic mail usage without block
test "mail() should set the headers of the mail message" do
email = BaseMailer.welcome
assert_equal(['system@test.lindsaar.net'], email.to)
assert_equal(['jose@test.plataformatec.com'], email.from)
assert_equal('The first email on new API!', email.subject)
end
test "mail() with from overwrites the class level default" do
email = BaseMailer.welcome(from: 'someone@example.com',
to: 'another@example.org')
assert_equal(['someone@example.com'], email.from)
assert_equal(['another@example.org'], email.to)
end
test "mail() with bcc, cc, content_type, charset, mime_version, reply_to and date" do
time = Time.now.beginning_of_day.to_datetime
email = BaseMailer.welcome(bcc: 'bcc@test.lindsaar.net',
cc: 'cc@test.lindsaar.net',
content_type: 'multipart/mixed',
charset: 'iso-8559-1',
mime_version: '2.0',
reply_to: 'reply-to@test.lindsaar.net',
date: time)
assert_equal(['bcc@test.lindsaar.net'], email.bcc)
assert_equal(['cc@test.lindsaar.net'], email.cc)
assert_equal('multipart/mixed; charset=iso-8559-1', email.content_type)
assert_equal('iso-8559-1', email.charset)
assert_equal('2.0', email.mime_version)
assert_equal(['reply-to@test.lindsaar.net'], email.reply_to)
assert_equal(time, email.date)
end
test "mail() renders the template using the method being processed" do
email = BaseMailer.welcome
assert_equal("Welcome", email.body.encoded)
end
test "can pass in :body to the mail method hash" do
email = BaseMailer.welcome(body: "Hello there")
assert_equal("text/plain", email.mime_type)
assert_equal("Hello there", email.body.encoded)
end
test "should set template content type if mail has only one part" do
mail = BaseMailer.html_only
assert_equal('text/html', mail.mime_type)
mail = BaseMailer.plain_text_only
assert_equal('text/plain', mail.mime_type)
end
# Custom headers
test "custom headers" do
email = BaseMailer.welcome
assert_equal("Not SPAM", email['X-SPAM'].decoded)
end
test "can pass random headers in as a hash to mail" do
hash = {'X-Special-Domain-Specific-Header' => "SecretValue",
'In-Reply-To' => '1234@mikel.me.com' }
mail = BaseMailer.welcome(hash)
assert_equal('SecretValue', mail['X-Special-Domain-Specific-Header'].decoded)
assert_equal('1234@mikel.me.com', mail['In-Reply-To'].decoded)
end
test "can pass random headers in as a hash to headers" do
hash = {'X-Special-Domain-Specific-Header' => "SecretValue",
'In-Reply-To' => '1234@mikel.me.com' }
mail = BaseMailer.welcome_with_headers(hash)
assert_equal('SecretValue', mail['X-Special-Domain-Specific-Header'].decoded)
assert_equal('1234@mikel.me.com', mail['In-Reply-To'].decoded)
end
# Attachments
test "attachment with content" do
email = BaseMailer.attachment_with_content
assert_equal(1, email.attachments.length)
assert_equal('invoice.pdf', email.attachments[0].filename)
assert_equal('This is test File content', email.attachments['invoice.pdf'].decoded)
end
test "attachment gets content type from filename" do
email = BaseMailer.attachment_with_content
assert_equal('invoice.pdf', email.attachments[0].filename)
assert_equal('application/pdf', email.attachments[0].mime_type)
end
test "attachment with hash" do
email = BaseMailer.attachment_with_hash
assert_equal(1, email.attachments.length)
assert_equal('invoice.jpg', email.attachments[0].filename)
expected = "\312\213\254\232)b"
expected.force_encoding(Encoding::BINARY)
assert_equal expected, email.attachments['invoice.jpg'].decoded
end
test "attachment with hash using default mail encoding" do
email = BaseMailer.attachment_with_hash_default_encoding
assert_equal(1, email.attachments.length)
assert_equal('invoice.jpg', email.attachments[0].filename)
expected = "\312\213\254\232)b"
expected.force_encoding(Encoding::BINARY)
assert_equal expected, email.attachments['invoice.jpg'].decoded
end
test "sets mime type to multipart/mixed when attachment is included" do
email = BaseMailer.attachment_with_content
assert_equal(1, email.attachments.length)
assert_equal("multipart/mixed", email.mime_type)
end
test "adds the rendered template as part" do
email = BaseMailer.attachment_with_content
assert_equal(2, email.parts.length)
assert_equal("multipart/mixed", email.mime_type)
assert_equal("text/html", email.parts[0].mime_type)
assert_equal("Attachment with content", email.parts[0].body.encoded)
assert_equal("application/pdf", email.parts[1].mime_type)
assert_equal("VGhpcyBpcyB0ZXN0IEZpbGUgY29udGVudA==\r\n", email.parts[1].body.encoded)
end
test "adds the given :body as part" do
email = BaseMailer.attachment_with_content(body: "I'm the eggman")
assert_equal(2, email.parts.length)
assert_equal("multipart/mixed", email.mime_type)
assert_equal("text/plain", email.parts[0].mime_type)
assert_equal("I'm the eggman", email.parts[0].body.encoded)
assert_equal("application/pdf", email.parts[1].mime_type)
assert_equal("VGhpcyBpcyB0ZXN0IEZpbGUgY29udGVudA==\r\n", email.parts[1].body.encoded)
end
test "can embed an inline attachment" do
email = BaseMailer.inline_attachment
# Need to call #encoded to force the JIT sort on parts
email.encoded
assert_equal(2, email.parts.length)
assert_equal("multipart/related", email.mime_type)
assert_equal("multipart/alternative", email.parts[0].mime_type)
assert_equal("text/plain", email.parts[0].parts[0].mime_type)
assert_equal("text/html", email.parts[0].parts[1].mime_type)
assert_equal("logo.png", email.parts[1].filename)
end
# Defaults values
test "uses default charset from class" do
with_default BaseMailer, charset: "US-ASCII" do
email = BaseMailer.welcome
assert_equal("US-ASCII", email.charset)
email = BaseMailer.welcome(charset: "iso-8559-1")
assert_equal("iso-8559-1", email.charset)
end
end
test "uses default content type from class" do
with_default BaseMailer, content_type: "text/html" do
email = BaseMailer.welcome
assert_equal("text/html", email.mime_type)
email = BaseMailer.welcome(content_type: "text/plain")
assert_equal("text/plain", email.mime_type)
end
end
test "uses default mime version from class" do
with_default BaseMailer, mime_version: "2.0" do
email = BaseMailer.welcome
assert_equal("2.0", email.mime_version)
email = BaseMailer.welcome(mime_version: "1.0")
assert_equal("1.0", email.mime_version)
end
end
test "uses random default headers from class" do
with_default BaseMailer, "X-Custom" => "Custom" do
email = BaseMailer.welcome
assert_equal("Custom", email["X-Custom"].decoded)
end
end
test "subject gets default from I18n" do
with_default BaseMailer, subject: nil do
email = BaseMailer.welcome(subject: nil)
assert_equal "Welcome", email.subject
with_translation 'en', base_mailer: {welcome: {subject: "New Subject!"}} do
email = BaseMailer.welcome(subject: nil)
assert_equal "New Subject!", email.subject
end
end
end
test 'default subject can have interpolations' do
with_translation 'en', base_mailer: {with_subject_interpolations: {subject: 'Will the real %{rapper_or_impersonator} please stand up?'}} do
email = BaseMailer.with_subject_interpolations
assert_equal 'Will the real Slim Shady please stand up?', email.subject
end
end
test "translations are scoped properly" do
with_translation 'en', base_mailer: {email_with_translations: {greet_user: "Hello %{name}!"}} do
email = BaseMailer.email_with_translations
assert_equal 'Hello lifo!', email.body.encoded
end
end
test "adding attachments after mail was called raises exception" do
class LateAttachmentMailer < ActionMailer::Base
def welcome
mail body: "yay", from: "welcome@example.com", to: "to@example.com"
attachments['invoice.pdf'] = 'This is test File content'
end
end
e = assert_raises(RuntimeError) { LateAttachmentMailer.welcome.message }
assert_match(/Can't add attachments after `mail` was called./, e.message)
end
test "adding inline attachments after mail was called raises exception" do
class LateInlineAttachmentMailer < ActionMailer::Base
def welcome
mail body: "yay", from: "welcome@example.com", to: "to@example.com"
attachments.inline['invoice.pdf'] = 'This is test File content'
end
end
e = assert_raises(RuntimeError) { LateInlineAttachmentMailer.welcome.message }
assert_match(/Can't add attachments after `mail` was called./, e.message)
end
test "adding inline attachments while rendering mail works" do
class LateInlineAttachmentMailer < ActionMailer::Base
def on_render
mail from: "welcome@example.com", to: "to@example.com"
end
end
mail = LateInlineAttachmentMailer.on_render
assert_nothing_raised { mail.message }
assert_equal ["image/jpeg; filename=controller_attachments.jpg",
"image/jpeg; filename=attachments.jpg"], mail.attachments.inline.map {|a| a['Content-Type'].to_s }
end
test "accessing attachments works after mail was called" do
class LateAttachmentAccessorMailer < ActionMailer::Base
def welcome
attachments['invoice.pdf'] = 'This is test File content'
mail body: "yay", from: "welcome@example.com", to: "to@example.com"
unless attachments.map(&:filename) == ["invoice.pdf"]
raise Minitest::Assertion, "Should allow access to attachments"
end
end
end
assert_nothing_raised { LateAttachmentAccessorMailer.welcome }
end
# Implicit multipart
test "implicit multipart" do
email = BaseMailer.implicit_multipart
assert_equal(2, email.parts.size)
assert_equal("multipart/alternative", email.mime_type)
assert_equal("text/plain", email.parts[0].mime_type)
assert_equal("TEXT Implicit Multipart", email.parts[0].body.encoded)
assert_equal("text/html", email.parts[1].mime_type)
assert_equal("HTML Implicit Multipart", email.parts[1].body.encoded)
end
test "implicit multipart with sort order" do
order = ["text/html", "text/plain"]
with_default BaseMailer, parts_order: order do
email = BaseMailer.implicit_multipart
assert_equal("text/html", email.parts[0].mime_type)
assert_equal("text/plain", email.parts[1].mime_type)
email = BaseMailer.implicit_multipart(parts_order: order.reverse)
assert_equal("text/plain", email.parts[0].mime_type)
assert_equal("text/html", email.parts[1].mime_type)
end
end
test "implicit multipart with attachments creates nested parts" do
email = BaseMailer.implicit_multipart(attachments: true)
assert_equal("application/pdf", email.parts[0].mime_type)
assert_equal("multipart/alternative", email.parts[1].mime_type)
assert_equal("text/plain", email.parts[1].parts[0].mime_type)
assert_equal("TEXT Implicit Multipart", email.parts[1].parts[0].body.encoded)
assert_equal("text/html", email.parts[1].parts[1].mime_type)
assert_equal("HTML Implicit Multipart", email.parts[1].parts[1].body.encoded)
end
test "implicit multipart with attachments and sort order" do
order = ["text/html", "text/plain"]
with_default BaseMailer, parts_order: order do
email = BaseMailer.implicit_multipart(attachments: true)
assert_equal("application/pdf", email.parts[0].mime_type)
assert_equal("multipart/alternative", email.parts[1].mime_type)
assert_equal("text/plain", email.parts[1].parts[1].mime_type)
assert_equal("text/html", email.parts[1].parts[0].mime_type)
end
end
test "implicit multipart with default locale" do
email = BaseMailer.implicit_with_locale
assert_equal(2, email.parts.size)
assert_equal("multipart/alternative", email.mime_type)
assert_equal("text/plain", email.parts[0].mime_type)
assert_equal("Implicit with locale TEXT", email.parts[0].body.encoded)
assert_equal("text/html", email.parts[1].mime_type)
assert_equal("Implicit with locale EN HTML", email.parts[1].body.encoded)
end
test "implicit multipart with other locale" do
swap I18n, locale: :pl do
email = BaseMailer.implicit_with_locale
assert_equal(2, email.parts.size)
assert_equal("multipart/alternative", email.mime_type)
assert_equal("text/plain", email.parts[0].mime_type)
assert_equal("Implicit with locale PL TEXT", email.parts[0].body.encoded)
assert_equal("text/html", email.parts[1].mime_type)
assert_equal("Implicit with locale HTML", email.parts[1].body.encoded)
end
end
test "implicit multipart with several view paths uses the first one with template" do
old = BaseMailer.view_paths
begin
BaseMailer.view_paths = [File.join(FIXTURE_LOAD_PATH, "another.path")] + old.dup
email = BaseMailer.welcome
assert_equal("Welcome from another path", email.body.encoded)
ensure
BaseMailer.view_paths = old
end
end
test "implicit multipart with inexistent templates uses the next view path" do
old = BaseMailer.view_paths
begin
BaseMailer.view_paths = [File.join(FIXTURE_LOAD_PATH, "unknown")] + old.dup
email = BaseMailer.welcome
assert_equal("Welcome", email.body.encoded)
ensure
BaseMailer.view_paths = old
end
end
# Explicit multipart
test "explicit multipart" do
email = BaseMailer.explicit_multipart
assert_equal(2, email.parts.size)
assert_equal("multipart/alternative", email.mime_type)
assert_equal("text/plain", email.parts[0].mime_type)
assert_equal("TEXT Explicit Multipart", email.parts[0].body.encoded)
assert_equal("text/html", email.parts[1].mime_type)
assert_equal("HTML Explicit Multipart", email.parts[1].body.encoded)
end
test "explicit multipart have a boundary" do
mail = BaseMailer.explicit_multipart
assert_not_nil(mail.content_type_parameters[:boundary])
end
test "explicit multipart with attachments creates nested parts" do
email = BaseMailer.explicit_multipart(attachments: true)
assert_equal("application/pdf", email.parts[0].mime_type)
assert_equal("multipart/alternative", email.parts[1].mime_type)
assert_equal("text/plain", email.parts[1].parts[0].mime_type)
assert_equal("TEXT Explicit Multipart", email.parts[1].parts[0].body.encoded)
assert_equal("text/html", email.parts[1].parts[1].mime_type)
assert_equal("HTML Explicit Multipart", email.parts[1].parts[1].body.encoded)
end
test "explicit multipart with templates" do
email = BaseMailer.explicit_multipart_templates
assert_equal(2, email.parts.size)
assert_equal("multipart/alternative", email.mime_type)
assert_equal("text/plain", email.parts[0].mime_type)
assert_equal("TEXT Explicit Multipart Templates", email.parts[0].body.encoded)
assert_equal("text/html", email.parts[1].mime_type)
assert_equal("HTML Explicit Multipart Templates", email.parts[1].body.encoded)
end
test "explicit multipart with format.any" do
email = BaseMailer.explicit_multipart_with_any
assert_equal(2, email.parts.size)
assert_equal("multipart/alternative", email.mime_type)
assert_equal("text/plain", email.parts[0].mime_type)
assert_equal("Format with any!", email.parts[0].body.encoded)
assert_equal("text/html", email.parts[1].mime_type)
assert_equal("Format with any!", email.parts[1].body.encoded)
end
test "explicit multipart with format(Hash)" do
email = BaseMailer.explicit_multipart_with_options(true)
email.ready_to_send!
assert_equal(2, email.parts.size)
assert_equal("multipart/alternative", email.mime_type)
assert_equal("text/plain", email.parts[0].mime_type)
assert_equal("base64", email.parts[0].content_transfer_encoding)
assert_equal("text/html", email.parts[1].mime_type)
assert_equal("7bit", email.parts[1].content_transfer_encoding)
end
test "explicit multipart with one part is rendered as body and options are merged" do
email = BaseMailer.explicit_multipart_with_options
assert_equal(0, email.parts.size)
assert_equal("text/plain", email.mime_type)
assert_equal("base64", email.content_transfer_encoding)
end
test "explicit multipart with one template has the expected format" do
email = BaseMailer.explicit_multipart_with_one_template
assert_equal(2, email.parts.size)
assert_equal("multipart/alternative", email.mime_type)
assert_equal("text/plain", email.parts[0].mime_type)
assert_equal("[:text]", email.parts[0].body.encoded)
assert_equal("text/html", email.parts[1].mime_type)
assert_equal("[:html]", email.parts[1].body.encoded)
end
test "explicit multipart with sort order" do
order = ["text/html", "text/plain"]
with_default BaseMailer, parts_order: order do
email = BaseMailer.explicit_multipart
assert_equal("text/html", email.parts[0].mime_type)
assert_equal("text/plain", email.parts[1].mime_type)
email = BaseMailer.explicit_multipart(parts_order: order.reverse)
assert_equal("text/plain", email.parts[0].mime_type)
assert_equal("text/html", email.parts[1].mime_type)
end
end
# Class level API with method missing
test "should respond to action methods" do
assert_respond_to BaseMailer, :welcome
assert_respond_to BaseMailer, :implicit_multipart
assert !BaseMailer.respond_to?(:mail)
assert !BaseMailer.respond_to?(:headers)
end
test "calling just the action should return the generated mail object" do
email = BaseMailer.welcome
assert_equal(0, BaseMailer.deliveries.length)
assert_equal('The first email on new API!', email.subject)
end
test "calling deliver on the action should deliver the mail object" do
BaseMailer.expects(:deliver_mail).once
mail = BaseMailer.welcome.deliver_now
assert_equal 'The first email on new API!', mail.subject
end
test "calling deliver on the action should increment the deliveries collection if using the test mailer" do
BaseMailer.welcome.deliver_now
assert_equal(1, BaseMailer.deliveries.length)
end
test "calling deliver, ActionMailer should yield back to mail to let it call :do_delivery on itself" do
mail = Mail::Message.new
mail.expects(:do_delivery).once
BaseMailer.expects(:welcome).returns(mail)
BaseMailer.welcome.deliver
end
# Rendering
test "you can specify a different template for implicit render" do
mail = BaseMailer.implicit_different_template('implicit_multipart').deliver_now
assert_equal("HTML Implicit Multipart", mail.html_part.body.decoded)
assert_equal("TEXT Implicit Multipart", mail.text_part.body.decoded)
end
test "should raise if missing template in implicit render" do
assert_raises ActionView::MissingTemplate do
BaseMailer.implicit_different_template('missing_template').deliver_now
end
assert_equal(0, BaseMailer.deliveries.length)
end
test "you can specify a different template for explicit render" do
mail = BaseMailer.explicit_different_template('explicit_multipart_templates').deliver_now
assert_equal("HTML Explicit Multipart Templates", mail.html_part.body.decoded)
assert_equal("TEXT Explicit Multipart Templates", mail.text_part.body.decoded)
end
test "you can specify a different layout" do
mail = BaseMailer.different_layout('different_layout').deliver_now
assert_equal("HTML -- HTML", mail.html_part.body.decoded)
assert_equal("PLAIN -- PLAIN", mail.text_part.body.decoded)
end
test "you can specify the template path for implicit lookup" do
mail = BaseMailer.welcome_from_another_path('another.path/base_mailer').deliver_now
assert_equal("Welcome from another path", mail.body.encoded)
mail = BaseMailer.welcome_from_another_path(['unknown/invalid', 'another.path/base_mailer']).deliver_now
assert_equal("Welcome from another path", mail.body.encoded)
end
test "assets tags should use ActionMailer's asset_host settings" do
ActionMailer::Base.config.asset_host = "http://global.com"
ActionMailer::Base.config.assets_dir = "global/"
mail = AssetMailer.welcome
assert_dom_equal(%{
}, mail.body.to_s.strip)
end
test "assets tags should use a Mailer's asset_host settings when available" do
ActionMailer::Base.config.asset_host = "http://global.com"
ActionMailer::Base.config.assets_dir = "global/"
TempAssetMailer = Class.new(AssetMailer) do
self.mailer_name = "asset_mailer"
self.asset_host = "http://local.com"
end
mail = TempAssetMailer.welcome
assert_dom_equal(%{
}, mail.body.to_s.strip)
end
test 'the view is not rendered when mail was never called' do
mail = BaseMailer.without_mail_call
assert_equal('', mail.body.to_s.strip)
mail.deliver_now
end
test 'the return value of mailer methods is not relevant' do
mail = BaseMailer.with_nil_as_return_value
assert_equal('Welcome', mail.body.to_s.strip)
mail.deliver_now
end
# Before and After hooks
class MyObserver
def self.delivered_email(mail)
end
end
class MySecondObserver
def self.delivered_email(mail)
end
end
test "you can register an observer to the mail object that gets informed on email delivery" do
mail_side_effects do
ActionMailer::Base.register_observer(MyObserver)
mail = BaseMailer.welcome
MyObserver.expects(:delivered_email).with(mail)
mail.deliver_now
end
end
test "you can register an observer using its stringified name to the mail object that gets informed on email delivery" do
mail_side_effects do
ActionMailer::Base.register_observer("BaseTest::MyObserver")
mail = BaseMailer.welcome
MyObserver.expects(:delivered_email).with(mail)
mail.deliver_now
end
end
test "you can register an observer using its symbolized underscored name to the mail object that gets informed on email delivery" do
mail_side_effects do
ActionMailer::Base.register_observer(:"base_test/my_observer")
mail = BaseMailer.welcome
MyObserver.expects(:delivered_email).with(mail)
mail.deliver_now
end
end
test "you can register multiple observers to the mail object that both get informed on email delivery" do
mail_side_effects do
ActionMailer::Base.register_observers("BaseTest::MyObserver", MySecondObserver)
mail = BaseMailer.welcome
MyObserver.expects(:delivered_email).with(mail)
MySecondObserver.expects(:delivered_email).with(mail)
mail.deliver_now
end
end
class MyInterceptor
def self.delivering_email(mail); end
def self.previewing_email(mail); end
end
class MySecondInterceptor
def self.delivering_email(mail); end
def self.previewing_email(mail); end
end
test "you can register an interceptor to the mail object that gets passed the mail object before delivery" do
mail_side_effects do
ActionMailer::Base.register_interceptor(MyInterceptor)
mail = BaseMailer.welcome
MyInterceptor.expects(:delivering_email).with(mail)
mail.deliver_now
end
end
test "you can register an interceptor using its stringified name to the mail object that gets passed the mail object before delivery" do
mail_side_effects do
ActionMailer::Base.register_interceptor("BaseTest::MyInterceptor")
mail = BaseMailer.welcome
MyInterceptor.expects(:delivering_email).with(mail)
mail.deliver_now
end
end
test "you can register an interceptor using its symbolized underscored name to the mail object that gets passed the mail object before delivery" do
mail_side_effects do
ActionMailer::Base.register_interceptor(:"base_test/my_interceptor")
mail = BaseMailer.welcome
MyInterceptor.expects(:delivering_email).with(mail)
mail.deliver_now
end
end
test "you can register multiple interceptors to the mail object that both get passed the mail object before delivery" do
mail_side_effects do
ActionMailer::Base.register_interceptors("BaseTest::MyInterceptor", MySecondInterceptor)
mail = BaseMailer.welcome
MyInterceptor.expects(:delivering_email).with(mail)
MySecondInterceptor.expects(:delivering_email).with(mail)
mail.deliver_now
end
end
test "being able to put proc's into the defaults hash and they get evaluated on mail sending" do
mail1 = ProcMailer.welcome['X-Proc-Method']
yesterday = 1.day.ago
Time.stubs(:now).returns(yesterday)
mail2 = ProcMailer.welcome['X-Proc-Method']
assert(mail1.to_s.to_i > mail2.to_s.to_i)
end
test 'default values which have to_proc (e.g. symbols) should not be considered procs' do
assert(ProcMailer.welcome['x-has-to-proc'].to_s == 'symbol')
end
test "we can call other defined methods on the class as needed" do
mail = ProcMailer.welcome
assert_equal("Thanks for signing up this afternoon", mail.subject)
end
test "modifying the mail message with a before_action" do
class BeforeActionMailer < ActionMailer::Base
before_action :add_special_header!
def welcome ; mail ; end
private
def add_special_header!
headers('X-Special-Header' => 'Wow, so special')
end
end
assert_equal('Wow, so special', BeforeActionMailer.welcome['X-Special-Header'].to_s)
end
test "modifying the mail message with an after_action" do
class AfterActionMailer < ActionMailer::Base
after_action :add_special_header!
def welcome ; mail ; end
private
def add_special_header!
headers('X-Special-Header' => 'Testing')
end
end
assert_equal('Testing', AfterActionMailer.welcome['X-Special-Header'].to_s)
end
test "adding an inline attachment using a before_action" do
class DefaultInlineAttachmentMailer < ActionMailer::Base
before_action :add_inline_attachment!
def welcome ; mail ; end
private
def add_inline_attachment!
attachments.inline["footer.jpg"] = 'hey there'
end
end
mail = DefaultInlineAttachmentMailer.welcome
assert_equal('image/jpeg; filename=footer.jpg', mail.attachments.inline.first['Content-Type'].to_s)
end
test "action methods should be refreshed after defining new method" do
class FooMailer < ActionMailer::Base
# this triggers action_methods
self.respond_to?(:foo)
def notify
end
end
assert_equal Set.new(["notify"]), FooMailer.action_methods
end
test "mailer can be anonymous" do
mailer = Class.new(ActionMailer::Base) do
def welcome
mail
end
end
assert_equal "anonymous", mailer.mailer_name
assert_equal "Welcome", mailer.welcome.subject
assert_equal "Anonymous mailer body", mailer.welcome.body.encoded.strip
end
test "default_from can be set" do
class DefaultFromMailer < ActionMailer::Base
default to: 'system@test.lindsaar.net'
self.default_options = {from: "robert.pankowecki@gmail.com"}
def welcome
mail(subject: "subject", body: "hello world")
end
end
assert_equal ["robert.pankowecki@gmail.com"], DefaultFromMailer.welcome.from
end
test "mail() without arguments serves as getter for the current mail message" do
class MailerWithCallback < ActionMailer::Base
after_action :a_callback
def welcome
headers('X-Special-Header' => 'special indeed!')
mail subject: "subject", body: "hello world", to: ["joe@example.com"]
end
def a_callback
mail.to << "jane@example.com"
end
end
mail = MailerWithCallback.welcome
assert_equal "subject", mail.subject
assert_equal ["joe@example.com", "jane@example.com"], mail.to
assert_equal "hello world", mail.body.encoded.strip
assert_equal "special indeed!", mail["X-Special-Header"].to_s
end
protected
# Execute the block setting the given values and restoring old values after
# the block is executed.
def swap(klass, new_values)
old_values = {}
new_values.each do |key, value|
old_values[key] = klass.send key
klass.send :"#{key}=", value
end
yield
ensure
old_values.each do |key, value|
klass.send :"#{key}=", value
end
end
def with_default(klass, new_values)
old = klass.default_params
klass.default(new_values)
yield
ensure
klass.default_params = old
end
# A simple hack to restore the observers and interceptors for Mail, as it
# does not have an unregister API yet.
def mail_side_effects
old_observers = Mail.class_variable_get(:@@delivery_notification_observers)
old_delivery_interceptors = Mail.class_variable_get(:@@delivery_interceptors)
yield
ensure
Mail.class_variable_set(:@@delivery_notification_observers, old_observers)
Mail.class_variable_set(:@@delivery_interceptors, old_delivery_interceptors)
end
def with_translation(locale, data)
I18n.backend.store_translations(locale, data)
yield
ensure
I18n.backend.reload!
end
end
class BasePreviewInterceptorsTest < ActiveSupport::TestCase
teardown do
ActionMailer::Base.preview_interceptors.clear
end
class BaseMailerPreview < ActionMailer::Preview
def welcome
BaseMailer.welcome
end
end
class MyInterceptor
def self.delivering_email(mail); end
def self.previewing_email(mail); end
end
class MySecondInterceptor
def self.delivering_email(mail); end
def self.previewing_email(mail); end
end
test "you can register a preview interceptor to the mail object that gets passed the mail object before previewing" do
ActionMailer::Base.register_preview_interceptor(MyInterceptor)
mail = BaseMailer.welcome
BaseMailerPreview.any_instance.stubs(:welcome).returns(mail)
MyInterceptor.expects(:previewing_email).with(mail)
BaseMailerPreview.call(:welcome)
end
test "you can register a preview interceptor using its stringified name to the mail object that gets passed the mail object before previewing" do
ActionMailer::Base.register_preview_interceptor("BasePreviewInterceptorsTest::MyInterceptor")
mail = BaseMailer.welcome
BaseMailerPreview.any_instance.stubs(:welcome).returns(mail)
MyInterceptor.expects(:previewing_email).with(mail)
BaseMailerPreview.call(:welcome)
end
test "you can register an interceptor using its symbolized underscored name to the mail object that gets passed the mail object before previewing" do
ActionMailer::Base.register_preview_interceptor(:"base_preview_interceptors_test/my_interceptor")
mail = BaseMailer.welcome
BaseMailerPreview.any_instance.stubs(:welcome).returns(mail)
MyInterceptor.expects(:previewing_email).with(mail)
BaseMailerPreview.call(:welcome)
end
test "you can register multiple preview interceptors to the mail object that both get passed the mail object before previewing" do
ActionMailer::Base.register_preview_interceptors("BasePreviewInterceptorsTest::MyInterceptor", MySecondInterceptor)
mail = BaseMailer.welcome
BaseMailerPreview.any_instance.stubs(:welcome).returns(mail)
MyInterceptor.expects(:previewing_email).with(mail)
MySecondInterceptor.expects(:previewing_email).with(mail)
BaseMailerPreview.call(:welcome)
end
end
rails-4.2.6/actionmailer/test/delivery_methods_test.rb 0000664 0000000 0000000 00000017026 12667400506 0023231 0 ustar 00root root 0000000 0000000 require 'abstract_unit'
require 'mail'
class MyCustomDelivery
end
class MyOptionedDelivery
attr_reader :options
def initialize(options)
@options = options
end
end
class BogusDelivery
def initialize(*)
end
def deliver!(mail)
raise "failed"
end
end
class DefaultsDeliveryMethodsTest < ActiveSupport::TestCase
test "default smtp settings" do
settings = { address: "localhost",
port: 25,
domain: 'localhost.localdomain',
user_name: nil,
password: nil,
authentication: nil,
enable_starttls_auto: true }
assert_equal settings, ActionMailer::Base.smtp_settings
end
test "default file delivery settings" do
settings = {location: "#{Dir.tmpdir}/mails"}
assert_equal settings, ActionMailer::Base.file_settings
end
test "default sendmail settings" do
settings = {
location: '/usr/sbin/sendmail',
arguments: '-i -t'
}
assert_equal settings, ActionMailer::Base.sendmail_settings
end
end
class CustomDeliveryMethodsTest < ActiveSupport::TestCase
setup do
@old_delivery_method = ActionMailer::Base.delivery_method
ActionMailer::Base.add_delivery_method :custom, MyCustomDelivery
end
teardown do
ActionMailer::Base.delivery_method = @old_delivery_method
new = ActionMailer::Base.delivery_methods.dup
new.delete(:custom)
ActionMailer::Base.delivery_methods = new
end
test "allow to add custom delivery method" do
ActionMailer::Base.delivery_method = :custom
assert_equal :custom, ActionMailer::Base.delivery_method
end
test "allow to customize custom settings" do
ActionMailer::Base.custom_settings = { foo: :bar }
assert_equal Hash[foo: :bar], ActionMailer::Base.custom_settings
end
test "respond to custom settings" do
assert_respond_to ActionMailer::Base, :custom_settings
assert_respond_to ActionMailer::Base, :custom_settings=
end
test "does not respond to unknown settings" do
assert_raise NoMethodError do
ActionMailer::Base.another_settings
end
end
end
class MailDeliveryTest < ActiveSupport::TestCase
class DeliveryMailer < ActionMailer::Base
DEFAULT_HEADERS = {
to: 'mikel@test.lindsaar.net',
from: 'jose@test.plataformatec.com'
}
def welcome(hash={})
mail(DEFAULT_HEADERS.merge(hash))
end
end
setup do
@old_delivery_method = DeliveryMailer.delivery_method
end
teardown do
DeliveryMailer.delivery_method = @old_delivery_method
DeliveryMailer.deliveries.clear
end
test "ActionMailer should be told when Mail gets delivered" do
DeliveryMailer.expects(:deliver_mail).once
DeliveryMailer.welcome.deliver_now
end
test "delivery method can be customized per instance" do
Mail::SMTP.any_instance.expects(:deliver!)
email = DeliveryMailer.welcome.deliver_now
assert_instance_of Mail::SMTP, email.delivery_method
email = DeliveryMailer.welcome(delivery_method: :test).deliver_now
assert_instance_of Mail::TestMailer, email.delivery_method
end
test "delivery method can be customized in subclasses not changing the parent" do
DeliveryMailer.delivery_method = :test
assert_equal :smtp, ActionMailer::Base.delivery_method
email = DeliveryMailer.welcome.deliver_now
assert_instance_of Mail::TestMailer, email.delivery_method
end
test "delivery method options default to class level options" do
default_options = {a: "b"}
ActionMailer::Base.add_delivery_method :optioned, MyOptionedDelivery, default_options
mail_instance = DeliveryMailer.welcome(delivery_method: :optioned)
assert_equal default_options, mail_instance.delivery_method.options
end
test "delivery method options can be overridden per mail instance" do
default_options = {a: "b"}
ActionMailer::Base.add_delivery_method :optioned, MyOptionedDelivery, default_options
overridden_options = {a: "a"}
mail_instance = DeliveryMailer.welcome(delivery_method: :optioned, delivery_method_options: overridden_options)
assert_equal overridden_options, mail_instance.delivery_method.options
end
test "default delivery options can be overridden per mail instance" do
settings = {
address: "localhost",
port: 25,
domain: 'localhost.localdomain',
user_name: nil,
password: nil,
authentication: nil,
enable_starttls_auto: true
}
assert_equal settings, ActionMailer::Base.smtp_settings
overridden_options = {user_name: "overridden", password: "somethingobtuse"}
mail_instance = DeliveryMailer.welcome(delivery_method_options: overridden_options)
delivery_method_instance = mail_instance.delivery_method
assert_equal "overridden", delivery_method_instance.settings[:user_name]
assert_equal "somethingobtuse", delivery_method_instance.settings[:password]
assert_equal delivery_method_instance.settings.merge(overridden_options), delivery_method_instance.settings
# make sure that overriding delivery method options per mail instance doesn't affect the Base setting
assert_equal settings, ActionMailer::Base.smtp_settings
end
test "non registered delivery methods raises errors" do
DeliveryMailer.delivery_method = :unknown
assert_raise RuntimeError do
DeliveryMailer.welcome.deliver_now
end
end
test "undefined delivery methods raises errors" do
DeliveryMailer.delivery_method = nil
assert_raise RuntimeError do
DeliveryMailer.welcome.deliver_now
end
end
test "does not perform deliveries if requested" do
old_perform_deliveries = DeliveryMailer.perform_deliveries
begin
DeliveryMailer.perform_deliveries = false
Mail::Message.any_instance.expects(:deliver!).never
DeliveryMailer.welcome.deliver_now
ensure
DeliveryMailer.perform_deliveries = old_perform_deliveries
end
end
test "does not append the deliveries collection if told not to perform the delivery" do
old_perform_deliveries = DeliveryMailer.perform_deliveries
begin
DeliveryMailer.perform_deliveries = false
DeliveryMailer.welcome.deliver_now
assert_equal [], DeliveryMailer.deliveries
ensure
DeliveryMailer.perform_deliveries = old_perform_deliveries
end
end
test "raise errors on bogus deliveries" do
DeliveryMailer.delivery_method = BogusDelivery
assert_raise RuntimeError do
DeliveryMailer.welcome.deliver_now
end
end
test "does not increment the deliveries collection on error" do
DeliveryMailer.delivery_method = BogusDelivery
assert_raise RuntimeError do
DeliveryMailer.welcome.deliver_now
end
assert_equal [], DeliveryMailer.deliveries
end
test "does not raise errors on bogus deliveries if set" do
old_raise_delivery_errors = DeliveryMailer.raise_delivery_errors
begin
DeliveryMailer.delivery_method = BogusDelivery
DeliveryMailer.raise_delivery_errors = false
assert_nothing_raised do
DeliveryMailer.welcome.deliver_now
end
ensure
DeliveryMailer.raise_delivery_errors = old_raise_delivery_errors
end
end
test "does not increment the deliveries collection on bogus deliveries" do
old_raise_delivery_errors = DeliveryMailer.raise_delivery_errors
begin
DeliveryMailer.delivery_method = BogusDelivery
DeliveryMailer.raise_delivery_errors = false
DeliveryMailer.welcome.deliver_now
assert_equal [], DeliveryMailer.deliveries
ensure
DeliveryMailer.raise_delivery_errors = old_raise_delivery_errors
end
end
end
rails-4.2.6/actionmailer/test/fixtures/ 0000775 0000000 0000000 00000000000 12667400506 0020142 5 ustar 00root root 0000000 0000000 rails-4.2.6/actionmailer/test/fixtures/anonymous/ 0000775 0000000 0000000 00000000000 12667400506 0022172 5 ustar 00root root 0000000 0000000 rails-4.2.6/actionmailer/test/fixtures/anonymous/welcome.erb 0000664 0000000 0000000 00000000026 12667400506 0024315 0 ustar 00root root 0000000 0000000 Anonymous mailer body
rails-4.2.6/actionmailer/test/fixtures/another.path/ 0000775 0000000 0000000 00000000000 12667400506 0022535 5 ustar 00root root 0000000 0000000 rails-4.2.6/actionmailer/test/fixtures/another.path/base_mailer/ 0000775 0000000 0000000 00000000000 12667400506 0025000 5 ustar 00root root 0000000 0000000 rails-4.2.6/actionmailer/test/fixtures/another.path/base_mailer/welcome.erb 0000664 0000000 0000000 00000000031 12667400506 0027117 0 ustar 00root root 0000000 0000000 Welcome from another path rails-4.2.6/actionmailer/test/fixtures/asset_host_mailer/ 0000775 0000000 0000000 00000000000 12667400506 0023647 5 ustar 00root root 0000000 0000000 rails-4.2.6/actionmailer/test/fixtures/asset_host_mailer/email_with_asset.html.erb 0000664 0000000 0000000 00000000037 12667400506 0030625 0 ustar 00root root 0000000 0000000 <%= image_tag "somelogo.png" %> rails-4.2.6/actionmailer/test/fixtures/asset_mailer/ 0000775 0000000 0000000 00000000000 12667400506 0022612 5 ustar 00root root 0000000 0000000 rails-4.2.6/actionmailer/test/fixtures/asset_mailer/welcome.html.erb 0000664 0000000 0000000 00000000034 12667400506 0025677 0 ustar 00root root 0000000 0000000 <%= image_tag "dummy.png" %> rails-4.2.6/actionmailer/test/fixtures/async_mailer/ 0000775 0000000 0000000 00000000000 12667400506 0022610 5 ustar 00root root 0000000 0000000 rails-4.2.6/actionmailer/test/fixtures/async_mailer/welcome.erb 0000664 0000000 0000000 00000000007 12667400506 0024732 0 ustar 00root root 0000000 0000000 Welcome rails-4.2.6/actionmailer/test/fixtures/attachments/ 0000775 0000000 0000000 00000000000 12667400506 0022455 5 ustar 00root root 0000000 0000000 rails-4.2.6/actionmailer/test/fixtures/attachments/foo.jpg 0000664 0000000 0000000 00000003755 12667400506 0023754 0 ustar 00root root 0000000 0000000 ÿØÿà JFIF d d ÿì Ducky <