├── .github └── workflows │ └── main.yml ├── .gitignore ├── .rubocop.yml ├── .solargraph.yml ├── .standard.yml ├── Changelog.md ├── Gemfile ├── LICENSE.txt ├── README.md ├── Rakefile ├── Upgrading.md ├── codecov.yml ├── flake.lock ├── flake.nix ├── lib ├── roadie-rails.rb └── roadie │ ├── rails.rb │ └── rails │ ├── asset_pipeline_provider.rb │ ├── asset_propshaft_provider.rb │ ├── automatic.rb │ ├── document_builder.rb │ ├── inline_on_delivery.rb │ ├── mail_inliner.rb │ ├── mailer.rb │ ├── options.rb │ ├── railtie.rb │ ├── utils.rb │ └── version.rb ├── roadie-rails.gemspec ├── setup.sh └── spec ├── integration_spec.rb ├── lib └── roadie │ └── rails │ ├── asset_pipeline_provider_spec.rb │ ├── automatic_spec.rb │ ├── document_builder_spec.rb │ ├── inline_on_delivery_spec.rb │ ├── mail_inliner_spec.rb │ ├── mailer_spec.rb │ ├── options_spec.rb │ └── railtie_spec.rb ├── railsapps ├── README.md ├── rails_51 │ ├── .gitignore │ ├── Gemfile │ ├── app │ │ ├── assets │ │ │ ├── config │ │ │ │ └── manifest.js │ │ │ ├── images │ │ │ │ └── rails.png │ │ │ └── stylesheets │ │ │ │ └── email.css.scss │ │ ├── mailers │ │ │ ├── auto_mailer.rb │ │ │ └── mailer.rb │ │ └── views │ │ │ ├── auto_mailer │ │ │ ├── normal_email.html.erb │ │ │ └── normal_email.text │ │ │ └── mailer │ │ │ ├── normal_email.html.erb │ │ │ └── normal_email.text │ ├── bin │ │ └── rails │ ├── config.ru │ ├── config │ │ ├── application.rb │ │ ├── boot.rb │ │ ├── environment.rb │ │ ├── environments │ │ │ ├── development.rb │ │ │ ├── production.rb │ │ │ └── test.rb │ │ ├── initializers │ │ │ ├── application_controller_renderer.rb │ │ │ ├── assets.rb │ │ │ ├── backtrace_silencers.rb │ │ │ ├── cookies_serializer.rb │ │ │ ├── filter_parameter_logging.rb │ │ │ ├── inflections.rb │ │ │ ├── mime_types.rb │ │ │ ├── new_framework_defaults.rb │ │ │ ├── session_store.rb │ │ │ └── wrap_parameters.rb │ │ ├── locales │ │ │ └── en.yml │ │ └── routes.rb │ └── log │ │ └── .keep ├── rails_52 │ ├── .gitignore │ ├── Gemfile │ ├── app │ │ ├── assets │ │ │ ├── config │ │ │ │ └── manifest.js │ │ │ ├── images │ │ │ │ └── rails.png │ │ │ └── stylesheets │ │ │ │ └── email.css.scss │ │ ├── mailers │ │ │ ├── auto_mailer.rb │ │ │ └── mailer.rb │ │ └── views │ │ │ ├── auto_mailer │ │ │ ├── normal_email.html.erb │ │ │ └── normal_email.text │ │ │ └── mailer │ │ │ ├── normal_email.html.erb │ │ │ └── normal_email.text │ ├── bin │ │ └── rails │ ├── config.ru │ ├── config │ │ ├── application.rb │ │ ├── boot.rb │ │ ├── environment.rb │ │ ├── environments │ │ │ ├── development.rb │ │ │ ├── production.rb │ │ │ └── test.rb │ │ ├── initializers │ │ │ ├── application_controller_renderer.rb │ │ │ ├── assets.rb │ │ │ ├── backtrace_silencers.rb │ │ │ ├── cookies_serializer.rb │ │ │ ├── filter_parameter_logging.rb │ │ │ ├── inflections.rb │ │ │ ├── mime_types.rb │ │ │ ├── new_framework_defaults.rb │ │ │ ├── session_store.rb │ │ │ └── wrap_parameters.rb │ │ ├── locales │ │ │ └── en.yml │ │ └── routes.rb │ └── log │ │ └── .keep ├── rails_60 │ ├── .gitignore │ ├── Gemfile │ ├── Rakefile │ ├── app │ │ ├── assets │ │ ├── mailers │ │ └── views │ ├── bin │ │ └── rails │ ├── config.ru │ └── config │ │ ├── application.rb │ │ ├── boot.rb │ │ ├── environment.rb │ │ ├── environments │ │ └── development.rb │ │ ├── initializers │ │ ├── assets.rb │ │ ├── cookies_serializer.rb │ │ ├── filter_parameter_logging.rb │ │ └── wrap_parameters.rb │ │ └── routes.rb ├── rails_61 │ ├── .gitignore │ ├── Gemfile │ ├── Rakefile │ ├── app │ │ ├── assets │ │ ├── mailers │ │ └── views │ ├── bin │ │ └── rails │ ├── config.ru │ └── config │ │ ├── application.rb │ │ ├── boot.rb │ │ ├── environment.rb │ │ ├── environments │ │ └── development.rb │ │ ├── initializers │ │ ├── assets.rb │ │ ├── cookies_serializer.rb │ │ ├── filter_parameter_logging.rb │ │ └── wrap_parameters.rb │ │ └── routes.rb ├── rails_70 │ ├── Gemfile │ ├── Rakefile │ ├── app │ │ ├── assets │ │ ├── mailers │ │ └── views │ ├── bin │ │ ├── bundle │ │ ├── rails │ │ ├── rake │ │ └── setup │ ├── config.ru │ └── config │ │ ├── application.rb │ │ ├── boot.rb │ │ ├── environment.rb │ │ ├── environments │ │ └── development.rb │ │ ├── initializers │ │ ├── assets.rb │ │ ├── backtrace_silencers.rb │ │ ├── content_security_policy.rb │ │ ├── filter_parameter_logging.rb │ │ ├── inflections.rb │ │ ├── mime_types.rb │ │ ├── permissions_policy.rb │ │ └── wrap_parameters.rb │ │ └── routes.rb ├── rails_71 │ ├── Gemfile │ ├── Rakefile │ ├── app │ │ ├── assets │ │ │ ├── config │ │ │ │ └── manifest.js │ │ │ ├── images │ │ │ │ └── rails.png │ │ │ └── stylesheets │ │ │ │ └── email.css.scss │ │ ├── mailers │ │ │ ├── auto_mailer.rb │ │ │ └── mailer.rb │ │ └── views │ │ │ ├── auto_mailer │ │ │ ├── normal_email.html.erb │ │ │ └── normal_email.text │ │ │ └── mailer │ │ │ ├── normal_email.html.erb │ │ │ └── normal_email.text │ ├── bin │ │ ├── bundle │ │ ├── rails │ │ ├── rake │ │ └── setup │ ├── config.ru │ └── config │ │ ├── application.rb │ │ ├── boot.rb │ │ ├── environment.rb │ │ ├── environments │ │ └── development.rb │ │ ├── initializers │ │ ├── assets.rb │ │ ├── backtrace_silencers.rb │ │ ├── content_security_policy.rb │ │ ├── filter_parameter_logging.rb │ │ ├── inflections.rb │ │ ├── mime_types.rb │ │ ├── permissions_policy.rb │ │ └── wrap_parameters.rb │ │ └── routes.rb ├── rails_71_with_propshaft │ ├── Gemfile │ ├── Rakefile │ ├── app │ │ ├── assets │ │ │ ├── builds │ │ │ │ └── .gitkeep │ │ │ ├── images │ │ │ │ └── rails.png │ │ │ └── stylesheets │ │ │ │ └── email.css │ │ ├── mailers │ │ │ ├── auto_mailer.rb │ │ │ └── mailer.rb │ │ └── views │ │ │ ├── auto_mailer │ │ │ ├── normal_email.html.erb │ │ │ └── normal_email.text │ │ │ └── mailer │ │ │ ├── normal_email.html.erb │ │ │ └── normal_email.text │ ├── bin │ │ ├── bundle │ │ ├── rails │ │ ├── rake │ │ └── setup │ ├── config.ru │ └── config │ │ ├── application.rb │ │ ├── boot.rb │ │ ├── environment.rb │ │ ├── environments │ │ └── development.rb │ │ ├── initializers │ │ ├── backtrace_silencers.rb │ │ ├── content_security_policy.rb │ │ ├── filter_parameter_logging.rb │ │ ├── inflections.rb │ │ ├── mime_types.rb │ │ ├── permissions_policy.rb │ │ └── wrap_parameters.rb │ │ └── routes.rb ├── rails_80_with_propshaft │ ├── Gemfile │ ├── Rakefile │ ├── app │ │ ├── assets │ │ │ ├── builds │ │ │ │ └── .gitkeep │ │ │ ├── images │ │ │ │ └── rails.png │ │ │ └── stylesheets │ │ │ │ └── email.css │ │ ├── mailers │ │ │ ├── auto_mailer.rb │ │ │ └── mailer.rb │ │ └── views │ │ │ ├── auto_mailer │ │ │ ├── normal_email.html.erb │ │ │ └── normal_email.text │ │ │ └── mailer │ │ │ ├── normal_email.html.erb │ │ │ └── normal_email.text │ ├── bin │ │ ├── bundle │ │ ├── rails │ │ ├── rake │ │ └── setup │ ├── config.ru │ └── config │ │ ├── application.rb │ │ ├── boot.rb │ │ ├── environment.rb │ │ ├── environments │ │ └── development.rb │ │ ├── initializers │ │ ├── backtrace_silencers.rb │ │ ├── content_security_policy.rb │ │ ├── filter_parameter_logging.rb │ │ ├── inflections.rb │ │ ├── mime_types.rb │ │ ├── permissions_policy.rb │ │ └── wrap_parameters.rb │ │ └── routes.rb └── shared │ ├── all │ └── app │ │ ├── mailers │ │ ├── auto_mailer.rb │ │ └── mailer.rb │ │ └── views │ │ ├── auto_mailer │ │ └── mailer │ │ ├── normal_email.html.erb │ │ └── normal_email.text │ └── pipeline │ └── app │ └── assets │ ├── config │ └── manifest.js │ ├── images │ └── rails.png │ └── stylesheets │ └── email.css.scss ├── spec_helper.rb └── support ├── fake_mail.rb ├── fake_pipeline.rb ├── have_no_styling_matcher.rb ├── have_selector_matcher.rb ├── have_styling_matcher.rb └── rails_app.rb /.github/workflows/main.yml: -------------------------------------------------------------------------------- 1 | name: Main 2 | on: 3 | schedule: 4 | # Run on the first day of every month 5 | # https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#schedule 6 | - cron: '0 0 1 * *' 7 | # Allow running manually 8 | # For more details: https://docs.github.com/en/actions/using-workflows/manually-running-a-workflow?tool=webui 9 | workflow_dispatch: 10 | push: 11 | branches: 12 | - main 13 | - master 14 | paths-ignore: 15 | - '**.md' 16 | - '**.txt' 17 | 18 | pull_request: 19 | types: [opened, synchronize, reopened] 20 | 21 | jobs: 22 | base: 23 | name: Ruby ${{ matrix.ruby }} 24 | runs-on: ubuntu-latest 25 | strategy: 26 | fail-fast: false 27 | matrix: 28 | ruby: 29 | - "2.7" 30 | - "3.0" 31 | - "3.1" 32 | - "3.2" 33 | - "3.3" 34 | - "3.4" 35 | 36 | steps: 37 | - name: Checkout code 38 | uses: actions/checkout@v4 39 | 40 | # This setup is not compatible with the way Travis CI was 41 | # setup, so the cache will only work for the root folder. 42 | - name: Setup Ruby 43 | uses: ruby/setup-ruby@v1 44 | with: 45 | ruby-version: ${{ matrix.ruby }} 46 | bundler-cache: true 47 | 48 | - name: Rake 49 | run: bundle exec rake 50 | 51 | - uses: codecov/codecov-action@v4 52 | 53 | lint: 54 | runs-on: ubuntu-latest 55 | steps: 56 | - name: Checkout code 57 | uses: actions/checkout@v4 58 | 59 | # This setup is not compatible with the way Travis CI was 60 | # setup, so the cache will only work for the root folder. 61 | - name: Setup Ruby 62 | uses: ruby/setup-ruby@v1 63 | with: 64 | ruby-version: "3.4" 65 | bundler-cache: true 66 | 67 | - name: standardrb 68 | run: bundle exec standardrb 69 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.gem 2 | *.rbc 3 | .bundle 4 | .config 5 | .yardoc 6 | .ruby-version 7 | Gemfile.lock 8 | InstalledFiles 9 | _yardoc 10 | coverage 11 | doc/ 12 | lib/bundler/man 13 | pkg 14 | rdoc 15 | spec/reports 16 | test/tmp 17 | test/version_tmp 18 | tmp 19 | **/*.log 20 | -------------------------------------------------------------------------------- /.rubocop.yml: -------------------------------------------------------------------------------- 1 | AllCops: 2 | TargetRubyVersion: 2.5 3 | Exclude: 4 | - spec/railsapps/**/* 5 | 6 | Naming/FileName: 7 | Exclude: 8 | # This is named intentionally this way (the gem name), in case someone 9 | # includes it instead of "roadie/rails". 10 | - lib/roadie-rails.rb 11 | 12 | Style/StringLiterals: 13 | EnforcedStyle: double_quotes 14 | 15 | Style/TrailingCommaInHashLiteral: 16 | EnforcedStyleForMultiline: comma 17 | 18 | Style/TrailingCommaInArguments: 19 | EnforcedStyleForMultiline: comma 20 | 21 | Style/TrailingCommaInArrayLiteral: 22 | EnforcedStyleForMultiline: consistent_comma 23 | 24 | Layout/SpaceInsideHashLiteralBraces: 25 | EnforcedStyle: no_space 26 | 27 | Style/Documentation: 28 | Enabled: false 29 | 30 | Layout/FirstArrayElementIndentation: 31 | EnforcedStyle: consistent 32 | 33 | Layout/MultilineMethodCallIndentation: 34 | EnforcedStyle: indented 35 | 36 | Layout/EmptyLinesAroundAccessModifier: 37 | Enabled: false 38 | 39 | Style/GuardClause: 40 | Enabled: false 41 | 42 | Style/IfUnlessModifier: 43 | Enabled: false 44 | 45 | Style/SignalException: 46 | Enabled: false 47 | 48 | Style/BlockDelimiters: 49 | Enabled: true 50 | EnforcedStyle: braces_for_chaining 51 | Exclude: 52 | - 'spec/**/*' 53 | 54 | Metrics/BlockLength: 55 | ExcludedMethods: 56 | - refine 57 | - describe 58 | - context 59 | - shared_examples 60 | Exclude: 61 | - 'Rakefile' 62 | - '**/*.rake' 63 | - 'spec/*_spec.rb' 64 | - 'spec/**/*_spec.rb' 65 | - 'spec/shared_examples/*.rb' 66 | 67 | Layout/LineLength: 68 | IgnoredPatterns: 69 | - '^\s*it\s' # Test names can be long 70 | Exclude: 71 | - roadie-rails.gemspec 72 | -------------------------------------------------------------------------------- /.solargraph.yml: -------------------------------------------------------------------------------- 1 | --- 2 | include: 3 | - "**/*.rb" 4 | exclude: 5 | - spec/**/* 6 | - test/**/* 7 | - vendor/**/* 8 | - ".bundle/**/*" 9 | require: [] 10 | domains: [] 11 | plugins: 12 | - solargraph-standardrb 13 | reporters: 14 | - standardrb 15 | require_paths: [] 16 | max_files: 5000 17 | -------------------------------------------------------------------------------- /.standard.yml: -------------------------------------------------------------------------------- 1 | ruby_version: 2.6 2 | parallel: true 3 | -------------------------------------------------------------------------------- /Changelog.md: -------------------------------------------------------------------------------- 1 | ### development version 2 | 3 | [full changelog](https://github.com/Mange/roadie-rails/compare/v3.3.0...master) 4 | 5 | ### 3.3.0 6 | 7 | [full changelog](https://github.com/Mange/roadie-rails/compare/v3.2.0...v3.3.0) 8 | 9 | - Add support for Rails 8.0 - [Andrea Fomera](https://github.com/afomera) 10 | 11 | ### 3.2.0 12 | 13 | [full changelog](https://github.com/Mange/roadie-rails/compare/v3.1.0...v3.2.0) 14 | 15 | - Support [Propshaft](https://github.com/rails/propshaft) - [Juani Villarejo](https://github.com/jvillarejo) [#114](https://github.com/Mange/roadie-rails/pull/114) 16 | - Add support (CI) for Ruby 3.3. 17 | - Last version for supporting Ruby 2.6 (EoL). 18 | 19 | ### 3.1.0 20 | 21 | [full changelog](https://github.com/Mange/roadie-rails/compare/v3.0.0...v3.1.0) 22 | 23 | - Support Rails 7.1 - [Frederik Spang](https://github.com/frederikspang) 24 | - Add support for Ruby 3.2. 25 | 26 | Development changes: 27 | 28 | - Fix Github CI lint job with standardrb. 29 | 30 | ### 3.0.0 31 | 32 | [full changelog](https://github.com/Mange/roadie-rails/compare/v2.3.0...v3.0.0) 33 | 34 | - Drop support for Ruby versions < 2.6. 35 | - Add support for Ruby 3.0 and 3.1. 36 | 37 | Development changes: 38 | 39 | - Replace Travis CI with Github CI. 40 | 41 | ### 2.3.0 42 | 43 | [full changelog](https://github.com/Mange/roadie-rails/compare/v2.2.0...v2.3.0) 44 | 45 | - Support Rails 7.0 - [Sean Floyd (SeanLF)](https://github.com/SeanLF) 46 | - Drop support for Ruby 2.5 (EoL). 47 | 48 | ### 2.2.0 49 | 50 | [full changelog](https://github.com/Mange/roadie-rails/compare/v2.1.1...v2.2.0) 51 | 52 | - Support Rails 6.1 - [A. Fomera (afomera)](https://github.com/afomera) 53 | 54 | ### 2.1.1 55 | 56 | [full changelog](https://github.com/Mange/roadie-rails/compare/v2.1.0...v2.1.1) 57 | 58 | - Relax Roadie dependency to allow v4.x 59 | 60 | Development changes: 61 | 62 | - Updated embedded Rails apps (used in tests) to work with new Sprockets 4. 63 | - Updated Rubocop config to work with newer Rubocop versions. 64 | 65 | ### 2.1.0 66 | 67 | [full changelog](https://github.com/Mange/roadie-rails/compare/v2.0.0...v2.1.0) 68 | 69 | - Rails 6 support (#88) - [Gleb Mazovetskiy (glebm)](https://github.com/glebm) 70 | 71 | ### 2.0.0 72 | 73 | [full changelog](https://github.com/Mange/roadie-rails/compare/v1.3.0...v2.0.0) 74 | 75 | - Drop support for Ruby before 2.5. 76 | - Drop support for Rails before 5.1. 77 | - Add support for Ruby 2.5. 78 | - Add support for Ruby 2.6. 79 | - Fix arity of `Roadie::Rails::Mailer#roadie_mail` - [Adrian Lehmann (ownadi)](https://github.com/ownadi) 80 | 81 | ### 1.3.0 82 | 83 | [full changelog](https://github.com/Mange/roadie-rails/compare/v1.2.1...v1.3.0) 84 | 85 | - Dropped support for Rubunius and JRuby. 86 | - They do not have many users and are a constant source of problems. If this is a problem for you, let me know and I might reconsider. 87 | - Add support for Rails 5.2. 88 | 89 | ### 1.2.1 90 | 91 | [full changelog](https://github.com/Mange/roadie-rails/compare/v1.2.0...v1.2.1) 92 | 93 | - Don't allow installation in Ruby < 2.2. 94 | - Fix install on Windows machines. 95 | - Less bloat in gem file, making it much smaller. 96 | 97 | ### 1.2.0 98 | 99 | [full changelog](https://github.com/Mange/roadie-rails/compare/v1.1.1...v1.2.0) 100 | 101 | **Note:** Support for Rails < 4.2 is now dropped. 102 | 103 | **Note:** Support for Ruby < 2.2 is now dropped. 104 | 105 | - Sprockets 4.0 support (#60) - [Miklós Fazekas (mfazekas)](https://github.com/mfazekas) 106 | - Rails 5.1 support (#70) - [Gleb Mazovetskiy (glebm)](https://github.com/glebm) 107 | 108 | ### 1.1.1 109 | 110 | [full changelog](https://github.com/Mange/roadie-rails/compare/v1.1.0...v1.1.1) 111 | 112 | - Add support for Rails 5.0 (#50) — [Scott Ringwelski (sgringwe)](https://github.com/sgringwe) 113 | - Also build on Ruby 2.3.0. 114 | 115 | ### 1.1.0 116 | 117 | [full changelog](https://github.com/Mange/roadie-rails/compare/v1.1.0.rc2...v1.1.0) 118 | 119 | - Bug fixes: 120 | - Support for sprockets-rails 3 (#46) — [Rafael Mendonça França (rafaelfranca)](https://github.com/rafaelfranca) 121 | - Support `Mailer#deliver!` in `AutomaticMailer` (#47) — [Julien Vanier (monkbroc)](https://github.com/monkbroc) 122 | 123 | ### 1.1.0.rc2 124 | 125 | [full changelog](https://github.com/Mange/roadie-rails/compare/v1.1.0.rc1...v1.1.0.rc2) 126 | 127 | - Add support for `roadie`'s `external_asset_providers` option. 128 | 129 | ### 1.1.0.rc1 130 | 131 | [full changelog](https://github.com/Mange/roadie-rails/compare/v1.0.6...v1.1.0.rc1) 132 | 133 | - Add support for `roadie`'s `keep_uninlinable_css` option. 134 | 135 | ### 1.0.6 136 | 137 | [full changelog](https://github.com/Mange/roadie-rails/compare/v1.0.5...v1.0.6) 138 | 139 | - Bug fixes: 140 | - Support Sprockets 3's new hash length (#41) 141 | 142 | ### 1.0.5 143 | 144 | [full changelog](https://github.com/Mange/roadie-rails/compare/v1.0.4...v1.0.5) 145 | 146 | - Enhancements: 147 | - Remove dependency on `rails` in favor of `railties` — [Mark J. Titorenko (mjtko)](https://github.com/mjtko) 148 | - Bug fixes: 149 | - Support for Rails 4.2 default configuration — [Tomas Celizna (tomasc)](https://github.com/tomasc) 150 | - It's possible to inline assets with a digest (hash at the end of the filename), which is how Rails 4.2 defaults to, even when assets are not stored on disk. 151 | 152 | ### 1.0.4 153 | 154 | [full changelog](https://github.com/Mange/roadie-rails/compare/v1.0.3...v1.0.4) 155 | 156 | - Enhancements: 157 | - Support for Rails 4.2 — [Ryunosuke SATO (tricknotes)](https://github.com/tricknotes) 158 | 159 | ### 1.0.3 160 | 161 | [full changelog](https://github.com/Mange/roadie-rails/compare/v1.0.2...v1.0.3) 162 | 163 | - Bug fixes 164 | - Don't change `asset_providers` of a `Roadie::Document` when applying Options with no `asset_providers` set. 165 | - Support assets inside subdirectories. 166 | - Don't add `AssetPipelineProvider` when asset pipeline is unavailable (e.g. inside Rails engines). 167 | - Raise error when initializing `AssetPipelineProvider` with `nil` provider. 168 | 169 | ### 1.0.2 170 | 171 | [full changelog](https://github.com/Mange/roadie-rails/compare/v1.0.1...v1.0.2) 172 | 173 | - Bug fixes 174 | - Don't crash on `nil` `roadie_options` 175 | 176 | ### 1.0.1 177 | 178 | [full changelog](https://github.com/Mange/roadie-rails/compare/v1.0.0...v1.0.1) 179 | 180 | - Bug fixes 181 | - Inline HTML in emails without a plaintext part 182 | 183 | ### 1.0.0 184 | 185 | [full changelog](https://github.com/Mange/roadie-rails/compare/v1.0.0.pre1...v1.0.0) 186 | 187 | - Use released version of Roadie 3.0.0 188 | 189 | ### 1.0.0.pre1 190 | 191 | [full changelog](https://github.com/Mange/roadie-rails/compare/0000000...v1.0.0.pre1) 192 | 193 | - First implementation 194 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | source "https://rubygems.org" 4 | 5 | # Specify your gem's dependencies in roadie-rails.gemspec 6 | gemspec 7 | 8 | # Added here so it does not show up on the Gemspec; I only want it for CI builds 9 | gem "simplecov", group: :test, require: false 10 | gem "simplecov-cobertura", group: :test, require: false 11 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2013-2017 Magnus Bergmark, and contributors. 2 | 3 | MIT License 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining 6 | a copy of this software and associated documentation files (the 7 | "Software"), to deal in the Software without restriction, including 8 | without limitation the rights to use, copy, modify, merge, publish, 9 | distribute, sublicense, and/or sell copies of the Software, and to 10 | permit persons to whom the Software is furnished to do so, subject to 11 | the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be 14 | included in all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 20 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 21 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 22 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require "bundler/gem_tasks" 4 | 5 | desc "Install gems for embedded Rails apps" 6 | task :install_gems do 7 | Bundler.with_unbundled_env do 8 | sh "./setup.sh install" 9 | end 10 | end 11 | 12 | desc "Update gems for embedded Rails apps" 13 | task :update_gems do 14 | Bundler.with_unbundled_env do 15 | sh "./setup.sh update" 16 | end 17 | end 18 | 19 | desc "Run specs" 20 | task :spec do 21 | sh "bundle exec rspec -f progress" 22 | end 23 | 24 | desc "Default: Update gems and run specs" 25 | task default: %i[update_gems spec] 26 | -------------------------------------------------------------------------------- /Upgrading.md: -------------------------------------------------------------------------------- 1 | # Upgrading from Roadie 2 2 | 3 | ## Project 4 | 5 | Start by adding `roadie-rails` to your `Gemfile`. Remember to specify version requirements! 6 | 7 | You'll need to change your configuration too. The main change is that Roadie now uses its own configuration for URL options: 8 | 9 | ```ruby 10 | config.roadie.url_options = {host: "myapp.com"} 11 | ``` 12 | 13 | Most other options should be easy to convert: 14 | 15 | ```ruby 16 | config.roadie.enabled => Removed 17 | # Override `#roadie_options` in the mailers to control enabling (if using Automatic) or do it manually (if using Mailer). 18 | 19 | config.roadie.before_inlining => config.roadie.before_transformation 20 | config.roadie.provider => config.roadie.asset_providers 21 | ``` 22 | 23 | ## Mailers 24 | 25 | Next, find all mailers that you want to inline and include the `Roadie::Rails::Automatic` module: 26 | 27 | ```ruby 28 | class MyMailer < ActionMailer::Base 29 | include Roadie::Rails::Automatic 30 | 31 | def cool_mail 32 | mail(options) 33 | end 34 | end 35 | ``` 36 | 37 | You'll also need to remove any uses of the `:css` option to `mail` and `default_options`. Include CSS files by using `stylesheet_link_tag` instead. 38 | 39 | **Before:** 40 | 41 | ```ruby 42 | class MyMailer < ActionMailer::Base 43 | defaults css: :email 44 | 45 | def cool 46 | mail(css: [:email, :cool]) 47 | end 48 | end 49 | ``` 50 | 51 | 52 | **After:** 53 | 54 | ```erb 55 | 56 | <%= stylesheet_link_tag :email, :cool %> 57 | 58 | ``` 59 | 60 | ## Views 61 | 62 | Search through your templates after uses of `data-immutable` and change them to `data-roadie-ignore`. 63 | 64 | ## Tests 65 | 66 | If your tests relied on the styles being applied, they will fail unless you deliver the email. `Roadie::Rails::Automatic` does not inline stylesheets when you don't deliver the email. Either change how your tests work, or call `deliver` on the generated emails where you need it. If the problem is major, switch from `Roadie::Rails::Automatic` to `Roadie::Rails::Mailer` and follow the instructions in the documentation. 67 | 68 | ## Custom asset providers 69 | 70 | The API has changed a bit. Read the new examples in the README and you should be able to convert without any great effort. 71 | -------------------------------------------------------------------------------- /codecov.yml: -------------------------------------------------------------------------------- 1 | ignore: 2 | - ".bundle/**/*" 3 | - "./spec/railsapps/*/.bundle/**/*" 4 | -------------------------------------------------------------------------------- /flake.lock: -------------------------------------------------------------------------------- 1 | { 2 | "nodes": { 3 | "flake-utils": { 4 | "inputs": { 5 | "systems": "systems" 6 | }, 7 | "locked": { 8 | "lastModified": 1726560853, 9 | "narHash": "sha256-X6rJYSESBVr3hBoH0WbKE5KvhPU5bloyZ2L4K60/fPQ=", 10 | "owner": "numtide", 11 | "repo": "flake-utils", 12 | "rev": "c1dfcf08411b08f6b8615f7d8971a2bfa81d5e8a", 13 | "type": "github" 14 | }, 15 | "original": { 16 | "owner": "numtide", 17 | "repo": "flake-utils", 18 | "type": "github" 19 | } 20 | }, 21 | "nixpkgs": { 22 | "locked": { 23 | "lastModified": 1730963269, 24 | "narHash": "sha256-rz30HrFYCHiWEBCKHMffHbMdWJ35hEkcRVU0h7ms3x0=", 25 | "owner": "NixOS", 26 | "repo": "nixpkgs", 27 | "rev": "83fb6c028368e465cd19bb127b86f971a5e41ebc", 28 | "type": "github" 29 | }, 30 | "original": { 31 | "owner": "NixOS", 32 | "ref": "nixos-24.05", 33 | "repo": "nixpkgs", 34 | "type": "github" 35 | } 36 | }, 37 | "root": { 38 | "inputs": { 39 | "flake-utils": "flake-utils", 40 | "nixpkgs": "nixpkgs" 41 | } 42 | }, 43 | "systems": { 44 | "locked": { 45 | "lastModified": 1681028828, 46 | "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", 47 | "owner": "nix-systems", 48 | "repo": "default", 49 | "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", 50 | "type": "github" 51 | }, 52 | "original": { 53 | "owner": "nix-systems", 54 | "repo": "default", 55 | "type": "github" 56 | } 57 | } 58 | }, 59 | "root": "root", 60 | "version": 7 61 | } 62 | -------------------------------------------------------------------------------- /flake.nix: -------------------------------------------------------------------------------- 1 | { 2 | inputs = { 3 | nixpkgs.url = "github:NixOS/nixpkgs/nixos-24.05"; 4 | flake-utils.url = "github:numtide/flake-utils"; 5 | }; 6 | 7 | outputs = { self, nixpkgs, flake-utils }: 8 | flake-utils.lib.eachDefaultSystem (system: 9 | let 10 | pkgs = nixpkgs.legacyPackages.${system}; 11 | in { 12 | devShell = with pkgs; 13 | mkShell { 14 | buildInputs = [ 15 | ruby_3_2 16 | libyaml 17 | ]; 18 | }; 19 | }); 20 | } 21 | -------------------------------------------------------------------------------- /lib/roadie-rails.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require "roadie/rails" 4 | -------------------------------------------------------------------------------- /lib/roadie/rails.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Roadie 4 | module Rails 5 | end 6 | end 7 | 8 | require "roadie" 9 | 10 | require "roadie/rails/version" 11 | require "roadie/rails/utils" 12 | require "roadie/rails/options" 13 | 14 | require "roadie/rails/document_builder" 15 | require "roadie/rails/mail_inliner" 16 | 17 | require "roadie/rails/asset_pipeline_provider" 18 | require "roadie/rails/asset_propshaft_provider" 19 | 20 | require "roadie/rails/mailer" 21 | 22 | require "roadie/rails/automatic" 23 | require "roadie/rails/inline_on_delivery" 24 | 25 | require "roadie/rails/railtie" 26 | -------------------------------------------------------------------------------- /lib/roadie/rails/asset_pipeline_provider.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Roadie 4 | module Rails 5 | class AssetPipelineProvider 6 | include Roadie::AssetProvider 7 | attr_reader :pipeline 8 | 9 | def initialize(pipeline) 10 | unless pipeline 11 | raise( 12 | ArgumentError, 13 | "You need to pass a pipeline to initialize AssetPipelineProvider" 14 | ) 15 | end 16 | 17 | super() 18 | @pipeline = pipeline 19 | end 20 | 21 | def find_stylesheet(name) 22 | if (asset = find_asset_in_pipeline(name)) 23 | Stylesheet.new("#{filename(asset)} (live compiled)", asset.to_s) 24 | end 25 | end 26 | 27 | private 28 | 29 | def filename(asset) 30 | if asset.respond_to?(:filename) # sprockets 4 or later 31 | asset.filename 32 | else 33 | asset.pathname 34 | end 35 | end 36 | 37 | def find_asset_in_pipeline(name) 38 | normalized_name = normalize_asset_name(name) 39 | @pipeline[normalized_name] || 40 | @pipeline[remove_asset_digest(normalized_name)] 41 | end 42 | 43 | def normalize_asset_name(href) 44 | remove_asset_prefix(href.split("?").first) 45 | end 46 | 47 | DIGEST_PATTERN = / 48 | - # Digest comes after a dash 49 | (?: 50 | [a-z0-9]{32} | # Old style is 32 character hash 51 | [a-z0-9]{64} # New style is 64 characters 52 | ) 53 | \. # Dot for the file extension 54 | /x 55 | private_constant :DIGEST_PATTERN 56 | 57 | def remove_asset_digest(path) 58 | path.gsub(DIGEST_PATTERN, ".") 59 | end 60 | 61 | def remove_asset_prefix(path) 62 | path.sub(Regexp.new("^#{Regexp.quote(asset_prefix)}/?"), "") 63 | end 64 | 65 | def asset_prefix 66 | ::Rails.application.try(:config).try(:assets).try(:prefix) || "/assets" 67 | end 68 | end 69 | end 70 | end 71 | -------------------------------------------------------------------------------- /lib/roadie/rails/asset_propshaft_provider.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Roadie 4 | module Rails 5 | class AssetPropshaftProvider 6 | include Roadie::AssetProvider 7 | 8 | def initialize(assembly) 9 | @assembly = assembly 10 | @stylesheets = {} 11 | end 12 | 13 | def find_stylesheet(stylesheet_asset_path) 14 | stylesheet = @stylesheets[stylesheet_asset_path] 15 | return stylesheet if stylesheet.present? 16 | 17 | path, digest = extract_path_and_digest(stylesheet_asset_path) 18 | 19 | asset = @assembly.load_path.find(path) 20 | if asset.present? && asset.fresh?(digest) 21 | compiled_content = @assembly.compilers.compile(asset) 22 | 23 | stylesheet = Stylesheet.new(stylesheet_asset_path, compiled_content.force_encoding("UTF-8")) 24 | @stylesheets[stylesheet_asset_path] = stylesheet 25 | end 26 | 27 | stylesheet 28 | end 29 | 30 | private 31 | 32 | def extract_path_and_digest(stylesheet_asset_path) 33 | full_path = stylesheet_asset_path.sub(%r{#{::Rails.configuration.assets.prefix}/}, "") 34 | digest = full_path[/-([0-9a-zA-Z]{7,128})\.(?!digested)[^.]+\z/, 1] 35 | path = digest ? full_path.sub("-#{digest}", "") : full_path 36 | 37 | [path, digest] 38 | end 39 | end 40 | end 41 | end 42 | -------------------------------------------------------------------------------- /lib/roadie/rails/automatic.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Roadie 4 | module Rails 5 | module Automatic 6 | def mail(*args, &block) 7 | super.tap do |email| 8 | email.extend InlineOnDelivery 9 | email.roadie_options = roadie_options.try(:dup) 10 | end 11 | end 12 | 13 | def roadie_options 14 | ::Rails.application.config.roadie 15 | end 16 | end 17 | end 18 | end 19 | -------------------------------------------------------------------------------- /lib/roadie/rails/document_builder.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Roadie 4 | module Rails 5 | class DocumentBuilder 6 | def self.build(html, options) 7 | document = Document.new(html) 8 | options.apply_to document 9 | document 10 | end 11 | end 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /lib/roadie/rails/inline_on_delivery.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Roadie 4 | module Rails 5 | # Extend instances of Mail with this to have it inlined automatically when 6 | # delivered. You'll need to assign some #roadie_options for it to actually 7 | # do anything. 8 | module InlineOnDelivery 9 | attr_accessor :roadie_options 10 | 11 | def deliver 12 | inline_styles 13 | super 14 | end 15 | 16 | def deliver! 17 | inline_styles 18 | super 19 | end 20 | 21 | private 22 | 23 | def inline_styles 24 | if (options = roadie_options) 25 | MailInliner.new(self, options).execute 26 | end 27 | end 28 | end 29 | end 30 | end 31 | -------------------------------------------------------------------------------- /lib/roadie/rails/mail_inliner.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Roadie 4 | module Rails 5 | class MailInliner 6 | attr_reader :email, :options 7 | 8 | def initialize(email, options) 9 | @email = email 10 | @options = options 11 | end 12 | 13 | def execute 14 | if options 15 | improve_body if %r{^text/html}.match?(email.content_type) 16 | improve_html_part(email.html_part) if email.html_part 17 | end 18 | email 19 | end 20 | 21 | private 22 | 23 | def improve_body 24 | email.body = transform_html(email.body.decoded) 25 | end 26 | 27 | def improve_html_part(html_part) 28 | html_part.body = transform_html(html_part.body.decoded) 29 | end 30 | 31 | def transform_html(old_html) 32 | DocumentBuilder.build(old_html, options).transform 33 | end 34 | end 35 | end 36 | end 37 | -------------------------------------------------------------------------------- /lib/roadie/rails/mailer.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Roadie 4 | module Rails 5 | module Mailer 6 | # Generate an email and run Roadie on it. Will use #roadie_options to get 7 | # default options if not passed in. 8 | def roadie_mail( 9 | options = {}, 10 | final_roadie_options = roadie_options, 11 | &block 12 | ) 13 | email = mail(options, &block) 14 | MailInliner.new(email, final_roadie_options).execute 15 | end 16 | 17 | def roadie_options 18 | ::Rails.application.config.roadie 19 | end 20 | end 21 | end 22 | end 23 | -------------------------------------------------------------------------------- /lib/roadie/rails/options.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Roadie 4 | module Rails 5 | class Options 6 | ATTRIBUTE_NAMES = %i[ 7 | after_transformation 8 | asset_providers 9 | before_transformation 10 | external_asset_providers 11 | keep_uninlinable_css 12 | url_options 13 | ].freeze 14 | private_constant :ATTRIBUTE_NAMES 15 | 16 | attr_reader(*ATTRIBUTE_NAMES) 17 | attr_writer( 18 | :url_options, 19 | :before_transformation, 20 | :after_transformation, 21 | :keep_uninlinable_css 22 | ) 23 | 24 | def initialize(options = {}) 25 | complain_about_unknown_keys options.keys 26 | options.each_pair do |name, value| 27 | self[name] = value 28 | end 29 | end 30 | 31 | def asset_providers=(providers) 32 | # TODO: Raise an error when setting to nil in order to make this not a 33 | # silent error. 34 | if providers 35 | @asset_providers = ProviderList.wrap providers 36 | end 37 | end 38 | 39 | def external_asset_providers=(providers) 40 | # TODO: Raise an error when setting to nil in order to make this not a 41 | # silent error. 42 | if providers 43 | @external_asset_providers = ProviderList.wrap providers 44 | end 45 | end 46 | 47 | def apply_to(document) 48 | document.url_options = url_options 49 | document.before_transformation = before_transformation 50 | document.after_transformation = after_transformation 51 | 52 | document.asset_providers = asset_providers if asset_providers 53 | 54 | if external_asset_providers 55 | document.external_asset_providers = external_asset_providers 56 | end 57 | 58 | unless keep_uninlinable_css.nil? 59 | document.keep_uninlinable_css = keep_uninlinable_css 60 | end 61 | end 62 | 63 | def merge(options) 64 | dup.merge! options 65 | end 66 | 67 | def merge!(options) 68 | ATTRIBUTE_NAMES.each do |attribute| 69 | self[attribute] = options.fetch(attribute, self[attribute]) 70 | end 71 | self 72 | end 73 | 74 | def combine(options) 75 | dup.combine! options 76 | end 77 | 78 | def combine!(options) 79 | %i[after_transformation before_transformation].each do |name| 80 | self[name] = Utils.combine_callable(self[name], options[name]) 81 | end 82 | 83 | %i[asset_providers external_asset_providers].each do |name| 84 | self[name] = Utils.combine_providers(self[name], options[name]) 85 | end 86 | 87 | if options.key?(:keep_uninlinable_css) 88 | self.keep_uninlinable_css = options[:keep_uninlinable_css] 89 | end 90 | 91 | self.url_options = Utils.combine_hash( 92 | url_options, 93 | options[:url_options] 94 | ) 95 | 96 | self 97 | end 98 | 99 | def [](option) 100 | if ATTRIBUTE_NAMES.include?(option) 101 | public_send(option) 102 | else 103 | raise ArgumentError, "#{option.inspect} is not a valid option" 104 | end 105 | end 106 | 107 | def []=(option, value) 108 | if ATTRIBUTE_NAMES.include?(option) 109 | public_send(:"#{option}=", value) 110 | else 111 | raise ArgumentError, "#{option.inspect} is not a valid option" 112 | end 113 | end 114 | 115 | private 116 | 117 | def complain_about_unknown_keys(keys) 118 | invalid_keys = keys - ATTRIBUTE_NAMES 119 | unless invalid_keys.empty? 120 | raise( 121 | ArgumentError, 122 | "Unknown configuration parameters: #{invalid_keys}", 123 | caller(1) 124 | ) 125 | end 126 | end 127 | end 128 | end 129 | end 130 | -------------------------------------------------------------------------------- /lib/roadie/rails/railtie.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require "rails" 4 | 5 | module Roadie 6 | module Rails 7 | class Railtie < ::Rails::Railtie 8 | config.roadie = Roadie::Rails::Options.new 9 | 10 | initializer "roadie-rails.setup" do |app| 11 | config.roadie.asset_providers = [ 12 | Roadie::FilesystemProvider.new(::Rails.root.join("public").to_s) 13 | ] 14 | 15 | if app.config.respond_to?(:assets) && app.config.assets 16 | if app.assets 17 | config.roadie.asset_providers << AssetPipelineProvider.new(app.assets) 18 | elsif defined?(Propshaft) 19 | config.after_initialize do |app| 20 | config.roadie.asset_providers << AssetPropshaftProvider.new(app.assets) 21 | end 22 | else 23 | app.config.assets.configure do |env| 24 | config.roadie.asset_providers << 25 | AssetPipelineProvider.new(env) 26 | end 27 | end 28 | end 29 | end 30 | end 31 | end 32 | end 33 | -------------------------------------------------------------------------------- /lib/roadie/rails/utils.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Roadie 4 | module Rails 5 | module Utils 6 | module_function 7 | 8 | # Combine two hashes, or return the non-nil hash if either is nil. 9 | # Returns nil if both are nil. 10 | def combine_hash(first, second) 11 | combine_nilable(first, second) do |a, b| 12 | a.merge(b) 13 | end 14 | end 15 | 16 | # Return a callable that will call both inputs. If either is nil, then 17 | # just return the other. 18 | # 19 | # The result from the second one will be the result of the combined 20 | # callable. 21 | # 22 | # ```ruby 23 | # combine_callable(-> { 1 }, -> { 2 }).call # => 2 24 | # combine_callable(-> { 1 }, nil).call # => 1 25 | # combine_callable(nil, nil).nil? # => true 26 | # ``` 27 | def combine_callable(first, second) 28 | combine_nilable(first, second) do |a, b| 29 | lambda do |*args| 30 | a.call(*args) 31 | b.call(*args) 32 | end 33 | end 34 | end 35 | 36 | # Combine two Provider ducks into a ProviderList. If either is nil, pick 37 | # the non-nil value instead. 38 | def combine_providers(first, second) 39 | combine_nilable(first, second) do |a, b| 40 | ProviderList.new(a.to_a + Array.wrap(b)) 41 | end 42 | end 43 | 44 | # Discard the nil value. If neither is nil, then yield both and return 45 | # the result from the block. 46 | # 47 | # ```ruby 48 | # combine_nilable(nil, 5) { |a, b| a+b } # => 5 49 | # combine_nilable(7, nil) { |a, b| a+b } # => 7 50 | # combine_nilable(nil, nil) { |a, b| a+b } # => nil 51 | # combine_nilable(7, 5) { |a, b| a+b } # => 12 52 | # ``` 53 | def combine_nilable(first, second) 54 | if first && second 55 | yield first, second 56 | else 57 | first || second 58 | end 59 | end 60 | end 61 | end 62 | end 63 | -------------------------------------------------------------------------------- /lib/roadie/rails/version.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Roadie 4 | module Rails 5 | VERSION = "3.3.0" 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /roadie-rails.gemspec: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | lib = File.expand_path("lib", __dir__) 4 | $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) 5 | require "roadie/rails/version" 6 | 7 | Gem::Specification.new do |spec| 8 | spec.name = "roadie-rails" 9 | spec.version = Roadie::Rails::VERSION 10 | spec.authors = ["Magnus Bergmark"] 11 | spec.email = ["magnus.bergmark@gmail.com"] 12 | spec.homepage = "https://github.com/Mange/roadie-rails" 13 | spec.summary = "Making HTML emails comfortable for the Rails rockstars" 14 | spec.description = "Hooks Roadie into your Rails application to help with email generation." 15 | spec.license = "MIT" 16 | 17 | spec.required_ruby_version = ">= 2.7" 18 | 19 | spec.files = `git ls-files | grep -v ^spec`.split($INPUT_RECORD_SEPARATOR) 20 | spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) } 21 | spec.extra_rdoc_files = %w[README.md Changelog.md LICENSE.txt] 22 | spec.require_paths = ["lib"] 23 | 24 | spec.add_dependency "railties", ">= 5.1", "< 8.1" 25 | spec.add_dependency "roadie", "~> 5.0" 26 | 27 | spec.add_development_dependency "bundler", "~> 2.2" 28 | spec.add_development_dependency "rails", ">= 5.1", "< 8.1" 29 | spec.add_development_dependency "rspec", "~> 3.10" 30 | spec.add_development_dependency "rspec-collection_matchers" 31 | spec.add_development_dependency "rspec-rails" 32 | spec.add_development_dependency "standard" 33 | spec.add_development_dependency "ostruct" 34 | 35 | spec.post_install_message = "This would be the last version that supports ruby 2.7" 36 | end 37 | -------------------------------------------------------------------------------- /setup.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # This cannot be executed from within a Ruby-based environment (like Rake) 4 | # since Bundler will affect the subshell environments. 5 | 6 | set -e 7 | 8 | function header() { 9 | echo -e "\n$(tput setaf 5)$(tput smul)$1:$(tput sgr0)" 10 | } 11 | 12 | function green() { 13 | echo "$(tput setaf 2)$*$(tput sgr0)" 14 | } 15 | 16 | function update() { 17 | bundle config --local path .bundle 18 | bundle update | grep -ve "^Using " 19 | } 20 | 21 | function install() { 22 | bundle install --quiet --path=.bundle && green " OK" 23 | } 24 | 25 | root=$(dirname "$0") 26 | 27 | # Previously needed by Travis CI; might still be needed at Github Actions 28 | # due to nested repos 29 | unset BUNDLE_GEMFILE 30 | 31 | if [[ $1 == "install" ]]; then 32 | header "Installing gem dependencies" 33 | install 34 | 35 | for app_path in "$root"/spec/railsapps/rails_*; do 36 | ( 37 | header "Rails app $(basename "$app_path")" 38 | cd "$app_path" 39 | echo -n "Installing gems for $(basename "$app_path")" 40 | install 41 | ) 42 | done 43 | echo "" 44 | 45 | elif [[ $1 == "update" ]]; then 46 | header "Updating gem dependencies" 47 | update 48 | 49 | for app_path in "$root"/spec/railsapps/rails_*; do 50 | ( 51 | cd "$app_path" 52 | header "Updating $(basename "$app_path")" 53 | update 54 | ) 55 | done 56 | echo "" 57 | 58 | else 59 | echo "Usage: $0 [install|update]" 60 | echo "" 61 | echo " Install: Install all bundled updates." 62 | echo " Update: Run bundle update on all bundles." 63 | echo "" 64 | exit 127 65 | fi 66 | -------------------------------------------------------------------------------- /spec/integration_spec.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require "spec_helper" 4 | require "tempfile" 5 | require "mail" 6 | 7 | describe "Integrations" do 8 | def parse_html_in_email(mail) 9 | Nokogiri::HTML.parse mail.html_part.body.decoded 10 | end 11 | 12 | rails_apps = [ 13 | RailsApp.new("Rails 5.1", "rails_51", max_ruby_version: "2.7"), 14 | RailsApp.new("Rails 5.2", "rails_52", max_ruby_version: "2.7"), 15 | RailsApp.new("Rails 6.0", "rails_60", max_ruby_version: "3.0"), 16 | RailsApp.new("Rails 6.1", "rails_61", max_ruby_version: "3.0"), 17 | RailsApp.new("Rails 7.0", "rails_70", min_ruby_version: "2.7"), 18 | RailsApp.new("Rails 7.1 with sprockets", "rails_71", min_ruby_version: "2.7"), 19 | RailsApp.new("Rails 7.1 with propshaft", "rails_71_with_propshaft", min_ruby_version: "2.7", asset_pipeline: :propshaft), 20 | RailsApp.new("Rails 8.0 with propshaft", "rails_80_with_propshaft", min_ruby_version: "3.2", asset_pipeline: :propshaft) 21 | ] 22 | 23 | shared_examples "generates valid email" do |message| 24 | it "inlines styles #{message}" do 25 | expect(email.to).to eq(["example@example.org"]) 26 | expect(email.from).to eq(["john@example.com"]) 27 | expect(email).to have(2).parts 28 | 29 | expect(email.text_part.body.decoded).not_to match(/<.*>/) 30 | 31 | html = email.html_part.body.decoded 32 | expect(html).to include " "url(#{expected_image_url})" 43 | ).at_selector(".image") 44 | 45 | # If we deliver mails we can catch weird problems with headers being 46 | # invalid 47 | email.delivery_method :test 48 | email.deliver 49 | end 50 | end 51 | 52 | rails_apps.select(&:supported?).select(&:with_sprockets?).each do |app| 53 | describe "with #{app}" do 54 | before { app.reset } 55 | 56 | include_examples "generates valid email", "for multipart emails" do 57 | let(:email) { app.read_email(:normal_email) } 58 | end 59 | 60 | include_examples "generates valid email", "with automatic mailer" do 61 | let(:email) { app.read_delivered_email(:normal_email) } 62 | end 63 | 64 | include_examples( 65 | "generates valid email", 66 | "with automatic mailer and forced delivery" 67 | ) do 68 | let(:email) do 69 | app.read_delivered_email(:normal_email, force_delivery: true) 70 | end 71 | end 72 | 73 | it "inlines no styles when roadie_options are nil" do 74 | email = app.read_delivered_email(:disabled_email) 75 | 76 | expect(email.to).to eq(["example@example.org"]) 77 | expect(email.from).to eq(["john@example.com"]) 78 | expect(email).to have(2).parts 79 | 80 | document = parse_html_in_email(email) 81 | expect(document).to have_no_styling.at_selector(".image") 82 | 83 | # If we deliver mails we can catch weird problems with headers being 84 | # invalid 85 | email.delivery_method :test 86 | email.deliver 87 | end 88 | 89 | it "has a AssetPipelineProvider together with a FilesystemProvider" do 90 | expect(app.read_providers).to eq( 91 | %w[ 92 | Roadie::FilesystemProvider 93 | Roadie::Rails::AssetPipelineProvider 94 | ] 95 | ) 96 | end 97 | end 98 | end 99 | 100 | rails_apps.select(&:supported?).select(&:with_propshaft?).each do |app| 101 | describe "with #{app}" do 102 | before { app.reset } 103 | 104 | it "inlines styles for multipart emails" do 105 | email = app.read_email(:normal_email) 106 | 107 | expect(email.to).to eq(["example@example.org"]) 108 | expect(email.from).to eq(["john@example.com"]) 109 | expect(email).to have(2).parts 110 | 111 | expect(email.text_part.body.decoded).not_to match(/<.*>/) 112 | 113 | html = email.html_part.body.decoded 114 | expect(html).to include " "green" 122 | ).at_selector("body") 123 | 124 | expected_image_url = 125 | "https://example.app.org/assets/rails-fbe4356d.png" 126 | 127 | expect(document).to have_styling( 128 | "background" => "url(\"#{expected_image_url}\")" 129 | ).at_selector(".image") 130 | 131 | # If we deliver mails we can catch weird problems with headers being 132 | # invalid 133 | email.delivery_method :test 134 | email.deliver 135 | end 136 | 137 | it "inlines styles with automatic mailer" do 138 | email = app.read_delivered_email(:normal_email) 139 | 140 | expect(email.to).to eq(["example@example.org"]) 141 | expect(email.from).to eq(["john@example.com"]) 142 | expect(email).to have(2).parts 143 | 144 | expect(email.text_part.body.decoded).not_to match(/<.*>/) 145 | 146 | html = email.html_part.body.decoded 147 | expect(html).to include " "green" 155 | ).at_selector("body") 156 | 157 | expected_image_url = 158 | "https://example.app.org/assets/rails-fbe4356d.png" 159 | 160 | expect(document).to have_styling( 161 | "background" => "url(\"#{expected_image_url}\")" 162 | ).at_selector(".image") 163 | 164 | # If we deliver mails we can catch weird problems with headers being 165 | # invalid 166 | email.delivery_method :test 167 | email.deliver 168 | end 169 | 170 | it "has a AssetPropshaftProvider together with a FilesystemProvider" do 171 | expect(app.read_providers).to eq( 172 | %w[ 173 | Roadie::FilesystemProvider 174 | Roadie::Rails::AssetPropshaftProvider 175 | ] 176 | ) 177 | end 178 | end 179 | end 180 | end 181 | -------------------------------------------------------------------------------- /spec/lib/roadie/rails/asset_pipeline_provider_spec.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require "spec_helper" 4 | require "roadie/rspec" 5 | 6 | module Roadie 7 | module Rails 8 | describe AssetPipelineProvider do 9 | let(:pipeline) { FakePipeline.new } 10 | 11 | it "requires a passed pipeline" do 12 | expect { 13 | AssetPipelineProvider.new(nil) 14 | }.to raise_error(ArgumentError) 15 | end 16 | 17 | it_behaves_like( 18 | "roadie asset provider", 19 | valid_name: "existing.css", 20 | invalid_name: "bad.css" 21 | ) do 22 | subject { AssetPipelineProvider.new(pipeline) } 23 | before do 24 | pipeline.add_asset "existing.css", "existing.css", "" 25 | end 26 | end 27 | 28 | describe "finding stylesheets" do 29 | it "searches the asset pipeline" do 30 | pipeline.add_asset( 31 | "good.css", 32 | "/path/to/good.css.scss", 33 | "body { color: red; }" 34 | ) 35 | provider = AssetPipelineProvider.new(pipeline) 36 | 37 | stylesheet = provider.find_stylesheet("good.css") 38 | expect(stylesheet.name).to eq( 39 | "/path/to/good.css.scss (live compiled)" 40 | ) 41 | expect(stylesheet.to_s).to eq("body{color:red}") 42 | end 43 | 44 | it "ignores query string and asset prefix" do 45 | pipeline.add_asset "good.css", "good.css.scss", "" 46 | provider = AssetPipelineProvider.new(pipeline) 47 | expect( 48 | provider.find_stylesheet("/assets/good.css?body=1") 49 | ).not_to be_nil 50 | end 51 | 52 | it "ignores asset digest" do 53 | pipeline.add_asset "good.css", "good.css.scss", "" 54 | provider = AssetPipelineProvider.new(pipeline) 55 | 56 | # Old digest length 57 | expect( 58 | provider.find_stylesheet( 59 | "/assets/good-a1b605c3ff85456f0bf7bbbe3f59030a.css" 60 | ) 61 | ).not_to be_nil 62 | 63 | # New digest length 64 | expect( 65 | provider.find_stylesheet( 66 | "/assets/good-00acbfe0213dff8c5ba7232e3dabb3584c9e216bdb" \ 67 | "489f69d7aa20e0e101f3e6.css" 68 | ) 69 | ).not_to be_nil 70 | end 71 | 72 | it "will still find assets actually named with a hash at the end" do 73 | pipeline.add_asset( 74 | "vendor-a1b605c3ff85456f0bf7bbbe3f59030a.css", 75 | "vendor-a1b605c3ff85456f0bf7bbbe3f59030a.css", 76 | "" 77 | ) 78 | provider = AssetPipelineProvider.new(pipeline) 79 | expect( 80 | provider.find_stylesheet( 81 | "/assets/vendor-a1b605c3ff85456f0bf7bbbe3f59030a.css" 82 | ) 83 | ).not_to be_nil 84 | end 85 | 86 | it "supports stylesheets inside subdirectories" do 87 | pipeline.add_asset( 88 | "sub/deep.css", 89 | "/path/to/sub/deep.css.scss", 90 | "body { color: green; }" 91 | ) 92 | provider = AssetPipelineProvider.new(pipeline) 93 | 94 | stylesheet = provider.find_stylesheet("sub/deep.css") 95 | expect(stylesheet.name).to eq( 96 | "/path/to/sub/deep.css.scss (live compiled)" 97 | ) 98 | expect(stylesheet.to_s).to eq("body{color:green}") 99 | end 100 | end 101 | end 102 | end 103 | end 104 | -------------------------------------------------------------------------------- /spec/lib/roadie/rails/automatic_spec.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require "spec_helper" 4 | require "mail" 5 | 6 | module Roadie 7 | module Rails 8 | describe Automatic do 9 | base_mailer = Class.new do 10 | def initialize(email = nil) 11 | @email = email 12 | end 13 | 14 | def mail(_options = {}) 15 | @email 16 | end 17 | end 18 | 19 | some_mailer = Class.new(base_mailer) do 20 | include Automatic 21 | end 22 | 23 | describe "#roadie_options" do 24 | it "returns Rails' roadie config" do 25 | allow(::Rails).to receive_message_chain( 26 | :application, :config, :roadie 27 | ).and_return("roadie config") 28 | expect(some_mailer.new.roadie_options).to eq("roadie config") 29 | end 30 | end 31 | 32 | describe "#mail" do 33 | let(:email) { Mail.new(to: "foo@example.com", from: "me@example.com") } 34 | let(:instance) { some_mailer.new(email) } 35 | 36 | it "extends the email with InlineOnDelivery and assigns roadie options" do 37 | options = Options.new(url_options: {host: "somehost.com"}) 38 | allow(instance).to receive(:roadie_options).and_return options 39 | 40 | email = instance.mail 41 | 42 | expect(email).to be_kind_of(InlineOnDelivery) 43 | expect(email.roadie_options).not_to be_nil 44 | expect(email.roadie_options.url_options).to eq options.url_options 45 | end 46 | 47 | it "assigns nil roadie options if no options are present" do 48 | allow(instance).to receive(:roadie_options).and_return nil 49 | 50 | email = instance.mail 51 | 52 | expect(email).to be_kind_of(InlineOnDelivery) 53 | expect(email.roadie_options).to be_nil 54 | end 55 | end 56 | end 57 | end 58 | end 59 | -------------------------------------------------------------------------------- /spec/lib/roadie/rails/document_builder_spec.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require "spec_helper" 4 | 5 | module Roadie 6 | module Rails 7 | describe DocumentBuilder do 8 | it "builds documents with the given HTML" do 9 | document = DocumentBuilder.build("foo", Options.new) 10 | expect(document.html).to eq("foo") 11 | end 12 | 13 | it "applies the options to the document" do 14 | options = Options.new 15 | allow(options).to receive(:apply_to).and_call_original 16 | 17 | DocumentBuilder.build("", options) 18 | 19 | expect(options).to have_received(:apply_to).with(instance_of(Document)) 20 | end 21 | end 22 | end 23 | end 24 | -------------------------------------------------------------------------------- /spec/lib/roadie/rails/inline_on_delivery_spec.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require "spec_helper" 4 | require "mail" 5 | 6 | module Roadie 7 | module Rails 8 | describe InlineOnDelivery do 9 | it "inlines on #delivery" do 10 | inliner = instance_double(MailInliner, execute: nil) 11 | options = instance_double(Options) 12 | mail = FakeMail.new 13 | allow(MailInliner).to receive(:new).and_return(inliner) 14 | 15 | mail.extend(InlineOnDelivery) 16 | mail.roadie_options = options 17 | 18 | expect { mail.deliver }.to change(mail, :delivered?).to(true) 19 | 20 | expect(MailInliner).to have_received(:new).with(mail, options) 21 | expect(inliner).to have_received(:execute) 22 | end 23 | 24 | it "inlines on #delivery!" do 25 | inliner = instance_double(MailInliner, execute: nil) 26 | options = instance_double(Options) 27 | mail = FakeMail.new 28 | allow(MailInliner).to receive(:new).and_return(inliner) 29 | 30 | mail.extend(InlineOnDelivery) 31 | mail.roadie_options = options 32 | 33 | expect { mail.deliver! }.to change(mail, :delivered?).to(true) 34 | 35 | expect(MailInliner).to have_received(:new).with(mail, options) 36 | expect(inliner).to have_received(:execute) 37 | end 38 | end 39 | end 40 | end 41 | -------------------------------------------------------------------------------- /spec/lib/roadie/rails/mail_inliner_spec.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require "spec_helper" 4 | require "mail" 5 | 6 | module Roadie 7 | module Rails 8 | describe MailInliner do 9 | let(:email) { Mail.new } 10 | let(:options) { Options.new } 11 | subject(:inliner) { MailInliner.new(email, options) } 12 | 13 | it "takes an email and options" do 14 | inliner = MailInliner.new(email, options) 15 | expect(inliner.email).to eq(email) 16 | expect(inliner.options).to eq(options) 17 | end 18 | 19 | context "with an plaintext email" do 20 | let(:email) do 21 | Mail.new do 22 | body "Hello world" 23 | end 24 | end 25 | 26 | it "returns the email without doing anything" do 27 | expect(inliner.execute).to eq(email) 28 | expect(email.html_part).to be_nil 29 | expect(email.body.decoded).to eq("Hello world") 30 | end 31 | 32 | it "does nothing when given nil options" do 33 | inliner = MailInliner.new(email, nil) 34 | expect { inliner.execute }.to_not raise_error 35 | end 36 | end 37 | 38 | context "with an HTML email" do 39 | let(:html) { "

