pax_global_header 0000666 0000000 0000000 00000000064 13162731520 0014512 g ustar 00root root 0000000 0000000 52 comment=6b9a1ac484a4eda1b43aba7ed864952aac743ab9 rails-4.2.10/ 0000775 0000000 0000000 00000000000 13162731520 0012710 5 ustar 00root root 0000000 0000000 rails-4.2.10/.gitignore 0000664 0000000 0000000 00000000756 13162731520 0014710 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.10/.travis.yml 0000664 0000000 0000000 00000002436 13162731520 0015026 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" - "gem update bundler" before_script: - bundle update cache: bundler env: global: - JRUBY_OPTS='-J-Xmx1024M' matrix: - "GEM=railties" - "GEM=ap" - "GEM=am,amo,as,av,aj" - "GEM=as PRESERVE_TIMEZONES=1" - "GEM=ar:mysql" - "GEM=ar:mysql2" - "GEM=ar:sqlite3" - "GEM=ar:postgresql" - "GEM=aj:integration" rvm: - 1.9.3 - 2.0.0-p648 - 2.1.10 - 2.2.7 - 2.3.4 - 2.4.1 matrix: allow_failures: - rvm: 1.9.3 env: "GEM=ar:mysql" - rvm: 2.0.0 env: "GEM=ar:mysql" - env: "GEM=aj:integration" exclude: - rvm: 2.4.1 env: "GEM=ar:mysql" 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: --jobs 3 --retry 3 services: - memcached - redis - rabbitmq addons: postgresql: "9.3" rails-4.2.10/.yardopts 0000664 0000000 0000000 00000000104 13162731520 0014551 0 ustar 00root root 0000000 0000000 --exclude /templates/ --quiet act*/lib/**/*.rb railties/lib/**/*.rb rails-4.2.10/CONTRIBUTING.md 0000664 0000000 0000000 00000002255 13162731520 0015145 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.10/Gemfile 0000664 0000000 0000000 00000007605 13162731520 0014213 0 ustar 00root root 0000000 0000000 source 'https://rubygems.org' ruby "~> #{RUBY_VERSION}" if ENV["TRAVIS"] git_source(:github) do |repo_name| repo_name = "#{repo_name}/#{repo_name}" unless repo_name.include?("/") "https://github.com/#{repo_name}.git" end 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 # mime-types 3 only support ruby >= 2 gem 'mime-types', '< 3', require: false group :doc do gem 'sdoc', '>= 1.0.0.rc1', '< 1.1' gem 'redcarpet', '~> 3.1.2', platforms: :ruby gem 'w3c_validators', RUBY_VERSION < '2.0' ? '1.2' : nil 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', RUBY_VERSION < '2.2' ? '< 5' : nil, require: false gem 'sucker_punch', '< 2.0', require: false gem 'delayed_job', require: false gem 'queue_classic', require: false, platforms: :ruby gem 'sneakers', '< 2.0.0', 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_21 do gem 'stackprof' end gem 'benchmark-ips' end platforms :ruby do gem 'nokogiri', RUBY_VERSION < '2.1' ? '~> 1.6.0' : '>= 1.7' # 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 'mysql2', '>= 0.4.0' end end platforms :mri_19, :mri_20, :mri_21, :mri_22, :mri_23 do group :db do gem 'mysql', '>= 2.9.0' end end platforms :jruby do 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.10/Gemfile.lock 0000664 0000000 0000000 00000015662 13162731520 0015144 0 ustar 00root root 0000000 0000000 GIT remote: https://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.10) actionpack (= 4.2.10) actionview (= 4.2.10) activejob (= 4.2.10) mail (~> 2.5, >= 2.5.4) rails-dom-testing (~> 1.0, >= 1.0.5) actionpack (4.2.10) actionview (= 4.2.10) activesupport (= 4.2.10) 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.10) activesupport (= 4.2.10) builder (~> 3.1) erubis (~> 2.7.0) rails-dom-testing (~> 1.0, >= 1.0.5) rails-html-sanitizer (~> 1.0, >= 1.0.3) activejob (4.2.10) activesupport (= 4.2.10) globalid (>= 0.3.0) activemodel (4.2.10) activesupport (= 4.2.10) builder (~> 3.1) activerecord (4.2.10) activemodel (= 4.2.10) activesupport (= 4.2.10) arel (~> 6.0) activesupport (4.2.10) i18n (~> 0.7) minitest (~> 5.1) thread_safe (~> 0.3, >= 0.3.4) tzinfo (~> 1.1) rails (4.2.10) actionmailer (= 4.2.10) actionpack (= 4.2.10) actionview (= 4.2.10) activejob (= 4.2.10) activemodel (= 4.2.10) activerecord (= 4.2.10) activesupport (= 4.2.10) bundler (>= 1.3.0, < 2.0) railties (= 4.2.10) sprockets-rails railties (4.2.10) actionpack (= 4.2.10) activesupport (= 4.2.10) rake (>= 0.8.7) thor (>= 0.18.1, < 2.0) GEM remote: https://rubygems.org/ specs: amq-protocol (1.9.2) arel (6.0.4) backburner (1.4.1) beaneater (~> 1.0) concurrent-ruby (~> 1.0.1) dante (> 0.1.5) bcrypt (3.1.11) bcrypt (3.1.11-x64-mingw32) bcrypt (3.1.11-x86-mingw32) beaneater (1.0.0) benchmark-ips (2.7.2) builder (3.2.3) bunny (2.0.0) amq-protocol (>= 1.9.2) celluloid (0.17.3) celluloid-essentials celluloid-extras celluloid-fsm celluloid-pool celluloid-supervision timers (>= 4.1.1) celluloid-essentials (0.20.5) timers (>= 4.1.1) celluloid-extras (0.20.5) timers (>= 4.1.1) celluloid-fsm (0.20.5) timers (>= 4.1.1) celluloid-pool (0.20.5) timers (>= 4.1.1) celluloid-supervision (0.20.6) timers (>= 4.1.1) 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.12.2) concurrent-ruby (1.0.5) connection_pool (2.2.1) dalli (2.7.6) dante (0.2.0) delayed_job (4.1.3) activesupport (>= 3.0, < 5.2) delayed_job_active_record (4.1.2) activerecord (>= 3.0, < 5.2) delayed_job (>= 3.0, < 5) erubis (2.7.0) et-orbi (1.0.4) tzinfo execjs (2.4.0) globalid (0.4.0) activesupport (>= 4.2.0) hitimes (1.2.5) hitimes (1.2.5-x86-mingw32) i18n (0.8.4) jquery-rails (4.3.1) rails-dom-testing (>= 1, < 3) railties (>= 4.2.0) thor (>= 0.14, < 2.0) json (2.1.0) kindlerb (0.1.1) mustache nokogiri loofah (2.0.3) nokogiri (>= 1.5.9) mail (2.6.6) mime-types (>= 1.16, < 4) metaclass (0.0.4) mime-types (2.99.3) mini_portile2 (2.2.0) minitest (5.3.3) mocha (0.14.0) metaclass (~> 0.0.1) mono_logger (1.1.0) multi_json (1.12.1) mustache (0.99.8) mysql (2.9.1) mysql2 (0.4.6) nokogiri (1.8.0) mini_portile2 (~> 2.2.0) nokogiri (1.8.0-x64-mingw32) mini_portile2 (~> 2.2.0) nokogiri (1.8.0-x86-mingw32) mini_portile2 (~> 2.2.0) pg (0.18.4) psych (2.2.4) que (0.13.0) queue_classic (3.1.0) pg (>= 0.17, < 0.19) racc (1.4.14) rack (1.6.8) rack-cache (1.7.0) 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.8) activesupport (>= 4.2.0.beta, < 5.0) nokogiri (~> 1.6) rails-deprecated_sanitizer (>= 1.0.1) rails-html-sanitizer (1.0.3) loofah (~> 2.0) rake (12.0.0) rdoc (5.1.0) redcarpet (3.1.2) redis (3.3.3) redis-namespace (1.5.3) redis (~> 3.0, >= 3.0.4) resque (1.27.4) mono_logger (~> 1.0) multi_json (~> 1.0) redis-namespace (~> 1.3) sinatra (>= 0.9.2) vegas (~> 0.1.2) resque-scheduler (4.3.0) mono_logger (~> 1.0) redis (~> 3.3) resque (~> 1.26) rufus-scheduler (~> 3.2) ruby-prof (0.11.3) rufus-scheduler (3.4.2) et-orbi (~> 1.0) sdoc (1.0.0.rc2) rdoc (~> 5.0) sequel (4.47.0) serverengine (1.5.11) sigdump (~> 0.2.2) sidekiq (5.0.2) concurrent-ruby (~> 1.0) connection_pool (~> 2.2, >= 2.2.0) rack-protection (>= 1.5.0) redis (~> 3.3, >= 3.3.3) sigdump (0.2.4) sinatra (1.4.8) rack (~> 1.5) rack-protection (~> 1.4) tilt (>= 1.3, < 3) sneakers (1.1.2) bunny (>= 1.7.0, <= 2.0.0) serverengine (~> 1.5.5) thor thread (~> 0.1.7) sprockets (3.0.3) rack (~> 1.0) sprockets-rails (3.2.0) actionpack (>= 4.0) activesupport (>= 4.0) sprockets (>= 3.0.0) sqlite3 (1.3.13) stackprof (0.2.10) sucker_punch (1.6.0) celluloid (~> 0.17.2) thor (0.19.4) thread (0.1.7) thread_safe (0.3.6) tilt (2.0.7) timers (4.1.2) hitimes turbolinks (5.0.1) turbolinks-source (~> 5) turbolinks-source (5.0.3) tzinfo (1.2.3) thread_safe (~> 0.1) uglifier (3.2.0) execjs (>= 0.3.0, < 3) vegas (0.1.11) rack (>= 1.0.0) w3c_validators (1.3.2) json (>= 1.8) nokogiri (~> 1.6) 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) kindlerb (= 0.1.1) mime-types (< 3) minitest (< 5.3.4) mocha (~> 0.14) mustache (~> 0.99.8) mysql (>= 2.9.0) mysql2 (>= 0.4.0) nokogiri (>= 1.7) 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 (>= 1.0.0.rc1, < 1.1) sequel sidekiq sneakers (< 2.0.0) 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.15.1 rails-4.2.10/RAILS_VERSION 0000664 0000000 0000000 00000000007 13162731520 0014707 0 ustar 00root root 0000000 0000000 4.2.10 rails-4.2.10/README.md 0000664 0000000 0000000 00000010152 13162731520 0014166 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.10/RELEASING_RAILS.rdoc 0000664 0000000 0000000 00000016031 13162731520 0016025 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.10/Rakefile 0000664 0000000 0000000 00000003704 13162731520 0014361 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.10/actionmailer/ 0000775 0000000 0000000 00000000000 13162731520 0015357 5 ustar 00root root 0000000 0000000 rails-4.2.10/actionmailer/CHANGELOG.md 0000664 0000000 0000000 00000006342 13162731520 0017175 0 ustar 00root root 0000000 0000000 ## Rails 4.2.10 (September 27, 2017) ## * No changes. ## Rails 4.2.9 (June 26, 2017) ## * No changes. ## Rails 4.2.8 (February 21, 2017) ## * No changes. ## Rails 4.2.7 (July 12, 2016) ## * Removes `-t` from default Sendmail arguments to match the underlying `Mail::Sendmail` setting. *Clayton Liggitt* ## 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.10/actionmailer/MIT-LICENSE 0000664 0000000 0000000 00000002062 13162731520 0017013 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.10/actionmailer/README.rdoc 0000664 0000000 0000000 00000013050 13162731520 0017164 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.10/actionmailer/Rakefile 0000664 0000000 0000000 00000001334 13162731520 0017025 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.10/actionmailer/actionmailer.gemspec 0000664 0000000 0000000 00000002014 13162731520 0021370 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.10/actionmailer/lib/ 0000775 0000000 0000000 00000000000 13162731520 0016125 5 ustar 00root root 0000000 0000000 rails-4.2.10/actionmailer/lib/action_mailer.rb 0000664 0000000 0000000 00000003752 13162731520 0021267 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.10/actionmailer/lib/action_mailer/ 0000775 0000000 0000000 00000000000 13162731520 0020733 5 ustar 00root root 0000000 0000000 rails-4.2.10/actionmailer/lib/action_mailer/base.rb 0000664 0000000 0000000 00000113670 13162731520 0022202 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 Watcherfoo
bar
foo
bar
}, 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.10/actionmailer/test/base_test.rb 0000664 0000000 0000000 00000100436 13162731520 0020640 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.10/actionmailer/test/delivery_methods_test.rb 0000664 0000000 0000000 00000017023 13162731520 0023273 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'
}
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.10/actionmailer/test/fixtures/ 0000775 0000000 0000000 00000000000 13162731520 0020207 5 ustar 00root root 0000000 0000000 rails-4.2.10/actionmailer/test/fixtures/anonymous/ 0000775 0000000 0000000 00000000000 13162731520 0022237 5 ustar 00root root 0000000 0000000 rails-4.2.10/actionmailer/test/fixtures/anonymous/welcome.erb 0000664 0000000 0000000 00000000026 13162731520 0024362 0 ustar 00root root 0000000 0000000 Anonymous mailer body
rails-4.2.10/actionmailer/test/fixtures/another.path/ 0000775 0000000 0000000 00000000000 13162731520 0022602 5 ustar 00root root 0000000 0000000 rails-4.2.10/actionmailer/test/fixtures/another.path/base_mailer/ 0000775 0000000 0000000 00000000000 13162731520 0025045 5 ustar 00root root 0000000 0000000 rails-4.2.10/actionmailer/test/fixtures/another.path/base_mailer/welcome.erb 0000664 0000000 0000000 00000000031 13162731520 0027164 0 ustar 00root root 0000000 0000000 Welcome from another path rails-4.2.10/actionmailer/test/fixtures/asset_host_mailer/ 0000775 0000000 0000000 00000000000 13162731520 0023714 5 ustar 00root root 0000000 0000000 rails-4.2.10/actionmailer/test/fixtures/asset_host_mailer/email_with_asset.html.erb 0000664 0000000 0000000 00000000037 13162731520 0030672 0 ustar 00root root 0000000 0000000 <%= image_tag "somelogo.png" %> rails-4.2.10/actionmailer/test/fixtures/asset_mailer/ 0000775 0000000 0000000 00000000000 13162731520 0022657 5 ustar 00root root 0000000 0000000 rails-4.2.10/actionmailer/test/fixtures/asset_mailer/welcome.html.erb 0000664 0000000 0000000 00000000034 13162731520 0025744 0 ustar 00root root 0000000 0000000 <%= image_tag "dummy.png" %> rails-4.2.10/actionmailer/test/fixtures/async_mailer/ 0000775 0000000 0000000 00000000000 13162731520 0022655 5 ustar 00root root 0000000 0000000 rails-4.2.10/actionmailer/test/fixtures/async_mailer/welcome.erb 0000664 0000000 0000000 00000000007 13162731520 0024777 0 ustar 00root root 0000000 0000000 Welcome rails-4.2.10/actionmailer/test/fixtures/attachments/ 0000775 0000000 0000000 00000000000 13162731520 0022522 5 ustar 00root root 0000000 0000000 rails-4.2.10/actionmailer/test/fixtures/attachments/foo.jpg 0000664 0000000 0000000 00000003755 13162731520 0024021 0 ustar 00root root 0000000 0000000 ÿØÿà JFIF d d ÿì Ducky <