Hello world!

" } 40 | let(:email) do 41 | html_string = html 42 | Mail.new do 43 | content_type "text/html; charset=UTF-8" 44 | body html_string 45 | end 46 | end 47 | 48 | it "adjusts the html part using Roadie" do 49 | document = double "A document", transform: "transformed HTML" 50 | allow(DocumentBuilder).to receive(:build).and_return(document) 51 | 52 | inliner.execute 53 | 54 | expect(email.body.decoded).to eq("transformed HTML") 55 | expect(DocumentBuilder).to have_received(:build).with( 56 | html, 57 | instance_of(Options) 58 | ) 59 | end 60 | 61 | it "does nothing when given nil options" do 62 | inliner = MailInliner.new(email, nil) 63 | expect { inliner.execute }.to_not raise_error 64 | end 65 | end 66 | 67 | context "with an multipart email" do 68 | let(:html) { "

Hello world!

" } 69 | let(:email) do 70 | html_string = html 71 | Mail.new do 72 | text_part { body "Hello world" } 73 | html_part { body html_string } 74 | end 75 | end 76 | 77 | it "returns the email" do 78 | expect(inliner.execute).to eq(email) 79 | end 80 | 81 | it "adjusts the html part using Roadie" do 82 | document = double "A document", transform: "transformed HTML" 83 | allow(DocumentBuilder).to receive(:build).and_return(document) 84 | 85 | inliner.execute 86 | 87 | expect(email.html_part.body.decoded).to eq("transformed HTML") 88 | expect(DocumentBuilder).to have_received(:build).with( 89 | html, 90 | instance_of(Options) 91 | ) 92 | end 93 | 94 | it "does nothing when given nil options" do 95 | inliner = MailInliner.new(email, nil) 96 | expect { inliner.execute }.to_not raise_error 97 | end 98 | end 99 | end 100 | end 101 | end 102 | -------------------------------------------------------------------------------- /spec/lib/roadie/rails/mailer_spec.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require "spec_helper" 4 | require "mail" 5 | 6 | module Roadie 7 | module Rails 8 | describe Mailer do 9 | some_mailer = Class.new do 10 | include Mailer 11 | 12 | def initialize(email = nil) 13 | @email = email 14 | end 15 | 16 | def mail(_options = {}) 17 | @email 18 | end 19 | end 20 | 21 | describe "#roadie_options" do 22 | it "returns Rails' roadie config" do 23 | allow(::Rails).to receive_message_chain( 24 | :application, :config, :roadie 25 | ).and_return("roadie config") 26 | expect(some_mailer.new.roadie_options).to eq("roadie config") 27 | end 28 | end 29 | 30 | describe "#roadie_mail" do 31 | let(:email) { Mail.new } 32 | let(:instance) { some_mailer.new(email) } 33 | 34 | before do 35 | allow(instance).to receive(:roadie_options).and_return(Options.new) 36 | end 37 | 38 | before do 39 | inliner = double "Mail inliner" 40 | allow(inliner).to receive(:execute) { |email| email } 41 | allow(MailInliner).to receive(:new).and_return(inliner) 42 | end 43 | 44 | it "calls the original mail method with all options and the block" do 45 | expect(instance).to receive(:mail) do |options, &block| 46 | expect(options).to eq(some: "option") 47 | expect(block).not_to be_nil 48 | email 49 | end 50 | 51 | instance.roadie_mail(some: "option") {} 52 | end 53 | 54 | it "inlines the email" do 55 | inliner = instance_double(MailInliner, execute: "inlined email") 56 | allow(MailInliner).to receive(:new).and_return(inliner) 57 | 58 | expect(instance.roadie_mail).to eq("inlined email") 59 | 60 | expect(MailInliner).to have_received(:new).with( 61 | email, 62 | instance_of(Options) 63 | ) 64 | expect(inliner).to have_received(:execute) 65 | end 66 | 67 | it "allows to override roadie options" do 68 | inliner = instance_double(MailInliner, execute: "inlined email") 69 | allow(MailInliner).to receive(:new).and_return(inliner) 70 | 71 | expect( 72 | instance.roadie_mail({}, foo: "bar") 73 | ).to eq("inlined email") 74 | 75 | expect(MailInliner).to have_received(:new).with(email, foo: "bar") 76 | expect(inliner).to have_received(:execute) 77 | end 78 | end 79 | end 80 | end 81 | end 82 | -------------------------------------------------------------------------------- /spec/lib/roadie/rails/options_spec.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require "spec_helper" 4 | require "ostruct" 5 | 6 | module Roadie 7 | module Rails 8 | describe Options do 9 | it "raises errors when constructed with unknown options" do 10 | expect { 11 | Options.new(unknown_option: "maybe a misspelling?") 12 | }.to raise_error(ArgumentError, /unknown_option/) 13 | end 14 | 15 | it "raises errors when setting or reading unknown options" do 16 | options = Options.new 17 | expect { options[:foo] }.to raise_error(ArgumentError, /foo/) 18 | expect { options[:foo] = true }.to raise_error(ArgumentError, /foo/) 19 | end 20 | 21 | shared_examples_for "attribute" do |name| 22 | describe name do 23 | it "defaults to nil" do 24 | expect(Options.new[name]).to be_nil 25 | end 26 | 27 | it "can be set in the constructor" do 28 | options = Options.new(name => valid_value) 29 | expect(options[name]).to eq(valid_value) 30 | end 31 | 32 | it "can be changed using setter" do 33 | options = Options.new 34 | options.send :"#{name}=", valid_value 35 | expect(options[name]).to eq(valid_value) 36 | end 37 | 38 | it "can be changed using brackets" do 39 | options = Options.new 40 | options[name] = valid_value 41 | expect(options[name]).to eq(valid_value) 42 | end 43 | 44 | it "can be applied to documents" do 45 | fake_document = OpenStruct.new 46 | options = Options.new(name => valid_value) 47 | options.apply_to(fake_document) 48 | expect(fake_document[name]).to eq(valid_value) 49 | end 50 | 51 | describe "merging" do 52 | it "replaces values" do 53 | options = Options.new(name => valid_value) 54 | merged = options.merge(name => other_valid_value) 55 | expect(merged[name]).to eq(other_valid_value) 56 | end 57 | 58 | it "does not mutate instance" do 59 | options = Options.new(name => valid_value) 60 | options.merge(name => other_valid_value) 61 | expect(options[name]).to eq(valid_value) 62 | end 63 | end 64 | 65 | describe "destructive merging" do 66 | it "replaces values" do 67 | options = Options.new(name => valid_value) 68 | merged = options.merge(name => other_valid_value) 69 | expect(merged[name]).to eq(other_valid_value) 70 | end 71 | end 72 | 73 | describe "combining" do 74 | it "combines the old and the new value" do 75 | options = Options.new(name => valid_value) 76 | combined = options.combine(name => other_valid_value) 77 | expect_combinated_value(combined[name]) 78 | end 79 | 80 | it "does not mutate instance" do 81 | options = Options.new(name => valid_value) 82 | options.combine(name => other_valid_value) 83 | expect(options[name]).to eq(valid_value) 84 | end 85 | 86 | it "does not touch initial value if no new value is passed" do 87 | options = Options.new(name => valid_value) 88 | combined = options.combine({}) 89 | expect(combined[name]).to eq(valid_value) 90 | end 91 | end 92 | 93 | describe "destructive combining" do 94 | it "combines the old and the new value in the instance" do 95 | options = Options.new(name => valid_value) 96 | options.combine!(name => other_valid_value) 97 | expect_combinated_value(options[name]) 98 | end 99 | end 100 | end 101 | end 102 | 103 | it_behaves_like "attribute", :url_options do 104 | let(:valid_value) { {host: "foo.com", port: 3000} } 105 | let(:other_valid_value) { {host: "bar.com", scheme: "https"} } 106 | 107 | def expect_combinated_value(value) 108 | expect(value).to eq(host: "bar.com", port: 3000, scheme: "https") 109 | end 110 | end 111 | 112 | it_behaves_like "attribute", :keep_uninlinable_css do 113 | let(:valid_value) { true } 114 | let(:other_valid_value) { false } 115 | 116 | def expect_combinated_value(value) 117 | expect(value).to eq other_valid_value 118 | end 119 | end 120 | 121 | it_behaves_like "attribute", :before_transformation do 122 | let(:valid_value) { -> {} } 123 | let(:other_valid_value) { -> {} } 124 | 125 | def expect_combinated_value(value) 126 | allow(valid_value).to receive(:call).and_return 1 127 | allow(other_valid_value).to receive(:call).and_return 2 128 | 129 | expect(value.call).to eq(2) 130 | 131 | expect(valid_value).to have_received(:call).once.ordered 132 | expect(other_valid_value).to have_received(:call).once.ordered 133 | end 134 | end 135 | 136 | it_behaves_like "attribute", :after_transformation do 137 | let(:valid_value) { -> {} } 138 | let(:other_valid_value) { -> {} } 139 | 140 | def expect_combinated_value(value) 141 | allow(valid_value).to receive(:call).and_return 1 142 | allow(other_valid_value).to receive(:call).and_return 2 143 | 144 | expect(value.call).to eq(2) 145 | 146 | expect(valid_value).to have_received(:call).once.ordered 147 | expect(other_valid_value).to have_received(:call).once.ordered 148 | end 149 | end 150 | 151 | it_behaves_like "attribute", :asset_providers do 152 | let(:provider1) { double "Asset provider 1" } 153 | let(:provider2) { double "Asset provider 2" } 154 | 155 | let(:valid_value) { ProviderList.new([provider1]) } 156 | let(:other_valid_value) { ProviderList.new([provider2]) } 157 | 158 | def expect_combinated_value(value) 159 | expect(value).to be_instance_of(ProviderList) 160 | expect(value.to_a).to eq([provider1, provider2]) 161 | end 162 | end 163 | 164 | it_behaves_like "attribute", :external_asset_providers do 165 | let(:provider1) { double "Asset provider 1" } 166 | let(:provider2) { double "Asset provider 2" } 167 | 168 | let(:valid_value) { ProviderList.new([provider1]) } 169 | let(:other_valid_value) { ProviderList.new([provider2]) } 170 | 171 | def expect_combinated_value(value) 172 | expect(value).to be_instance_of(ProviderList) 173 | expect(value.to_a).to eq([provider1, provider2]) 174 | end 175 | end 176 | 177 | describe "asset_providers" do 178 | it "automatically wraps values in a ProviderList" do 179 | provider = double "Asset provider" 180 | options = Options.new(asset_providers: [provider]) 181 | expect(options.asset_providers).to be_instance_of(ProviderList) 182 | expect(options.asset_providers.to_a).to eq([provider]) 183 | end 184 | end 185 | 186 | describe "applying to a document" do 187 | it "does not change the default asset_providers if option is never set" do 188 | fake_document = OpenStruct.new(asset_providers: "original") 189 | Options.new.apply_to(fake_document) 190 | expect(fake_document.asset_providers).to eq("original") 191 | end 192 | end 193 | end 194 | end 195 | end 196 | -------------------------------------------------------------------------------- /spec/lib/roadie/rails/railtie_spec.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require "spec_helper" 4 | 5 | module Roadie 6 | module Rails 7 | describe Railtie do 8 | let(:rails_application) do 9 | double("Application", config: ::Rails::Railtie::Configuration.new) 10 | end 11 | 12 | before do 13 | allow(::Rails).to receive(:root).and_return Pathname.new("rails-root") 14 | allow(::Rails).to receive(:application).and_return rails_application 15 | end 16 | 17 | def run_initializer 18 | # Hack to make the Railtie able to be initialized again 19 | # Railties are global state, after all, stored on the classes. 20 | Railtie.instance_variable_set(:@instance, nil) # Embrace me, Cthulhu! 21 | Railtie.instance_variable_set(:@ran, nil) 22 | Railtie.run_initializers :default, rails_application 23 | end 24 | 25 | describe "asset providers" do 26 | it "has filesystem providers to common asset paths if asset pipeline is disabled" do 27 | run_initializer 28 | providers = Railtie.config.roadie.asset_providers.to_a 29 | expect(providers).to have(1).item 30 | 31 | expect(providers[0]).to be_instance_of(FilesystemProvider) 32 | expect(providers[0].path).to eq("rails-root/public") 33 | end 34 | 35 | it "also gets a AssetPipelineProvider if assets are enabled" do 36 | rails_application.config.assets = ActiveSupport::OrderedOptions.new 37 | 38 | asset_pipeline = double "The asset pipeline" 39 | allow(rails_application).to receive(:assets).and_return asset_pipeline 40 | run_initializer 41 | 42 | providers = Railtie.config.roadie.asset_providers.to_a 43 | expect(providers).to have(2).items 44 | expect(providers[0]).to be_instance_of(FilesystemProvider) 45 | expect(providers[1]).to be_instance_of(AssetPipelineProvider) 46 | expect(providers[1].pipeline).to eq(asset_pipeline) 47 | end 48 | 49 | # This happens inside a Rails engine as the parent app is the one 50 | # holding on to the pipeline. 51 | it "gets no AssetPipelineProvider if assets are enabled but not available" do 52 | rails_application.config.assets = ActiveSupport::OrderedOptions.new 53 | allow(rails_application).to receive(:assets).and_return nil 54 | 55 | run_initializer 56 | 57 | providers = Railtie.config.roadie.asset_providers.to_a 58 | expect(providers).to have(1).item 59 | expect(providers[0]).to be_instance_of(FilesystemProvider) 60 | end 61 | end 62 | end 63 | end 64 | end 65 | -------------------------------------------------------------------------------- /spec/railsapps/README.md: -------------------------------------------------------------------------------- 1 | # How to add another Rails app 2 | 3 | You need to follow certain steps in order to construct a proper integration with a new version of Rails. First, a quick summary: 4 | 5 | 1. Install the correct version of the `rails` gem 6 | 2. Using that version of `rails`, generate a new app 7 | 3. Strip out things we don't need from the app 8 | 4. Copy the mailers and templates to the app 9 | 5. Apply Roadie options and add Roadie to the Gemfile 10 | 6. Add it to `integration_spec.rb` 11 | 12 | ## Installing Rails 13 | 14 | ```bash 15 | gem install rails -v x.y.z 16 | ``` 17 | 18 | ## Generate Rails app 19 | 20 | ```bash 21 | APP_DIR=rails_xy 22 | rails _x.y.z._ new $APP_DIR --skip-javascript --skip-keeps --skip-active-record --skip-test-unit 23 | ``` 24 | 25 | ## Clean up the app 26 | 27 | ```bash 28 | cd $APP_DIR 29 | ``` 30 | 31 | The next step is of course specific to each Rails version. One of the easiest methods is to just start by deleting directories you know you have no use for, like `tmp`, `log` and `README.md`. 32 | 33 | ```bash 34 | rm -rf README.* tmp log db app/controllers app/helpers app/views/layouts public doc 35 | ``` 36 | 37 | You should also go through the initializers under `config` and remove the ones that don't apply; only keep the `development` environment. You should also strip away documentation comments and similar from all the files under `config`. Make them compact and only keep what is needed. 38 | 39 | After doing this, run `git add .` and inspect the list of added files. If there's any file there you didn't intend to add, just remove it with `git rm -f`. 40 | 41 | ## Copy mailer and templates 42 | 43 | ```bash 44 | cd .. 45 | rm -rf $APP_DIR/app/assets $APP_DIR/app/mailers $APP_DIR/app/views 46 | ln -s ../../shared/pipeline/app/assets $APP_DIR/app/assets 47 | ln -s ../../shared/all/app/mailers $APP_DIR/app/mailers 48 | ln -s ../../shared/all/app/views $APP_DIR/app/views 49 | ``` 50 | 51 | ## Apply options and add gem 52 | 53 | Add the following line to `config/initializers/assets.rb`: 54 | 55 | ```ruby 56 | Rails.application.config.assets.precompile += %w( email.css ) 57 | ``` 58 | 59 | Open up `config/application.rb` and add the following options: 60 | 61 | ```ruby 62 | config.roadie.url_options = {host: 'example.app.org'} 63 | ``` 64 | 65 | Then open up the `Gemfile` and add: 66 | 67 | ```ruby 68 | gem 'roadie-rails', :path => '../../..' 69 | ``` 70 | 71 | ## Add to integration_spec.rb 72 | 73 | Add the information needed in `spec/integration_spec.rb` and run `setup.sh` before finally running the tests themselves. When everything's good, `git add` everything and commit. 74 | -------------------------------------------------------------------------------- /spec/railsapps/rails_51/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files for more about ignoring files. 2 | # 3 | # If you find yourself ignoring temporary files generated by your text editor 4 | # or operating system, you probably want to add a global ignore instead: 5 | # git config --global core.excludesfile '~/.gitignore_global' 6 | 7 | # Ignore bundler config. 8 | /.bundle 9 | 10 | # Ignore all logfiles and tempfiles. 11 | /log/* 12 | /tmp/* 13 | !/log/.keep 14 | !/tmp/.keep 15 | 16 | # Ignore Byebug command history file. 17 | .byebug_history 18 | -------------------------------------------------------------------------------- /spec/railsapps/rails_51/Gemfile: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | source "https://rubygems.org" 4 | 5 | gem "rails", "~> 5.1.0" 6 | gem "sass-rails" 7 | gem "sprockets-rails" 8 | gem "listen" 9 | 10 | gem "roadie-rails", path: "../../.." 11 | -------------------------------------------------------------------------------- /spec/railsapps/rails_51/app/assets/config/manifest.js: -------------------------------------------------------------------------------- 1 | //= link_tree ../images 2 | //= link_directory ../stylesheets .css 3 | -------------------------------------------------------------------------------- /spec/railsapps/rails_51/app/assets/images/rails.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mange/roadie-rails/117b2567ad6aa4cbf1d1fc0a470f4f0ac756e2db/spec/railsapps/rails_51/app/assets/images/rails.png -------------------------------------------------------------------------------- /spec/railsapps/rails_51/app/assets/stylesheets/email.css.scss: -------------------------------------------------------------------------------- 1 | body { background-color: green; } 2 | .image { background: image-url("rails.png"); } 3 | -------------------------------------------------------------------------------- /spec/railsapps/rails_51/app/mailers/auto_mailer.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | class AutoMailer < ActionMailer::Base 4 | include Roadie::Rails::Automatic 5 | 6 | default from: "john@example.com" 7 | 8 | def normal_email 9 | generate_email 10 | end 11 | 12 | def disabled_email 13 | generate_email 14 | end 15 | 16 | private 17 | 18 | def roadie_options 19 | unless /disabled/.match?(action_name) 20 | super.combine(url_options: {protocol: "https"}) 21 | end 22 | end 23 | 24 | def generate_email 25 | mail(to: "example@example.org", subject: "Notification for you") do |format| 26 | format.html { render :normal_email } 27 | format.text { render :normal_email } 28 | end 29 | end 30 | end 31 | -------------------------------------------------------------------------------- /spec/railsapps/rails_51/app/mailers/mailer.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | class Mailer < ActionMailer::Base 4 | include Roadie::Rails::Mailer 5 | 6 | default from: "john@example.com" 7 | 8 | def normal_email 9 | roadie_mail(to: "example@example.org", subject: "Notification for you") do |format| 10 | format.html 11 | format.text 12 | end 13 | end 14 | 15 | private 16 | 17 | def roadie_options 18 | super.combine(url_options: {protocol: "https"}) 19 | end 20 | end 21 | -------------------------------------------------------------------------------- /spec/railsapps/rails_51/app/views/auto_mailer/normal_email.html.erb: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | <%= stylesheet_link_tag "email" %> 6 | 7 | 8 |

Normal email

9 |
10 | 11 | 12 | -------------------------------------------------------------------------------- /spec/railsapps/rails_51/app/views/auto_mailer/normal_email.text: -------------------------------------------------------------------------------- 1 | Normal email 2 | -------------------------------------------------------------------------------- /spec/railsapps/rails_51/app/views/mailer/normal_email.html.erb: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | <%= stylesheet_link_tag "email" %> 6 | 7 | 8 |

Normal email

9 |
10 | 11 | 12 | -------------------------------------------------------------------------------- /spec/railsapps/rails_51/app/views/mailer/normal_email.text: -------------------------------------------------------------------------------- 1 | Normal email 2 | -------------------------------------------------------------------------------- /spec/railsapps/rails_51/bin/rails: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # frozen_string_literal: true 3 | 4 | APP_PATH = File.expand_path("../../config/application", __FILE__) 5 | require_relative "../config/boot" 6 | require "rails/commands" 7 | -------------------------------------------------------------------------------- /spec/railsapps/rails_51/config.ru: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | # This file is used by Rack-based servers to start the application. 4 | 5 | require_relative "config/environment" 6 | 7 | run Rails.application 8 | -------------------------------------------------------------------------------- /spec/railsapps/rails_51/config/application.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require_relative "boot" 4 | 5 | require "action_controller/railtie" 6 | require "action_mailer/railtie" 7 | require "action_view/railtie" 8 | require "sprockets/railtie" 9 | 10 | # Require the gems listed in Gemfile, including any gems 11 | # you've limited to :test, :development, or :production. 12 | Bundler.require(*Rails.groups) 13 | 14 | module Rails51 15 | class Application < Rails::Application 16 | config.roadie.url_options = {host: "example.app.org"} 17 | end 18 | end 19 | -------------------------------------------------------------------------------- /spec/railsapps/rails_51/config/boot.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __dir__) 4 | 5 | require "bundler/setup" # Set up gems listed in the Gemfile. 6 | -------------------------------------------------------------------------------- /spec/railsapps/rails_51/config/environment.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | # Load the Rails application. 4 | require_relative "application" 5 | 6 | # Initialize the Rails application. 7 | Rails.application.initialize! 8 | -------------------------------------------------------------------------------- /spec/railsapps/rails_51/config/environments/development.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | Rails.application.configure do 4 | # Settings specified here will take precedence over those in config/application.rb. 5 | 6 | # In the development environment your application's code is reloaded on 7 | # every request. This slows down response time but is perfect for development 8 | # since you don't have to restart the web server when you make code changes. 9 | config.cache_classes = false 10 | 11 | # Do not eager load code on boot. 12 | config.eager_load = false 13 | 14 | # Show full error reports. 15 | config.consider_all_requests_local = true 16 | 17 | # Enable/disable caching. By default caching is disabled. 18 | if Rails.root.join("tmp/caching-dev.txt").exist? 19 | config.action_controller.perform_caching = true 20 | 21 | config.cache_store = :memory_store 22 | config.public_file_server.headers = { 23 | "Cache-Control" => "public, max-age=172800" 24 | } 25 | else 26 | config.action_controller.perform_caching = false 27 | 28 | config.cache_store = :null_store 29 | end 30 | 31 | # Don't care if the mailer can't send. 32 | config.action_mailer.raise_delivery_errors = false 33 | 34 | config.action_mailer.perform_caching = false 35 | 36 | # Print deprecation notices to the Rails logger. 37 | config.active_support.deprecation = :log 38 | 39 | # Debug mode disables concatenation and preprocessing of assets. 40 | # This option may cause significant delays in view rendering with a large 41 | # number of complex assets. 42 | config.assets.debug = true 43 | 44 | # Suppress logger output for asset requests. 45 | config.assets.quiet = true 46 | 47 | # Raises error for missing translations 48 | # config.action_view.raise_on_missing_translations = true 49 | 50 | # Use an evented file watcher to asynchronously detect changes in source code, 51 | # routes, locales, etc. This feature depends on the listen gem. 52 | config.file_watcher = ActiveSupport::EventedFileUpdateChecker 53 | end 54 | -------------------------------------------------------------------------------- /spec/railsapps/rails_51/config/environments/production.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | Rails.application.configure do 4 | # Settings specified here will take precedence over those in config/application.rb. 5 | 6 | # Code is not reloaded between requests. 7 | config.cache_classes = true 8 | 9 | # Eager load code on boot. This eager loads most of Rails and 10 | # your application in memory, allowing both threaded web servers 11 | # and those relying on copy on write to perform better. 12 | # Rake tasks automatically ignore this option for performance. 13 | config.eager_load = true 14 | 15 | # Full error reports are disabled and caching is turned on. 16 | config.consider_all_requests_local = false 17 | config.action_controller.perform_caching = true 18 | 19 | # Disable serving static files from the `/public` folder by default since 20 | # Apache or NGINX already handles this. 21 | config.public_file_server.enabled = ENV["RAILS_SERVE_STATIC_FILES"].present? 22 | 23 | # Compress JavaScripts and CSS. 24 | config.assets.js_compressor = :uglifier 25 | # config.assets.css_compressor = :sass 26 | 27 | # Do not fallback to assets pipeline if a precompiled asset is missed. 28 | config.assets.compile = false 29 | 30 | # `config.assets.precompile` and `config.assets.version` have moved to config/initializers/assets.rb 31 | 32 | # Enable serving of images, stylesheets, and JavaScripts from an asset server. 33 | # config.action_controller.asset_host = 'http://assets.example.com' 34 | 35 | # Specifies the header that your server uses for sending files. 36 | # config.action_dispatch.x_sendfile_header = 'X-Sendfile' # for Apache 37 | # config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for NGINX 38 | 39 | # Mount Action Cable outside main process or domain 40 | # config.action_cable.mount_path = nil 41 | # config.action_cable.url = 'wss://example.com/cable' 42 | # config.action_cable.allowed_request_origins = [ 'http://example.com', /http:\/\/example.*/ ] 43 | 44 | # Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies. 45 | # config.force_ssl = true 46 | 47 | # Use the lowest log level to ensure availability of diagnostic information 48 | # when problems arise. 49 | config.log_level = :debug 50 | 51 | # Prepend all log lines with the following tags. 52 | config.log_tags = [:request_id] 53 | 54 | # Use a different cache store in production. 55 | # config.cache_store = :mem_cache_store 56 | 57 | # Use a real queuing backend for Active Job (and separate queues per environment) 58 | # config.active_job.queue_adapter = :resque 59 | # config.active_job.queue_name_prefix = "rails_51_#{Rails.env}" 60 | config.action_mailer.perform_caching = false 61 | 62 | # Ignore bad email addresses and do not raise email delivery errors. 63 | # Set this to true and configure the email server for immediate delivery to raise delivery errors. 64 | # config.action_mailer.raise_delivery_errors = false 65 | 66 | # Enable locale fallbacks for I18n (makes lookups for any locale fall back to 67 | # the I18n.default_locale when a translation cannot be found). 68 | config.i18n.fallbacks = true 69 | 70 | # Send deprecation notices to registered listeners. 71 | config.active_support.deprecation = :notify 72 | 73 | # Use default logging formatter so that PID and timestamp are not suppressed. 74 | config.log_formatter = ::Logger::Formatter.new 75 | 76 | # Use a different logger for distributed setups. 77 | # require 'syslog/logger' 78 | # config.logger = ActiveSupport::TaggedLogging.new(Syslog::Logger.new 'app-name') 79 | 80 | if ENV["RAILS_LOG_TO_STDOUT"].present? 81 | logger = ActiveSupport::Logger.new($stdout) 82 | logger.formatter = config.log_formatter 83 | config.logger = ActiveSupport::TaggedLogging.new(logger) 84 | end 85 | end 86 | -------------------------------------------------------------------------------- /spec/railsapps/rails_51/config/environments/test.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | Rails.application.configure do 4 | # Settings specified here will take precedence over those in config/application.rb. 5 | 6 | # The test environment is used exclusively to run your application's 7 | # test suite. You never need to work with it otherwise. Remember that 8 | # your test database is "scratch space" for the test suite and is wiped 9 | # and recreated between test runs. Don't rely on the data there! 10 | config.cache_classes = true 11 | 12 | # Do not eager load code on boot. This avoids loading your whole application 13 | # just for the purpose of running a single test. If you are using a tool that 14 | # preloads Rails for running tests, you may have to set it to true. 15 | config.eager_load = false 16 | 17 | # Configure public file server for tests with Cache-Control for performance. 18 | config.public_file_server.enabled = true 19 | config.public_file_server.headers = { 20 | "Cache-Control" => "public, max-age=3600" 21 | } 22 | 23 | # Show full error reports and disable caching. 24 | config.consider_all_requests_local = true 25 | config.action_controller.perform_caching = false 26 | 27 | # Raise exceptions instead of rendering exception templates. 28 | config.action_dispatch.show_exceptions = false 29 | 30 | # Disable request forgery protection in test environment. 31 | config.action_controller.allow_forgery_protection = false 32 | config.action_mailer.perform_caching = false 33 | 34 | # Tell Action Mailer not to deliver emails to the real world. 35 | # The :test delivery method accumulates sent emails in the 36 | # ActionMailer::Base.deliveries array. 37 | config.action_mailer.delivery_method = :test 38 | 39 | # Print deprecation notices to the stderr. 40 | config.active_support.deprecation = :stderr 41 | 42 | # Raises error for missing translations 43 | # config.action_view.raise_on_missing_translations = true 44 | end 45 | -------------------------------------------------------------------------------- /spec/railsapps/rails_51/config/initializers/application_controller_renderer.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | # Be sure to restart your server when you modify this file. 4 | 5 | # ApplicationController.renderer.defaults.merge!( 6 | # http_host: 'example.org', 7 | # https: false 8 | # ) 9 | -------------------------------------------------------------------------------- /spec/railsapps/rails_51/config/initializers/assets.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | # Be sure to restart your server when you modify this file. 4 | 5 | # Version of your assets, change this if you want to expire all your assets. 6 | Rails.application.config.assets.version = "1.0" 7 | 8 | # Add additional assets to the asset load path 9 | # Rails.application.config.assets.paths << Emoji.images_path 10 | 11 | # Precompile additional assets. 12 | # application.js, application.css, and all non-JS/CSS in app/assets folder are already added. 13 | Rails.application.config.assets.precompile += %w[email.css] 14 | -------------------------------------------------------------------------------- /spec/railsapps/rails_51/config/initializers/backtrace_silencers.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | # Be sure to restart your server when you modify this file. 4 | 5 | # You can add backtrace silencers for libraries that you're using but don't wish to see in your backtraces. 6 | # Rails.backtrace_cleaner.add_silencer { |line| line =~ /my_noisy_library/ } 7 | 8 | # You can also remove all the silencers if you're trying to debug a problem that might stem from framework code. 9 | # Rails.backtrace_cleaner.remove_silencers! 10 | -------------------------------------------------------------------------------- /spec/railsapps/rails_51/config/initializers/cookies_serializer.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | # Be sure to restart your server when you modify this file. 4 | 5 | # Specify a serializer for the signed and encrypted cookie jars. 6 | # Valid options are :json, :marshal, and :hybrid. 7 | Rails.application.config.action_dispatch.cookies_serializer = :json 8 | -------------------------------------------------------------------------------- /spec/railsapps/rails_51/config/initializers/filter_parameter_logging.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | # Be sure to restart your server when you modify this file. 4 | 5 | # Configure sensitive parameters which will be filtered from the log file. 6 | Rails.application.config.filter_parameters += [:password] 7 | -------------------------------------------------------------------------------- /spec/railsapps/rails_51/config/initializers/inflections.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | # Be sure to restart your server when you modify this file. 4 | 5 | # Add new inflection rules using the following format. Inflections 6 | # are locale specific, and you may define rules for as many different 7 | # locales as you wish. All of these examples are active by default: 8 | # ActiveSupport::Inflector.inflections(:en) do |inflect| 9 | # inflect.plural /^(ox)$/i, '\1en' 10 | # inflect.singular /^(ox)en/i, '\1' 11 | # inflect.irregular 'person', 'people' 12 | # inflect.uncountable %w( fish sheep ) 13 | # end 14 | 15 | # These inflection rules are supported but not enabled by default: 16 | # ActiveSupport::Inflector.inflections(:en) do |inflect| 17 | # inflect.acronym 'RESTful' 18 | # end 19 | -------------------------------------------------------------------------------- /spec/railsapps/rails_51/config/initializers/mime_types.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | # Be sure to restart your server when you modify this file. 4 | 5 | # Add new mime types for use in respond_to blocks: 6 | # Mime::Type.register "text/richtext", :rtf 7 | -------------------------------------------------------------------------------- /spec/railsapps/rails_51/config/initializers/new_framework_defaults.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | # Be sure to restart your server when you modify this file. 4 | # 5 | # This file contains migration options to ease your Rails 5.0 upgrade. 6 | # 7 | # Read the Guide for Upgrading Ruby on Rails for more info on each option. 8 | 9 | # Enable per-form CSRF tokens. Previous versions had false. 10 | Rails.application.config.action_controller.per_form_csrf_tokens = true 11 | 12 | # Enable origin-checking CSRF mitigation. Previous versions had false. 13 | Rails.application.config.action_controller.forgery_protection_origin_check = true 14 | 15 | # Make Ruby 2.4 preserve the timezone of the receiver when calling `to_time`. 16 | # Previous versions had false. 17 | ActiveSupport.to_time_preserves_timezone = true 18 | 19 | # Do not halt callback chains when a callback returns false. Previous versions had true. 20 | ActiveSupport.halt_callback_chains_on_return_false = false 21 | 22 | # Configure SSL options to enable HSTS with subdomains. Previous versions had false. 23 | Rails.application.config.ssl_options = {hsts: {subdomains: true}} 24 | -------------------------------------------------------------------------------- /spec/railsapps/rails_51/config/initializers/session_store.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | # Be sure to restart your server when you modify this file. 4 | 5 | Rails.application.config.session_store :cookie_store, key: "_rails_51_session" 6 | -------------------------------------------------------------------------------- /spec/railsapps/rails_51/config/initializers/wrap_parameters.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | # Be sure to restart your server when you modify this file. 4 | 5 | # This file contains settings for ActionController::ParamsWrapper which 6 | # is enabled by default. 7 | 8 | # Enable parameter wrapping for JSON. You can disable this by setting :format to an empty array. 9 | ActiveSupport.on_load(:action_controller) do 10 | wrap_parameters format: [:json] 11 | end 12 | -------------------------------------------------------------------------------- /spec/railsapps/rails_51/config/locales/en.yml: -------------------------------------------------------------------------------- 1 | # Files in the config/locales directory are used for internationalization 2 | # and are automatically loaded by Rails. If you want to use locales other 3 | # than English, add the necessary files in this directory. 4 | # 5 | # To use the locales, use `I18n.t`: 6 | # 7 | # I18n.t 'hello' 8 | # 9 | # In views, this is aliased to just `t`: 10 | # 11 | # <%= t('hello') %> 12 | # 13 | # To use a different locale, set it with `I18n.locale`: 14 | # 15 | # I18n.locale = :es 16 | # 17 | # This would use the information in config/locales/es.yml. 18 | # 19 | # To learn more, please read the Rails Internationalization guide 20 | # available at http://guides.rubyonrails.org/i18n.html. 21 | 22 | en: 23 | hello: "Hello world" 24 | -------------------------------------------------------------------------------- /spec/railsapps/rails_51/config/routes.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | Rails.application.routes.draw do 4 | # For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html 5 | end 6 | -------------------------------------------------------------------------------- /spec/railsapps/rails_51/log/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mange/roadie-rails/117b2567ad6aa4cbf1d1fc0a470f4f0ac756e2db/spec/railsapps/rails_51/log/.keep -------------------------------------------------------------------------------- /spec/railsapps/rails_52/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files for more about ignoring files. 2 | # 3 | # If you find yourself ignoring temporary files generated by your text editor 4 | # or operating system, you probably want to add a global ignore instead: 5 | # git config --global core.excludesfile '~/.gitignore_global' 6 | 7 | # Ignore bundler config. 8 | /.bundle 9 | 10 | # Ignore all logfiles and tempfiles. 11 | /log/* 12 | /tmp/* 13 | !/log/.keep 14 | !/tmp/.keep 15 | 16 | # Ignore Byebug command history file. 17 | .byebug_history 18 | -------------------------------------------------------------------------------- /spec/railsapps/rails_52/Gemfile: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | source "https://rubygems.org" 4 | 5 | gem "rails", "~> 5.2.0" 6 | gem "sass-rails" 7 | gem "sprockets-rails" 8 | gem "listen" 9 | 10 | gem "roadie-rails", path: "../../.." 11 | -------------------------------------------------------------------------------- /spec/railsapps/rails_52/app/assets/config/manifest.js: -------------------------------------------------------------------------------- 1 | //= link_tree ../images 2 | //= link_directory ../stylesheets .css 3 | -------------------------------------------------------------------------------- /spec/railsapps/rails_52/app/assets/images/rails.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mange/roadie-rails/117b2567ad6aa4cbf1d1fc0a470f4f0ac756e2db/spec/railsapps/rails_52/app/assets/images/rails.png -------------------------------------------------------------------------------- /spec/railsapps/rails_52/app/assets/stylesheets/email.css.scss: -------------------------------------------------------------------------------- 1 | body { background-color: green; } 2 | .image { background: image-url("rails.png"); } 3 | -------------------------------------------------------------------------------- /spec/railsapps/rails_52/app/mailers/auto_mailer.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | class AutoMailer < ActionMailer::Base 4 | include Roadie::Rails::Automatic 5 | 6 | default from: "john@example.com" 7 | 8 | def normal_email 9 | generate_email 10 | end 11 | 12 | def disabled_email 13 | generate_email 14 | end 15 | 16 | private 17 | 18 | def roadie_options 19 | unless /disabled/.match?(action_name) 20 | super.combine(url_options: {protocol: "https"}) 21 | end 22 | end 23 | 24 | def generate_email 25 | mail(to: "example@example.org", subject: "Notification for you") do |format| 26 | format.html { render :normal_email } 27 | format.text { render :normal_email } 28 | end 29 | end 30 | end 31 | -------------------------------------------------------------------------------- /spec/railsapps/rails_52/app/mailers/mailer.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | class Mailer < ActionMailer::Base 4 | include Roadie::Rails::Mailer 5 | 6 | default from: "john@example.com" 7 | 8 | def normal_email 9 | roadie_mail(to: "example@example.org", subject: "Notification for you") do |format| 10 | format.html 11 | format.text 12 | end 13 | end 14 | 15 | private 16 | 17 | def roadie_options 18 | super.combine(url_options: {protocol: "https"}) 19 | end 20 | end 21 | -------------------------------------------------------------------------------- /spec/railsapps/rails_52/app/views/auto_mailer/normal_email.html.erb: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | <%= stylesheet_link_tag "email" %> 6 | 7 | 8 |

Normal email

9 |
10 | 11 | 12 | -------------------------------------------------------------------------------- /spec/railsapps/rails_52/app/views/auto_mailer/normal_email.text: -------------------------------------------------------------------------------- 1 | Normal email 2 | -------------------------------------------------------------------------------- /spec/railsapps/rails_52/app/views/mailer/normal_email.html.erb: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | <%= stylesheet_link_tag "email" %> 6 | 7 | 8 |

Normal email

9 |
10 | 11 | 12 | -------------------------------------------------------------------------------- /spec/railsapps/rails_52/app/views/mailer/normal_email.text: -------------------------------------------------------------------------------- 1 | Normal email 2 | -------------------------------------------------------------------------------- /spec/railsapps/rails_52/bin/rails: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # frozen_string_literal: true 3 | 4 | APP_PATH = File.expand_path("../../config/application", __FILE__) 5 | require_relative "../config/boot" 6 | require "rails/commands" 7 | -------------------------------------------------------------------------------- /spec/railsapps/rails_52/config.ru: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | # This file is used by Rack-based servers to start the application. 4 | 5 | require_relative "config/environment" 6 | 7 | run Rails.application 8 | -------------------------------------------------------------------------------- /spec/railsapps/rails_52/config/application.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require_relative "boot" 4 | 5 | require "action_controller/railtie" 6 | require "action_mailer/railtie" 7 | require "action_view/railtie" 8 | require "sprockets/railtie" 9 | 10 | # Require the gems listed in Gemfile, including any gems 11 | # you've limited to :test, :development, or :production. 12 | Bundler.require(*Rails.groups) 13 | 14 | module Rails52 15 | class Application < Rails::Application 16 | config.roadie.url_options = {host: "example.app.org"} 17 | end 18 | end 19 | -------------------------------------------------------------------------------- /spec/railsapps/rails_52/config/boot.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __dir__) 4 | 5 | require "bundler/setup" # Set up gems listed in the Gemfile. 6 | -------------------------------------------------------------------------------- /spec/railsapps/rails_52/config/environment.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | # Load the Rails application. 4 | require_relative "application" 5 | 6 | # Initialize the Rails application. 7 | Rails.application.initialize! 8 | -------------------------------------------------------------------------------- /spec/railsapps/rails_52/config/environments/development.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | Rails.application.configure do 4 | # Settings specified here will take precedence over those in config/application.rb. 5 | 6 | # In the development environment your application's code is reloaded on 7 | # every request. This slows down response time but is perfect for development 8 | # since you don't have to restart the web server when you make code changes. 9 | config.cache_classes = false 10 | 11 | # Do not eager load code on boot. 12 | config.eager_load = false 13 | 14 | # Show full error reports. 15 | config.consider_all_requests_local = true 16 | 17 | # Enable/disable caching. By default caching is disabled. 18 | if Rails.root.join("tmp/caching-dev.txt").exist? 19 | config.action_controller.perform_caching = true 20 | 21 | config.cache_store = :memory_store 22 | config.public_file_server.headers = { 23 | "Cache-Control" => "public, max-age=172800" 24 | } 25 | else 26 | config.action_controller.perform_caching = false 27 | 28 | config.cache_store = :null_store 29 | end 30 | 31 | # Don't care if the mailer can't send. 32 | config.action_mailer.raise_delivery_errors = false 33 | 34 | config.action_mailer.perform_caching = false 35 | 36 | # Print deprecation notices to the Rails logger. 37 | config.active_support.deprecation = :log 38 | 39 | # Debug mode disables concatenation and preprocessing of assets. 40 | # This option may cause significant delays in view rendering with a large 41 | # number of complex assets. 42 | config.assets.debug = true 43 | 44 | # Suppress logger output for asset requests. 45 | config.assets.quiet = true 46 | 47 | # Raises error for missing translations 48 | # config.action_view.raise_on_missing_translations = true 49 | 50 | # Use an evented file watcher to asynchronously detect changes in source code, 51 | # routes, locales, etc. This feature depends on the listen gem. 52 | config.file_watcher = ActiveSupport::EventedFileUpdateChecker 53 | end 54 | -------------------------------------------------------------------------------- /spec/railsapps/rails_52/config/environments/production.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | Rails.application.configure do 4 | # Settings specified here will take precedence over those in config/application.rb. 5 | 6 | # Code is not reloaded between requests. 7 | config.cache_classes = true 8 | 9 | # Eager load code on boot. This eager loads most of Rails and 10 | # your application in memory, allowing both threaded web servers 11 | # and those relying on copy on write to perform better. 12 | # Rake tasks automatically ignore this option for performance. 13 | config.eager_load = true 14 | 15 | # Full error reports are disabled and caching is turned on. 16 | config.consider_all_requests_local = false 17 | config.action_controller.perform_caching = true 18 | 19 | # Disable serving static files from the `/public` folder by default since 20 | # Apache or NGINX already handles this. 21 | config.public_file_server.enabled = ENV["RAILS_SERVE_STATIC_FILES"].present? 22 | 23 | # Compress JavaScripts and CSS. 24 | config.assets.js_compressor = :uglifier 25 | # config.assets.css_compressor = :sass 26 | 27 | # Do not fallback to assets pipeline if a precompiled asset is missed. 28 | config.assets.compile = false 29 | 30 | # `config.assets.precompile` and `config.assets.version` have moved to config/initializers/assets.rb 31 | 32 | # Enable serving of images, stylesheets, and JavaScripts from an asset server. 33 | # config.action_controller.asset_host = 'http://assets.example.com' 34 | 35 | # Specifies the header that your server uses for sending files. 36 | # config.action_dispatch.x_sendfile_header = 'X-Sendfile' # for Apache 37 | # config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for NGINX 38 | 39 | # Mount Action Cable outside main process or domain 40 | # config.action_cable.mount_path = nil 41 | # config.action_cable.url = 'wss://example.com/cable' 42 | # config.action_cable.allowed_request_origins = [ 'http://example.com', /http:\/\/example.*/ ] 43 | 44 | # Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies. 45 | # config.force_ssl = true 46 | 47 | # Use the lowest log level to ensure availability of diagnostic information 48 | # when problems arise. 49 | config.log_level = :debug 50 | 51 | # Prepend all log lines with the following tags. 52 | config.log_tags = [:request_id] 53 | 54 | # Use a different cache store in production. 55 | # config.cache_store = :mem_cache_store 56 | 57 | # Use a real queuing backend for Active Job (and separate queues per environment) 58 | # config.active_job.queue_adapter = :resque 59 | # config.active_job.queue_name_prefix = "rails_51_#{Rails.env}" 60 | config.action_mailer.perform_caching = false 61 | 62 | # Ignore bad email addresses and do not raise email delivery errors. 63 | # Set this to true and configure the email server for immediate delivery to raise delivery errors. 64 | # config.action_mailer.raise_delivery_errors = false 65 | 66 | # Enable locale fallbacks for I18n (makes lookups for any locale fall back to 67 | # the I18n.default_locale when a translation cannot be found). 68 | config.i18n.fallbacks = true 69 | 70 | # Send deprecation notices to registered listeners. 71 | config.active_support.deprecation = :notify 72 | 73 | # Use default logging formatter so that PID and timestamp are not suppressed. 74 | config.log_formatter = ::Logger::Formatter.new 75 | 76 | # Use a different logger for distributed setups. 77 | # require 'syslog/logger' 78 | # config.logger = ActiveSupport::TaggedLogging.new(Syslog::Logger.new 'app-name') 79 | 80 | if ENV["RAILS_LOG_TO_STDOUT"].present? 81 | logger = ActiveSupport::Logger.new($stdout) 82 | logger.formatter = config.log_formatter 83 | config.logger = ActiveSupport::TaggedLogging.new(logger) 84 | end 85 | end 86 | -------------------------------------------------------------------------------- /spec/railsapps/rails_52/config/environments/test.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | Rails.application.configure do 4 | # Settings specified here will take precedence over those in config/application.rb. 5 | 6 | # The test environment is used exclusively to run your application's 7 | # test suite. You never need to work with it otherwise. Remember that 8 | # your test database is "scratch space" for the test suite and is wiped 9 | # and recreated between test runs. Don't rely on the data there! 10 | config.cache_classes = true 11 | 12 | # Do not eager load code on boot. This avoids loading your whole application 13 | # just for the purpose of running a single test. If you are using a tool that 14 | # preloads Rails for running tests, you may have to set it to true. 15 | config.eager_load = false 16 | 17 | # Configure public file server for tests with Cache-Control for performance. 18 | config.public_file_server.enabled = true 19 | config.public_file_server.headers = { 20 | "Cache-Control" => "public, max-age=3600" 21 | } 22 | 23 | # Show full error reports and disable caching. 24 | config.consider_all_requests_local = true 25 | config.action_controller.perform_caching = false 26 | 27 | # Raise exceptions instead of rendering exception templates. 28 | config.action_dispatch.show_exceptions = false 29 | 30 | # Disable request forgery protection in test environment. 31 | config.action_controller.allow_forgery_protection = false 32 | config.action_mailer.perform_caching = false 33 | 34 | # Tell Action Mailer not to deliver emails to the real world. 35 | # The :test delivery method accumulates sent emails in the 36 | # ActionMailer::Base.deliveries array. 37 | config.action_mailer.delivery_method = :test 38 | 39 | # Print deprecation notices to the stderr. 40 | config.active_support.deprecation = :stderr 41 | 42 | # Raises error for missing translations 43 | # config.action_view.raise_on_missing_translations = true 44 | end 45 | -------------------------------------------------------------------------------- /spec/railsapps/rails_52/config/initializers/application_controller_renderer.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | # Be sure to restart your server when you modify this file. 4 | 5 | # ApplicationController.renderer.defaults.merge!( 6 | # http_host: 'example.org', 7 | # https: false 8 | # ) 9 | -------------------------------------------------------------------------------- /spec/railsapps/rails_52/config/initializers/assets.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | # Be sure to restart your server when you modify this file. 4 | 5 | # Version of your assets, change this if you want to expire all your assets. 6 | Rails.application.config.assets.version = "1.0" 7 | 8 | # Add additional assets to the asset load path 9 | # Rails.application.config.assets.paths << Emoji.images_path 10 | 11 | # Precompile additional assets. 12 | # application.js, application.css, and all non-JS/CSS in app/assets folder are already added. 13 | Rails.application.config.assets.precompile += %w[email.css] 14 | -------------------------------------------------------------------------------- /spec/railsapps/rails_52/config/initializers/backtrace_silencers.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | # Be sure to restart your server when you modify this file. 4 | 5 | # You can add backtrace silencers for libraries that you're using but don't wish to see in your backtraces. 6 | # Rails.backtrace_cleaner.add_silencer { |line| line =~ /my_noisy_library/ } 7 | 8 | # You can also remove all the silencers if you're trying to debug a problem that might stem from framework code. 9 | # Rails.backtrace_cleaner.remove_silencers! 10 | -------------------------------------------------------------------------------- /spec/railsapps/rails_52/config/initializers/cookies_serializer.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | # Be sure to restart your server when you modify this file. 4 | 5 | # Specify a serializer for the signed and encrypted cookie jars. 6 | # Valid options are :json, :marshal, and :hybrid. 7 | Rails.application.config.action_dispatch.cookies_serializer = :json 8 | -------------------------------------------------------------------------------- /spec/railsapps/rails_52/config/initializers/filter_parameter_logging.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | # Be sure to restart your server when you modify this file. 4 | 5 | # Configure sensitive parameters which will be filtered from the log file. 6 | Rails.application.config.filter_parameters += [:password] 7 | -------------------------------------------------------------------------------- /spec/railsapps/rails_52/config/initializers/inflections.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | # Be sure to restart your server when you modify this file. 4 | 5 | # Add new inflection rules using the following format. Inflections 6 | # are locale specific, and you may define rules for as many different 7 | # locales as you wish. All of these examples are active by default: 8 | # ActiveSupport::Inflector.inflections(:en) do |inflect| 9 | # inflect.plural /^(ox)$/i, '\1en' 10 | # inflect.singular /^(ox)en/i, '\1' 11 | # inflect.irregular 'person', 'people' 12 | # inflect.uncountable %w( fish sheep ) 13 | # end 14 | 15 | # These inflection rules are supported but not enabled by default: 16 | # ActiveSupport::Inflector.inflections(:en) do |inflect| 17 | # inflect.acronym 'RESTful' 18 | # end 19 | -------------------------------------------------------------------------------- /spec/railsapps/rails_52/config/initializers/mime_types.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | # Be sure to restart your server when you modify this file. 4 | 5 | # Add new mime types for use in respond_to blocks: 6 | # Mime::Type.register "text/richtext", :rtf 7 | -------------------------------------------------------------------------------- /spec/railsapps/rails_52/config/initializers/new_framework_defaults.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | # Be sure to restart your server when you modify this file. 4 | # 5 | # This file contains migration options to ease your Rails 5.0 upgrade. 6 | # 7 | # Read the Guide for Upgrading Ruby on Rails for more info on each option. 8 | 9 | # Enable per-form CSRF tokens. Previous versions had false. 10 | Rails.application.config.action_controller.per_form_csrf_tokens = true 11 | 12 | # Enable origin-checking CSRF mitigation. Previous versions had false. 13 | Rails.application.config.action_controller.forgery_protection_origin_check = true 14 | 15 | # Make Ruby 2.4 preserve the timezone of the receiver when calling `to_time`. 16 | # Previous versions had false. 17 | ActiveSupport.to_time_preserves_timezone = true 18 | 19 | # Configure SSL options to enable HSTS with subdomains. Previous versions had false. 20 | Rails.application.config.ssl_options = {hsts: {subdomains: true}} 21 | -------------------------------------------------------------------------------- /spec/railsapps/rails_52/config/initializers/session_store.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | # Be sure to restart your server when you modify this file. 4 | 5 | Rails.application.config.session_store :cookie_store, key: "_rails_51_session" 6 | -------------------------------------------------------------------------------- /spec/railsapps/rails_52/config/initializers/wrap_parameters.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | # Be sure to restart your server when you modify this file. 4 | 5 | # This file contains settings for ActionController::ParamsWrapper which 6 | # is enabled by default. 7 | 8 | # Enable parameter wrapping for JSON. You can disable this by setting :format to an empty array. 9 | ActiveSupport.on_load(:action_controller) do 10 | wrap_parameters format: [:json] 11 | end 12 | -------------------------------------------------------------------------------- /spec/railsapps/rails_52/config/locales/en.yml: -------------------------------------------------------------------------------- 1 | # Files in the config/locales directory are used for internationalization 2 | # and are automatically loaded by Rails. If you want to use locales other 3 | # than English, add the necessary files in this directory. 4 | # 5 | # To use the locales, use `I18n.t`: 6 | # 7 | # I18n.t 'hello' 8 | # 9 | # In views, this is aliased to just `t`: 10 | # 11 | # <%= t('hello') %> 12 | # 13 | # To use a different locale, set it with `I18n.locale`: 14 | # 15 | # I18n.locale = :es 16 | # 17 | # This would use the information in config/locales/es.yml. 18 | # 19 | # To learn more, please read the Rails Internationalization guide 20 | # available at http://guides.rubyonrails.org/i18n.html. 21 | 22 | en: 23 | hello: "Hello world" 24 | -------------------------------------------------------------------------------- /spec/railsapps/rails_52/config/routes.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | Rails.application.routes.draw do 4 | # For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html 5 | end 6 | -------------------------------------------------------------------------------- /spec/railsapps/rails_52/log/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mange/roadie-rails/117b2567ad6aa4cbf1d1fc0a470f4f0ac756e2db/spec/railsapps/rails_52/log/.keep -------------------------------------------------------------------------------- /spec/railsapps/rails_60/.gitignore: -------------------------------------------------------------------------------- 1 | /.bundle 2 | /log/* 3 | /tmp/* 4 | /public/assets 5 | .byebug_history 6 | -------------------------------------------------------------------------------- /spec/railsapps/rails_60/Gemfile: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | source "https://rubygems.org" 4 | 5 | gem "rails", "~> 6.0.0" 6 | gem "sass-rails" 7 | gem "sprockets-rails" 8 | gem "listen" 9 | 10 | gem "roadie-rails", path: "../../.." 11 | 12 | gem "bigdecimal" 13 | gem "mutex_m" 14 | gem "logger" 15 | gem "benchmark" 16 | -------------------------------------------------------------------------------- /spec/railsapps/rails_60/Rakefile: -------------------------------------------------------------------------------- 1 | # Add your own tasks in files placed in lib/tasks ending in .rake, 2 | # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake. 3 | 4 | require_relative "config/application" 5 | 6 | Rails.application.load_tasks 7 | -------------------------------------------------------------------------------- /spec/railsapps/rails_60/app/assets: -------------------------------------------------------------------------------- 1 | ../../shared/pipeline/app/assets -------------------------------------------------------------------------------- /spec/railsapps/rails_60/app/mailers: -------------------------------------------------------------------------------- 1 | ../../shared/all/app/mailers -------------------------------------------------------------------------------- /spec/railsapps/rails_60/app/views: -------------------------------------------------------------------------------- 1 | ../../shared/all/app/views -------------------------------------------------------------------------------- /spec/railsapps/rails_60/bin/rails: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | APP_PATH = File.expand_path("../config/application", __dir__) 3 | require_relative "../config/boot" 4 | require "rails/commands" 5 | -------------------------------------------------------------------------------- /spec/railsapps/rails_60/config.ru: -------------------------------------------------------------------------------- 1 | require_relative "config/environment" 2 | run Rails.application 3 | -------------------------------------------------------------------------------- /spec/railsapps/rails_60/config/application.rb: -------------------------------------------------------------------------------- 1 | require_relative "boot" 2 | 3 | require "active_model/railtie" 4 | require "action_controller/railtie" 5 | require "action_mailer/railtie" 6 | require "action_view/railtie" 7 | require "sprockets/railtie" 8 | require "rails/test_unit/railtie" 9 | 10 | Bundler.require(*Rails.groups) 11 | 12 | module Rails60 13 | class Application < Rails::Application 14 | config.load_defaults 6.0 15 | config.roadie.url_options = {host: "example.app.org"} 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /spec/railsapps/rails_60/config/boot.rb: -------------------------------------------------------------------------------- 1 | ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __dir__) 2 | 3 | require "bundler/setup" 4 | # Workaround for uninitialized constant ActiveSupport::LoggerThreadSafeLevel::Logger 5 | require "logger" 6 | -------------------------------------------------------------------------------- /spec/railsapps/rails_60/config/environment.rb: -------------------------------------------------------------------------------- 1 | require_relative "application" 2 | Rails.application.initialize! 3 | -------------------------------------------------------------------------------- /spec/railsapps/rails_60/config/environments/development.rb: -------------------------------------------------------------------------------- 1 | Rails.application.configure do 2 | config.cache_classes = false 3 | config.eager_load = false 4 | config.consider_all_requests_local = true 5 | if Rails.root.join("tmp", "caching-dev.txt").exist? 6 | config.action_controller.perform_caching = true 7 | config.action_controller.enable_fragment_cache_logging = true 8 | config.cache_store = :memory_store 9 | config.public_file_server.headers = { 10 | "Cache-Control" => "public, max-age=#{2.days.to_i}" 11 | } 12 | else 13 | config.action_controller.perform_caching = false 14 | config.cache_store = :null_store 15 | end 16 | config.action_mailer.raise_delivery_errors = false 17 | config.action_mailer.perform_caching = false 18 | config.active_support.deprecation = :log 19 | config.assets.debug = true 20 | config.assets.quiet = true 21 | config.file_watcher = ActiveSupport::EventedFileUpdateChecker 22 | end 23 | -------------------------------------------------------------------------------- /spec/railsapps/rails_60/config/initializers/assets.rb: -------------------------------------------------------------------------------- 1 | Rails.application.config.assets.version = "1.0" 2 | Rails.application.config.assets.precompile += %w[email.css] 3 | -------------------------------------------------------------------------------- /spec/railsapps/rails_60/config/initializers/cookies_serializer.rb: -------------------------------------------------------------------------------- 1 | Rails.application.config.action_dispatch.cookies_serializer = :json 2 | -------------------------------------------------------------------------------- /spec/railsapps/rails_60/config/initializers/filter_parameter_logging.rb: -------------------------------------------------------------------------------- 1 | Rails.application.config.filter_parameters += [:password] 2 | -------------------------------------------------------------------------------- /spec/railsapps/rails_60/config/initializers/wrap_parameters.rb: -------------------------------------------------------------------------------- 1 | ActiveSupport.on_load(:action_controller) do 2 | wrap_parameters format: [:json] 3 | end 4 | -------------------------------------------------------------------------------- /spec/railsapps/rails_60/config/routes.rb: -------------------------------------------------------------------------------- 1 | Rails.application.routes.draw do 2 | end 3 | -------------------------------------------------------------------------------- /spec/railsapps/rails_61/.gitignore: -------------------------------------------------------------------------------- 1 | /.bundle 2 | /log/* 3 | /tmp/* 4 | /public/assets 5 | /config/master.key 6 | -------------------------------------------------------------------------------- /spec/railsapps/rails_61/Gemfile: -------------------------------------------------------------------------------- 1 | source "https://rubygems.org" 2 | 3 | gem "rails", "~> 6.1.0" 4 | 5 | gem "bootsnap", ">= 1.4.4", require: false 6 | gem "listen" 7 | gem "sass-rails", ">= 6" 8 | gem "sprockets-rails" 9 | 10 | gem "roadie-rails", path: "../../.." 11 | 12 | gem "bigdecimal" 13 | gem "mutex_m" 14 | gem "logger" 15 | gem "benchmark" 16 | -------------------------------------------------------------------------------- /spec/railsapps/rails_61/Rakefile: -------------------------------------------------------------------------------- 1 | require_relative "config/application" 2 | Rails.application.load_tasks 3 | -------------------------------------------------------------------------------- /spec/railsapps/rails_61/app/assets: -------------------------------------------------------------------------------- 1 | ../../shared/pipeline/app/assets -------------------------------------------------------------------------------- /spec/railsapps/rails_61/app/mailers: -------------------------------------------------------------------------------- 1 | ../../shared/all/app/mailers -------------------------------------------------------------------------------- /spec/railsapps/rails_61/app/views: -------------------------------------------------------------------------------- 1 | ../../shared/all/app/views -------------------------------------------------------------------------------- /spec/railsapps/rails_61/bin/rails: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | APP_PATH = File.expand_path("../config/application", __dir__) 3 | require_relative "../config/boot" 4 | require "rails/commands" 5 | -------------------------------------------------------------------------------- /spec/railsapps/rails_61/config.ru: -------------------------------------------------------------------------------- 1 | require_relative "config/environment" 2 | run Rails.application 3 | Rails.application.load_server 4 | -------------------------------------------------------------------------------- /spec/railsapps/rails_61/config/application.rb: -------------------------------------------------------------------------------- 1 | require_relative "boot" 2 | 3 | require "rails" 4 | require "active_model/railtie" 5 | require "action_controller/railtie" 6 | require "action_mailer/railtie" 7 | require "action_view/railtie" 8 | require "sprockets/railtie" 9 | require "rails/test_unit/railtie" 10 | 11 | Bundler.require(*Rails.groups) 12 | 13 | module Rails61 14 | class Application < Rails::Application 15 | config.load_defaults 6.1 16 | config.roadie.url_options = {host: "example.app.org"} 17 | end 18 | end 19 | -------------------------------------------------------------------------------- /spec/railsapps/rails_61/config/boot.rb: -------------------------------------------------------------------------------- 1 | ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __dir__) 2 | 3 | require "bundler/setup" 4 | # Workaround for uninitialized constant ActiveSupport::LoggerThreadSafeLevel::Logger 5 | require "logger" 6 | require "bootsnap/setup" 7 | -------------------------------------------------------------------------------- /spec/railsapps/rails_61/config/environment.rb: -------------------------------------------------------------------------------- 1 | require_relative "application" 2 | Rails.application.initialize! 3 | -------------------------------------------------------------------------------- /spec/railsapps/rails_61/config/environments/development.rb: -------------------------------------------------------------------------------- 1 | require "active_support/core_ext/integer/time" 2 | 3 | Rails.application.configure do 4 | config.cache_classes = false 5 | config.eager_load = false 6 | config.consider_all_requests_local = true 7 | if Rails.root.join("tmp", "caching-dev.txt").exist? 8 | config.action_controller.perform_caching = true 9 | config.action_controller.enable_fragment_cache_logging = true 10 | 11 | config.cache_store = :memory_store 12 | config.public_file_server.headers = { 13 | "Cache-Control" => "public, max-age=#{2.days.to_i}" 14 | } 15 | else 16 | config.action_controller.perform_caching = false 17 | 18 | config.cache_store = :null_store 19 | end 20 | config.action_mailer.raise_delivery_errors = false 21 | config.action_mailer.perform_caching = false 22 | config.active_support.deprecation = :log 23 | config.active_support.disallowed_deprecation = :raise 24 | config.active_support.disallowed_deprecation_warnings = [] 25 | config.assets.debug = true 26 | config.assets.quiet = true 27 | config.file_watcher = ActiveSupport::EventedFileUpdateChecker 28 | end 29 | -------------------------------------------------------------------------------- /spec/railsapps/rails_61/config/initializers/assets.rb: -------------------------------------------------------------------------------- 1 | Rails.application.config.assets.version = "1.0" 2 | Rails.application.config.assets.precompile += %w[email.css] 3 | -------------------------------------------------------------------------------- /spec/railsapps/rails_61/config/initializers/cookies_serializer.rb: -------------------------------------------------------------------------------- 1 | Rails.application.config.action_dispatch.cookies_serializer = :json 2 | -------------------------------------------------------------------------------- /spec/railsapps/rails_61/config/initializers/filter_parameter_logging.rb: -------------------------------------------------------------------------------- 1 | Rails.application.config.filter_parameters += [ 2 | :passw, :secret, :token, :_key, :crypt, :salt, :certificate, :otp, :ssn 3 | ] 4 | -------------------------------------------------------------------------------- /spec/railsapps/rails_61/config/initializers/wrap_parameters.rb: -------------------------------------------------------------------------------- 1 | ActiveSupport.on_load(:action_controller) do 2 | wrap_parameters format: [:json] 3 | end 4 | -------------------------------------------------------------------------------- /spec/railsapps/rails_61/config/routes.rb: -------------------------------------------------------------------------------- 1 | Rails.application.routes.draw do 2 | end 3 | -------------------------------------------------------------------------------- /spec/railsapps/rails_70/Gemfile: -------------------------------------------------------------------------------- 1 | source "https://rubygems.org" 2 | 3 | # Bundle edge Rails instead: gem "rails", github: "rails/rails", branch: "main" 4 | gem "rails", "~> 7.0.0" 5 | 6 | # Reduces boot times through caching; required in config/boot.rb 7 | gem "bootsnap", ">= 1.4.4", require: false 8 | gem "sass-rails" 9 | gem "sprockets-rails" 10 | gem "roadie-rails", path: "../../.." 11 | 12 | gem "bigdecimal" 13 | gem "mutex_m" 14 | gem "logger" 15 | gem "benchmark" 16 | -------------------------------------------------------------------------------- /spec/railsapps/rails_70/Rakefile: -------------------------------------------------------------------------------- 1 | # Add your own tasks in files placed in lib/tasks ending in .rake, 2 | # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake. 3 | 4 | require_relative "config/application" 5 | 6 | Rails.application.load_tasks 7 | -------------------------------------------------------------------------------- /spec/railsapps/rails_70/app/assets: -------------------------------------------------------------------------------- 1 | ../../shared/pipeline/app/assets -------------------------------------------------------------------------------- /spec/railsapps/rails_70/app/mailers: -------------------------------------------------------------------------------- 1 | ../../shared/all/app/mailers -------------------------------------------------------------------------------- /spec/railsapps/rails_70/app/views: -------------------------------------------------------------------------------- 1 | ../../shared/all/app/views -------------------------------------------------------------------------------- /spec/railsapps/rails_70/bin/bundle: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # frozen_string_literal: true 3 | 4 | # 5 | # This file was generated by Bundler. 6 | # 7 | # The application 'bundle' is installed as part of a gem, and 8 | # this file is here to facilitate running it. 9 | # 10 | 11 | require "rubygems" 12 | 13 | m = Module.new do 14 | module_function 15 | 16 | def invoked_as_script? 17 | File.expand_path($0) == File.expand_path(__FILE__) 18 | end 19 | 20 | def env_var_version 21 | ENV["BUNDLER_VERSION"] 22 | end 23 | 24 | def cli_arg_version 25 | return unless invoked_as_script? # don't want to hijack other binstubs 26 | return unless "update".start_with?(ARGV.first || " ") # must be running `bundle update` 27 | bundler_version = nil 28 | update_index = nil 29 | ARGV.each_with_index do |a, i| 30 | if update_index && update_index.succ == i && a =~ Gem::Version::ANCHORED_VERSION_PATTERN 31 | bundler_version = a 32 | end 33 | next unless a =~ /\A--bundler(?:[= ](#{Gem::Version::VERSION_PATTERN}))?\z/o 34 | bundler_version = $1 35 | update_index = i 36 | end 37 | bundler_version 38 | end 39 | 40 | def gemfile 41 | gemfile = ENV["BUNDLE_GEMFILE"] 42 | return gemfile if gemfile && !gemfile.empty? 43 | 44 | File.expand_path("../../Gemfile", __FILE__) 45 | end 46 | 47 | def lockfile 48 | lockfile = 49 | case File.basename(gemfile) 50 | when "gems.rb" then gemfile.sub(/\.rb$/, gemfile) 51 | else "#{gemfile}.lock" 52 | end 53 | File.expand_path(lockfile) 54 | end 55 | 56 | def lockfile_version 57 | return unless File.file?(lockfile) 58 | lockfile_contents = File.read(lockfile) 59 | return unless lockfile_contents =~ /\n\nBUNDLED WITH\n\s{2,}(#{Gem::Version::VERSION_PATTERN})\n/o 60 | Regexp.last_match(1) 61 | end 62 | 63 | def bundler_requirement 64 | @bundler_requirement ||= 65 | env_var_version || cli_arg_version || 66 | bundler_requirement_for(lockfile_version) 67 | end 68 | 69 | def bundler_requirement_for(version) 70 | return "#{Gem::Requirement.default}.a" unless version 71 | 72 | bundler_gem_version = Gem::Version.new(version) 73 | 74 | requirement = bundler_gem_version.approximate_recommendation 75 | 76 | return requirement unless Gem::Version.new(Gem::VERSION) < Gem::Version.new("2.7.0") 77 | 78 | requirement += ".a" if bundler_gem_version.prerelease? 79 | 80 | requirement 81 | end 82 | 83 | def load_bundler! 84 | ENV["BUNDLE_GEMFILE"] ||= gemfile 85 | 86 | activate_bundler 87 | end 88 | 89 | def activate_bundler 90 | gem_error = activation_error_handling do 91 | gem "bundler", bundler_requirement 92 | end 93 | return if gem_error.nil? 94 | require_error = activation_error_handling do 95 | require "bundler/version" 96 | end 97 | return if require_error.nil? && Gem::Requirement.new(bundler_requirement).satisfied_by?(Gem::Version.new(Bundler::VERSION)) 98 | warn "Activating bundler (#{bundler_requirement}) failed:\n#{gem_error.message}\n\nTo install the version of bundler this project requires, run `gem install bundler -v '#{bundler_requirement}'`" 99 | exit 42 100 | end 101 | 102 | def activation_error_handling 103 | yield 104 | nil 105 | rescue StandardError, LoadError => e 106 | e 107 | end 108 | end 109 | 110 | m.load_bundler! 111 | 112 | if m.invoked_as_script? 113 | load Gem.bin_path("bundler", "bundle") 114 | end 115 | -------------------------------------------------------------------------------- /spec/railsapps/rails_70/bin/rails: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | APP_PATH = File.expand_path("../config/application", __dir__) 3 | require_relative "../config/boot" 4 | require "rails/commands" 5 | -------------------------------------------------------------------------------- /spec/railsapps/rails_70/bin/rake: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require_relative "../config/boot" 3 | require "rake" 4 | Rake.application.run 5 | -------------------------------------------------------------------------------- /spec/railsapps/rails_70/bin/setup: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require "fileutils" 3 | 4 | # path to your application root. 5 | APP_ROOT = File.expand_path("..", __dir__) 6 | 7 | def system!(*args) 8 | system(*args) || abort("\n== Command #{args} failed ==") 9 | end 10 | 11 | FileUtils.chdir APP_ROOT do 12 | # This script is a way to set up or update your development environment automatically. 13 | # This script is idempotent, so that you can run it at any time and get an expectable outcome. 14 | # Add necessary setup steps to this file. 15 | 16 | puts "== Installing dependencies ==" 17 | system! "gem install bundler --conservative" 18 | system("bundle check") || system!("bundle install") 19 | 20 | puts "\n== Removing old logs and tempfiles ==" 21 | system! "bin/rails log:clear tmp:clear" 22 | 23 | puts "\n== Restarting application server ==" 24 | system! "bin/rails restart" 25 | end 26 | -------------------------------------------------------------------------------- /spec/railsapps/rails_70/config.ru: -------------------------------------------------------------------------------- 1 | # This file is used by Rack-based servers to start the application. 2 | 3 | require_relative "config/environment" 4 | 5 | run Rails.application 6 | Rails.application.load_server 7 | -------------------------------------------------------------------------------- /spec/railsapps/rails_70/config/application.rb: -------------------------------------------------------------------------------- 1 | require_relative "boot" 2 | 3 | require "rails" 4 | # Pick the frameworks you want: 5 | # require "active_model/railtie" 6 | # require "active_job/railtie" 7 | # require "active_record/railtie" 8 | # require "active_storage/engine" 9 | require "action_controller/railtie" 10 | require "action_mailer/railtie" 11 | # require "action_mailbox/engine" 12 | # require "action_text/engine" 13 | require "action_view/railtie" 14 | # require "action_cable/engine" 15 | require "sprockets/railtie" 16 | # require "rails/test_unit/railtie" 17 | 18 | # Require the gems listed in Gemfile, including any gems 19 | # you've limited to :test, :development, or :production. 20 | Bundler.require(*Rails.groups) 21 | 22 | module Rails70 23 | class Application < Rails::Application 24 | # Initialize configuration defaults for originally generated Rails version. 25 | config.load_defaults 7.0 26 | 27 | # Configuration for the application, engines, and railties goes here. 28 | # 29 | # These settings can be overridden in specific environments using the files 30 | # in config/environments, which are processed later. 31 | # 32 | # config.time_zone = "Central Time (US & Canada)" 33 | # config.eager_load_paths << Rails.root.join("extras") 34 | config.roadie.url_options = {host: "example.app.org"} 35 | config.action_view.preload_links_header = false 36 | end 37 | end 38 | -------------------------------------------------------------------------------- /spec/railsapps/rails_70/config/boot.rb: -------------------------------------------------------------------------------- 1 | ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __dir__) 2 | 3 | require "bundler/setup" # Set up gems listed in the Gemfile. 4 | # Workaround for uninitialized constant ActiveSupport::LoggerThreadSafeLevel::Logger 5 | require "logger" 6 | require "bootsnap/setup" # Speed up boot time by caching expensive operations. 7 | -------------------------------------------------------------------------------- /spec/railsapps/rails_70/config/environment.rb: -------------------------------------------------------------------------------- 1 | # Load the Rails application. 2 | require_relative "application" 3 | 4 | # Initialize the Rails application. 5 | Rails.application.initialize! 6 | -------------------------------------------------------------------------------- /spec/railsapps/rails_70/config/environments/development.rb: -------------------------------------------------------------------------------- 1 | require "active_support/core_ext/integer/time" 2 | 3 | Rails.application.configure do 4 | # Settings specified here will take precedence over those in config/application.rb. 5 | 6 | # In the development environment your application's code is reloaded any time 7 | # it changes. This slows down response time but is perfect for development 8 | # since you don't have to restart the web server when you make code changes. 9 | config.cache_classes = false 10 | 11 | # Do not eager load code on boot. 12 | config.eager_load = false 13 | 14 | # Show full error reports. 15 | config.consider_all_requests_local = true 16 | 17 | # Enable/disable caching. By default caching is disabled. 18 | # Run rails dev:cache to toggle caching. 19 | if Rails.root.join("tmp/caching-dev.txt").exist? 20 | config.action_controller.perform_caching = true 21 | config.action_controller.enable_fragment_cache_logging = true 22 | 23 | config.cache_store = :memory_store 24 | config.public_file_server.headers = { 25 | "Cache-Control" => "public, max-age=#{2.days.to_i}" 26 | } 27 | else 28 | config.action_controller.perform_caching = false 29 | 30 | config.cache_store = :null_store 31 | end 32 | 33 | # Don't care if the mailer can't send. 34 | config.action_mailer.raise_delivery_errors = false 35 | 36 | config.action_mailer.perform_caching = false 37 | 38 | # Print deprecation notices to the Rails logger. 39 | config.active_support.deprecation = :log 40 | 41 | # Raise exceptions for disallowed deprecations. 42 | config.active_support.disallowed_deprecation = :raise 43 | 44 | # Tell Active Support which deprecation messages to disallow. 45 | config.active_support.disallowed_deprecation_warnings = [] 46 | 47 | # Suppress logger output for asset requests. 48 | config.assets.quiet = true 49 | 50 | # Raises error for missing translations. 51 | # config.i18n.raise_on_missing_translations = true 52 | 53 | # Annotate rendered view with file names. 54 | # config.action_view.annotate_rendered_view_with_filenames = true 55 | 56 | # Uncomment if you wish to allow Action Cable access from any origin. 57 | # config.action_cable.disable_request_forgery_protection = true 58 | end 59 | -------------------------------------------------------------------------------- /spec/railsapps/rails_70/config/initializers/assets.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Version of your assets, change this if you want to expire all your assets. 4 | Rails.application.config.assets.version = "1.0" 5 | 6 | # Add additional assets to the asset load path. 7 | # Rails.application.config.assets.paths << Emoji.images_path 8 | 9 | # Precompile additional assets. 10 | # application.js, application.css, and all non-JS/CSS in the app/assets 11 | # folder are already added. 12 | # Rails.application.config.assets.precompile += %w( admin.js admin.css ) 13 | Rails.application.config.assets.precompile += %w[email.css] 14 | -------------------------------------------------------------------------------- /spec/railsapps/rails_70/config/initializers/backtrace_silencers.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # You can add backtrace silencers for libraries that you're using but don't wish to see in your backtraces. 4 | # Rails.backtrace_cleaner.add_silencer { |line| /my_noisy_library/.match?(line) } 5 | 6 | # You can also remove all the silencers if you're trying to debug a problem that might stem from framework code 7 | # by setting BACKTRACE=1 before calling your invocation, like "BACKTRACE=1 ./bin/rails runner 'MyClass.perform'". 8 | Rails.backtrace_cleaner.remove_silencers! if ENV["BACKTRACE"] 9 | -------------------------------------------------------------------------------- /spec/railsapps/rails_70/config/initializers/content_security_policy.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Define an application-wide content security policy 4 | # For further information see the following documentation 5 | # https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy 6 | 7 | # Rails.application.config.content_security_policy do |policy| 8 | # policy.default_src :self, :https 9 | # policy.font_src :self, :https, :data 10 | # policy.img_src :self, :https, :data 11 | # policy.object_src :none 12 | # policy.script_src :self, :https 13 | # policy.style_src :self, :https 14 | # # Specify URI for violation reports 15 | # # policy.report_uri "/csp-violation-report-endpoint" 16 | # end 17 | 18 | # If you are using UJS then enable automatic nonce generation 19 | # Rails.application.config.content_security_policy_nonce_generator = -> request { SecureRandom.base64(16) } 20 | 21 | # Set the nonce only to specific directives 22 | # Rails.application.config.content_security_policy_nonce_directives = %w(script-src) 23 | 24 | # Report CSP violations to a specified URI 25 | # For further information see the following documentation: 26 | # https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy-Report-Only 27 | # Rails.application.config.content_security_policy_report_only = true 28 | -------------------------------------------------------------------------------- /spec/railsapps/rails_70/config/initializers/filter_parameter_logging.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Configure sensitive parameters which will be filtered from the log file. 4 | Rails.application.config.filter_parameters += [ 5 | :passw, :secret, :token, :_key, :crypt, :salt, :certificate, :otp, :ssn 6 | ] 7 | -------------------------------------------------------------------------------- /spec/railsapps/rails_70/config/initializers/inflections.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Add new inflection rules using the following format. Inflections 4 | # are locale specific, and you may define rules for as many different 5 | # locales as you wish. All of these examples are active by default: 6 | # ActiveSupport::Inflector.inflections(:en) do |inflect| 7 | # inflect.plural /^(ox)$/i, "\\1en" 8 | # inflect.singular /^(ox)en/i, "\\1" 9 | # inflect.irregular "person", "people" 10 | # inflect.uncountable %w( fish sheep ) 11 | # end 12 | 13 | # These inflection rules are supported but not enabled by default: 14 | # ActiveSupport::Inflector.inflections(:en) do |inflect| 15 | # inflect.acronym "RESTful" 16 | # end 17 | -------------------------------------------------------------------------------- /spec/railsapps/rails_70/config/initializers/mime_types.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Add new mime types for use in respond_to blocks: 4 | # Mime::Type.register "text/richtext", :rtf 5 | -------------------------------------------------------------------------------- /spec/railsapps/rails_70/config/initializers/permissions_policy.rb: -------------------------------------------------------------------------------- 1 | # Define an application-wide HTTP permissions policy. For further 2 | # information see https://developers.google.com/web/updates/2018/06/feature-policy 3 | # 4 | # Rails.application.config.permissions_policy do |f| 5 | # f.camera :none 6 | # f.gyroscope :none 7 | # f.microphone :none 8 | # f.usb :none 9 | # f.fullscreen :self 10 | # f.payment :self, "https://secure.example.com" 11 | # end 12 | -------------------------------------------------------------------------------- /spec/railsapps/rails_70/config/initializers/wrap_parameters.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # This file contains settings for ActionController::ParamsWrapper which 4 | # is enabled by default. 5 | 6 | # Enable parameter wrapping for JSON. You can disable this by setting :format to an empty array. 7 | ActiveSupport.on_load(:action_controller) do 8 | wrap_parameters format: [:json] 9 | end 10 | -------------------------------------------------------------------------------- /spec/railsapps/rails_70/config/routes.rb: -------------------------------------------------------------------------------- 1 | Rails.application.routes.draw do 2 | # For details on the DSL available within this file, see https://guides.rubyonrails.org/routing.html 3 | 4 | # Almost every application defines a route for the root path ("/") at the top of this file. 5 | # root "articles#index" 6 | end 7 | -------------------------------------------------------------------------------- /spec/railsapps/rails_71/Gemfile: -------------------------------------------------------------------------------- 1 | source "https://rubygems.org" 2 | 3 | # Bundle edge Rails instead: gem "rails", github: "rails/rails", branch: "main" 4 | gem "rails", "~> 7.1.0" 5 | 6 | # Reduces boot times through caching; required in config/boot.rb 7 | gem "bootsnap", ">= 1.4.4", require: false 8 | gem "sass-rails" 9 | gem "sprockets-rails" 10 | gem "roadie-rails", path: "../../.." 11 | -------------------------------------------------------------------------------- /spec/railsapps/rails_71/Rakefile: -------------------------------------------------------------------------------- 1 | # Add your own tasks in files placed in lib/tasks ending in .rake, 2 | # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake. 3 | 4 | require_relative "config/application" 5 | 6 | Rails.application.load_tasks 7 | -------------------------------------------------------------------------------- /spec/railsapps/rails_71/app/assets/config/manifest.js: -------------------------------------------------------------------------------- 1 | //= link_tree ../images 2 | //= link_directory ../stylesheets .css 3 | -------------------------------------------------------------------------------- /spec/railsapps/rails_71/app/assets/images/rails.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mange/roadie-rails/117b2567ad6aa4cbf1d1fc0a470f4f0ac756e2db/spec/railsapps/rails_71/app/assets/images/rails.png -------------------------------------------------------------------------------- /spec/railsapps/rails_71/app/assets/stylesheets/email.css.scss: -------------------------------------------------------------------------------- 1 | body { background-color: green; } 2 | .image { background: image-url("rails.png"); } 3 | -------------------------------------------------------------------------------- /spec/railsapps/rails_71/app/mailers/auto_mailer.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | class AutoMailer < ActionMailer::Base 4 | include Roadie::Rails::Automatic 5 | 6 | default from: "john@example.com" 7 | 8 | def normal_email 9 | generate_email 10 | end 11 | 12 | def disabled_email 13 | generate_email 14 | end 15 | 16 | private 17 | 18 | def roadie_options 19 | unless /disabled/.match?(action_name) 20 | super.combine(url_options: {protocol: "https"}) 21 | end 22 | end 23 | 24 | def generate_email 25 | mail(to: "example@example.org", subject: "Notification for you") do |format| 26 | format.html { render :normal_email } 27 | format.text { render :normal_email } 28 | end 29 | end 30 | end 31 | -------------------------------------------------------------------------------- /spec/railsapps/rails_71/app/mailers/mailer.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | class Mailer < ActionMailer::Base 4 | include Roadie::Rails::Mailer 5 | 6 | default from: "john@example.com" 7 | 8 | def normal_email 9 | roadie_mail(to: "example@example.org", subject: "Notification for you") do |format| 10 | format.html 11 | format.text 12 | end 13 | end 14 | 15 | private 16 | 17 | def roadie_options 18 | super.combine(url_options: {protocol: "https"}) 19 | end 20 | end 21 | -------------------------------------------------------------------------------- /spec/railsapps/rails_71/app/views/auto_mailer/normal_email.html.erb: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | <%= stylesheet_link_tag "email" %> 6 | 7 | 8 |

Normal email

9 |
10 | 11 | 12 | -------------------------------------------------------------------------------- /spec/railsapps/rails_71/app/views/auto_mailer/normal_email.text: -------------------------------------------------------------------------------- 1 | Normal email 2 | -------------------------------------------------------------------------------- /spec/railsapps/rails_71/app/views/mailer/normal_email.html.erb: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | <%= stylesheet_link_tag "email" %> 6 | 7 | 8 |

Normal email

9 |
10 | 11 | 12 | -------------------------------------------------------------------------------- /spec/railsapps/rails_71/app/views/mailer/normal_email.text: -------------------------------------------------------------------------------- 1 | Normal email 2 | -------------------------------------------------------------------------------- /spec/railsapps/rails_71/bin/bundle: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # frozen_string_literal: true 3 | 4 | # 5 | # This file was generated by Bundler. 6 | # 7 | # The application 'bundle' is installed as part of a gem, and 8 | # this file is here to facilitate running it. 9 | # 10 | 11 | require "rubygems" 12 | 13 | m = Module.new do 14 | module_function 15 | 16 | def invoked_as_script? 17 | File.expand_path($0) == File.expand_path(__FILE__) 18 | end 19 | 20 | def env_var_version 21 | ENV["BUNDLER_VERSION"] 22 | end 23 | 24 | def cli_arg_version 25 | return unless invoked_as_script? # don't want to hijack other binstubs 26 | return unless "update".start_with?(ARGV.first || " ") # must be running `bundle update` 27 | bundler_version = nil 28 | update_index = nil 29 | ARGV.each_with_index do |a, i| 30 | if update_index && update_index.succ == i && a =~ Gem::Version::ANCHORED_VERSION_PATTERN 31 | bundler_version = a 32 | end 33 | next unless a =~ /\A--bundler(?:[= ](#{Gem::Version::VERSION_PATTERN}))?\z/o 34 | bundler_version = $1 35 | update_index = i 36 | end 37 | bundler_version 38 | end 39 | 40 | def gemfile 41 | gemfile = ENV["BUNDLE_GEMFILE"] 42 | return gemfile if gemfile && !gemfile.empty? 43 | 44 | File.expand_path("../../Gemfile", __FILE__) 45 | end 46 | 47 | def lockfile 48 | lockfile = 49 | case File.basename(gemfile) 50 | when "gems.rb" then gemfile.sub(/\.rb$/, gemfile) 51 | else "#{gemfile}.lock" 52 | end 53 | File.expand_path(lockfile) 54 | end 55 | 56 | def lockfile_version 57 | return unless File.file?(lockfile) 58 | lockfile_contents = File.read(lockfile) 59 | return unless lockfile_contents =~ /\n\nBUNDLED WITH\n\s{2,}(#{Gem::Version::VERSION_PATTERN})\n/o 60 | Regexp.last_match(1) 61 | end 62 | 63 | def bundler_requirement 64 | @bundler_requirement ||= 65 | env_var_version || cli_arg_version || 66 | bundler_requirement_for(lockfile_version) 67 | end 68 | 69 | def bundler_requirement_for(version) 70 | return "#{Gem::Requirement.default}.a" unless version 71 | 72 | bundler_gem_version = Gem::Version.new(version) 73 | 74 | requirement = bundler_gem_version.approximate_recommendation 75 | 76 | return requirement unless Gem::Version.new(Gem::VERSION) < Gem::Version.new("2.7.0") 77 | 78 | requirement += ".a" if bundler_gem_version.prerelease? 79 | 80 | requirement 81 | end 82 | 83 | def load_bundler! 84 | ENV["BUNDLE_GEMFILE"] ||= gemfile 85 | 86 | activate_bundler 87 | end 88 | 89 | def activate_bundler 90 | gem_error = activation_error_handling do 91 | gem "bundler", bundler_requirement 92 | end 93 | return if gem_error.nil? 94 | require_error = activation_error_handling do 95 | require "bundler/version" 96 | end 97 | return if require_error.nil? && Gem::Requirement.new(bundler_requirement).satisfied_by?(Gem::Version.new(Bundler::VERSION)) 98 | warn "Activating bundler (#{bundler_requirement}) failed:\n#{gem_error.message}\n\nTo install the version of bundler this project requires, run `gem install bundler -v '#{bundler_requirement}'`" 99 | exit 42 100 | end 101 | 102 | def activation_error_handling 103 | yield 104 | nil 105 | rescue StandardError, LoadError => e 106 | e 107 | end 108 | end 109 | 110 | m.load_bundler! 111 | 112 | if m.invoked_as_script? 113 | load Gem.bin_path("bundler", "bundle") 114 | end 115 | -------------------------------------------------------------------------------- /spec/railsapps/rails_71/bin/rails: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | APP_PATH = File.expand_path("../config/application", __dir__) 3 | require_relative "../config/boot" 4 | require "rails/commands" 5 | -------------------------------------------------------------------------------- /spec/railsapps/rails_71/bin/rake: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require_relative "../config/boot" 3 | require "rake" 4 | Rake.application.run 5 | -------------------------------------------------------------------------------- /spec/railsapps/rails_71/bin/setup: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require "fileutils" 3 | 4 | # path to your application root. 5 | APP_ROOT = File.expand_path("..", __dir__) 6 | 7 | def system!(*args) 8 | system(*args) || abort("\n== Command #{args} failed ==") 9 | end 10 | 11 | FileUtils.chdir APP_ROOT do 12 | # This script is a way to set up or update your development environment automatically. 13 | # This script is idempotent, so that you can run it at any time and get an expectable outcome. 14 | # Add necessary setup steps to this file. 15 | 16 | puts "== Installing dependencies ==" 17 | system! "gem install bundler --conservative" 18 | system("bundle check") || system!("bundle install") 19 | 20 | puts "\n== Removing old logs and tempfiles ==" 21 | system! "bin/rails log:clear tmp:clear" 22 | 23 | puts "\n== Restarting application server ==" 24 | system! "bin/rails restart" 25 | end 26 | -------------------------------------------------------------------------------- /spec/railsapps/rails_71/config.ru: -------------------------------------------------------------------------------- 1 | # This file is used by Rack-based servers to start the application. 2 | 3 | require_relative "config/environment" 4 | 5 | run Rails.application 6 | Rails.application.load_server 7 | -------------------------------------------------------------------------------- /spec/railsapps/rails_71/config/application.rb: -------------------------------------------------------------------------------- 1 | require_relative "boot" 2 | 3 | require "rails" 4 | # Pick the frameworks you want: 5 | # require "active_model/railtie" 6 | # require "active_job/railtie" 7 | # require "active_record/railtie" 8 | # require "active_storage/engine" 9 | require "action_controller/railtie" 10 | require "action_mailer/railtie" 11 | # require "action_mailbox/engine" 12 | # require "action_text/engine" 13 | require "action_view/railtie" 14 | # require "action_cable/engine" 15 | require "sprockets/railtie" 16 | # require "rails/test_unit/railtie" 17 | 18 | # Require the gems listed in Gemfile, including any gems 19 | # you've limited to :test, :development, or :production. 20 | Bundler.require(*Rails.groups) 21 | 22 | module Rails70 23 | class Application < Rails::Application 24 | # Initialize configuration defaults for originally generated Rails version. 25 | config.load_defaults 7.1 26 | 27 | # Configuration for the application, engines, and railties goes here. 28 | # 29 | # These settings can be overridden in specific environments using the files 30 | # in config/environments, which are processed later. 31 | # 32 | # config.time_zone = "Central Time (US & Canada)" 33 | # config.eager_load_paths << Rails.root.join("extras") 34 | config.roadie.url_options = {host: "example.app.org"} 35 | config.action_view.preload_links_header = false 36 | end 37 | end 38 | -------------------------------------------------------------------------------- /spec/railsapps/rails_71/config/boot.rb: -------------------------------------------------------------------------------- 1 | ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __dir__) 2 | 3 | require "bundler/setup" # Set up gems listed in the Gemfile. 4 | require "bootsnap/setup" # Speed up boot time by caching expensive operations. 5 | -------------------------------------------------------------------------------- /spec/railsapps/rails_71/config/environment.rb: -------------------------------------------------------------------------------- 1 | # Load the Rails application. 2 | require_relative "application" 3 | 4 | # Initialize the Rails application. 5 | Rails.application.initialize! 6 | -------------------------------------------------------------------------------- /spec/railsapps/rails_71/config/environments/development.rb: -------------------------------------------------------------------------------- 1 | require "active_support/core_ext/integer/time" 2 | 3 | Rails.application.configure do 4 | # Settings specified here will take precedence over those in config/application.rb. 5 | 6 | # In the development environment your application's code is reloaded any time 7 | # it changes. This slows down response time but is perfect for development 8 | # since you don't have to restart the web server when you make code changes. 9 | config.cache_classes = false 10 | 11 | # Do not eager load code on boot. 12 | config.eager_load = false 13 | 14 | # Show full error reports. 15 | config.consider_all_requests_local = true 16 | 17 | # Enable/disable caching. By default caching is disabled. 18 | # Run rails dev:cache to toggle caching. 19 | if Rails.root.join("tmp/caching-dev.txt").exist? 20 | config.action_controller.perform_caching = true 21 | config.action_controller.enable_fragment_cache_logging = true 22 | 23 | config.cache_store = :memory_store 24 | config.public_file_server.headers = { 25 | "Cache-Control" => "public, max-age=#{2.days.to_i}" 26 | } 27 | else 28 | config.action_controller.perform_caching = false 29 | 30 | config.cache_store = :null_store 31 | end 32 | 33 | # Don't care if the mailer can't send. 34 | config.action_mailer.raise_delivery_errors = false 35 | 36 | config.action_mailer.perform_caching = false 37 | 38 | # Print deprecation notices to the Rails logger. 39 | config.active_support.deprecation = :log 40 | 41 | # Raise exceptions for disallowed deprecations. 42 | config.active_support.disallowed_deprecation = :raise 43 | 44 | # Tell Active Support which deprecation messages to disallow. 45 | config.active_support.disallowed_deprecation_warnings = [] 46 | 47 | # Suppress logger output for asset requests. 48 | config.assets.quiet = true 49 | 50 | # Raises error for missing translations. 51 | # config.i18n.raise_on_missing_translations = true 52 | 53 | # Annotate rendered view with file names. 54 | # config.action_view.annotate_rendered_view_with_filenames = true 55 | 56 | # Uncomment if you wish to allow Action Cable access from any origin. 57 | # config.action_cable.disable_request_forgery_protection = true 58 | end 59 | -------------------------------------------------------------------------------- /spec/railsapps/rails_71/config/initializers/assets.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Version of your assets, change this if you want to expire all your assets. 4 | Rails.application.config.assets.version = "1.0" 5 | 6 | # Add additional assets to the asset load path. 7 | # Rails.application.config.assets.paths << Emoji.images_path 8 | 9 | # Precompile additional assets. 10 | # application.js, application.css, and all non-JS/CSS in the app/assets 11 | # folder are already added. 12 | # Rails.application.config.assets.precompile += %w( admin.js admin.css ) 13 | Rails.application.config.assets.precompile += %w[email.css] 14 | -------------------------------------------------------------------------------- /spec/railsapps/rails_71/config/initializers/backtrace_silencers.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # You can add backtrace silencers for libraries that you're using but don't wish to see in your backtraces. 4 | # Rails.backtrace_cleaner.add_silencer { |line| /my_noisy_library/.match?(line) } 5 | 6 | # You can also remove all the silencers if you're trying to debug a problem that might stem from framework code 7 | # by setting BACKTRACE=1 before calling your invocation, like "BACKTRACE=1 ./bin/rails runner 'MyClass.perform'". 8 | Rails.backtrace_cleaner.remove_silencers! if ENV["BACKTRACE"] 9 | -------------------------------------------------------------------------------- /spec/railsapps/rails_71/config/initializers/content_security_policy.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Define an application-wide content security policy 4 | # For further information see the following documentation 5 | # https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy 6 | 7 | # Rails.application.config.content_security_policy do |policy| 8 | # policy.default_src :self, :https 9 | # policy.font_src :self, :https, :data 10 | # policy.img_src :self, :https, :data 11 | # policy.object_src :none 12 | # policy.script_src :self, :https 13 | # policy.style_src :self, :https 14 | # # Specify URI for violation reports 15 | # # policy.report_uri "/csp-violation-report-endpoint" 16 | # end 17 | 18 | # If you are using UJS then enable automatic nonce generation 19 | # Rails.application.config.content_security_policy_nonce_generator = -> request { SecureRandom.base64(16) } 20 | 21 | # Set the nonce only to specific directives 22 | # Rails.application.config.content_security_policy_nonce_directives = %w(script-src) 23 | 24 | # Report CSP violations to a specified URI 25 | # For further information see the following documentation: 26 | # https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy-Report-Only 27 | # Rails.application.config.content_security_policy_report_only = true 28 | -------------------------------------------------------------------------------- /spec/railsapps/rails_71/config/initializers/filter_parameter_logging.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Configure sensitive parameters which will be filtered from the log file. 4 | Rails.application.config.filter_parameters += [ 5 | :passw, :secret, :token, :_key, :crypt, :salt, :certificate, :otp, :ssn 6 | ] 7 | -------------------------------------------------------------------------------- /spec/railsapps/rails_71/config/initializers/inflections.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Add new inflection rules using the following format. Inflections 4 | # are locale specific, and you may define rules for as many different 5 | # locales as you wish. All of these examples are active by default: 6 | # ActiveSupport::Inflector.inflections(:en) do |inflect| 7 | # inflect.plural /^(ox)$/i, "\\1en" 8 | # inflect.singular /^(ox)en/i, "\\1" 9 | # inflect.irregular "person", "people" 10 | # inflect.uncountable %w( fish sheep ) 11 | # end 12 | 13 | # These inflection rules are supported but not enabled by default: 14 | # ActiveSupport::Inflector.inflections(:en) do |inflect| 15 | # inflect.acronym "RESTful" 16 | # end 17 | -------------------------------------------------------------------------------- /spec/railsapps/rails_71/config/initializers/mime_types.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Add new mime types for use in respond_to blocks: 4 | # Mime::Type.register "text/richtext", :rtf 5 | -------------------------------------------------------------------------------- /spec/railsapps/rails_71/config/initializers/permissions_policy.rb: -------------------------------------------------------------------------------- 1 | # Define an application-wide HTTP permissions policy. For further 2 | # information see https://developers.google.com/web/updates/2018/06/feature-policy 3 | # 4 | # Rails.application.config.permissions_policy do |f| 5 | # f.camera :none 6 | # f.gyroscope :none 7 | # f.microphone :none 8 | # f.usb :none 9 | # f.fullscreen :self 10 | # f.payment :self, "https://secure.example.com" 11 | # end 12 | -------------------------------------------------------------------------------- /spec/railsapps/rails_71/config/initializers/wrap_parameters.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # This file contains settings for ActionController::ParamsWrapper which 4 | # is enabled by default. 5 | 6 | # Enable parameter wrapping for JSON. You can disable this by setting :format to an empty array. 7 | ActiveSupport.on_load(:action_controller) do 8 | wrap_parameters format: [:json] 9 | end 10 | -------------------------------------------------------------------------------- /spec/railsapps/rails_71/config/routes.rb: -------------------------------------------------------------------------------- 1 | Rails.application.routes.draw do 2 | # For details on the DSL available within this file, see https://guides.rubyonrails.org/routing.html 3 | 4 | # Almost every application defines a route for the root path ("/") at the top of this file. 5 | # root "articles#index" 6 | end 7 | -------------------------------------------------------------------------------- /spec/railsapps/rails_71_with_propshaft/Gemfile: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | source "https://rubygems.org" 4 | 5 | # Bundle edge Rails instead: gem "rails", github: "rails/rails", branch: "main" 6 | gem "rails", "~> 7.1.0" 7 | 8 | # Reduces boot times through caching; required in config/boot.rb 9 | gem "bootsnap", ">= 1.4.4", require: false 10 | gem "propshaft" 11 | gem "roadie-rails", path: "../../.." 12 | -------------------------------------------------------------------------------- /spec/railsapps/rails_71_with_propshaft/Rakefile: -------------------------------------------------------------------------------- 1 | # Add your own tasks in files placed in lib/tasks ending in .rake, 2 | # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake. 3 | 4 | require_relative "config/application" 5 | 6 | Rails.application.load_tasks 7 | -------------------------------------------------------------------------------- /spec/railsapps/rails_71_with_propshaft/app/assets/builds/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mange/roadie-rails/117b2567ad6aa4cbf1d1fc0a470f4f0ac756e2db/spec/railsapps/rails_71_with_propshaft/app/assets/builds/.gitkeep -------------------------------------------------------------------------------- /spec/railsapps/rails_71_with_propshaft/app/assets/images/rails.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mange/roadie-rails/117b2567ad6aa4cbf1d1fc0a470f4f0ac756e2db/spec/railsapps/rails_71_with_propshaft/app/assets/images/rails.png -------------------------------------------------------------------------------- /spec/railsapps/rails_71_with_propshaft/app/assets/stylesheets/email.css: -------------------------------------------------------------------------------- 1 | body { background-color: green; } 2 | .image { background: url("/rails.png"); } 3 | -------------------------------------------------------------------------------- /spec/railsapps/rails_71_with_propshaft/app/mailers/auto_mailer.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | class AutoMailer < ActionMailer::Base 4 | include Roadie::Rails::Automatic 5 | 6 | default from: "john@example.com" 7 | 8 | def normal_email 9 | generate_email 10 | end 11 | 12 | def disabled_email 13 | generate_email 14 | end 15 | 16 | private 17 | 18 | def roadie_options 19 | unless /disabled/.match?(action_name) 20 | super.combine(url_options: {protocol: "https"}) 21 | end 22 | end 23 | 24 | def generate_email 25 | mail(to: "example@example.org", subject: "Notification for you") do |format| 26 | format.html { render :normal_email } 27 | format.text { render :normal_email } 28 | end 29 | end 30 | end 31 | -------------------------------------------------------------------------------- /spec/railsapps/rails_71_with_propshaft/app/mailers/mailer.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | class Mailer < ActionMailer::Base 4 | include Roadie::Rails::Mailer 5 | 6 | default from: "john@example.com" 7 | 8 | def normal_email 9 | roadie_mail(to: "example@example.org", subject: "Notification for you") do |format| 10 | format.html 11 | format.text 12 | end 13 | end 14 | 15 | private 16 | 17 | def roadie_options 18 | super.combine(url_options: {protocol: "https"}) 19 | end 20 | end 21 | -------------------------------------------------------------------------------- /spec/railsapps/rails_71_with_propshaft/app/views/auto_mailer/normal_email.html.erb: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | <%= stylesheet_link_tag "email" %> 6 | 7 | 8 |

Normal email

9 |
10 | 11 | 12 | -------------------------------------------------------------------------------- /spec/railsapps/rails_71_with_propshaft/app/views/auto_mailer/normal_email.text: -------------------------------------------------------------------------------- 1 | Normal email 2 | -------------------------------------------------------------------------------- /spec/railsapps/rails_71_with_propshaft/app/views/mailer/normal_email.html.erb: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | <%= stylesheet_link_tag "email" %> 6 | 7 | 8 |

Normal email

9 |
10 | 11 | 12 | -------------------------------------------------------------------------------- /spec/railsapps/rails_71_with_propshaft/app/views/mailer/normal_email.text: -------------------------------------------------------------------------------- 1 | Normal email 2 | -------------------------------------------------------------------------------- /spec/railsapps/rails_71_with_propshaft/bin/bundle: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # frozen_string_literal: true 3 | 4 | # 5 | # This file was generated by Bundler. 6 | # 7 | # The application 'bundle' is installed as part of a gem, and 8 | # this file is here to facilitate running it. 9 | # 10 | 11 | require "rubygems" 12 | 13 | m = Module.new do 14 | module_function 15 | 16 | def invoked_as_script? 17 | File.expand_path($0) == File.expand_path(__FILE__) 18 | end 19 | 20 | def env_var_version 21 | ENV["BUNDLER_VERSION"] 22 | end 23 | 24 | def cli_arg_version 25 | return unless invoked_as_script? # don't want to hijack other binstubs 26 | return unless "update".start_with?(ARGV.first || " ") # must be running `bundle update` 27 | bundler_version = nil 28 | update_index = nil 29 | ARGV.each_with_index do |a, i| 30 | if update_index && update_index.succ == i && a =~ Gem::Version::ANCHORED_VERSION_PATTERN 31 | bundler_version = a 32 | end 33 | next unless a =~ /\A--bundler(?:[= ](#{Gem::Version::VERSION_PATTERN}))?\z/o 34 | bundler_version = $1 35 | update_index = i 36 | end 37 | bundler_version 38 | end 39 | 40 | def gemfile 41 | gemfile = ENV["BUNDLE_GEMFILE"] 42 | return gemfile if gemfile && !gemfile.empty? 43 | 44 | File.expand_path("../../Gemfile", __FILE__) 45 | end 46 | 47 | def lockfile 48 | lockfile = 49 | case File.basename(gemfile) 50 | when "gems.rb" then gemfile.sub(/\.rb$/, gemfile) 51 | else "#{gemfile}.lock" 52 | end 53 | File.expand_path(lockfile) 54 | end 55 | 56 | def lockfile_version 57 | return unless File.file?(lockfile) 58 | lockfile_contents = File.read(lockfile) 59 | return unless lockfile_contents =~ /\n\nBUNDLED WITH\n\s{2,}(#{Gem::Version::VERSION_PATTERN})\n/o 60 | Regexp.last_match(1) 61 | end 62 | 63 | def bundler_requirement 64 | @bundler_requirement ||= 65 | env_var_version || cli_arg_version || 66 | bundler_requirement_for(lockfile_version) 67 | end 68 | 69 | def bundler_requirement_for(version) 70 | return "#{Gem::Requirement.default}.a" unless version 71 | 72 | bundler_gem_version = Gem::Version.new(version) 73 | 74 | requirement = bundler_gem_version.approximate_recommendation 75 | 76 | return requirement unless Gem::Version.new(Gem::VERSION) < Gem::Version.new("2.7.0") 77 | 78 | requirement += ".a" if bundler_gem_version.prerelease? 79 | 80 | requirement 81 | end 82 | 83 | def load_bundler! 84 | ENV["BUNDLE_GEMFILE"] ||= gemfile 85 | 86 | activate_bundler 87 | end 88 | 89 | def activate_bundler 90 | gem_error = activation_error_handling do 91 | gem "bundler", bundler_requirement 92 | end 93 | return if gem_error.nil? 94 | require_error = activation_error_handling do 95 | require "bundler/version" 96 | end 97 | return if require_error.nil? && Gem::Requirement.new(bundler_requirement).satisfied_by?(Gem::Version.new(Bundler::VERSION)) 98 | warn "Activating bundler (#{bundler_requirement}) failed:\n#{gem_error.message}\n\nTo install the version of bundler this project requires, run `gem install bundler -v '#{bundler_requirement}'`" 99 | exit 42 100 | end 101 | 102 | def activation_error_handling 103 | yield 104 | nil 105 | rescue StandardError, LoadError => e 106 | e 107 | end 108 | end 109 | 110 | m.load_bundler! 111 | 112 | if m.invoked_as_script? 113 | load Gem.bin_path("bundler", "bundle") 114 | end 115 | -------------------------------------------------------------------------------- /spec/railsapps/rails_71_with_propshaft/bin/rails: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | APP_PATH = File.expand_path("../config/application", __dir__) 3 | require_relative "../config/boot" 4 | require "rails/commands" 5 | -------------------------------------------------------------------------------- /spec/railsapps/rails_71_with_propshaft/bin/rake: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require_relative "../config/boot" 3 | require "rake" 4 | Rake.application.run 5 | -------------------------------------------------------------------------------- /spec/railsapps/rails_71_with_propshaft/bin/setup: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require "fileutils" 3 | 4 | # path to your application root. 5 | APP_ROOT = File.expand_path("..", __dir__) 6 | 7 | def system!(*args) 8 | system(*args) || abort("\n== Command #{args} failed ==") 9 | end 10 | 11 | FileUtils.chdir APP_ROOT do 12 | # This script is a way to set up or update your development environment automatically. 13 | # This script is idempotent, so that you can run it at any time and get an expectable outcome. 14 | # Add necessary setup steps to this file. 15 | 16 | puts "== Installing dependencies ==" 17 | system! "gem install bundler --conservative" 18 | system("bundle check") || system!("bundle install") 19 | 20 | puts "\n== Removing old logs and tempfiles ==" 21 | system! "bin/rails log:clear tmp:clear" 22 | 23 | puts "\n== Restarting application server ==" 24 | system! "bin/rails restart" 25 | end 26 | -------------------------------------------------------------------------------- /spec/railsapps/rails_71_with_propshaft/config.ru: -------------------------------------------------------------------------------- 1 | # This file is used by Rack-based servers to start the application. 2 | 3 | require_relative "config/environment" 4 | 5 | run Rails.application 6 | Rails.application.load_server 7 | -------------------------------------------------------------------------------- /spec/railsapps/rails_71_with_propshaft/config/application.rb: -------------------------------------------------------------------------------- 1 | require_relative "boot" 2 | 3 | require "rails" 4 | # Pick the frameworks you want: 5 | # require "active_model/railtie" 6 | # require "active_job/railtie" 7 | # require "active_record/railtie" 8 | # require "active_storage/engine" 9 | require "action_controller/railtie" 10 | require "action_mailer/railtie" 11 | # require "action_mailbox/engine" 12 | # require "action_text/engine" 13 | require "action_view/railtie" 14 | # require "action_cable/engine" 15 | # require "rails/test_unit/railtie" 16 | 17 | # Require the gems listed in Gemfile, including any gems 18 | # you've limited to :test, :development, or :production. 19 | Bundler.require(*Rails.groups) 20 | require "propshaft" 21 | 22 | module Rails70 23 | class Application < Rails::Application 24 | # Initialize configuration defaults for originally generated Rails version. 25 | config.load_defaults 7.1 26 | 27 | # Configuration for the application, engines, and railties goes here. 28 | # 29 | # These settings can be overridden in specific environments using the files 30 | # in config/environments, which are processed later. 31 | # 32 | # config.time_zone = "Central Time (US & Canada)" 33 | # config.eager_load_paths << Rails.root.join("extras") 34 | config.roadie.url_options = {host: "example.app.org"} 35 | config.action_view.preload_links_header = false 36 | end 37 | end 38 | -------------------------------------------------------------------------------- /spec/railsapps/rails_71_with_propshaft/config/boot.rb: -------------------------------------------------------------------------------- 1 | ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __dir__) 2 | 3 | require "bundler/setup" # Set up gems listed in the Gemfile. 4 | require "bootsnap/setup" # Speed up boot time by caching expensive operations. 5 | -------------------------------------------------------------------------------- /spec/railsapps/rails_71_with_propshaft/config/environment.rb: -------------------------------------------------------------------------------- 1 | # Load the Rails application. 2 | require_relative "application" 3 | 4 | # Initialize the Rails application. 5 | Rails.application.initialize! 6 | -------------------------------------------------------------------------------- /spec/railsapps/rails_71_with_propshaft/config/environments/development.rb: -------------------------------------------------------------------------------- 1 | require "active_support/core_ext/integer/time" 2 | 3 | Rails.application.configure do 4 | # Settings specified here will take precedence over those in config/application.rb. 5 | 6 | # In the development environment your application's code is reloaded any time 7 | # it changes. This slows down response time but is perfect for development 8 | # since you don't have to restart the web server when you make code changes. 9 | config.cache_classes = false 10 | 11 | # Do not eager load code on boot. 12 | config.eager_load = false 13 | 14 | # Show full error reports. 15 | config.consider_all_requests_local = true 16 | 17 | # Enable/disable caching. By default caching is disabled. 18 | # Run rails dev:cache to toggle caching. 19 | if Rails.root.join("tmp/caching-dev.txt").exist? 20 | config.action_controller.perform_caching = true 21 | config.action_controller.enable_fragment_cache_logging = true 22 | 23 | config.cache_store = :memory_store 24 | config.public_file_server.headers = { 25 | "Cache-Control" => "public, max-age=#{2.days.to_i}" 26 | } 27 | else 28 | config.action_controller.perform_caching = false 29 | 30 | config.cache_store = :null_store 31 | end 32 | 33 | # Don't care if the mailer can't send. 34 | config.action_mailer.raise_delivery_errors = false 35 | 36 | config.action_mailer.perform_caching = false 37 | 38 | # Print deprecation notices to the Rails logger. 39 | config.active_support.deprecation = :log 40 | 41 | # Raise exceptions for disallowed deprecations. 42 | config.active_support.disallowed_deprecation = :raise 43 | 44 | # Tell Active Support which deprecation messages to disallow. 45 | config.active_support.disallowed_deprecation_warnings = [] 46 | 47 | # Suppress logger output for asset requests. 48 | config.assets.quiet = true 49 | 50 | # Raises error for missing translations. 51 | # config.i18n.raise_on_missing_translations = true 52 | 53 | # Annotate rendered view with file names. 54 | # config.action_view.annotate_rendered_view_with_filenames = true 55 | 56 | # Uncomment if you wish to allow Action Cable access from any origin. 57 | # config.action_cable.disable_request_forgery_protection = true 58 | end 59 | -------------------------------------------------------------------------------- /spec/railsapps/rails_71_with_propshaft/config/initializers/backtrace_silencers.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # You can add backtrace silencers for libraries that you're using but don't wish to see in your backtraces. 4 | # Rails.backtrace_cleaner.add_silencer { |line| /my_noisy_library/.match?(line) } 5 | 6 | # You can also remove all the silencers if you're trying to debug a problem that might stem from framework code 7 | # by setting BACKTRACE=1 before calling your invocation, like "BACKTRACE=1 ./bin/rails runner 'MyClass.perform'". 8 | Rails.backtrace_cleaner.remove_silencers! if ENV["BACKTRACE"] 9 | -------------------------------------------------------------------------------- /spec/railsapps/rails_71_with_propshaft/config/initializers/content_security_policy.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Define an application-wide content security policy 4 | # For further information see the following documentation 5 | # https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy 6 | 7 | # Rails.application.config.content_security_policy do |policy| 8 | # policy.default_src :self, :https 9 | # policy.font_src :self, :https, :data 10 | # policy.img_src :self, :https, :data 11 | # policy.object_src :none 12 | # policy.script_src :self, :https 13 | # policy.style_src :self, :https 14 | # # Specify URI for violation reports 15 | # # policy.report_uri "/csp-violation-report-endpoint" 16 | # end 17 | 18 | # If you are using UJS then enable automatic nonce generation 19 | # Rails.application.config.content_security_policy_nonce_generator = -> request { SecureRandom.base64(16) } 20 | 21 | # Set the nonce only to specific directives 22 | # Rails.application.config.content_security_policy_nonce_directives = %w(script-src) 23 | 24 | # Report CSP violations to a specified URI 25 | # For further information see the following documentation: 26 | # https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy-Report-Only 27 | # Rails.application.config.content_security_policy_report_only = true 28 | -------------------------------------------------------------------------------- /spec/railsapps/rails_71_with_propshaft/config/initializers/filter_parameter_logging.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Configure sensitive parameters which will be filtered from the log file. 4 | Rails.application.config.filter_parameters += [ 5 | :passw, :secret, :token, :_key, :crypt, :salt, :certificate, :otp, :ssn 6 | ] 7 | -------------------------------------------------------------------------------- /spec/railsapps/rails_71_with_propshaft/config/initializers/inflections.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Add new inflection rules using the following format. Inflections 4 | # are locale specific, and you may define rules for as many different 5 | # locales as you wish. All of these examples are active by default: 6 | # ActiveSupport::Inflector.inflections(:en) do |inflect| 7 | # inflect.plural /^(ox)$/i, "\\1en" 8 | # inflect.singular /^(ox)en/i, "\\1" 9 | # inflect.irregular "person", "people" 10 | # inflect.uncountable %w( fish sheep ) 11 | # end 12 | 13 | # These inflection rules are supported but not enabled by default: 14 | # ActiveSupport::Inflector.inflections(:en) do |inflect| 15 | # inflect.acronym "RESTful" 16 | # end 17 | -------------------------------------------------------------------------------- /spec/railsapps/rails_71_with_propshaft/config/initializers/mime_types.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Add new mime types for use in respond_to blocks: 4 | # Mime::Type.register "text/richtext", :rtf 5 | -------------------------------------------------------------------------------- /spec/railsapps/rails_71_with_propshaft/config/initializers/permissions_policy.rb: -------------------------------------------------------------------------------- 1 | # Define an application-wide HTTP permissions policy. For further 2 | # information see https://developers.google.com/web/updates/2018/06/feature-policy 3 | # 4 | # Rails.application.config.permissions_policy do |f| 5 | # f.camera :none 6 | # f.gyroscope :none 7 | # f.microphone :none 8 | # f.usb :none 9 | # f.fullscreen :self 10 | # f.payment :self, "https://secure.example.com" 11 | # end 12 | -------------------------------------------------------------------------------- /spec/railsapps/rails_71_with_propshaft/config/initializers/wrap_parameters.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # This file contains settings for ActionController::ParamsWrapper which 4 | # is enabled by default. 5 | 6 | # Enable parameter wrapping for JSON. You can disable this by setting :format to an empty array. 7 | ActiveSupport.on_load(:action_controller) do 8 | wrap_parameters format: [:json] 9 | end 10 | -------------------------------------------------------------------------------- /spec/railsapps/rails_71_with_propshaft/config/routes.rb: -------------------------------------------------------------------------------- 1 | Rails.application.routes.draw do 2 | # For details on the DSL available within this file, see https://guides.rubyonrails.org/routing.html 3 | 4 | # Almost every application defines a route for the root path ("/") at the top of this file. 5 | # root "articles#index" 6 | end 7 | -------------------------------------------------------------------------------- /spec/railsapps/rails_80_with_propshaft/Gemfile: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | source "https://rubygems.org" 4 | 5 | # Bundle edge Rails instead: gem "rails", github: "rails/rails", branch: "main" 6 | gem "rails", "~> 8.0.0" 7 | 8 | # Reduces boot times through caching; required in config/boot.rb 9 | gem "bootsnap", ">= 1.4.4", require: false 10 | gem "propshaft" 11 | gem "roadie-rails", path: "../../.." 12 | -------------------------------------------------------------------------------- /spec/railsapps/rails_80_with_propshaft/Rakefile: -------------------------------------------------------------------------------- 1 | # Add your own tasks in files placed in lib/tasks ending in .rake, 2 | # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake. 3 | 4 | require_relative "config/application" 5 | 6 | Rails.application.load_tasks 7 | -------------------------------------------------------------------------------- /spec/railsapps/rails_80_with_propshaft/app/assets/builds/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mange/roadie-rails/117b2567ad6aa4cbf1d1fc0a470f4f0ac756e2db/spec/railsapps/rails_80_with_propshaft/app/assets/builds/.gitkeep -------------------------------------------------------------------------------- /spec/railsapps/rails_80_with_propshaft/app/assets/images/rails.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mange/roadie-rails/117b2567ad6aa4cbf1d1fc0a470f4f0ac756e2db/spec/railsapps/rails_80_with_propshaft/app/assets/images/rails.png -------------------------------------------------------------------------------- /spec/railsapps/rails_80_with_propshaft/app/assets/stylesheets/email.css: -------------------------------------------------------------------------------- 1 | body { background-color: green; } 2 | .image { background: url("/rails.png"); } 3 | -------------------------------------------------------------------------------- /spec/railsapps/rails_80_with_propshaft/app/mailers/auto_mailer.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | class AutoMailer < ActionMailer::Base 4 | include Roadie::Rails::Automatic 5 | 6 | default from: "john@example.com" 7 | 8 | def normal_email 9 | generate_email 10 | end 11 | 12 | def disabled_email 13 | generate_email 14 | end 15 | 16 | private 17 | 18 | def roadie_options 19 | unless /disabled/.match?(action_name) 20 | super.combine(url_options: {protocol: "https"}) 21 | end 22 | end 23 | 24 | def generate_email 25 | mail(to: "example@example.org", subject: "Notification for you") do |format| 26 | format.html { render :normal_email } 27 | format.text { render :normal_email } 28 | end 29 | end 30 | end 31 | -------------------------------------------------------------------------------- /spec/railsapps/rails_80_with_propshaft/app/mailers/mailer.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | class Mailer < ActionMailer::Base 4 | include Roadie::Rails::Mailer 5 | 6 | default from: "john@example.com" 7 | 8 | def normal_email 9 | roadie_mail(to: "example@example.org", subject: "Notification for you") do |format| 10 | format.html 11 | format.text 12 | end 13 | end 14 | 15 | private 16 | 17 | def roadie_options 18 | super.combine(url_options: {protocol: "https"}) 19 | end 20 | end 21 | -------------------------------------------------------------------------------- /spec/railsapps/rails_80_with_propshaft/app/views/auto_mailer/normal_email.html.erb: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | <%= stylesheet_link_tag "email" %> 6 | 7 | 8 |

Normal email

9 |
10 | 11 | 12 | -------------------------------------------------------------------------------- /spec/railsapps/rails_80_with_propshaft/app/views/auto_mailer/normal_email.text: -------------------------------------------------------------------------------- 1 | Normal email 2 | -------------------------------------------------------------------------------- /spec/railsapps/rails_80_with_propshaft/app/views/mailer/normal_email.html.erb: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | <%= stylesheet_link_tag "email" %> 6 | 7 | 8 |

Normal email

9 |
10 | 11 | 12 | -------------------------------------------------------------------------------- /spec/railsapps/rails_80_with_propshaft/app/views/mailer/normal_email.text: -------------------------------------------------------------------------------- 1 | Normal email 2 | -------------------------------------------------------------------------------- /spec/railsapps/rails_80_with_propshaft/bin/bundle: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # frozen_string_literal: true 3 | 4 | # 5 | # This file was generated by Bundler. 6 | # 7 | # The application 'bundle' is installed as part of a gem, and 8 | # this file is here to facilitate running it. 9 | # 10 | 11 | require "rubygems" 12 | 13 | m = Module.new do 14 | module_function 15 | 16 | def invoked_as_script? 17 | File.expand_path($0) == File.expand_path(__FILE__) 18 | end 19 | 20 | def env_var_version 21 | ENV["BUNDLER_VERSION"] 22 | end 23 | 24 | def cli_arg_version 25 | return unless invoked_as_script? # don't want to hijack other binstubs 26 | return unless "update".start_with?(ARGV.first || " ") # must be running `bundle update` 27 | bundler_version = nil 28 | update_index = nil 29 | ARGV.each_with_index do |a, i| 30 | if update_index && update_index.succ == i && a =~ Gem::Version::ANCHORED_VERSION_PATTERN 31 | bundler_version = a 32 | end 33 | next unless a =~ /\A--bundler(?:[= ](#{Gem::Version::VERSION_PATTERN}))?\z/o 34 | bundler_version = $1 35 | update_index = i 36 | end 37 | bundler_version 38 | end 39 | 40 | def gemfile 41 | gemfile = ENV["BUNDLE_GEMFILE"] 42 | return gemfile if gemfile && !gemfile.empty? 43 | 44 | File.expand_path("../../Gemfile", __FILE__) 45 | end 46 | 47 | def lockfile 48 | lockfile = 49 | case File.basename(gemfile) 50 | when "gems.rb" then gemfile.sub(/\.rb$/, gemfile) 51 | else "#{gemfile}.lock" 52 | end 53 | File.expand_path(lockfile) 54 | end 55 | 56 | def lockfile_version 57 | return unless File.file?(lockfile) 58 | lockfile_contents = File.read(lockfile) 59 | return unless lockfile_contents =~ /\n\nBUNDLED WITH\n\s{2,}(#{Gem::Version::VERSION_PATTERN})\n/o 60 | Regexp.last_match(1) 61 | end 62 | 63 | def bundler_requirement 64 | @bundler_requirement ||= 65 | env_var_version || cli_arg_version || 66 | bundler_requirement_for(lockfile_version) 67 | end 68 | 69 | def bundler_requirement_for(version) 70 | return "#{Gem::Requirement.default}.a" unless version 71 | 72 | bundler_gem_version = Gem::Version.new(version) 73 | 74 | requirement = bundler_gem_version.approximate_recommendation 75 | 76 | return requirement unless Gem::Version.new(Gem::VERSION) < Gem::Version.new("2.7.0") 77 | 78 | requirement += ".a" if bundler_gem_version.prerelease? 79 | 80 | requirement 81 | end 82 | 83 | def load_bundler! 84 | ENV["BUNDLE_GEMFILE"] ||= gemfile 85 | 86 | activate_bundler 87 | end 88 | 89 | def activate_bundler 90 | gem_error = activation_error_handling do 91 | gem "bundler", bundler_requirement 92 | end 93 | return if gem_error.nil? 94 | require_error = activation_error_handling do 95 | require "bundler/version" 96 | end 97 | return if require_error.nil? && Gem::Requirement.new(bundler_requirement).satisfied_by?(Gem::Version.new(Bundler::VERSION)) 98 | warn "Activating bundler (#{bundler_requirement}) failed:\n#{gem_error.message}\n\nTo install the version of bundler this project requires, run `gem install bundler -v '#{bundler_requirement}'`" 99 | exit 42 100 | end 101 | 102 | def activation_error_handling 103 | yield 104 | nil 105 | rescue StandardError, LoadError => e 106 | e 107 | end 108 | end 109 | 110 | m.load_bundler! 111 | 112 | if m.invoked_as_script? 113 | load Gem.bin_path("bundler", "bundle") 114 | end 115 | -------------------------------------------------------------------------------- /spec/railsapps/rails_80_with_propshaft/bin/rails: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | APP_PATH = File.expand_path("../config/application", __dir__) 3 | require_relative "../config/boot" 4 | require "rails/commands" 5 | -------------------------------------------------------------------------------- /spec/railsapps/rails_80_with_propshaft/bin/rake: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require_relative "../config/boot" 3 | require "rake" 4 | Rake.application.run 5 | -------------------------------------------------------------------------------- /spec/railsapps/rails_80_with_propshaft/bin/setup: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require "fileutils" 3 | 4 | # path to your application root. 5 | APP_ROOT = File.expand_path("..", __dir__) 6 | 7 | def system!(*args) 8 | system(*args) || abort("\n== Command #{args} failed ==") 9 | end 10 | 11 | FileUtils.chdir APP_ROOT do 12 | # This script is a way to set up or update your development environment automatically. 13 | # This script is idempotent, so that you can run it at any time and get an expectable outcome. 14 | # Add necessary setup steps to this file. 15 | 16 | puts "== Installing dependencies ==" 17 | system! "gem install bundler --conservative" 18 | system("bundle check") || system!("bundle install") 19 | 20 | puts "\n== Removing old logs and tempfiles ==" 21 | system! "bin/rails log:clear tmp:clear" 22 | 23 | puts "\n== Restarting application server ==" 24 | system! "bin/rails restart" 25 | end 26 | -------------------------------------------------------------------------------- /spec/railsapps/rails_80_with_propshaft/config.ru: -------------------------------------------------------------------------------- 1 | # This file is used by Rack-based servers to start the application. 2 | 3 | require_relative "config/environment" 4 | 5 | run Rails.application 6 | Rails.application.load_server 7 | -------------------------------------------------------------------------------- /spec/railsapps/rails_80_with_propshaft/config/application.rb: -------------------------------------------------------------------------------- 1 | require_relative "boot" 2 | 3 | require "rails" 4 | # Pick the frameworks you want: 5 | # require "active_model/railtie" 6 | # require "active_job/railtie" 7 | # require "active_record/railtie" 8 | # require "active_storage/engine" 9 | require "action_controller/railtie" 10 | require "action_mailer/railtie" 11 | # require "action_mailbox/engine" 12 | # require "action_text/engine" 13 | require "action_view/railtie" 14 | # require "action_cable/engine" 15 | # require "rails/test_unit/railtie" 16 | 17 | # Require the gems listed in Gemfile, including any gems 18 | # you've limited to :test, :development, or :production. 19 | Bundler.require(*Rails.groups) 20 | require "propshaft" 21 | 22 | module Rails80 23 | class Application < Rails::Application 24 | # Initialize configuration defaults for originally generated Rails version. 25 | config.load_defaults 8.0 26 | 27 | # Configuration for the application, engines, and railties goes here. 28 | # 29 | # These settings can be overridden in specific environments using the files 30 | # in config/environments, which are processed later. 31 | # 32 | # config.time_zone = "Central Time (US & Canada)" 33 | # config.eager_load_paths << Rails.root.join("extras") 34 | config.roadie.url_options = {host: "example.app.org"} 35 | config.action_view.preload_links_header = false 36 | end 37 | end 38 | -------------------------------------------------------------------------------- /spec/railsapps/rails_80_with_propshaft/config/boot.rb: -------------------------------------------------------------------------------- 1 | ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __dir__) 2 | 3 | require "bundler/setup" # Set up gems listed in the Gemfile. 4 | require "bootsnap/setup" # Speed up boot time by caching expensive operations. 5 | -------------------------------------------------------------------------------- /spec/railsapps/rails_80_with_propshaft/config/environment.rb: -------------------------------------------------------------------------------- 1 | # Load the Rails application. 2 | require_relative "application" 3 | 4 | # Initialize the Rails application. 5 | Rails.application.initialize! 6 | -------------------------------------------------------------------------------- /spec/railsapps/rails_80_with_propshaft/config/environments/development.rb: -------------------------------------------------------------------------------- 1 | require "active_support/core_ext/integer/time" 2 | 3 | Rails.application.configure do 4 | # Settings specified here will take precedence over those in config/application.rb. 5 | 6 | # In the development environment your application's code is reloaded any time 7 | # it changes. This slows down response time but is perfect for development 8 | # since you don't have to restart the web server when you make code changes. 9 | config.cache_classes = false 10 | 11 | # Do not eager load code on boot. 12 | config.eager_load = false 13 | 14 | # Show full error reports. 15 | config.consider_all_requests_local = true 16 | 17 | # Enable/disable caching. By default caching is disabled. 18 | # Run rails dev:cache to toggle caching. 19 | if Rails.root.join("tmp/caching-dev.txt").exist? 20 | config.action_controller.perform_caching = true 21 | config.action_controller.enable_fragment_cache_logging = true 22 | 23 | config.cache_store = :memory_store 24 | config.public_file_server.headers = { 25 | "Cache-Control" => "public, max-age=#{2.days.to_i}" 26 | } 27 | else 28 | config.action_controller.perform_caching = false 29 | 30 | config.cache_store = :null_store 31 | end 32 | 33 | # Don't care if the mailer can't send. 34 | config.action_mailer.raise_delivery_errors = false 35 | 36 | config.action_mailer.perform_caching = false 37 | 38 | # Print deprecation notices to the Rails logger. 39 | config.active_support.deprecation = :log 40 | 41 | # Raise exceptions for disallowed deprecations. 42 | config.active_support.disallowed_deprecation = :raise 43 | 44 | # Tell Active Support which deprecation messages to disallow. 45 | config.active_support.disallowed_deprecation_warnings = [] 46 | 47 | # Suppress logger output for asset requests. 48 | config.assets.quiet = true 49 | 50 | # Raises error for missing translations. 51 | # config.i18n.raise_on_missing_translations = true 52 | 53 | # Annotate rendered view with file names. 54 | # config.action_view.annotate_rendered_view_with_filenames = true 55 | 56 | # Uncomment if you wish to allow Action Cable access from any origin. 57 | # config.action_cable.disable_request_forgery_protection = true 58 | end 59 | -------------------------------------------------------------------------------- /spec/railsapps/rails_80_with_propshaft/config/initializers/backtrace_silencers.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # You can add backtrace silencers for libraries that you're using but don't wish to see in your backtraces. 4 | # Rails.backtrace_cleaner.add_silencer { |line| /my_noisy_library/.match?(line) } 5 | 6 | # You can also remove all the silencers if you're trying to debug a problem that might stem from framework code 7 | # by setting BACKTRACE=1 before calling your invocation, like "BACKTRACE=1 ./bin/rails runner 'MyClass.perform'". 8 | Rails.backtrace_cleaner.remove_silencers! if ENV["BACKTRACE"] 9 | -------------------------------------------------------------------------------- /spec/railsapps/rails_80_with_propshaft/config/initializers/content_security_policy.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Define an application-wide content security policy 4 | # For further information see the following documentation 5 | # https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy 6 | 7 | # Rails.application.config.content_security_policy do |policy| 8 | # policy.default_src :self, :https 9 | # policy.font_src :self, :https, :data 10 | # policy.img_src :self, :https, :data 11 | # policy.object_src :none 12 | # policy.script_src :self, :https 13 | # policy.style_src :self, :https 14 | # # Specify URI for violation reports 15 | # # policy.report_uri "/csp-violation-report-endpoint" 16 | # end 17 | 18 | # If you are using UJS then enable automatic nonce generation 19 | # Rails.application.config.content_security_policy_nonce_generator = -> request { SecureRandom.base64(16) } 20 | 21 | # Set the nonce only to specific directives 22 | # Rails.application.config.content_security_policy_nonce_directives = %w(script-src) 23 | 24 | # Report CSP violations to a specified URI 25 | # For further information see the following documentation: 26 | # https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy-Report-Only 27 | # Rails.application.config.content_security_policy_report_only = true 28 | -------------------------------------------------------------------------------- /spec/railsapps/rails_80_with_propshaft/config/initializers/filter_parameter_logging.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Configure sensitive parameters which will be filtered from the log file. 4 | Rails.application.config.filter_parameters += [ 5 | :passw, :secret, :token, :_key, :crypt, :salt, :certificate, :otp, :ssn 6 | ] 7 | -------------------------------------------------------------------------------- /spec/railsapps/rails_80_with_propshaft/config/initializers/inflections.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Add new inflection rules using the following format. Inflections 4 | # are locale specific, and you may define rules for as many different 5 | # locales as you wish. All of these examples are active by default: 6 | # ActiveSupport::Inflector.inflections(:en) do |inflect| 7 | # inflect.plural /^(ox)$/i, "\\1en" 8 | # inflect.singular /^(ox)en/i, "\\1" 9 | # inflect.irregular "person", "people" 10 | # inflect.uncountable %w( fish sheep ) 11 | # end 12 | 13 | # These inflection rules are supported but not enabled by default: 14 | # ActiveSupport::Inflector.inflections(:en) do |inflect| 15 | # inflect.acronym "RESTful" 16 | # end 17 | -------------------------------------------------------------------------------- /spec/railsapps/rails_80_with_propshaft/config/initializers/mime_types.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Add new mime types for use in respond_to blocks: 4 | # Mime::Type.register "text/richtext", :rtf 5 | -------------------------------------------------------------------------------- /spec/railsapps/rails_80_with_propshaft/config/initializers/permissions_policy.rb: -------------------------------------------------------------------------------- 1 | # Define an application-wide HTTP permissions policy. For further 2 | # information see https://developers.google.com/web/updates/2018/06/feature-policy 3 | # 4 | # Rails.application.config.permissions_policy do |f| 5 | # f.camera :none 6 | # f.gyroscope :none 7 | # f.microphone :none 8 | # f.usb :none 9 | # f.fullscreen :self 10 | # f.payment :self, "https://secure.example.com" 11 | # end 12 | -------------------------------------------------------------------------------- /spec/railsapps/rails_80_with_propshaft/config/initializers/wrap_parameters.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # This file contains settings for ActionController::ParamsWrapper which 4 | # is enabled by default. 5 | 6 | # Enable parameter wrapping for JSON. You can disable this by setting :format to an empty array. 7 | ActiveSupport.on_load(:action_controller) do 8 | wrap_parameters format: [:json] 9 | end 10 | -------------------------------------------------------------------------------- /spec/railsapps/rails_80_with_propshaft/config/routes.rb: -------------------------------------------------------------------------------- 1 | Rails.application.routes.draw do 2 | # For details on the DSL available within this file, see https://guides.rubyonrails.org/routing.html 3 | 4 | # Almost every application defines a route for the root path ("/") at the top of this file. 5 | # root "articles#index" 6 | end 7 | -------------------------------------------------------------------------------- /spec/railsapps/shared/all/app/mailers/auto_mailer.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | class AutoMailer < ActionMailer::Base 4 | include Roadie::Rails::Automatic 5 | 6 | default from: "john@example.com" 7 | 8 | def normal_email 9 | generate_email 10 | end 11 | 12 | def disabled_email 13 | generate_email 14 | end 15 | 16 | private 17 | 18 | def roadie_options 19 | unless /disabled/.match?(action_name) 20 | super.combine(url_options: {protocol: "https"}) 21 | end 22 | end 23 | 24 | def generate_email 25 | mail(to: "example@example.org", subject: "Notification for you") do |format| 26 | format.html { render :normal_email } 27 | format.text { render :normal_email } 28 | end 29 | end 30 | end 31 | -------------------------------------------------------------------------------- /spec/railsapps/shared/all/app/mailers/mailer.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | class Mailer < ActionMailer::Base 4 | include Roadie::Rails::Mailer 5 | 6 | default from: "john@example.com" 7 | 8 | def normal_email 9 | roadie_mail(to: "example@example.org", subject: "Notification for you") do |format| 10 | format.html 11 | format.text 12 | end 13 | end 14 | 15 | private 16 | 17 | def roadie_options 18 | super.combine(url_options: {protocol: "https"}) 19 | end 20 | end 21 | -------------------------------------------------------------------------------- /spec/railsapps/shared/all/app/views/auto_mailer: -------------------------------------------------------------------------------- 1 | mailer -------------------------------------------------------------------------------- /spec/railsapps/shared/all/app/views/mailer/normal_email.html.erb: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | <%= stylesheet_link_tag "email" %> 6 | 7 | 8 |

Normal email

9 |
10 | 11 | 12 | -------------------------------------------------------------------------------- /spec/railsapps/shared/all/app/views/mailer/normal_email.text: -------------------------------------------------------------------------------- 1 | Normal email 2 | -------------------------------------------------------------------------------- /spec/railsapps/shared/pipeline/app/assets/config/manifest.js: -------------------------------------------------------------------------------- 1 | //= link_tree ../images 2 | //= link_directory ../stylesheets .css 3 | -------------------------------------------------------------------------------- /spec/railsapps/shared/pipeline/app/assets/images/rails.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mange/roadie-rails/117b2567ad6aa4cbf1d1fc0a470f4f0ac756e2db/spec/railsapps/shared/pipeline/app/assets/images/rails.png -------------------------------------------------------------------------------- /spec/railsapps/shared/pipeline/app/assets/stylesheets/email.css.scss: -------------------------------------------------------------------------------- 1 | body { background-color: green; } 2 | .image { background: image-url("rails.png"); } 3 | -------------------------------------------------------------------------------- /spec/spec_helper.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require "rspec/collection_matchers" 4 | 5 | if ENV["CI"] 6 | require "simplecov" 7 | SimpleCov.start do 8 | # Only cover lib/. Omit spec/railsapps. 9 | add_filter do |src| 10 | src.filename !~ %r{/lib/roadie/rails} 11 | end 12 | end 13 | 14 | require "simplecov-cobertura" 15 | SimpleCov.formatter = SimpleCov::Formatter::CoberturaFormatter 16 | end 17 | 18 | require "roadie-rails" 19 | 20 | RSpec.configure do |config| 21 | config.run_all_when_everything_filtered = true 22 | end 23 | 24 | Dir["./spec/support/**/*.rb"].sort.each { |file| require file } 25 | -------------------------------------------------------------------------------- /spec/support/fake_mail.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require "mail" 4 | 5 | class FakeMail < Mail::Message 6 | def delivered? 7 | @delivered 8 | end 9 | 10 | def deliver 11 | @delivered = true 12 | end 13 | 14 | def deliver! 15 | @delivered = true 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /spec/support/fake_pipeline.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | class FakePipeline 4 | # Interface 5 | def [](name) 6 | @files.find { |file| file.matching_name == name } 7 | end 8 | 9 | ### Test helpers ### 10 | 11 | def initialize 12 | @files = [] 13 | end 14 | 15 | def add_asset(matching_name, path, content) 16 | @files << AssetFile.new(matching_name, path, content) 17 | end 18 | 19 | AssetFile = Struct.new(:matching_name, :pathname, :to_s) 20 | private_constant :AssetFile 21 | end 22 | -------------------------------------------------------------------------------- /spec/support/have_no_styling_matcher.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | RSpec::Matchers.define :have_no_styling do 4 | chain(:at_selector) { |selector| @selector = selector } 5 | 6 | match do |document| 7 | @selector ||= "body > *:first" 8 | styles_at_selector(document).empty? 9 | end 10 | 11 | description do 12 | "have no styles at selector #{@selector.inspect}" 13 | end 14 | 15 | failure_message do |document| 16 | "expected no styles at #{@selector.inspect} but had:\n" \ 17 | "#{styles_at_selector(document)}" 18 | end 19 | 20 | failure_message_when_negated do 21 | "expected #{@selector.inspect} to have styles" 22 | end 23 | 24 | def styles_at_selector(document) 25 | expect(document).to have_selector(@selector) 26 | document.at_css(@selector)["style"] || "" 27 | end 28 | end 29 | -------------------------------------------------------------------------------- /spec/support/have_selector_matcher.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | RSpec::Matchers.define :have_selector do |selector| 4 | match { |dom| dom.at_css selector } 5 | end 6 | -------------------------------------------------------------------------------- /spec/support/have_styling_matcher.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | RSpec::Matchers.define :have_styling do |rules| 4 | normalized_rules = StylingExpectation.new(rules) 5 | 6 | chain(:at_selector) { |selector| @selector = selector } 7 | 8 | match do |document| 9 | @selector ||= "body > *:first" 10 | normalized_rules == styles_at_selector(document) 11 | end 12 | 13 | description do 14 | "have styles #{normalized_rules.inspect} at selector #{@selector.inspect}" 15 | end 16 | 17 | failure_message do |document| 18 | "expected styles at #{@selector.inspect} to be:\n#{normalized_rules}\n" \ 19 | "but was:\n#{styles_at_selector(document)}" 20 | end 21 | 22 | failure_message_when_negated do 23 | "expected styles at #{@selector.inspect} to not be:\n#{normalized_rules}" 24 | end 25 | 26 | def styles_at_selector(document) 27 | expect(document).to have_selector(@selector) 28 | style = document.at_css(@selector)["style"] 29 | StylingExpectation.new(style || "") 30 | end 31 | end 32 | 33 | class StylingExpectation 34 | def initialize(styling) 35 | case styling 36 | when String then @rules = parse_rules(styling) 37 | when Array then @rules = styling 38 | when Hash then @rules = styling.to_a 39 | else fail "I don't understand #{styling.inspect}!" 40 | end 41 | end 42 | 43 | def ==(other) 44 | rules == other.rules 45 | end 46 | 47 | def to_s 48 | rules.to_s 49 | end 50 | 51 | protected 52 | 53 | attr_reader :rules 54 | 55 | private 56 | 57 | def parse_rules(css) 58 | css.split(";").map { |property| parse_property(property) } 59 | end 60 | 61 | def parse_property(property) 62 | rule, value = property.split(":", 2).map(&:strip) 63 | [rule, normalize_quotes(value)] 64 | end 65 | 66 | # JRuby's Nokogiri encodes quotes 67 | def normalize_quotes(string) 68 | string.gsub "%22", '"' 69 | end 70 | end 71 | -------------------------------------------------------------------------------- /spec/support/rails_app.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | class RailsApp 4 | def initialize(name, path, min_ruby_version: nil, max_ruby_version: nil, asset_pipeline: :sprockets) 5 | @name = name 6 | @path = File.expand_path("../../railsapps/#{path}", __FILE__) 7 | @max_ruby_version = max_ruby_version && Gem::Version.new(max_ruby_version) 8 | @min_ruby_version = min_ruby_version && Gem::Version.new(min_ruby_version) 9 | @asset_pipeline = asset_pipeline 10 | end 11 | 12 | def supported? 13 | minimum = @min_ruby_version || Gem::Version.new("0.0.0") 14 | maximum = @max_ruby_version || Gem::Version.new("100.0.0") 15 | version = Gem::Version.new(RUBY_VERSION) 16 | 17 | version.between?(minimum, maximum) 18 | end 19 | 20 | def with_propshaft? 21 | @asset_pipeline == :propshaft 22 | end 23 | 24 | def with_sprockets? 25 | @asset_pipeline == :sprockets 26 | end 27 | 28 | def to_s 29 | @name 30 | end 31 | 32 | def read_email(mail_name) 33 | result = run("puts Mailer.#{mail_name}.to_s") 34 | 35 | if result.strip.empty? 36 | raise "No email returned. Did the rails application crash?" 37 | end 38 | 39 | Mail.read_from_string(result) 40 | end 41 | 42 | def read_delivered_email( 43 | mail_name, 44 | options = {} 45 | ) 46 | deliver = options[:force_delivery] ? "deliver!" : "deliver" 47 | result = run(<<~RUBY) 48 | mail = AutoMailer.#{mail_name} 49 | mail.delivery_method(:test) 50 | mail.#{deliver} 51 | puts mail.to_s 52 | RUBY 53 | 54 | if result.strip.empty? 55 | raise "No email returned. Did the rails application crash?" 56 | end 57 | 58 | Mail.read_from_string(result) 59 | end 60 | 61 | def read_providers 62 | result = run(<<-RUBY).strip 63 | providers = Rails.application.config.roadie.asset_providers 64 | puts providers.map { |p| p.class.name }.join(',') 65 | RUBY 66 | raise "No output present. Did the application crash?" if result.empty? 67 | 68 | result.split(",") 69 | end 70 | 71 | def reset 72 | @extra_code = "" 73 | run_in_app_context "mkdir -p tmp" 74 | run_in_app_context "rm -rf tmp/cache" 75 | end 76 | 77 | def before_mail(code) 78 | @extra_code << "\n" << code << "\n" 79 | end 80 | 81 | private 82 | 83 | def run(code) 84 | Tempfile.open("code") do |file| 85 | file << @extra_code unless @extra_code.empty? 86 | file << code 87 | file.close 88 | run_file_in_app_context file.path 89 | end 90 | end 91 | 92 | def run_file_in_app_context(file_path) 93 | run_in_app_context "bin/rails runner #{file_path.shellescape}" 94 | end 95 | 96 | def run_in_app_context(command) 97 | Bundler.with_unbundled_env do 98 | Dir.chdir @path do 99 | IO.popen(command).read 100 | end 101 | end 102 | end 103 | end 104 | --------------------------------------------------------------------------------