├── .github └── workflows │ └── tests.yml ├── .gitignore ├── .rspec ├── Appraisals ├── CHANGELOG.md ├── Gemfile ├── LICENSE.txt ├── README.md ├── Rakefile ├── examples └── sinatras_raygun.rb ├── gemfiles ├── rails_6.gemfile ├── rails_7.gemfile └── rails_7_sidekiq_6.gemfile ├── lib ├── generators │ └── raygun │ │ └── install_generator.rb ├── raygun.rb ├── raygun │ ├── affected_user.rb │ ├── breadcrumbs.rb │ ├── breadcrumbs │ │ ├── breadcrumb.rb │ │ └── store.rb │ ├── client.rb │ ├── configuration.rb │ ├── demo_exception.rb │ ├── error.rb │ ├── error_subscriber.rb │ ├── javascript_tracker.rb │ ├── middleware │ │ ├── breadcrumbs_store_initializer.rb │ │ ├── javascript_exception_tracking.rb │ │ ├── rack_exception_interceptor.rb │ │ └── rails_insert_affected_user.rb │ ├── railtie.rb │ ├── services │ │ └── apply_whitelist_filter_to_payload.rb │ ├── sidekiq.rb │ └── version.rb ├── raygun4ruby.rb ├── resque │ └── failure │ │ └── raygun.rb └── tasks │ └── raygun.tasks ├── raygun4ruby.gemspec ├── spec ├── features │ └── javascript_spec.rb ├── rails_applications │ ├── 6.1.4 │ │ ├── Gemfile │ │ ├── README.md │ │ ├── Rakefile │ │ ├── app │ │ │ ├── assets │ │ │ │ ├── config │ │ │ │ │ └── manifest.js │ │ │ │ ├── images │ │ │ │ │ └── .keep │ │ │ │ └── stylesheets │ │ │ │ │ └── application.css │ │ │ ├── channels │ │ │ │ └── application_cable │ │ │ │ │ ├── channel.rb │ │ │ │ │ └── connection.rb │ │ │ ├── controllers │ │ │ │ ├── application_controller.rb │ │ │ │ ├── concerns │ │ │ │ │ └── .keep │ │ │ │ └── home_controller.rb │ │ │ ├── helpers │ │ │ │ └── application_helper.rb │ │ │ ├── javascript │ │ │ │ ├── channels │ │ │ │ │ ├── consumer.js │ │ │ │ │ └── index.js │ │ │ │ └── packs │ │ │ │ │ └── application.js │ │ │ ├── jobs │ │ │ │ └── application_job.rb │ │ │ ├── mailers │ │ │ │ └── application_mailer.rb │ │ │ ├── models │ │ │ │ ├── application_record.rb │ │ │ │ └── concerns │ │ │ │ │ └── .keep │ │ │ └── views │ │ │ │ ├── home │ │ │ │ ├── index.html.erb │ │ │ │ └── index.json.erb │ │ │ │ └── layouts │ │ │ │ ├── application.html.erb │ │ │ │ ├── mailer.html.erb │ │ │ │ └── mailer.text.erb │ │ ├── bin │ │ │ ├── rails │ │ │ ├── rake │ │ │ ├── setup │ │ │ ├── spring │ │ │ └── yarn │ │ ├── config.ru │ │ ├── config │ │ │ ├── application.rb │ │ │ ├── boot.rb │ │ │ ├── cable.yml │ │ │ ├── credentials.yml.enc │ │ │ ├── database.yml │ │ │ ├── environment.rb │ │ │ ├── environments │ │ │ │ ├── development.rb │ │ │ │ ├── production.rb │ │ │ │ └── test.rb │ │ │ ├── initializers │ │ │ │ ├── application_controller_renderer.rb │ │ │ │ ├── assets.rb │ │ │ │ ├── backtrace_silencers.rb │ │ │ │ ├── content_security_policy.rb │ │ │ │ ├── cookies_serializer.rb │ │ │ │ ├── filter_parameter_logging.rb │ │ │ │ ├── inflections.rb │ │ │ │ ├── mime_types.rb │ │ │ │ ├── permissions_policy.rb │ │ │ │ └── wrap_parameters.rb │ │ │ ├── locales │ │ │ │ └── en.yml │ │ │ ├── master.key │ │ │ ├── puma.rb │ │ │ ├── routes.rb │ │ │ ├── spring.rb │ │ │ └── storage.yml │ │ ├── db │ │ │ ├── seeds.rb │ │ │ └── test.sqlite3 │ │ ├── lib │ │ │ ├── assets │ │ │ │ └── .keep │ │ │ └── tasks │ │ │ │ └── .keep │ │ ├── package.json │ │ ├── public │ │ │ ├── 404.html │ │ │ ├── 422.html │ │ │ ├── 500.html │ │ │ ├── apple-touch-icon-precomposed.png │ │ │ ├── apple-touch-icon.png │ │ │ ├── favicon.ico │ │ │ └── robots.txt │ │ └── storage │ │ │ └── .keep │ └── 7.1.3 │ │ ├── .dockerignore │ │ ├── .gitattributes │ │ ├── .gitignore │ │ ├── .ruby-version │ │ ├── Dockerfile │ │ ├── Gemfile │ │ ├── README.md │ │ ├── Rakefile │ │ ├── app │ │ ├── assets │ │ │ ├── config │ │ │ │ └── manifest.js │ │ │ ├── images │ │ │ │ └── .keep │ │ │ └── stylesheets │ │ │ │ └── application.css │ │ ├── channels │ │ │ └── application_cable │ │ │ │ ├── channel.rb │ │ │ │ └── connection.rb │ │ ├── controllers │ │ │ ├── application_controller.rb │ │ │ ├── concerns │ │ │ │ └── .keep │ │ │ └── home_controller.rb │ │ ├── helpers │ │ │ ├── application_helper.rb │ │ │ └── home_helper.rb │ │ ├── javascript │ │ │ ├── application.js │ │ │ └── controllers │ │ │ │ ├── application.js │ │ │ │ ├── hello_controller.js │ │ │ │ └── index.js │ │ ├── jobs │ │ │ └── application_job.rb │ │ ├── mailers │ │ │ └── application_mailer.rb │ │ ├── models │ │ │ ├── application_record.rb │ │ │ └── concerns │ │ │ │ └── .keep │ │ └── views │ │ │ ├── home │ │ │ ├── index.html.erb │ │ │ └── index.json.erb │ │ │ └── layouts │ │ │ ├── application.html.erb │ │ │ ├── mailer.html.erb │ │ │ └── mailer.text.erb │ │ ├── bin │ │ ├── bundle │ │ ├── docker-entrypoint │ │ ├── importmap │ │ ├── rails │ │ ├── rake │ │ └── setup │ │ ├── config.ru │ │ ├── config │ │ ├── application.rb │ │ ├── boot.rb │ │ ├── cable.yml │ │ ├── credentials.yml.enc │ │ ├── database.yml │ │ ├── environment.rb │ │ ├── environments │ │ │ ├── development.rb │ │ │ ├── production.rb │ │ │ └── test.rb │ │ ├── importmap.rb │ │ ├── initializers │ │ │ ├── assets.rb │ │ │ ├── content_security_policy.rb │ │ │ ├── filter_parameter_logging.rb │ │ │ ├── inflections.rb │ │ │ └── permissions_policy.rb │ │ ├── locales │ │ │ └── en.yml │ │ ├── puma.rb │ │ ├── routes.rb │ │ └── storage.yml │ │ ├── db │ │ └── seeds.rb │ │ ├── lib │ │ ├── assets │ │ │ └── .keep │ │ └── tasks │ │ │ └── .keep │ │ ├── public │ │ ├── 404.html │ │ ├── 422.html │ │ ├── 500.html │ │ ├── apple-touch-icon-precomposed.png │ │ ├── apple-touch-icon.png │ │ ├── favicon.ico │ │ └── robots.txt │ │ ├── storage │ │ └── .keep │ │ ├── test │ │ ├── application_system_test_case.rb │ │ ├── channels │ │ │ └── application_cable │ │ │ │ └── connection_test.rb │ │ ├── controllers │ │ │ ├── .keep │ │ │ └── home_controller_test.rb │ │ ├── fixtures │ │ │ └── files │ │ │ │ └── .keep │ │ ├── helpers │ │ │ └── .keep │ │ ├── integration │ │ │ └── .keep │ │ ├── mailers │ │ │ └── .keep │ │ ├── models │ │ │ └── .keep │ │ ├── system │ │ │ └── .keep │ │ └── test_helper.rb │ │ └── vendor │ │ ├── .keep │ │ └── javascript │ │ └── .keep ├── rails_helper.rb ├── raygun │ └── breadcrumbs │ │ ├── breadcrumb_spec.rb │ │ └── store_spec.rb ├── services │ └── apply_whitelist_filter_to_payload_spec.rb ├── spec_helper.rb └── support │ └── fake_logger.rb └── test ├── integration └── client_test.rb ├── rails_helper.rb ├── test_helper.rb └── unit ├── affected_user_test.rb ├── client_test.rb ├── configuration_test.rb ├── error_subscriber_test.rb ├── raygun_test.rb ├── resque_failure_test.rb └── sidekiq_failure_test.rb /.github/workflows/tests.yml: -------------------------------------------------------------------------------- 1 | name: Tests 2 | on: [push, pull_request] 3 | jobs: 4 | test: 5 | name: Run tests 6 | runs-on: ubuntu-20.04 7 | strategy: 8 | fail-fast: false 9 | matrix: 10 | ruby: ["3.0", 3.1, 3.2, 3.3] 11 | gemfile: 12 | - gemfiles/rails_6.gemfile 13 | - gemfiles/rails_7.gemfile 14 | - gemfiles/rails_7_sidekiq_6.gemfile 15 | include: 16 | - ruby: "3.0" 17 | gemfile: gemfiles/rails_6.gemfile 18 | - ruby: "3.0" 19 | gemfile: gemfiles/rails_7.gemfile 20 | - ruby: 3.1 21 | gemfile: gemfiles/rails_6.gemfile 22 | - ruby: 3.1 23 | gemfile: gemfiles/rails_7.gemfile 24 | - ruby: 3.2 25 | gemfile: gemfiles/rails_6.gemfile 26 | - ruby: 3.2 27 | gemfile: gemfiles/rails_7.gemfile 28 | - ruby: 3.3 29 | gemfile: gemfiles/rails_6.gemfile 30 | - ruby: 3.3 31 | gemfile: gemfiles/rails_7.gemfile 32 | 33 | env: 34 | BUNDLE_GEMFILE: ${{ matrix.gemfile }} 35 | 36 | steps: 37 | - uses: actions/checkout@v4 38 | 39 | - uses: ruby/setup-ruby@v1 40 | with: 41 | bundler: 2.3 42 | bundler-cache: true 43 | ruby-version: ${{ matrix.ruby }} 44 | 45 | - run: bundle install 46 | 47 | - name: Run tests 48 | run: bundle exec rake 49 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.gem 2 | *.rbc 3 | .bundle 4 | .config 5 | .yardoc 6 | Gemfile.lock 7 | gemfiles/*.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 | spec/rails_applications/*/log 20 | 21 | # JetBrains 22 | .idea 23 | -------------------------------------------------------------------------------- /.rspec: -------------------------------------------------------------------------------- 1 | --require spec_helper 2 | -------------------------------------------------------------------------------- /Appraisals: -------------------------------------------------------------------------------- 1 | appraise "rails-6" do 2 | gem "rails", "6.1.4" 3 | gem "sqlite3", "~> 1.4" 4 | gem "sidekiq", ">= 7" 5 | end 6 | 7 | appraise "rails-7" do 8 | gem "rails", "7.1.3" 9 | gem "sqlite3", "~> 1.4" 10 | gem "importmap-rails" 11 | gem "sidekiq", ">= 7" 12 | end 13 | 14 | appraise "rails-7-sidekiq-6" do 15 | gem "rails", "7.1.3" 16 | gem "sqlite3", "~> 1.4" 17 | gem "importmap-rails" 18 | gem "sidekiq", "~> 6.5" 19 | end -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## 4.0.1 (29/07/2024): 2 | 3 | - Adds the ability to unwrap `Sidekiq::JobRetry::Handled` exceptions (or ignore them entirely) ([#185](https://github.com/MindscapeHQ/raygun4ruby/pull/185)) 4 | 5 | ## 4.0.0 (20/05/2024): 6 | 7 | - BREAKING CHANGE: Remove support for end-of-life Ruby verisons and Rails versions prior to 6.0.0 8 | - Bug fix: Fix issue with breadcrumbs not being sent to Raygun when `send_in_background` is enabled (thanks to @jjb for the bug report) 9 | - Updates testing to reflect the above 10 | - Use `Kernel.caller` when backtrace is not available (thanks to @TSMMark) 11 | 12 | ## 3.2.6 (17/03/2021): 13 | 14 | - Bug fix: Rename Testable class to DemoException to ensure it is added to the bundle ([#166](https://github.com/MindscapeHQ/raygun4ruby/pull/166)) 15 | 16 | ## 3.2.5 (15/03/2021): 17 | 18 | - Bug fix: Ensure tags passed into track_exception are not persisted ([#164](https://github.com/MindscapeHQ/raygun4ruby/pull/164)) 19 | 20 | ## 3.2.4 (11/02/2021): 21 | 22 | - Set sidekiq tag on sidekiq errors ([#161](https://github.com/MindscapeHQ/raygun4ruby/pull/161)) 23 | 24 | ## 3.2.2 (10/06/2020): 25 | 26 | - Introduce support for Raygun APM exceptions correlation ([#154](https://github.com/MindscapeHQ/raygun4ruby/pull/154)) 27 | 28 | ## 3.2.1 (25/02/2019): 29 | 30 | Bugfix: 31 | 32 | - Remove Ruby 2.3 syntax to retain support for Ruby >= 2.0 ([#148](https://github.com/MindscapeHQ/raygun4ruby/pull/148)) 33 | 34 | ## 3.2.0 (21/02/2019): 35 | 36 | Bugfix: 37 | 38 | - Fix NoMethodError Exception: undefined method `include?' for nil:NilClass in `JavascriptExceptionTracking` class. Thanks @yamanaltereh for this ([#141](https://github.com/MindscapeHQ/raygun4ruby/pull/141)) 39 | - Fix ([#145](https://github.com/MindscapeHQ/raygun4ruby/issues/145)), "raygun4ruby will load pry if it is in the gem bundle". Thanks to @eoinkelly for reporting this 40 | 41 | Feature: 42 | 43 | - If you have recorded a large number of Breadcrumbs, or just very large ones, Raygun4Ruby will now only send up to 100KB of them instead of all of them, potentially going over the 128KB payload limit Raygun accepts ([#147](https://github.com/MindscapeHQ/raygun4ruby/pull/147)) 44 | 45 | ## 3.1.1 (16/01/2019): 46 | 47 | Bugfix: 48 | 49 | - Don't attempt to modify response unless JS api key is present 50 | - Don't attempt to modify response unless it responds to indexing ([]) 51 | - See PR ([#140](https://github.com/MindscapeHQ/raygun4ruby/pull/140)) 52 | 53 | ## 3.1.0 (15/01/2019): 54 | 55 | Feature: - Ability to automatically configure Raygun4JS on the client side by injecting it into outbound HTML pages. Thanks @MikeRogers0 for this ([#138](https://github.com/MindscapeHQ/raygun4ruby/pull/138)) 56 | 57 | ## 3.0.0 (18/12/2018): 58 | 59 | Breaking changes: 60 | Parameter filters are now applied if you are using the `filter_payload_with_whitelist` functionality. Previously if this was set to true the parameter filtering was bailed out of ([#136](https://github.com/MindscapeHQ/raygun4ruby/pull/136/files)) 61 | 62 | ## 2.7.1 (11/06/2018) 63 | 64 | This is a patch release to update the required ruby version to correctly be 2.0 or greater 65 | 66 | ## 2.7.0 (19/02/2018) 67 | 68 | Features 69 | 70 | - Add configuration option to control network timeouts when sending error reports, default value is 10 seconds ([#129](https://github.com/MindscapeHQ/raygun4ruby/pull/129)) 71 | 72 | ## 2.6.0 (25/10/2017) 73 | 74 | Features 75 | 76 | - Enhanced debug logging to assist in resolving issues from support requests ([#128](https://github.com/MindscapeHQ/raygun4ruby/pull/128)) 77 | 78 | ## 2.5.0 (04/10/2017) 79 | 80 | Features 81 | 82 | - Teach tags configuration how to handle a proc to allow dynamically settings tags ([#127](https://github.com/MindscapeHQ/raygun4ruby/pull/127)) 83 | 84 | Bugfixes 85 | 86 | - Fix crash when recording breadcrumb with uninitialized store ([#126](https://github.com/MindscapeHQ/raygun4ruby/pull/126)) 87 | - Make raw data handling more robust and fix in unicorn ([#125](https://github.com/MindscapeHQ/raygun4ruby/pull/125)) 88 | - Backwards compatible affected_user_identifier_methods ([#120](https://github.com/MindscapeHQ/raygun4ruby/pull/120)) 89 | 90 | ## 2.4.1 (29/08/2017) 91 | 92 | Bugfixes 93 | 94 | - Fix crash in `Client#raw_data` method when `rack.input` buffer is missing `pos` method 95 | 96 | ## 2.4.0 (31/07/2017) 97 | 98 | Features 99 | 100 | - Add functionality to track affected user/customer in Sidekiq jobs, refer to the README for more information, under the "Affected User Tracking/Customers in Sidekiq" heading ([#121](https://github.com/MindscapeHQ/raygun4ruby/pull/121)) 101 | 102 | ## 2.3.0 (09/05/2017)" 103 | 104 | Bugfixes 105 | 106 | - Fix issue preventing affected users/customers for a crash report from showing up in the affected users/customers page ([#119](https://github.com/MindscapeHQ/raygun4ruby/pull/119)) 107 | 108 | ## 2.2.0 (05/05/2017) 109 | 110 | Features 111 | 112 | - Opt in support for sending exceptions in a background thread to not block web request thread during IO ([#117](https://github.com/MindscapeHQ/raygun4ruby/pull/117)) 113 | 114 | Bugfixes 115 | 116 | - Don't attempt to read raw data during GET requests or if rack.input buffer is empty 117 | 118 | ## 2.1.0 (27/04/2017) 119 | 120 | Features 121 | 122 | - Ability to record breadcrumbs in your code that will be sent to Raygun along with a raised exception ([#113](https://github.com/MindscapeHQ/raygun4ruby/pull/113)) 123 | 124 | ## 2.0.0 (20/04/2017) 125 | 126 | Bugfixes: 127 | 128 | - Fix broken handling of raw request body reading in Rack applications ([#116](https://github.com/MindscapeHQ/raygun4ruby/pull/116)) 129 | - This is a breaking change to how raw data was being read before so it requires a major version bump 130 | - Raw request data reading is now disabled by default and can be enabled via the `record_raw_data` configuration option 131 | 132 | Since this is a major version bump this release also deprecates ruby versions < 2.0 133 | 134 | ## 1.5.0 (16/03/2017) 135 | 136 | Features 137 | 138 | - Send utcOffset with Raygun payload to calculate local server time in Raygun dashboard ([#112](https://github.com/MindscapeHQ/raygun4ruby/pull/112)) 139 | 140 | ## 1.4.0 (14/03/2017) 141 | 142 | Features: 143 | 144 | - Raygun API url is now configurable via `Configuration.api_url` ([#111](https://github.com/MindscapeHQ/raygun4ruby/pull/111)) 145 | - Added support for `Exception#cause` to be tracked as `innerError` on Raygun. Only supported on Ruby >= 2.1 ([#107](https://github.com/MindscapeHQ/raygun4ruby/pull/107)) 146 | 147 | ## 1.3.0 (10/03/2017) 148 | 149 | Features: 150 | 151 | - Improve affected user handling to let you specify all Raygun parameters, identifier, email, first name, full name and uuid. See [README.md](https://github.com/MindscapeHQ/raygun4ruby#affected-user-tracking) for details ([#34](https://github.com/MindscapeHQ/raygun4ruby/pull/34)) 152 | - Pass a user object as the third parameter to `Raygun.track_exception` to have affected user tracking/customers for manually tracked exceptions, see the above link for more information on configuring this ([#106](https://github.com/MindscapeHQ/raygun4ruby/pull/106)) 153 | - If the exception instance responds to `:raygun_custom_data` that method will be called and the return value merged into the `custom_data` hash sent to Raygun. For convenience a `Raygun::Error` class is provided that takes this custom data as a second argument ([#101](https://github.com/MindscapeHQ/raygun4ruby/pull/101)) 154 | - Allowed `Configuration.custom_data` to be set to a proc to allow a global custom data hook for all exceptions. It is passed as arguments the exception and the environment hash ([#108](https://github.com/MindscapeHQ/raygun4ruby/pull/108)) 155 | - Added `Configuration.debug` to enable logging the reason why an exception was not reported ([#109](https://github.com/MindscapeHQ/raygun4ruby/pull/109)) 156 | 157 | ## 1.2.1 (09/03/2017) 158 | 159 | Bugfixes: 160 | 161 | - dup input hashes before applying whitelist filtering, previously this was modifying the contents of `action_dispatch.request.parameters` ([#105](https://github.com/MindscapeHQ/raygun4ruby/pull/105)) 162 | 163 | ## 1.2.0 (09/03/2017) 164 | 165 | Features: 166 | 167 | - Added two new configuration options, `filter_payload_with_whitelist` and `whitelist_payload_shape` ([#100](https://github.com/MindscapeHQ/raygun4ruby/pull/100)) 168 | - See [README.md](https://github.com/MindscapeHQ/raygun4ruby#filtering-the-payload-by-whitelist) for an example of how to use them 169 | - When raygun4ruby encounters an exception trying to track an exception it will try once to send that exception to Raygun so you are notified ([#104](https://github.com/MindscapeHQ/raygun4ruby/pull/104)) 170 | 171 | Bugfixes: 172 | 173 | - raygun4ruby will no longer crash and suppress app exceptions when the API key is not configured ([#87](https://github.com/MindscapeHQ/raygun4ruby/pull/87)) 174 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | 3 | # Specify your gem's dependencies in raygun4ruby.gemspec 4 | gemspec 5 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2013 Nik Wakelin 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 | require "bundler/setup" 2 | require "bundler/gem_tasks" 3 | 4 | require "appraisal" 5 | require "rake/testtask" 6 | 7 | namespace :test do 8 | 9 | desc "Test the basics of the adapter" 10 | Rake::TestTask.new(:units) do |t| 11 | t.test_files = FileList["test/unit/*_test.rb"] 12 | end 13 | 14 | desc "Run a test against the live API" 15 | Rake::TestTask.new(:integration) do |t| 16 | t.test_files = FileList["test/integration/*_test.rb"] 17 | end 18 | 19 | begin 20 | require 'rspec/core/rake_task' 21 | 22 | RSpec::Core::RakeTask.new(:spec) 23 | 24 | rescue LoadError 25 | end 26 | end 27 | 28 | if !ENV["APPRAISAL_INITIALIZED"] && !ENV["CI"] 29 | task default: :appraisal 30 | else 31 | task default: ["test:units", "test:spec"] 32 | end 33 | -------------------------------------------------------------------------------- /examples/sinatras_raygun.rb: -------------------------------------------------------------------------------- 1 | # NB: You'll need to install the 'sinatra' gem for this to work :) 2 | # $ gem install sinatra 3 | # $ ruby sinatras_raygun.rb 4 | 5 | require 'sinatra' 6 | require_relative '../lib/raygun4ruby' 7 | 8 | Raygun.setup do |config| 9 | config.api_key = YOUR_RAYGUN_API_KEY_HERE 10 | end 11 | 12 | use Raygun::RackExceptionInterceptor 13 | 14 | set :raise_errors, true 15 | 16 | get '/' do 17 | raise "This is an exception that will be sent to Raygun!" 18 | end -------------------------------------------------------------------------------- /gemfiles/rails_6.gemfile: -------------------------------------------------------------------------------- 1 | # This file was generated by Appraisal 2 | 3 | source "https://rubygems.org" 4 | 5 | gem "rails", "6.1.4" 6 | gem "sqlite3", "~> 1.4" 7 | gem "sidekiq", ">= 7" 8 | 9 | gemspec path: "../" 10 | -------------------------------------------------------------------------------- /gemfiles/rails_7.gemfile: -------------------------------------------------------------------------------- 1 | # This file was generated by Appraisal 2 | 3 | source "https://rubygems.org" 4 | 5 | gem "rails", "7.1.3" 6 | gem "sqlite3", "~> 1.4" 7 | gem "importmap-rails" 8 | gem "sidekiq", ">= 7" 9 | 10 | gemspec path: "../" 11 | -------------------------------------------------------------------------------- /gemfiles/rails_7_sidekiq_6.gemfile: -------------------------------------------------------------------------------- 1 | # This file was generated by Appraisal 2 | 3 | source "https://rubygems.org" 4 | 5 | gem "rails", "7.1.3" 6 | gem "sqlite3", "~> 1.4" 7 | gem "importmap-rails" 8 | gem "sidekiq", "~> 6.5" 9 | 10 | gemspec path: "../" 11 | -------------------------------------------------------------------------------- /lib/generators/raygun/install_generator.rb: -------------------------------------------------------------------------------- 1 | module Raygun 2 | class InstallGenerator < Rails::Generators::Base 3 | 4 | argument :api_key 5 | 6 | desc "This generator creates a configuration file for the Raygun ruby adapter inside config/initializers" 7 | def create_configuration_file 8 | filter_parameters = if defined?(Rails) 9 | "config.filter_parameters = Rails.application.config.filter_parameters" 10 | else 11 | "config.filter_parameters = [ :password, :card_number, :cvv ] # don't forget to filter out sensitive parameters" 12 | end 13 | initializer "raygun.rb" do 14 | <<-EOS 15 | Raygun.setup do |config| 16 | config.api_key = "#{api_key}" 17 | #{filter_parameters} 18 | 19 | # The default is Rails.env.production? 20 | # config.enable_reporting = !Rails.env.development? && !Rails.env.test? 21 | end 22 | EOS 23 | end 24 | end 25 | end 26 | end 27 | -------------------------------------------------------------------------------- /lib/raygun.rb: -------------------------------------------------------------------------------- 1 | require "concurrent" 2 | require "httparty" 3 | require "logger" 4 | require "json" 5 | require "socket" 6 | require "rack" 7 | require "ostruct" 8 | 9 | require "raygun/version" 10 | require "raygun/configuration" 11 | require "raygun/client" 12 | require "raygun/javascript_tracker" 13 | require "raygun/middleware/rack_exception_interceptor" 14 | require "raygun/middleware/breadcrumbs_store_initializer" 15 | require "raygun/middleware/javascript_exception_tracking" 16 | require "raygun/demo_exception" 17 | require "raygun/error_subscriber" 18 | require "raygun/error" 19 | require "raygun/affected_user" 20 | require "raygun/services/apply_whitelist_filter_to_payload" 21 | require "raygun/breadcrumbs/breadcrumb" 22 | require "raygun/breadcrumbs/store" 23 | require "raygun/breadcrumbs" 24 | require "raygun/railtie" if defined?(Rails) 25 | 26 | module Raygun 27 | 28 | # used to identify ourselves to Raygun 29 | CLIENT_URL = "https://github.com/MindscapeHQ/raygun4ruby" 30 | CLIENT_NAME = "Raygun4Ruby Gem" 31 | 32 | class << self 33 | include DemoException 34 | 35 | # Configuration Object (instance of Raygun::Configuration) 36 | attr_writer :configuration 37 | 38 | # List of futures that are currently running 39 | @@active_futures = [] 40 | 41 | def setup 42 | yield(configuration) 43 | 44 | log("configuration settings: #{configuration.inspect}") 45 | end 46 | 47 | def configuration 48 | @configuration ||= Configuration.new 49 | end 50 | 51 | def default_configuration 52 | configuration.defaults 53 | end 54 | 55 | def reset_configuration 56 | @configuration = Configuration.new 57 | end 58 | 59 | def configured? 60 | !!configuration.api_key 61 | end 62 | 63 | def track_exception(exception_instance, env = {}, user = nil, retries_remaining = configuration.error_report_max_attempts - 1) 64 | log('tracking exception') 65 | 66 | exception_instance.set_backtrace(caller) if exception_instance.is_a?(Exception) && exception_instance.backtrace.nil? 67 | 68 | result = if configuration.send_in_background 69 | track_exception_async(exception_instance, env, user, retries_remaining) 70 | else 71 | track_exception_sync(exception_instance, env, user, retries_remaining) 72 | end 73 | 74 | result 75 | end 76 | 77 | def track_exceptions 78 | yield 79 | rescue => e 80 | track_exception(e) 81 | end 82 | 83 | def record_breadcrumb( 84 | message: nil, 85 | category: '', 86 | level: :info, 87 | timestamp: Time.now.utc, 88 | metadata: {}, 89 | class_name: nil, 90 | method_name: nil, 91 | line_number: nil 92 | ) 93 | log('recording breadcrumb') 94 | 95 | Raygun::Breadcrumbs::Store.record( 96 | message: message, 97 | category: category, 98 | level: level, 99 | timestamp: timestamp, 100 | metadata: metadata, 101 | class_name: class_name, 102 | method_name: method_name, 103 | line_number: line_number, 104 | ) 105 | end 106 | 107 | def log(message) 108 | return unless configuration.debug 109 | 110 | configuration.logger.info("[Raygun] #{message}") if configuration.logger 111 | end 112 | 113 | def failsafe_log(message) 114 | configuration.failsafe_logger.info(message) 115 | end 116 | 117 | def deprecation_warning(message) 118 | if defined?(ActiveSupport::Deprecation) 119 | ActiveSupport::Deprecation.warn(message) 120 | else 121 | puts message 122 | end 123 | end 124 | 125 | def wait_for_futures 126 | @@active_futures.each(&:value) 127 | end 128 | 129 | private 130 | 131 | def track_exception_async(exception_instance, env, user, retries_remaining) 132 | env[:rg_breadcrumb_store] = Raygun::Breadcrumbs::Store.take_until_size(Client::MAX_BREADCRUMBS_SIZE) if Raygun::Breadcrumbs::Store.any? 133 | 134 | future = Concurrent::Future.execute { track_exception_sync(exception_instance, env, user, retries_remaining) } 135 | future.add_observer(lambda do |_, value, reason| 136 | if value == nil || !value.responds_to?(:response) || value.response.code != "202" 137 | log("unexpected response from Raygun, could indicate error: #{value.inspect}") 138 | end 139 | @@active_futures.delete(future) 140 | end, :call) 141 | @@active_futures << future 142 | 143 | future 144 | end 145 | 146 | def track_exception_sync(exception_instance, env, user, retries_remaining) 147 | if should_report?(exception_instance) 148 | log('attempting to send exception') 149 | resp = Client.new.track_exception(exception_instance, env, user) 150 | log('sent payload to api') 151 | 152 | resp 153 | end 154 | rescue Exception => e 155 | log('error sending exception to raygun, see failsafe logger for more information') 156 | 157 | if configuration.failsafe_logger 158 | failsafe_log("Problem reporting exception to Raygun: #{e.class}: #{e.message}\n\n#{e.backtrace.join("\n")}") 159 | end 160 | 161 | if retries_remaining > 0 162 | new_exception = e.exception("raygun4ruby encountered an exception processing your exception") 163 | new_exception.set_backtrace(e.backtrace) 164 | 165 | env[:custom_data] ||= {} 166 | env[:custom_data].merge!(original_stacktrace: exception_instance.backtrace, retries_remaining: retries_remaining) 167 | 168 | ::Raygun::Breadcrumbs::Store.clear 169 | 170 | track_exception(new_exception, env, user, retries_remaining - 1) 171 | else 172 | if configuration.raise_on_failed_error_report 173 | raise e 174 | else 175 | retries = configuration.error_report_max_attempts - retries_remaining 176 | if configuration.failsafe_logger 177 | failsafe_log("Gave up reporting exception to Raygun after #{retries} #{retries == 1 ? "retry" : "retries"}: #{e.class}: #{e.message}\n\n#{e.backtrace.join("\n")}") 178 | end 179 | end 180 | end 181 | end 182 | 183 | 184 | def print_api_key_warning 185 | $stderr.puts(NO_API_KEY_MESSAGE) 186 | end 187 | 188 | def should_report?(exception) 189 | if configuration.silence_reporting 190 | log('skipping reporting because Configuration.silence_reporting is enabled') 191 | 192 | return false 193 | end 194 | 195 | if configuration.ignore.flatten.include?(exception.class.to_s) 196 | log("skipping reporting of exception #{exception.class} because it is in the ignore list") 197 | 198 | return false 199 | end 200 | 201 | true 202 | end 203 | end 204 | end 205 | -------------------------------------------------------------------------------- /lib/raygun/affected_user.rb: -------------------------------------------------------------------------------- 1 | module Raygun 2 | class AffectedUser 3 | 4 | DEFAULT_MAPPING = { 5 | identifier: [ :id, :username ], 6 | email: :email, 7 | full_name: [ :full_name, :name ], 8 | first_name: :first_name, 9 | uuid: :uuid 10 | }.freeze 11 | SUPPORTED_ATTRIBUTES = DEFAULT_MAPPING.keys.freeze 12 | NAME_TO_RAYGUN_NAME_MAPPING = { 13 | identifier: :identifier, 14 | email: :email, 15 | full_name: :fullName, 16 | first_name: :firstName, 17 | uuid: :uuid 18 | }.freeze 19 | 20 | class << self 21 | def information_hash(user_object) 22 | if user_object.nil? || user_object.is_a?(String) 23 | handle_anonymous_user(user_object) 24 | else 25 | handle_known_user(user_object) 26 | end 27 | end 28 | 29 | private 30 | 31 | def handle_anonymous_user(user_object) 32 | result = { isAnonymous: true } 33 | result[:identifier] = user_object unless user_object.nil? 34 | result 35 | end 36 | 37 | def handle_known_user(user_object) 38 | SUPPORTED_ATTRIBUTES.reduce({ isAnonymous: false }) do |result, attribute| 39 | mapping = Raygun.configuration.affected_user_mapping 40 | method = mapping[attribute] 41 | 42 | value = if method.is_a? Proc 43 | method.call(user_object) 44 | else 45 | attributes = Array(method) 46 | attribute_to_use = attributes.select do |attr| 47 | user_object.respond_to?(attr, true) 48 | end.first 49 | 50 | user_object.send(attribute_to_use) unless attribute_to_use == nil 51 | end 52 | 53 | result[NAME_TO_RAYGUN_NAME_MAPPING[attribute]] = value unless value == nil 54 | result 55 | end 56 | end 57 | end 58 | end 59 | end 60 | -------------------------------------------------------------------------------- /lib/raygun/breadcrumbs.rb: -------------------------------------------------------------------------------- 1 | module Raygun 2 | module Breadcrumbs 3 | BREADCRUMB_LEVELS = [ 4 | :debug, 5 | :info, 6 | :warning, 7 | :error, 8 | :fatal 9 | ] 10 | 11 | def record_breadcrumb( 12 | message: nil, 13 | category: '', 14 | level: :info, 15 | timestamp: Time.now.utc.to_i, 16 | metadata: {}, 17 | class_name: nil, 18 | method_name: nil, 19 | line_number: nil 20 | ) 21 | class_name = class_name || self.class.name 22 | Raygun::Breadcrumbs::Store.record( 23 | message: message, 24 | category: category, 25 | level: level, 26 | timestamp: timestamp, 27 | metadata: metadata, 28 | class_name: class_name, 29 | method_name: method_name, 30 | line_number: line_number, 31 | ) 32 | end 33 | end 34 | end 35 | -------------------------------------------------------------------------------- /lib/raygun/breadcrumbs/breadcrumb.rb: -------------------------------------------------------------------------------- 1 | module Raygun 2 | module Breadcrumbs 3 | class Breadcrumb 4 | ATTRIBUTES = [ 5 | :message, :category, :metadata, :class_name, 6 | :method_name, :line_number, :timestamp, :level, 7 | :type 8 | ] 9 | attr_accessor(*ATTRIBUTES) 10 | 11 | def build_payload 12 | payload = { 13 | message: message, 14 | category: category, 15 | level: Breadcrumbs::BREADCRUMB_LEVELS.index(level), 16 | CustomData: metadata, 17 | timestamp: timestamp, 18 | type: type 19 | } 20 | 21 | payload[:location] = "#{class_name}:#{method_name}" unless class_name == nil 22 | payload[:location] += ":#{line_number}" if payload.has_key?(:location) && line_number != nil 23 | 24 | Hash[payload.select do |k, v| 25 | v != nil 26 | end] 27 | end 28 | 29 | def size 30 | return message.length + 100 31 | end 32 | end 33 | end 34 | end 35 | -------------------------------------------------------------------------------- /lib/raygun/breadcrumbs/store.rb: -------------------------------------------------------------------------------- 1 | require_relative 'breadcrumb' 2 | 3 | module Raygun 4 | module Breadcrumbs 5 | class Store 6 | def self.initialize(with: []) 7 | Thread.current[:breadcrumbs] ||= with 8 | end 9 | 10 | def self.clear 11 | Thread.current[:breadcrumbs] = nil 12 | end 13 | 14 | def self.stored 15 | Thread.current[:breadcrumbs] 16 | end 17 | 18 | def self.record( 19 | message: nil, 20 | category: '', 21 | level: :info, 22 | timestamp: Time.now.utc.to_i, 23 | metadata: {}, 24 | class_name: nil, 25 | method_name: nil, 26 | line_number: nil 27 | ) 28 | raise ArgumentError.new('missing keyword: message') if message == nil 29 | crumb = Breadcrumb.new 30 | 31 | crumb.message = message 32 | crumb.category = category 33 | crumb.level = level 34 | crumb.metadata = metadata 35 | crumb.timestamp = timestamp 36 | crumb.type = 'manual' 37 | 38 | caller = caller_locations[1] 39 | crumb.class_name = class_name 40 | crumb.method_name = method_name || caller.label 41 | crumb.line_number = line_number || caller.lineno 42 | 43 | Thread.current[:breadcrumbs] << crumb if should_record?(crumb) 44 | end 45 | 46 | def self.any? 47 | stored != nil && stored.length > 0 48 | end 49 | 50 | def self.take_until_size(size) 51 | breadcrumb_size = 0 52 | 53 | stored.reverse.take_while do |crumb| 54 | breadcrumb_size += crumb.size 55 | 56 | breadcrumb_size < size 57 | end.reverse 58 | end 59 | 60 | private 61 | 62 | def self.should_record?(crumb) 63 | if stored.nil? 64 | if Raygun.configuration.debug 65 | Raygun.log('[Raygun.breadcrumbs] store is uninitialized while breadcrumb is being recorded, discarding breadcrumb') 66 | end 67 | 68 | return false 69 | end 70 | 71 | levels = Raygun::Breadcrumbs::BREADCRUMB_LEVELS 72 | 73 | active_level = levels.index(Raygun.configuration.breadcrumb_level) 74 | crumb_level = levels.index(crumb.level) || -1 75 | 76 | discard = crumb_level < active_level 77 | 78 | if discard && Raygun.configuration.debug 79 | Raygun.log("[Raygun.breadcrumbs] discarding breadcrumb because #{crumb.level} is below active breadcrumb level (#{Raygun.configuration.breadcrumb_level})") 80 | end 81 | 82 | !discard 83 | end 84 | end 85 | end 86 | end 87 | -------------------------------------------------------------------------------- /lib/raygun/client.rb: -------------------------------------------------------------------------------- 1 | module Raygun 2 | # client for the Raygun REST APIv1 3 | # as per https://raygun.com/documentation/product-guides/crash-reporting/api/ 4 | class Client 5 | 6 | ENV_IP_ADDRESS_KEYS = %w(action_dispatch.remote_ip raygun.remote_ip REMOTE_ADDR) 7 | NO_API_KEY_MESSAGE = "[RAYGUN] Just a note, you've got no API Key configured, which means we can't report exceptions. Specify your Raygun API key using Raygun#setup (find yours at https://app.raygun.com)" 8 | MAX_BREADCRUMBS_SIZE = 100_000 9 | 10 | include HTTParty 11 | 12 | def initialize 13 | @api_key = require_api_key 14 | @headers = { 15 | "X-ApiKey" => @api_key 16 | } 17 | 18 | enable_http_proxy if Raygun.configuration.proxy_settings[:address] 19 | self.class.base_uri Raygun.configuration.api_url 20 | self.class.default_timeout(Raygun.configuration.error_report_send_timeout) 21 | end 22 | 23 | def require_api_key 24 | Raygun.configuration.api_key || print_api_key_warning 25 | end 26 | 27 | def track_exception(exception_instance, env = {}, user = nil) 28 | create_entry(build_payload_hash(exception_instance, env, user)) 29 | end 30 | 31 | private 32 | 33 | def enable_http_proxy 34 | self.class.http_proxy(Raygun.configuration.proxy_settings[:address], 35 | Raygun.configuration.proxy_settings[:port] || "80", 36 | Raygun.configuration.proxy_settings[:username], 37 | Raygun.configuration.proxy_settings[:password]) 38 | end 39 | 40 | def client_details 41 | { 42 | name: Raygun::CLIENT_NAME, 43 | version: Raygun::VERSION, 44 | clientUrl: Raygun::CLIENT_URL 45 | } 46 | end 47 | 48 | def error_details(exception) 49 | details = { 50 | className: exception.class.to_s, 51 | message: exception.message.to_s.encode('UTF-16', :undef => :replace, :invalid => :replace).encode('UTF-8'), 52 | stackTrace: (exception.backtrace || []).map { |line| stack_trace_for(line) }, 53 | } 54 | 55 | details.update(innerError: error_details(exception.cause)) if exception.respond_to?(:cause) && exception.cause 56 | 57 | details 58 | end 59 | 60 | def stack_trace_for(line) 61 | # see http://www.ruby-doc.org/core-2.0/Exception.html#method-i-backtrace 62 | file_name, line_number, method = line.split(":") 63 | { 64 | lineNumber: line_number, 65 | fileName: file_name, 66 | methodName: method ? method.gsub(/^in `(.*?)'$/, "\\1") : "(none)" 67 | } 68 | end 69 | 70 | def hostname 71 | Socket.gethostname 72 | end 73 | 74 | def version 75 | Raygun.configuration.version 76 | end 77 | 78 | def user_information(env) 79 | env["raygun.affected_user"] 80 | end 81 | 82 | def affected_user_present?(env) 83 | !!env["raygun.affected_user"] 84 | end 85 | 86 | def rack_env 87 | ENV["RACK_ENV"] 88 | end 89 | 90 | def rails_env 91 | ENV["RAILS_ENV"] 92 | end 93 | 94 | def request_information(env) 95 | Raygun.log('retrieving request information') 96 | 97 | return {} if env.nil? || env.empty? 98 | { 99 | hostName: env["SERVER_NAME"], 100 | url: env["PATH_INFO"], 101 | httpMethod: env["REQUEST_METHOD"], 102 | iPAddress: "#{ip_address_from(env)}", 103 | queryString: Rack::Utils.parse_nested_query(env["QUERY_STRING"]), 104 | headers: headers(env), 105 | form: form_params(env), 106 | rawData: raw_data(env) 107 | } 108 | end 109 | 110 | def headers(rack_env) 111 | rack_env.select { |k, v| k.to_s.start_with?("HTTP_") }.inject({}) do |hsh, (k, v)| 112 | hsh[normalize_raygun_header_key(k)] = v 113 | hsh 114 | end 115 | end 116 | 117 | def normalize_raygun_header_key(key) 118 | key.sub(/^HTTP_/, '') 119 | .sub(/_/, ' ') 120 | .split.map(&:capitalize).join(' ') 121 | .sub(/ /, '-') 122 | end 123 | 124 | def form_params(env) 125 | Raygun.log('retrieving form params') 126 | 127 | params = action_dispatch_params(env) || rack_params(env) || {} 128 | filter_params_with_blacklist(params, env["action_dispatch.parameter_filter"]) 129 | end 130 | 131 | def action_dispatch_params(env) 132 | env["action_dispatch.request.parameters"] 133 | end 134 | 135 | def rack_params(env) 136 | request = Rack::Request.new(env) 137 | request.params if env["rack.input"] 138 | end 139 | 140 | def raw_data(rack_env) 141 | Raygun.log('retrieving raw data') 142 | request = Rack::Request.new(rack_env) 143 | 144 | return unless Raygun.configuration.record_raw_data 145 | return if request.get? 146 | Raygun.log('passed raw_data checks') 147 | 148 | input = rack_env['rack.input'] 149 | 150 | if input && !request.form_data? 151 | input.rewind 152 | 153 | body = input.read(4096) || '' 154 | input.rewind 155 | 156 | body 157 | else 158 | {} 159 | end 160 | end 161 | 162 | def filter_custom_data(env) 163 | params = env.delete(:custom_data) || {} 164 | filter_params_with_blacklist(params, env["action_dispatch.parameter_filter"]) 165 | end 166 | 167 | # see https://raygun.com/documentation/product-guides/crash-reporting/api/ 168 | def build_payload_hash(exception_instance, env = {}, user = nil) 169 | Raygun.log('building payload hash') 170 | custom_data = filter_custom_data(env) || {} 171 | exception_custom_data = if exception_instance.respond_to?(:raygun_custom_data) 172 | exception_instance.raygun_custom_data 173 | else 174 | {} 175 | end 176 | 177 | tags = env.delete(:tags) || [] 178 | 179 | if rails_env 180 | tags << rails_env 181 | else 182 | tags << rack_env 183 | end 184 | 185 | combined_tags = [] 186 | 187 | if Raygun.configuration.tags.is_a?(Proc) 188 | configuration_tags = Raygun.configuration.tags.call(exception_instance, env) 189 | else 190 | configuration_tags = Raygun.configuration.tags 191 | end 192 | 193 | combined_tags.concat(configuration_tags) 194 | 195 | Raygun.log('set tags') 196 | 197 | grouping_key = env.delete(:grouping_key) 198 | correlation_id = env.delete(:correlation_id) 199 | 200 | configuration_custom_data = Raygun.configuration.custom_data 201 | configured_custom_data = if configuration_custom_data.is_a?(Proc) 202 | configuration_custom_data.call(exception_instance, env) 203 | else 204 | configuration_custom_data 205 | end 206 | 207 | Raygun.log('set custom data') 208 | 209 | error_details = { 210 | machineName: hostname, 211 | version: version, 212 | client: client_details, 213 | error: error_details(exception_instance), 214 | userCustomData: exception_custom_data.merge(custom_data).merge(configured_custom_data), 215 | tags: combined_tags.concat(tags).compact.uniq, 216 | request: request_information(env), 217 | environment: { 218 | utcOffset: Time.now.utc_offset / 3600 219 | } 220 | } 221 | 222 | # If we have breadcrumbs passed to us as context from another thread, then include them 223 | # Otherwise, use the default store (which is thread-local) 224 | ::Raygun::Breadcrumbs::Store.initialize(with: env.delete(:rg_breadcrumb_store)) if env.key?(:rg_breadcrumb_store) 225 | 226 | store = ::Raygun::Breadcrumbs::Store 227 | error_details[:breadcrumbs] = store.take_until_size(MAX_BREADCRUMBS_SIZE).map(&:build_payload) if store.any? 228 | 229 | Raygun.log('set details and breadcrumbs') 230 | 231 | error_details.merge!(groupingKey: grouping_key) if grouping_key 232 | error_details.merge!(correlationId: correlation_id) if correlation_id 233 | 234 | user_details = if affected_user_present?(env) 235 | user_information(env) 236 | elsif user != nil 237 | AffectedUser.information_hash(user) 238 | end 239 | error_details.merge!(user: user_details) unless user_details == nil 240 | 241 | Raygun.log('set user details') 242 | 243 | if Raygun.configuration.filter_payload_with_whitelist 244 | Raygun.log('filtering payload with whitelist') 245 | error_details = filter_payload_with_whitelist(error_details) 246 | end 247 | 248 | { 249 | occurredOn: Time.now.utc.iso8601, 250 | details: error_details 251 | } 252 | end 253 | 254 | def create_entry(payload_hash) 255 | Raygun.log('sending payload to api') 256 | 257 | self.class.post( 258 | "/entries", 259 | verify_peer: true, 260 | verify: true, 261 | headers: @headers, 262 | body: JSON.generate(payload_hash), 263 | ) 264 | end 265 | 266 | def filter_params_with_blacklist(params_hash = {}, extra_filter_keys = nil) 267 | filter_parameters = Raygun.configuration.filter_parameters 268 | 269 | if filter_parameters.is_a? Proc 270 | filter_parameters.call(params_hash) 271 | else 272 | filter_keys = (Array(extra_filter_keys) + filter_parameters).map(&:to_s) 273 | 274 | filter_params_with_array(params_hash, filter_keys) 275 | end 276 | end 277 | 278 | def filter_payload_with_whitelist(payload_hash) 279 | shape = Raygun.configuration.whitelist_payload_shape 280 | 281 | if shape.is_a? Proc 282 | shape.call(payload_hash) 283 | else 284 | # Always keep the client hash, so force it to true here 285 | Services::ApplyWhitelistFilterToPayload.new.call(shape.merge(client: true), payload_hash) 286 | end 287 | end 288 | 289 | def filter_params_with_array(params_hash, filter_keys) 290 | # Recursive filtering of (nested) hashes 291 | (params_hash || {}).inject({}) do |result, (k, v)| 292 | result[k] = case v 293 | when Hash 294 | filter_params_with_array(v, filter_keys) 295 | else 296 | filter_keys.any? { |fk| /#{fk}/i === k.to_s } ? "[FILTERED]" : v 297 | end 298 | result 299 | end 300 | end 301 | 302 | def ip_address_from(env_hash) 303 | ENV_IP_ADDRESS_KEYS.each do |key_to_try| 304 | return env_hash[key_to_try] unless env_hash[key_to_try].nil? || env_hash[key_to_try] == "" 305 | end 306 | "(Not Available)" 307 | end 308 | 309 | def print_api_key_warning 310 | $stderr.puts(NO_API_KEY_MESSAGE) 311 | end 312 | end 313 | end 314 | -------------------------------------------------------------------------------- /lib/raygun/configuration.rb: -------------------------------------------------------------------------------- 1 | module Raygun 2 | class Configuration 3 | 4 | def self.config_option(name) 5 | define_method(name) do 6 | read_value(name) 7 | end 8 | 9 | define_method("#{name}=") do |value| 10 | set_value(name, value) 11 | end 12 | end 13 | 14 | def self.proc_config_option(name) 15 | define_method(name) do |&block| 16 | set_value(name, block) unless block == nil 17 | read_value(name) 18 | end 19 | 20 | define_method("#{name}=") do |value| 21 | set_value(name, value) 22 | end 23 | end 24 | 25 | # Your Raygun API Key - this can be found on your dashboard at https://app.raygun.com 26 | config_option :api_key 27 | 28 | # Your JS Raygun API Key - Should be different to your api_key, it's best practice to separate your errors between front end and back end. 29 | config_option :js_api_key 30 | 31 | # Your JS Raygun API Version, defaults to latest as found on https://raygun.com/documentation/language-guides/javascript/crash-reporting/installation/ 32 | config_option :js_api_version 33 | 34 | # Array of exception classes to ignore 35 | config_option :ignore 36 | 37 | # Version to use 38 | config_option :version 39 | 40 | # Custom Data to send with each exception 41 | proc_config_option :custom_data 42 | 43 | # Tags to send with each exception 44 | proc_config_option :tags 45 | 46 | # Logger to use when we find an exception :) 47 | config_option :logger 48 | 49 | # Should we actually report exceptions to Raygun? (Usually disabled in Development mode, for instance) 50 | config_option :enable_reporting 51 | 52 | # Failsafe logger (for exceptions that happen when we're attempting to report exceptions) 53 | config_option :failsafe_logger 54 | 55 | # Which controller method should we call to find out the affected user? 56 | config_option :affected_user_method 57 | 58 | # Mapping of methods for the affected user object - which methods should we call for user information 59 | config_option :affected_user_mapping 60 | 61 | # Which parameter keys should we filter out by default? 62 | proc_config_option :filter_parameters 63 | 64 | # Should we switch to a white listing mode for keys instead of the default blacklist? 65 | config_option :filter_payload_with_whitelist 66 | 67 | # If :filter_payload_with_whitelist is true, which keys should we whitelist? 68 | proc_config_option :whitelist_payload_shape 69 | 70 | # Hash of proxy settings - :address, :port (defaults to 80), :username and :password (both default to nil) 71 | config_option :proxy_settings 72 | 73 | # Set this to true to have raygun4ruby log the reason why it skips reporting an exception 74 | config_option :debug 75 | 76 | # Override this if you wish to connect to a different Raygun API than the standard one 77 | config_option :api_url 78 | 79 | # Should Raygun include the raw request body in the payload? This will not include 80 | # form submissions and will not be filtered by the blacklist 81 | config_option :record_raw_data 82 | 83 | # Should the exceptions to Raygun be sent asynchronously? 84 | config_option :send_in_background 85 | 86 | # How long to wait for the POST request to the API server before timing out 87 | config_option :error_report_send_timeout 88 | 89 | # How many times to try sending to Raygun before giving up 90 | config_option :error_report_max_attempts 91 | 92 | # Whether or not we should raise an exception if the error reporting fails 93 | config_option :raise_on_failed_error_report 94 | 95 | # Should we register an error handler with [Rails' built in API](https://edgeguides.rubyonrails.org/error_reporting.html) 96 | config_option :register_rails_error_handler 97 | 98 | # Should we track jobs that are retried in Sidekiq (ones that raise Sidekiq::JobRetry::Handled). Set to "false" to ignore. 99 | config_option :track_retried_sidekiq_jobs 100 | 101 | # Exception classes to ignore by default 102 | IGNORE_DEFAULT = ['ActiveRecord::RecordNotFound', 103 | 'ActionController::RoutingError', 104 | 'ActionController::InvalidAuthenticityToken', 105 | 'ActionDispatch::ParamsParser::ParseError', 106 | 'CGI::Session::CookieStore::TamperedWithCookie', 107 | 'ActionController::UnknownAction', 108 | 'AbstractController::ActionNotFound', 109 | 'Mongoid::Errors::DocumentNotFound', 110 | 'Sidekiq::JobRetry::Skip'] 111 | 112 | DEFAULT_FILTER_PARAMETERS = [ :password, :card_number, :cvv ] 113 | 114 | DEFAULT_WHITELIST_PAYLOAD_SHAPE_REQUEST = { 115 | hostName: true, 116 | url: true, 117 | httpMethod: true, 118 | iPAddress: true, 119 | queryString: true, 120 | headers: true, 121 | form: {}, # Set to empty hash so that it doesn't just filter out the whole thing, but instead filters out each individual param 122 | rawData: true 123 | }.freeze 124 | DEFAULT_WHITELIST_PAYLOAD_SHAPE = { 125 | machineName: true, 126 | version: true, 127 | error: true, 128 | userCustomData: true, 129 | tags: true, 130 | request: DEFAULT_WHITELIST_PAYLOAD_SHAPE_REQUEST 131 | }.freeze 132 | 133 | attr_reader :defaults 134 | 135 | def initialize 136 | @config_values = {} 137 | 138 | # set default attribute values 139 | @defaults = OpenStruct.new( 140 | ignore: IGNORE_DEFAULT, 141 | custom_data: {}, 142 | tags: [], 143 | enable_reporting: true, 144 | affected_user_method: :current_user, 145 | affected_user_mapping: AffectedUser::DEFAULT_MAPPING, 146 | filter_parameters: DEFAULT_FILTER_PARAMETERS, 147 | filter_payload_with_whitelist: false, 148 | whitelist_payload_shape: DEFAULT_WHITELIST_PAYLOAD_SHAPE, 149 | proxy_settings: {}, 150 | debug: false, 151 | api_url: 'https://api.raygun.com/', 152 | breadcrumb_level: :info, 153 | record_raw_data: false, 154 | send_in_background: false, 155 | error_report_send_timeout: 10, 156 | error_report_max_attempts: 1, 157 | raise_on_failed_error_report: false, 158 | track_retried_sidekiq_jobs: true 159 | ) 160 | end 161 | 162 | def [](key) 163 | read_value(key) 164 | end 165 | 166 | def []=(key, value) 167 | set_value(key, value) 168 | end 169 | 170 | def silence_reporting 171 | !enable_reporting 172 | end 173 | 174 | def silence_reporting=(value) 175 | self.enable_reporting = !value 176 | end 177 | 178 | def breadcrumb_level 179 | read_value(:breadcrumb_level) 180 | end 181 | 182 | def breadcrumb_level=(value) 183 | if Raygun::Breadcrumbs::BREADCRUMB_LEVELS.include?(value) 184 | set_value(:breadcrumb_level, value) 185 | elsif read_value(:debug) 186 | Raygun.log("[Raygun.configuration] unknown breadcrumb level: #{value} not setting") 187 | end 188 | end 189 | 190 | def affected_user_identifier_methods 191 | Raygun.deprecation_warning("Please note: You should now user config.affected_user_method_mapping.Identifier instead of config.affected_user_identifier_methods") 192 | read_value(:affected_user_mapping)[:identifier] 193 | end 194 | 195 | private 196 | 197 | def read_value(name) 198 | if @config_values.has_key?(name) 199 | @config_values[name] 200 | else 201 | @defaults.send(name) 202 | end 203 | end 204 | 205 | def set_value(name, value) 206 | @config_values[name] = value 207 | end 208 | 209 | end 210 | end 211 | -------------------------------------------------------------------------------- /lib/raygun/demo_exception.rb: -------------------------------------------------------------------------------- 1 | module Raygun 2 | 3 | class ItWorksException < StandardError; end 4 | 5 | module DemoException 6 | 7 | def track_test_exception 8 | Raygun.configuration.silence_reporting = false 9 | raise ItWorksException.new("Woohoo! Your Raygun<->Ruby connection is set up correctly") 10 | rescue ItWorksException => e 11 | response = Raygun.track_exception(e) 12 | 13 | if response.success? 14 | puts "Success! Now go check your Raygun Crash Reporting dashboard" 15 | else 16 | puts "Oh-oh, something went wrong - double check your API key" 17 | puts "API Key - " << Raygun.configuration.api_key << ")" 18 | puts "API Response - " << response 19 | end 20 | end 21 | 22 | end 23 | end -------------------------------------------------------------------------------- /lib/raygun/error.rb: -------------------------------------------------------------------------------- 1 | module Raygun 2 | class Error < StandardError 3 | attr_reader :raygun_custom_data 4 | 5 | def initialize(message, raygun_custom_data = {}) 6 | super(message) 7 | @raygun_custom_data = raygun_custom_data 8 | end 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /lib/raygun/error_subscriber.rb: -------------------------------------------------------------------------------- 1 | # Subscribes to errors using Rails' error reporting API 2 | # https://edgeguides.rubyonrails.org/error_reporting.html 3 | class Raygun::ErrorSubscriber 4 | def report(error, handled:, severity:, context:, source: nil) 5 | tags = context.delete(:tags) if context.is_a?(Hash) 6 | 7 | data = { 8 | custom_data: { 9 | "rails.error": { 10 | handled: handled, 11 | severity: severity, 12 | context: context, 13 | source: source 14 | }, 15 | }, 16 | tags: ["rails_error_reporter", *tags].compact 17 | } 18 | 19 | if source == "job.sidekiq" && defined?(Sidekiq) 20 | Raygun::SidekiqReporter.call(error, data) 21 | else 22 | Raygun.track_exception(error, data) 23 | end 24 | end 25 | end -------------------------------------------------------------------------------- /lib/raygun/javascript_tracker.rb: -------------------------------------------------------------------------------- 1 | # Client for injecting JavaScript code for tracking front end exceptions 2 | # https://raygun.com/docs/languages/javascript 3 | module Raygun 4 | class JavaScriptTracker 5 | def head_html 6 | return unless js_api_key? 7 | [ 8 | '' 15 | ].join('').html_safe 16 | end 17 | 18 | def body_html 19 | return unless js_api_key? 20 | [ 21 | '' 25 | ].join('').html_safe 26 | end 27 | 28 | private 29 | 30 | def js_api_key 31 | @js_api_key ||= Raygun.configuration.js_api_key 32 | end 33 | 34 | def js_api_version 35 | @js_api_version ||= Raygun.configuration.js_api_version ? "#{Raygun.configuration.js_api_version}/" : '' 36 | end 37 | 38 | def js_api_key? 39 | js_api_key.present? 40 | end 41 | end 42 | end 43 | -------------------------------------------------------------------------------- /lib/raygun/middleware/breadcrumbs_store_initializer.rb: -------------------------------------------------------------------------------- 1 | module Raygun 2 | module Middleware 3 | class BreadcrumbsStoreInitializer 4 | def initialize(app) 5 | @app = app 6 | end 7 | 8 | def call(env) 9 | Breadcrumbs::Store.initialize 10 | 11 | begin 12 | @app.call(env) 13 | ensure 14 | Breadcrumbs::Store.clear 15 | end 16 | end 17 | end 18 | end 19 | end 20 | -------------------------------------------------------------------------------- /lib/raygun/middleware/javascript_exception_tracking.rb: -------------------------------------------------------------------------------- 1 | module Raygun::Middleware 2 | class JavascriptExceptionTracking 3 | def initialize(app) 4 | @app = app 5 | end 6 | 7 | def call(env) 8 | status, headers, response = @app.call(env) 9 | 10 | # It's a html file, inject our JS 11 | if headers['Content-Type'] && headers['Content-Type'].include?('text/html') 12 | response = inject_javascript_to_response(response) 13 | end 14 | 15 | [status, headers, response] 16 | end 17 | 18 | def inject_javascript_to_response(response) 19 | if Raygun.configuration.js_api_key.present? 20 | if response.respond_to?('[]') 21 | response[0].gsub!('', "#{js_tracker.head_html}") 22 | response[0].gsub!('', "#{js_tracker.body_html}") 23 | end 24 | 25 | if response.respond_to?(:body) # Rack::BodyProxy 26 | body = response.body 27 | body.gsub!('', "#{js_tracker.head_html}") 28 | body.gsub!('', "#{js_tracker.body_html}") 29 | end 30 | end 31 | 32 | response 33 | end 34 | 35 | private 36 | def js_tracker 37 | @js_tracker = Raygun::JavaScriptTracker.new 38 | end 39 | end 40 | end 41 | -------------------------------------------------------------------------------- /lib/raygun/middleware/rack_exception_interceptor.rb: -------------------------------------------------------------------------------- 1 | module Raygun 2 | module Middleware 3 | class RackExceptionInterceptor 4 | 5 | def initialize(app) 6 | @app = app 7 | end 8 | 9 | def call(env) 10 | @app.call(env) 11 | rescue Exception => exception 12 | Raygun.track_exception(exception, env) if Raygun.configured? 13 | raise exception 14 | end 15 | 16 | end 17 | end 18 | end 19 | -------------------------------------------------------------------------------- /lib/raygun/middleware/rails_insert_affected_user.rb: -------------------------------------------------------------------------------- 1 | module Raygun 2 | module Middleware 3 | # Adapted from the Rollbar approach https://github.com/rollbar/rollbar-gem/blob/master/lib/rollbar/middleware/rails/rollbar_request_store.rb 4 | class RailsInsertAffectedUser 5 | 6 | def initialize(app) 7 | @app = app 8 | end 9 | 10 | def call(env) 11 | @app.call(env) 12 | rescue Exception => exception 13 | controller = env["action_controller.instance"] 14 | affected_user_method = Raygun.configuration.affected_user_method 15 | 16 | if controller && controller.respond_to?(affected_user_method, true) 17 | user = controller.send(affected_user_method) 18 | 19 | env["raygun.affected_user"] = Raygun::AffectedUser.information_hash(user) 20 | end 21 | 22 | raise exception 23 | end 24 | end 25 | end 26 | end 27 | -------------------------------------------------------------------------------- /lib/raygun/railtie.rb: -------------------------------------------------------------------------------- 1 | require "raygun/middleware/rails_insert_affected_user" 2 | 3 | class Raygun::Railtie < Rails::Railtie 4 | initializer "raygun.configure_rails_initialization" do |app| 5 | 6 | # Thanks Airbrake: See https://github.com/rails/rails/pull/8624 7 | middleware = if defined?(ActionDispatch::DebugExceptions) 8 | if Rails::VERSION::STRING >= "5" 9 | ActionDispatch::DebugExceptions 10 | else 11 | # Rails >= 3.2.0 12 | "ActionDispatch::DebugExceptions" 13 | end 14 | else 15 | # Rails < 3.2.0 16 | "ActionDispatch::ShowExceptions" 17 | end 18 | 19 | raygun_middleware = [ 20 | Raygun::Middleware::RailsInsertAffectedUser, 21 | Raygun::Middleware::RackExceptionInterceptor, 22 | Raygun::Middleware::BreadcrumbsStoreInitializer, 23 | Raygun::Middleware::JavascriptExceptionTracking 24 | ] 25 | raygun_middleware = raygun_middleware.map(&:to_s) unless Rails::VERSION::STRING >= "5" 26 | raygun_middleware.each do |m| 27 | app.config.middleware.insert_after(middleware, m) 28 | end 29 | end 30 | 31 | config.to_prepare do 32 | Raygun.default_configuration.logger = Rails.logger 33 | Raygun.default_configuration.enable_reporting = Rails.env.production? 34 | 35 | Raygun::Railtie.setup_error_subscriber 36 | end 37 | 38 | rake_tasks do 39 | load "tasks/raygun.tasks" 40 | end 41 | 42 | def self.setup_error_subscriber 43 | if ::Rails.version.to_f >= 7.0 && Raygun.configuration.register_rails_error_handler 44 | Rails.error.subscribe(Raygun::ErrorSubscriber.new) 45 | end 46 | end 47 | end 48 | -------------------------------------------------------------------------------- /lib/raygun/services/apply_whitelist_filter_to_payload.rb: -------------------------------------------------------------------------------- 1 | module Raygun 2 | module Services 3 | class ApplyWhitelistFilterToPayload 4 | def call(whitelist, payload) 5 | filter_hash(whitelist, payload) 6 | end 7 | 8 | private 9 | 10 | def filter_hash(whitelist, hash) 11 | # dup the input so each level of the hash is dup'd 12 | # not just the top as dup isn't deep 13 | hash = hash.dup 14 | 15 | hash.each do |k, v| 16 | unless whitelist && (whitelist[k] || whitelist[k.to_sym]) 17 | hash[k] = '[FILTERED]' 18 | end 19 | 20 | if v.is_a?(Hash) && whitelist[k].is_a?(Hash) 21 | hash[k] = filter_hash(whitelist[k], v) 22 | end 23 | end 24 | end 25 | end 26 | end 27 | end 28 | -------------------------------------------------------------------------------- /lib/raygun/sidekiq.rb: -------------------------------------------------------------------------------- 1 | # Adapted from Bugsnag code, and Sidekiq Erorr Handling instructions 2 | # 3 | # SideKiq: https://github.com/sidekiq/sidekiq/wiki/Error-Handling 4 | # Bugsnag: https://github.com/bugsnag/bugsnag-ruby/blob/master/lib/bugsnag/sidekiq.rb 5 | 6 | module Raygun 7 | 8 | class SidekiqReporter 9 | def self.call(exception, context_hash = {}, config = nil) 10 | user = affected_user(context_hash) 11 | data = { 12 | custom_data: { 13 | sidekiq_context: context_hash 14 | }, 15 | tags: ['sidekiq'] 16 | } 17 | 18 | if exception.is_a?(Sidekiq::JobRetry::Handled) && exception.cause 19 | if Raygun.configuration.track_retried_sidekiq_jobs 20 | data.merge!(sidekiq_retried: true) 21 | exception = exception.cause 22 | else 23 | return false 24 | end 25 | end 26 | 27 | if exception.instance_variable_defined?(:@__raygun_correlation_id) && correlation_id = exception.instance_variable_get(:@__raygun_correlation_id) 28 | data.merge!(correlation_id: correlation_id) 29 | end 30 | ::Raygun.track_exception( 31 | exception, 32 | data, 33 | user 34 | ) 35 | end 36 | 37 | # Extracts affected user information out of a Sidekiq worker class 38 | def self.affected_user(context_hash) 39 | job = context_hash[:job] 40 | 41 | return if job.nil? || job['class'].nil? || !Module.const_defined?(job['class']) 42 | 43 | worker_class = Module.const_get(job['class']) 44 | affected_user_method = Raygun.configuration.affected_user_method 45 | 46 | return if worker_class.nil? || !worker_class.respond_to?(affected_user_method) 47 | 48 | worker_class.send(affected_user_method, job['args']) 49 | rescue => e 50 | return unless Raygun.configuration.failsafe_logger 51 | 52 | failsafe_log("Problem in sidekiq affected user tracking: #{e.class}: #{e.message}\n\n#{e.backtrace.join("\n")}") 53 | 54 | nil 55 | end 56 | end 57 | end 58 | 59 | Sidekiq.configure_server do |config| 60 | config.error_handlers << Raygun::SidekiqReporter 61 | end 62 | -------------------------------------------------------------------------------- /lib/raygun/version.rb: -------------------------------------------------------------------------------- 1 | module Raygun 2 | VERSION = "4.0.2" 3 | end 4 | -------------------------------------------------------------------------------- /lib/raygun4ruby.rb: -------------------------------------------------------------------------------- 1 | require "raygun" 2 | -------------------------------------------------------------------------------- /lib/resque/failure/raygun.rb: -------------------------------------------------------------------------------- 1 | begin 2 | require 'resque' 3 | rescue LoadError 4 | raise "Can't find 'resque' gem. You'll need to require it before you require the Raygun Failure handler" 5 | end 6 | 7 | module Resque 8 | module Failure 9 | class Raygun < Base 10 | 11 | def save 12 | ::Raygun.track_exception(exception, 13 | custom_data: { 14 | resque: { 15 | worker: worker.to_s, 16 | queue: queue.to_s, 17 | job: payload['class'].to_s, 18 | args: payload['args'].inspect 19 | } 20 | } 21 | ) 22 | end 23 | 24 | end 25 | end 26 | end -------------------------------------------------------------------------------- /lib/tasks/raygun.tasks: -------------------------------------------------------------------------------- 1 | namespace :raygun do 2 | 3 | desc "Test Raygun integration" 4 | task :test => :environment do 5 | Raygun.track_test_exception 6 | end 7 | 8 | end -------------------------------------------------------------------------------- /raygun4ruby.gemspec: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | lib = File.expand_path("../lib", __FILE__) 3 | $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) 4 | require "raygun/version" 5 | 6 | Gem::Specification.new do |spec| 7 | spec.name = "raygun4ruby" 8 | spec.version = Raygun::VERSION 9 | spec.authors = ["Mindscape", "Nik Wakelin"] 10 | spec.email = ["hello@raygun.com"] 11 | spec.description = %q{Ruby Adapter for Raygun} 12 | spec.summary = %q{This gem provides support for Ruby and Ruby on Rails for the Raygun.com error reporter} 13 | spec.homepage = "https://raygun.com" 14 | spec.license = "MIT" 15 | spec.required_ruby_version = ">= 2.0" 16 | 17 | spec.files = `git ls-files | grep -Ev "^(test)"`.split("\n") 18 | spec.test_files = `git ls-files -- test/*`.split("\n") 19 | 20 | spec.executables = [] 21 | spec.require_paths = ["lib"] 22 | 23 | spec.add_runtime_dependency "httparty", "> 0.13.7" 24 | spec.add_runtime_dependency "json" 25 | spec.add_runtime_dependency "rack" 26 | spec.add_runtime_dependency "concurrent-ruby" 27 | spec.add_runtime_dependency "ostruct" 28 | 29 | spec.add_development_dependency "bundler", ">= 2.3" 30 | spec.add_development_dependency "rake", ">= 12.3.3" 31 | spec.add_development_dependency "appraisal" 32 | spec.add_development_dependency "timecop" 33 | spec.add_development_dependency "minitest", "~> 5.11" 34 | spec.add_development_dependency "redis-namespace", ">= 1.3.1" 35 | spec.add_development_dependency "resque" 36 | spec.add_development_dependency "mocha" 37 | spec.add_development_dependency "pry" 38 | spec.add_development_dependency "webmock" 39 | 40 | spec.add_development_dependency "capybara" 41 | spec.add_development_dependency "rspec-rails" 42 | spec.add_development_dependency "launchy" 43 | spec.add_development_dependency "simplecov" 44 | end 45 | -------------------------------------------------------------------------------- /spec/features/javascript_spec.rb: -------------------------------------------------------------------------------- 1 | require 'rails_helper' 2 | 3 | feature 'JavaScript Tracking', feature: true do 4 | before { Raygun.configuration.js_api_key = nil } 5 | after { Raygun.configuration.js_api_key = nil } 6 | 7 | it "Includes the Raygun Javascript Middleware" do 8 | expect(Rails.application.config.middleware).to include(Raygun::Middleware::JavascriptExceptionTracking) 9 | end 10 | 11 | it "Does not inject the JS snippet" do 12 | visit root_path 13 | 14 | expect(page.html).to_not include('cdn.raygun.io/raygun4js/raygun.min.js') 15 | expect(page.html).to_not include('rg4js(') 16 | end 17 | 18 | context 'With a JS API Key' do 19 | before { Raygun.configuration.js_api_key = 'Sample key' } 20 | 21 | it "Injects the JS snippet" do 22 | visit root_path 23 | 24 | expect(page.html).to include('cdn.raygun.io/raygun4js/raygun.min.js') 25 | expect(page.html).to include('rg4js(') 26 | end 27 | 28 | it "Does not inject the JS snippet" do 29 | visit root_path(format: :json) 30 | 31 | expect(page.html).to_not include('cdn.raygun.io/raygun4js/raygun.min.js') 32 | expect(page.html).to_not include('rg4js(') 33 | end 34 | end 35 | 36 | context "With JS version overriden" do 37 | before do 38 | Raygun.configuration.js_api_version = "2.14.1" 39 | Raygun.configuration.js_api_key = "Sample key" 40 | end 41 | 42 | it "Uses the overriden version" do 43 | visit root_path 44 | 45 | expect(page.html).to include('cdn.raygun.io/raygun4js/2.14.1/raygun.min.js') 46 | end 47 | end 48 | end 49 | -------------------------------------------------------------------------------- /spec/rails_applications/6.1.4/Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | git_source(:github) { |repo| "https://github.com/#{repo}.git" } 3 | 4 | ruby '2.6.3' 5 | 6 | # Bundle edge Rails instead: gem 'rails', github: 'rails/rails', branch: 'main' 7 | gem 'rails', '~> 6.1.4' 8 | # Use sqlite3 as the database for Active Record 9 | gem 'sqlite3', '~> 1.4' 10 | # Use Puma as the app server 11 | gem 'puma', '~> 5.0' 12 | # Use SCSS for stylesheets 13 | gem 'sass-rails', '>= 6' 14 | # Transpile app-like JavaScript. Read more: https://github.com/rails/webpacker 15 | gem 'webpacker', '~> 5.0' 16 | # Turbolinks makes navigating your web application faster. Read more: https://github.com/turbolinks/turbolinks 17 | gem 'turbolinks', '~> 5' 18 | # Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder 19 | gem 'jbuilder', '~> 2.7' 20 | # Use Redis adapter to run Action Cable in production 21 | # gem 'redis', '~> 4.0' 22 | # Use Active Model has_secure_password 23 | # gem 'bcrypt', '~> 3.1.7' 24 | 25 | # Use Active Storage variant 26 | # gem 'image_processing', '~> 1.2' 27 | 28 | # Reduces boot times through caching; required in config/boot.rb 29 | gem 'bootsnap', '>= 1.4.4', require: false 30 | 31 | group :development, :test do 32 | # Call 'byebug' anywhere in the code to stop execution and get a debugger console 33 | gem 'byebug', platforms: [:mri, :mingw, :x64_mingw] 34 | end 35 | 36 | group :development do 37 | # Access an interactive console on exception pages or by calling 'console' anywhere in the code. 38 | gem 'web-console', '>= 4.1.0' 39 | # Display performance information such as SQL time and flame graphs for each request in your browser. 40 | # Can be configured to work on production as well see: https://github.com/MiniProfiler/rack-mini-profiler/blob/master/README.md 41 | gem 'rack-mini-profiler', '~> 2.0' 42 | gem 'listen', '~> 3.3' 43 | # Spring speeds up development by keeping your application running in the background. Read more: https://github.com/rails/spring 44 | gem 'spring' 45 | end 46 | 47 | group :test do 48 | # Adds support for Capybara system testing and selenium driver 49 | gem 'capybara', '>= 3.26' 50 | gem 'selenium-webdriver' 51 | # Easy installation and use of web drivers to run system tests with browsers 52 | gem 'webdrivers' 53 | end 54 | 55 | # Windows does not include zoneinfo files, so bundle the tzinfo-data gem 56 | gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby] 57 | -------------------------------------------------------------------------------- /spec/rails_applications/6.1.4/README.md: -------------------------------------------------------------------------------- 1 | # README 2 | 3 | This README would normally document whatever steps are necessary to get the 4 | application up and running. 5 | 6 | Things you may want to cover: 7 | 8 | * Ruby version 9 | 10 | * System dependencies 11 | 12 | * Configuration 13 | 14 | * Database creation 15 | 16 | * Database initialization 17 | 18 | * How to run the test suite 19 | 20 | * Services (job queues, cache servers, search engines, etc.) 21 | 22 | * Deployment instructions 23 | 24 | * ... 25 | -------------------------------------------------------------------------------- /spec/rails_applications/6.1.4/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/rails_applications/6.1.4/app/assets/config/manifest.js: -------------------------------------------------------------------------------- 1 | //= link_tree ../images 2 | //= link_directory ../stylesheets .css 3 | -------------------------------------------------------------------------------- /spec/rails_applications/6.1.4/app/assets/images/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MindscapeHQ/raygun4ruby/5f6e26c34516ae09f9c1fac54e2a6f1df71030e4/spec/rails_applications/6.1.4/app/assets/images/.keep -------------------------------------------------------------------------------- /spec/rails_applications/6.1.4/app/assets/stylesheets/application.css: -------------------------------------------------------------------------------- 1 | /* 2 | * This is a manifest file that'll be compiled into application.css, which will include all the files 3 | * listed below. 4 | * 5 | * Any CSS and SCSS file within this directory, lib/assets/stylesheets, or any plugin's 6 | * vendor/assets/stylesheets directory can be referenced here using a relative path. 7 | * 8 | * You're free to add application-wide styles to this file and they'll appear at the bottom of the 9 | * compiled file so the styles you add here take precedence over styles defined in any other CSS/SCSS 10 | * files in this directory. Styles in this file should be added after the last require_* statement. 11 | * It is generally better to create a new file per style scope. 12 | * 13 | *= require_tree . 14 | *= require_self 15 | */ 16 | -------------------------------------------------------------------------------- /spec/rails_applications/6.1.4/app/channels/application_cable/channel.rb: -------------------------------------------------------------------------------- 1 | module ApplicationCable 2 | class Channel < ActionCable::Channel::Base 3 | end 4 | end 5 | -------------------------------------------------------------------------------- /spec/rails_applications/6.1.4/app/channels/application_cable/connection.rb: -------------------------------------------------------------------------------- 1 | module ApplicationCable 2 | class Connection < ActionCable::Connection::Base 3 | end 4 | end 5 | -------------------------------------------------------------------------------- /spec/rails_applications/6.1.4/app/controllers/application_controller.rb: -------------------------------------------------------------------------------- 1 | class ApplicationController < ActionController::Base 2 | end 3 | -------------------------------------------------------------------------------- /spec/rails_applications/6.1.4/app/controllers/concerns/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MindscapeHQ/raygun4ruby/5f6e26c34516ae09f9c1fac54e2a6f1df71030e4/spec/rails_applications/6.1.4/app/controllers/concerns/.keep -------------------------------------------------------------------------------- /spec/rails_applications/6.1.4/app/controllers/home_controller.rb: -------------------------------------------------------------------------------- 1 | class HomeController < ApplicationController 2 | def home 3 | end 4 | end 5 | -------------------------------------------------------------------------------- /spec/rails_applications/6.1.4/app/helpers/application_helper.rb: -------------------------------------------------------------------------------- 1 | module ApplicationHelper 2 | end 3 | -------------------------------------------------------------------------------- /spec/rails_applications/6.1.4/app/javascript/channels/consumer.js: -------------------------------------------------------------------------------- 1 | // Action Cable provides the framework to deal with WebSockets in Rails. 2 | // You can generate new channels where WebSocket features live using the `bin/rails generate channel` command. 3 | 4 | import { createConsumer } from "@rails/actioncable" 5 | 6 | export default createConsumer() 7 | -------------------------------------------------------------------------------- /spec/rails_applications/6.1.4/app/javascript/channels/index.js: -------------------------------------------------------------------------------- 1 | // Load all the channels within this directory and all subdirectories. 2 | // Channel files must be named *_channel.js. 3 | 4 | const channels = require.context('.', true, /_channel\.js$/) 5 | channels.keys().forEach(channels) 6 | -------------------------------------------------------------------------------- /spec/rails_applications/6.1.4/app/javascript/packs/application.js: -------------------------------------------------------------------------------- 1 | // This file is automatically compiled by Webpack, along with any other files 2 | // present in this directory. You're encouraged to place your actual application logic in 3 | // a relevant structure within app/javascript and only use these pack files to reference 4 | // that code so it'll be compiled. 5 | 6 | import Rails from "@rails/ujs" 7 | import Turbolinks from "turbolinks" 8 | import * as ActiveStorage from "@rails/activestorage" 9 | import "channels" 10 | 11 | Rails.start() 12 | Turbolinks.start() 13 | ActiveStorage.start() 14 | -------------------------------------------------------------------------------- /spec/rails_applications/6.1.4/app/jobs/application_job.rb: -------------------------------------------------------------------------------- 1 | class ApplicationJob < ActiveJob::Base 2 | # Automatically retry jobs that encountered a deadlock 3 | # retry_on ActiveRecord::Deadlocked 4 | 5 | # Most jobs are safe to ignore if the underlying records are no longer available 6 | # discard_on ActiveJob::DeserializationError 7 | end 8 | -------------------------------------------------------------------------------- /spec/rails_applications/6.1.4/app/mailers/application_mailer.rb: -------------------------------------------------------------------------------- 1 | class ApplicationMailer < ActionMailer::Base 2 | default from: 'from@example.com' 3 | layout 'mailer' 4 | end 5 | -------------------------------------------------------------------------------- /spec/rails_applications/6.1.4/app/models/application_record.rb: -------------------------------------------------------------------------------- 1 | class ApplicationRecord < ActiveRecord::Base 2 | self.abstract_class = true 3 | end 4 | -------------------------------------------------------------------------------- /spec/rails_applications/6.1.4/app/models/concerns/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MindscapeHQ/raygun4ruby/5f6e26c34516ae09f9c1fac54e2a6f1df71030e4/spec/rails_applications/6.1.4/app/models/concerns/.keep -------------------------------------------------------------------------------- /spec/rails_applications/6.1.4/app/views/home/index.html.erb: -------------------------------------------------------------------------------- 1 |

Home#index

2 |

Find me in app/views/home/index.html.erb

3 |

<%= Raygun.configuration.js_api_key %>

4 | -------------------------------------------------------------------------------- /spec/rails_applications/6.1.4/app/views/home/index.json.erb: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /spec/rails_applications/6.1.4/app/views/layouts/application.html.erb: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Dummy 5 | 6 | <%= csrf_meta_tags %> 7 | <%= csp_meta_tag %> 8 | 9 | 10 | 11 | <%= yield %> 12 | 13 | 14 | -------------------------------------------------------------------------------- /spec/rails_applications/6.1.4/app/views/layouts/mailer.html.erb: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 8 | 9 | 10 | 11 | <%= yield %> 12 | 13 | 14 | -------------------------------------------------------------------------------- /spec/rails_applications/6.1.4/app/views/layouts/mailer.text.erb: -------------------------------------------------------------------------------- 1 | <%= yield %> 2 | -------------------------------------------------------------------------------- /spec/rails_applications/6.1.4/bin/rails: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | load File.expand_path("spring", __dir__) 3 | APP_PATH = File.expand_path('../config/application', __dir__) 4 | require_relative "../config/boot" 5 | require "rails/commands" 6 | -------------------------------------------------------------------------------- /spec/rails_applications/6.1.4/bin/rake: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | load File.expand_path("spring", __dir__) 3 | require_relative "../config/boot" 4 | require "rake" 5 | Rake.application.run 6 | -------------------------------------------------------------------------------- /spec/rails_applications/6.1.4/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 | # Install JavaScript dependencies 21 | system! 'bin/yarn' 22 | 23 | # puts "\n== Copying sample files ==" 24 | # unless File.exist?('config/database.yml') 25 | # FileUtils.cp 'config/database.yml.sample', 'config/database.yml' 26 | # end 27 | 28 | puts "\n== Preparing database ==" 29 | system! 'bin/rails db:prepare' 30 | 31 | puts "\n== Removing old logs and tempfiles ==" 32 | system! 'bin/rails log:clear tmp:clear' 33 | 34 | puts "\n== Restarting application server ==" 35 | system! 'bin/rails restart' 36 | end 37 | -------------------------------------------------------------------------------- /spec/rails_applications/6.1.4/bin/spring: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | if !defined?(Spring) && [nil, "development", "test"].include?(ENV["RAILS_ENV"]) 3 | gem "bundler" 4 | require "bundler" 5 | 6 | # Load Spring without loading other gems in the Gemfile, for speed. 7 | Bundler.locked_gems&.specs&.find { |spec| spec.name == "spring" }&.tap do |spring| 8 | Gem.use_paths Gem.dir, Bundler.bundle_path.to_s, *Gem.path 9 | gem "spring", spring.version 10 | require "spring/binstub" 11 | rescue Gem::LoadError 12 | # Ignore when Spring is not installed. 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /spec/rails_applications/6.1.4/bin/yarn: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | APP_ROOT = File.expand_path('..', __dir__) 3 | Dir.chdir(APP_ROOT) do 4 | yarn = ENV["PATH"].split(File::PATH_SEPARATOR). 5 | select { |dir| File.expand_path(dir) != __dir__ }. 6 | product(["yarn", "yarn.cmd", "yarn.ps1"]). 7 | map { |dir, file| File.expand_path(file, dir) }. 8 | find { |file| File.executable?(file) } 9 | 10 | if yarn 11 | exec yarn, *ARGV 12 | else 13 | $stderr.puts "Yarn executable was not detected in the system." 14 | $stderr.puts "Download Yarn at https://yarnpkg.com/en/docs/install" 15 | exit 1 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /spec/rails_applications/6.1.4/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/rails_applications/6.1.4/config/application.rb: -------------------------------------------------------------------------------- 1 | require_relative "boot" 2 | 3 | require "rails/all" 4 | 5 | # Require the gems listed in Gemfile, including any gems 6 | # you've limited to :test, :development, or :production. 7 | Bundler.require(*Rails.groups) 8 | 9 | module Dummy 10 | class Application < Rails::Application 11 | # Initialize configuration defaults for originally generated Rails version. 12 | config.load_defaults 6.1 13 | 14 | # Configuration for the application, engines, and railties goes here. 15 | # 16 | # These settings can be overridden in specific environments using the files 17 | # in config/environments, which are processed later. 18 | # 19 | # config.time_zone = "Central Time (US & Canada)" 20 | # config.eager_load_paths << Rails.root.join("extras") 21 | end 22 | end 23 | -------------------------------------------------------------------------------- /spec/rails_applications/6.1.4/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 | -------------------------------------------------------------------------------- /spec/rails_applications/6.1.4/config/cable.yml: -------------------------------------------------------------------------------- 1 | development: 2 | adapter: async 3 | 4 | test: 5 | adapter: test 6 | 7 | production: 8 | adapter: redis 9 | url: <%= ENV.fetch("REDIS_URL") { "redis://localhost:6379/1" } %> 10 | channel_prefix: dummy_production 11 | -------------------------------------------------------------------------------- /spec/rails_applications/6.1.4/config/credentials.yml.enc: -------------------------------------------------------------------------------- 1 | TP13p+rsIB1CqXHd7WTBK/V7c8UoysyfwGwQi3NW2pETK4wrCDcae8NTlPABXjJE47tVttKGOLDviGP9lnCfrxW1fLMbCdNHEcuv0akgPjkBnTI2NAm/d1h+sqQxiD/cdTqSU84yYz4hnV/CzZ/SOnHj77XqGlBcF2eot2dI4JDayQfb6DK3cQC1Xbr0yi8WoIw5BfnH7jMSmstvSArzMi2GMA1swM2pZ2CEBRfF5OlSB+urrxVnA20wFReD+Nb9/0A/z1by6hP8PMMNgBRVYqRHvYGFu4zxSxQ9x416010+wRKwT/dfdUm9Y1hR9v0bSZpX07TEO4cdfz+Dc94HaB1ydWQ1OjJrUcz5gbE2DYZDjvZeQ4l1FL8frvm+1irZE7rAtk+qjHhHYqFpSi7/zVzTUrAv0Ny2MIhp--owt0TMtuGtE5tfhv--rqwMgDdo9gtJvq5rpa1cBQ== -------------------------------------------------------------------------------- /spec/rails_applications/6.1.4/config/database.yml: -------------------------------------------------------------------------------- 1 | # SQLite. Versions 3.8.0 and up are supported. 2 | # gem install sqlite3 3 | # 4 | # Ensure the SQLite 3 gem is defined in your Gemfile 5 | # gem 'sqlite3' 6 | # 7 | default: &default 8 | adapter: sqlite3 9 | pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %> 10 | timeout: 5000 11 | 12 | development: 13 | <<: *default 14 | database: db/development.sqlite3 15 | 16 | # Warning: The database defined as "test" will be erased and 17 | # re-generated from your development database when you run "rake". 18 | # Do not set this db to the same as development or production. 19 | test: 20 | <<: *default 21 | database: db/test.sqlite3 22 | 23 | production: 24 | <<: *default 25 | database: db/production.sqlite3 26 | -------------------------------------------------------------------------------- /spec/rails_applications/6.1.4/config/environment.rb: -------------------------------------------------------------------------------- 1 | # Load the Rails application. 2 | require_relative "application" 3 | 4 | # Initialize the Rails application. 5 | Rails.application.initialize! 6 | -------------------------------------------------------------------------------- /spec/rails_applications/6.1.4/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 | # Store uploaded files on the local file system (see config/storage.yml for options). 34 | config.active_storage.service = :local 35 | 36 | # Don't care if the mailer can't send. 37 | config.action_mailer.raise_delivery_errors = false 38 | 39 | config.action_mailer.perform_caching = false 40 | 41 | # Print deprecation notices to the Rails logger. 42 | config.active_support.deprecation = :log 43 | 44 | # Raise exceptions for disallowed deprecations. 45 | config.active_support.disallowed_deprecation = :raise 46 | 47 | # Tell Active Support which deprecation messages to disallow. 48 | config.active_support.disallowed_deprecation_warnings = [] 49 | 50 | # Raise an error on page load if there are pending migrations. 51 | config.active_record.migration_error = :page_load 52 | 53 | # Highlight code that triggered database queries in logs. 54 | config.active_record.verbose_query_logs = true 55 | 56 | # Debug mode disables concatenation and preprocessing of assets. 57 | # This option may cause significant delays in view rendering with a large 58 | # number of complex assets. 59 | config.assets.debug = true 60 | 61 | # Suppress logger output for asset requests. 62 | config.assets.quiet = true 63 | 64 | # Raises error for missing translations. 65 | # config.i18n.raise_on_missing_translations = true 66 | 67 | # Annotate rendered view with file names. 68 | # config.action_view.annotate_rendered_view_with_filenames = true 69 | 70 | # Use an evented file watcher to asynchronously detect changes in source code, 71 | # routes, locales, etc. This feature depends on the listen gem. 72 | config.file_watcher = ActiveSupport::EventedFileUpdateChecker 73 | 74 | # Uncomment if you wish to allow Action Cable access from any origin. 75 | # config.action_cable.disable_request_forgery_protection = true 76 | end 77 | -------------------------------------------------------------------------------- /spec/rails_applications/6.1.4/config/environments/production.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 | # 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 | # Ensures that a master key has been made available in either ENV["RAILS_MASTER_KEY"] 20 | # or in config/master.key. This key is used to decrypt credentials (and other encrypted files). 21 | # config.require_master_key = true 22 | 23 | # Disable serving static files from the `/public` folder by default since 24 | # Apache or NGINX already handles this. 25 | config.public_file_server.enabled = ENV['RAILS_SERVE_STATIC_FILES'].present? 26 | 27 | # Compress CSS using a preprocessor. 28 | # config.assets.css_compressor = :sass 29 | 30 | # Do not fallback to assets pipeline if a precompiled asset is missed. 31 | config.assets.compile = false 32 | 33 | # Enable serving of images, stylesheets, and JavaScripts from an asset server. 34 | # config.asset_host = 'http://assets.example.com' 35 | 36 | # Specifies the header that your server uses for sending files. 37 | # config.action_dispatch.x_sendfile_header = 'X-Sendfile' # for Apache 38 | # config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for NGINX 39 | 40 | # Store uploaded files on the local file system (see config/storage.yml for options). 41 | config.active_storage.service = :local 42 | 43 | # Mount Action Cable outside main process or domain. 44 | # config.action_cable.mount_path = nil 45 | # config.action_cable.url = 'wss://example.com/cable' 46 | # config.action_cable.allowed_request_origins = [ 'http://example.com', /http:\/\/example.*/ ] 47 | 48 | # Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies. 49 | # config.force_ssl = true 50 | 51 | # Include generic and useful information about system operation, but avoid logging too much 52 | # information to avoid inadvertent exposure of personally identifiable information (PII). 53 | config.log_level = :info 54 | 55 | # Prepend all log lines with the following tags. 56 | config.log_tags = [ :request_id ] 57 | 58 | # Use a different cache store in production. 59 | # config.cache_store = :mem_cache_store 60 | 61 | # Use a real queuing backend for Active Job (and separate queues per environment). 62 | # config.active_job.queue_adapter = :resque 63 | # config.active_job.queue_name_prefix = "dummy_production" 64 | 65 | config.action_mailer.perform_caching = false 66 | 67 | # Ignore bad email addresses and do not raise email delivery errors. 68 | # Set this to true and configure the email server for immediate delivery to raise delivery errors. 69 | # config.action_mailer.raise_delivery_errors = false 70 | 71 | # Enable locale fallbacks for I18n (makes lookups for any locale fall back to 72 | # the I18n.default_locale when a translation cannot be found). 73 | config.i18n.fallbacks = true 74 | 75 | # Send deprecation notices to registered listeners. 76 | config.active_support.deprecation = :notify 77 | 78 | # Log disallowed deprecations. 79 | config.active_support.disallowed_deprecation = :log 80 | 81 | # Tell Active Support which deprecation messages to disallow. 82 | config.active_support.disallowed_deprecation_warnings = [] 83 | 84 | # Use default logging formatter so that PID and timestamp are not suppressed. 85 | config.log_formatter = ::Logger::Formatter.new 86 | 87 | # Use a different logger for distributed setups. 88 | # require "syslog/logger" 89 | # config.logger = ActiveSupport::TaggedLogging.new(Syslog::Logger.new 'app-name') 90 | 91 | if ENV["RAILS_LOG_TO_STDOUT"].present? 92 | logger = ActiveSupport::Logger.new(STDOUT) 93 | logger.formatter = config.log_formatter 94 | config.logger = ActiveSupport::TaggedLogging.new(logger) 95 | end 96 | 97 | # Do not dump schema after migrations. 98 | config.active_record.dump_schema_after_migration = false 99 | 100 | # Inserts middleware to perform automatic connection switching. 101 | # The `database_selector` hash is used to pass options to the DatabaseSelector 102 | # middleware. The `delay` is used to determine how long to wait after a write 103 | # to send a subsequent read to the primary. 104 | # 105 | # The `database_resolver` class is used by the middleware to determine which 106 | # database is appropriate to use based on the time delay. 107 | # 108 | # The `database_resolver_context` class is used by the middleware to set 109 | # timestamps for the last write to the primary. The resolver uses the context 110 | # class timestamps to determine how long to wait before reading from the 111 | # replica. 112 | # 113 | # By default Rails will store a last write timestamp in the session. The 114 | # DatabaseSelector middleware is designed as such you can define your own 115 | # strategy for connection switching and pass that into the middleware through 116 | # these configuration options. 117 | # config.active_record.database_selector = { delay: 2.seconds } 118 | # config.active_record.database_resolver = ActiveRecord::Middleware::DatabaseSelector::Resolver 119 | # config.active_record.database_resolver_context = ActiveRecord::Middleware::DatabaseSelector::Resolver::Session 120 | end 121 | -------------------------------------------------------------------------------- /spec/rails_applications/6.1.4/config/environments/test.rb: -------------------------------------------------------------------------------- 1 | require "active_support/core_ext/integer/time" 2 | 3 | # The test environment is used exclusively to run your application's 4 | # test suite. You never need to work with it otherwise. Remember that 5 | # your test database is "scratch space" for the test suite and is wiped 6 | # and recreated between test runs. Don't rely on the data there! 7 | 8 | Rails.application.configure do 9 | # Settings specified here will take precedence over those in config/application.rb. 10 | 11 | config.cache_classes = false 12 | config.action_view.cache_template_loading = true 13 | 14 | # Do not eager load code on boot. This avoids loading your whole application 15 | # just for the purpose of running a single test. If you are using a tool that 16 | # preloads Rails for running tests, you may have to set it to true. 17 | config.eager_load = false 18 | 19 | # Configure public file server for tests with Cache-Control for performance. 20 | config.public_file_server.enabled = true 21 | config.public_file_server.headers = { 22 | 'Cache-Control' => "public, max-age=#{1.hour.to_i}" 23 | } 24 | 25 | # Show full error reports and disable caching. 26 | config.consider_all_requests_local = true 27 | config.action_controller.perform_caching = false 28 | config.cache_store = :null_store 29 | 30 | # Raise exceptions instead of rendering exception templates. 31 | config.action_dispatch.show_exceptions = false 32 | 33 | # Disable request forgery protection in test environment. 34 | config.action_controller.allow_forgery_protection = false 35 | 36 | # Store uploaded files on the local file system in a temporary directory. 37 | config.active_storage.service = :test 38 | 39 | config.action_mailer.perform_caching = false 40 | 41 | # Tell Action Mailer not to deliver emails to the real world. 42 | # The :test delivery method accumulates sent emails in the 43 | # ActionMailer::Base.deliveries array. 44 | config.action_mailer.delivery_method = :test 45 | 46 | # Print deprecation notices to the stderr. 47 | config.active_support.deprecation = :stderr 48 | 49 | # Raise exceptions for disallowed deprecations. 50 | config.active_support.disallowed_deprecation = :raise 51 | 52 | # Tell Active Support which deprecation messages to disallow. 53 | config.active_support.disallowed_deprecation_warnings = [] 54 | 55 | # Raises error for missing translations. 56 | # config.i18n.raise_on_missing_translations = true 57 | 58 | # Annotate rendered view with file names. 59 | # config.action_view.annotate_rendered_view_with_filenames = true 60 | end 61 | -------------------------------------------------------------------------------- /spec/rails_applications/6.1.4/config/initializers/application_controller_renderer.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # ActiveSupport::Reloader.to_prepare do 4 | # ApplicationController.renderer.defaults.merge!( 5 | # http_host: 'example.org', 6 | # https: false 7 | # ) 8 | # end 9 | -------------------------------------------------------------------------------- /spec/rails_applications/6.1.4/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 | # Add Yarn node_modules folder to the asset load path. 9 | Rails.application.config.assets.paths << Rails.root.join('node_modules') 10 | 11 | # Precompile additional assets. 12 | # application.js, application.css, and all non-JS/CSS in the app/assets 13 | # folder are already added. 14 | # Rails.application.config.assets.precompile += %w( admin.js admin.css ) 15 | -------------------------------------------------------------------------------- /spec/rails_applications/6.1.4/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/rails_applications/6.1.4/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 | # # If you are using webpack-dev-server then specify webpack-dev-server host 15 | # policy.connect_src :self, :https, "http://localhost:3035", "ws://localhost:3035" if Rails.env.development? 16 | 17 | # # Specify URI for violation reports 18 | # # policy.report_uri "/csp-violation-report-endpoint" 19 | # end 20 | 21 | # If you are using UJS then enable automatic nonce generation 22 | # Rails.application.config.content_security_policy_nonce_generator = -> request { SecureRandom.base64(16) } 23 | 24 | # Set the nonce only to specific directives 25 | # Rails.application.config.content_security_policy_nonce_directives = %w(script-src) 26 | 27 | # Report CSP violations to a specified URI 28 | # For further information see the following documentation: 29 | # https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy-Report-Only 30 | # Rails.application.config.content_security_policy_report_only = true 31 | -------------------------------------------------------------------------------- /spec/rails_applications/6.1.4/config/initializers/cookies_serializer.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Specify a serializer for the signed and encrypted cookie jars. 4 | # Valid options are :json, :marshal, and :hybrid. 5 | Rails.application.config.action_dispatch.cookies_serializer = :json 6 | -------------------------------------------------------------------------------- /spec/rails_applications/6.1.4/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/rails_applications/6.1.4/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/rails_applications/6.1.4/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/rails_applications/6.1.4/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/rails_applications/6.1.4/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 | 11 | # To enable root element in JSON for ActiveRecord objects. 12 | # ActiveSupport.on_load(:active_record) do 13 | # self.include_root_in_json = true 14 | # end 15 | -------------------------------------------------------------------------------- /spec/rails_applications/6.1.4/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 | # The following keys must be escaped otherwise they will not be retrieved by 20 | # the default I18n backend: 21 | # 22 | # true, false, on, off, yes, no 23 | # 24 | # Instead, surround them with single quotes. 25 | # 26 | # en: 27 | # 'true': 'foo' 28 | # 29 | # To learn more, please read the Rails Internationalization guide 30 | # available at https://guides.rubyonrails.org/i18n.html. 31 | 32 | en: 33 | hello: "Hello world" 34 | -------------------------------------------------------------------------------- /spec/rails_applications/6.1.4/config/master.key: -------------------------------------------------------------------------------- 1 | 38da412f92cc609d0a1de632d5619e30 -------------------------------------------------------------------------------- /spec/rails_applications/6.1.4/config/puma.rb: -------------------------------------------------------------------------------- 1 | # Puma can serve each request in a thread from an internal thread pool. 2 | # The `threads` method setting takes two numbers: a minimum and maximum. 3 | # Any libraries that use thread pools should be configured to match 4 | # the maximum value specified for Puma. Default is set to 5 threads for minimum 5 | # and maximum; this matches the default thread size of Active Record. 6 | # 7 | max_threads_count = ENV.fetch("RAILS_MAX_THREADS") { 5 } 8 | min_threads_count = ENV.fetch("RAILS_MIN_THREADS") { max_threads_count } 9 | threads min_threads_count, max_threads_count 10 | 11 | # Specifies the `worker_timeout` threshold that Puma will use to wait before 12 | # terminating a worker in development environments. 13 | # 14 | worker_timeout 3600 if ENV.fetch("RAILS_ENV", "development") == "development" 15 | 16 | # Specifies the `port` that Puma will listen on to receive requests; default is 3000. 17 | # 18 | port ENV.fetch("PORT") { 3000 } 19 | 20 | # Specifies the `environment` that Puma will run in. 21 | # 22 | environment ENV.fetch("RAILS_ENV") { "development" } 23 | 24 | # Specifies the `pidfile` that Puma will use. 25 | pidfile ENV.fetch("PIDFILE") { "tmp/pids/server.pid" } 26 | 27 | # Specifies the number of `workers` to boot in clustered mode. 28 | # Workers are forked web server processes. If using threads and workers together 29 | # the concurrency of the application would be max `threads` * `workers`. 30 | # Workers do not work on JRuby or Windows (both of which do not support 31 | # processes). 32 | # 33 | # workers ENV.fetch("WEB_CONCURRENCY") { 2 } 34 | 35 | # Use the `preload_app!` method when specifying a `workers` number. 36 | # This directive tells Puma to first boot the application and load code 37 | # before forking the application. This takes advantage of Copy On Write 38 | # process behavior so workers use less memory. 39 | # 40 | # preload_app! 41 | 42 | # Allow puma to be restarted by `rails restart` command. 43 | plugin :tmp_restart 44 | -------------------------------------------------------------------------------- /spec/rails_applications/6.1.4/config/routes.rb: -------------------------------------------------------------------------------- 1 | Rails.application.routes.draw do 2 | root to: 'home#index' 3 | # For details on the DSL available within this file, see https://guides.rubyonrails.org/routing.html 4 | end 5 | -------------------------------------------------------------------------------- /spec/rails_applications/6.1.4/config/spring.rb: -------------------------------------------------------------------------------- 1 | Spring.watch( 2 | ".ruby-version", 3 | ".rbenv-vars", 4 | "tmp/restart.txt", 5 | "tmp/caching-dev.txt" 6 | ) 7 | -------------------------------------------------------------------------------- /spec/rails_applications/6.1.4/config/storage.yml: -------------------------------------------------------------------------------- 1 | test: 2 | service: Disk 3 | root: <%= Rails.root.join("tmp/storage") %> 4 | 5 | local: 6 | service: Disk 7 | root: <%= Rails.root.join("storage") %> 8 | 9 | # Use rails credentials:edit to set the AWS secrets (as aws:access_key_id|secret_access_key) 10 | # amazon: 11 | # service: S3 12 | # access_key_id: <%= Rails.application.credentials.dig(:aws, :access_key_id) %> 13 | # secret_access_key: <%= Rails.application.credentials.dig(:aws, :secret_access_key) %> 14 | # region: us-east-1 15 | # bucket: your_own_bucket 16 | 17 | # Remember not to checkin your GCS keyfile to a repository 18 | # google: 19 | # service: GCS 20 | # project: your_project 21 | # credentials: <%= Rails.root.join("path/to/gcs.keyfile") %> 22 | # bucket: your_own_bucket 23 | 24 | # Use rails credentials:edit to set the Azure Storage secret (as azure_storage:storage_access_key) 25 | # microsoft: 26 | # service: AzureStorage 27 | # storage_account_name: your_account_name 28 | # storage_access_key: <%= Rails.application.credentials.dig(:azure_storage, :storage_access_key) %> 29 | # container: your_container_name 30 | 31 | # mirror: 32 | # service: Mirror 33 | # primary: local 34 | # mirrors: [ amazon, google, microsoft ] 35 | -------------------------------------------------------------------------------- /spec/rails_applications/6.1.4/db/seeds.rb: -------------------------------------------------------------------------------- 1 | # This file should contain all the record creation needed to seed the database with its default values. 2 | # The data can then be loaded with the bin/rails db:seed command (or created alongside the database with db:setup). 3 | # 4 | # Examples: 5 | # 6 | # movies = Movie.create([{ name: 'Star Wars' }, { name: 'Lord of the Rings' }]) 7 | # Character.create(name: 'Luke', movie: movies.first) 8 | -------------------------------------------------------------------------------- /spec/rails_applications/6.1.4/db/test.sqlite3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MindscapeHQ/raygun4ruby/5f6e26c34516ae09f9c1fac54e2a6f1df71030e4/spec/rails_applications/6.1.4/db/test.sqlite3 -------------------------------------------------------------------------------- /spec/rails_applications/6.1.4/lib/assets/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MindscapeHQ/raygun4ruby/5f6e26c34516ae09f9c1fac54e2a6f1df71030e4/spec/rails_applications/6.1.4/lib/assets/.keep -------------------------------------------------------------------------------- /spec/rails_applications/6.1.4/lib/tasks/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MindscapeHQ/raygun4ruby/5f6e26c34516ae09f9c1fac54e2a6f1df71030e4/spec/rails_applications/6.1.4/lib/tasks/.keep -------------------------------------------------------------------------------- /spec/rails_applications/6.1.4/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "dummy", 3 | "private": true, 4 | "dependencies": { 5 | "@rails/ujs": "^6.0.0", 6 | "turbolinks": "^5.2.0", 7 | "@rails/activestorage": "^6.0.0", 8 | "@rails/actioncable": "^6.0.0" 9 | }, 10 | "version": "0.1.0" 11 | } 12 | -------------------------------------------------------------------------------- /spec/rails_applications/6.1.4/public/404.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | The page you were looking for doesn't exist (404) 5 | 6 | 55 | 56 | 57 | 58 | 59 |
60 |
61 |

The page you were looking for doesn't exist.

62 |

You may have mistyped the address or the page may have moved.

63 |
64 |

If you are the application owner check the logs for more information.

65 |
66 | 67 | 68 | -------------------------------------------------------------------------------- /spec/rails_applications/6.1.4/public/422.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | The change you wanted was rejected (422) 5 | 6 | 55 | 56 | 57 | 58 | 59 |
60 |
61 |

The change you wanted was rejected.

62 |

Maybe you tried to change something you didn't have access to.

63 |
64 |

If you are the application owner check the logs for more information.

65 |
66 | 67 | 68 | -------------------------------------------------------------------------------- /spec/rails_applications/6.1.4/public/500.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | We're sorry, but something went wrong (500) 5 | 6 | 55 | 56 | 57 | 58 | 59 |
60 |
61 |

We're sorry, but something went wrong.

62 |
63 |

If you are the application owner check the logs for more information.

64 |
65 | 66 | 67 | -------------------------------------------------------------------------------- /spec/rails_applications/6.1.4/public/apple-touch-icon-precomposed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MindscapeHQ/raygun4ruby/5f6e26c34516ae09f9c1fac54e2a6f1df71030e4/spec/rails_applications/6.1.4/public/apple-touch-icon-precomposed.png -------------------------------------------------------------------------------- /spec/rails_applications/6.1.4/public/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MindscapeHQ/raygun4ruby/5f6e26c34516ae09f9c1fac54e2a6f1df71030e4/spec/rails_applications/6.1.4/public/apple-touch-icon.png -------------------------------------------------------------------------------- /spec/rails_applications/6.1.4/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MindscapeHQ/raygun4ruby/5f6e26c34516ae09f9c1fac54e2a6f1df71030e4/spec/rails_applications/6.1.4/public/favicon.ico -------------------------------------------------------------------------------- /spec/rails_applications/6.1.4/public/robots.txt: -------------------------------------------------------------------------------- 1 | # See https://www.robotstxt.org/robotstxt.html for documentation on how to use the robots.txt file 2 | -------------------------------------------------------------------------------- /spec/rails_applications/6.1.4/storage/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MindscapeHQ/raygun4ruby/5f6e26c34516ae09f9c1fac54e2a6f1df71030e4/spec/rails_applications/6.1.4/storage/.keep -------------------------------------------------------------------------------- /spec/rails_applications/7.1.3/.dockerignore: -------------------------------------------------------------------------------- 1 | # See https://docs.docker.com/engine/reference/builder/#dockerignore-file for more about ignoring files. 2 | 3 | # Ignore git directory. 4 | /.git/ 5 | 6 | # Ignore bundler config. 7 | /.bundle 8 | 9 | # Ignore all environment files (except templates). 10 | /.env* 11 | !/.env*.erb 12 | 13 | # Ignore all default key files. 14 | /config/master.key 15 | /config/credentials/*.key 16 | 17 | # Ignore all logfiles and tempfiles. 18 | /log/* 19 | /tmp/* 20 | !/log/.keep 21 | !/tmp/.keep 22 | 23 | # Ignore pidfiles, but keep the directory. 24 | /tmp/pids/* 25 | !/tmp/pids/.keep 26 | 27 | # Ignore storage (uploaded files in development and any SQLite databases). 28 | /storage/* 29 | !/storage/.keep 30 | /tmp/storage/* 31 | !/tmp/storage/.keep 32 | 33 | # Ignore assets. 34 | /node_modules/ 35 | /app/assets/builds/* 36 | !/app/assets/builds/.keep 37 | /public/assets 38 | -------------------------------------------------------------------------------- /spec/rails_applications/7.1.3/.gitattributes: -------------------------------------------------------------------------------- 1 | # See https://git-scm.com/docs/gitattributes for more about git attribute files. 2 | 3 | # Mark the database schema as having been generated. 4 | db/schema.rb linguist-generated 5 | 6 | # Mark any vendored files as having been vendored. 7 | vendor/* linguist-vendored 8 | config/credentials/*.yml.enc diff=rails_credentials 9 | config/credentials.yml.enc diff=rails_credentials 10 | -------------------------------------------------------------------------------- /spec/rails_applications/7.1.3/.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 environment files (except templates). 11 | /.env* 12 | !/.env*.erb 13 | 14 | # Ignore all logfiles and tempfiles. 15 | /log/* 16 | /tmp/* 17 | !/log/.keep 18 | !/tmp/.keep 19 | 20 | # Ignore pidfiles, but keep the directory. 21 | /tmp/pids/* 22 | !/tmp/pids/ 23 | !/tmp/pids/.keep 24 | 25 | # Ignore storage (uploaded files in development and any SQLite databases). 26 | /storage/* 27 | !/storage/.keep 28 | /tmp/storage/* 29 | !/tmp/storage/ 30 | !/tmp/storage/.keep 31 | 32 | /public/assets 33 | 34 | # Ignore master key for decrypting credentials and more. 35 | /config/master.key 36 | -------------------------------------------------------------------------------- /spec/rails_applications/7.1.3/.ruby-version: -------------------------------------------------------------------------------- 1 | 3.3.0 2 | -------------------------------------------------------------------------------- /spec/rails_applications/7.1.3/Dockerfile: -------------------------------------------------------------------------------- 1 | # syntax = docker/dockerfile:1 2 | 3 | # Make sure RUBY_VERSION matches the Ruby version in .ruby-version and Gemfile 4 | ARG RUBY_VERSION=3.3.0 5 | FROM registry.docker.com/library/ruby:$RUBY_VERSION-slim as base 6 | 7 | # Rails app lives here 8 | WORKDIR /rails 9 | 10 | # Set production environment 11 | ENV RAILS_ENV="production" \ 12 | BUNDLE_DEPLOYMENT="1" \ 13 | BUNDLE_PATH="/usr/local/bundle" \ 14 | BUNDLE_WITHOUT="development" 15 | 16 | 17 | # Throw-away build stage to reduce size of final image 18 | FROM base as build 19 | 20 | # Install packages needed to build gems 21 | RUN apt-get update -qq && \ 22 | apt-get install --no-install-recommends -y build-essential git libvips pkg-config 23 | 24 | # Install application gems 25 | COPY Gemfile Gemfile.lock ./ 26 | RUN bundle install && \ 27 | rm -rf ~/.bundle/ "${BUNDLE_PATH}"/ruby/*/cache "${BUNDLE_PATH}"/ruby/*/bundler/gems/*/.git && \ 28 | bundle exec bootsnap precompile --gemfile 29 | 30 | # Copy application code 31 | COPY . . 32 | 33 | # Precompile bootsnap code for faster boot times 34 | RUN bundle exec bootsnap precompile app/ lib/ 35 | 36 | # Precompiling assets for production without requiring secret RAILS_MASTER_KEY 37 | RUN SECRET_KEY_BASE_DUMMY=1 ./bin/rails assets:precompile 38 | 39 | 40 | # Final stage for app image 41 | FROM base 42 | 43 | # Install packages needed for deployment 44 | RUN apt-get update -qq && \ 45 | apt-get install --no-install-recommends -y curl libsqlite3-0 libvips && \ 46 | rm -rf /var/lib/apt/lists /var/cache/apt/archives 47 | 48 | # Copy built artifacts: gems, application 49 | COPY --from=build /usr/local/bundle /usr/local/bundle 50 | COPY --from=build /rails /rails 51 | 52 | # Run and own only the runtime files as a non-root user for security 53 | RUN useradd rails --create-home --shell /bin/bash && \ 54 | chown -R rails:rails db log storage tmp 55 | USER rails:rails 56 | 57 | # Entrypoint prepares the database. 58 | ENTRYPOINT ["/rails/bin/docker-entrypoint"] 59 | 60 | # Start the server by default, this can be overwritten at runtime 61 | EXPOSE 3000 62 | CMD ["./bin/rails", "server"] 63 | -------------------------------------------------------------------------------- /spec/rails_applications/7.1.3/Gemfile: -------------------------------------------------------------------------------- 1 | source "https://rubygems.org" 2 | 3 | ruby "3.3.0" 4 | 5 | # Bundle edge Rails instead: gem "rails", github: "rails/rails", branch: "main" 6 | gem "rails", "~> 7.1.3", ">= 7.1.3.2" 7 | 8 | # The original asset pipeline for Rails [https://github.com/rails/sprockets-rails] 9 | gem "sprockets-rails" 10 | 11 | # Use sqlite3 as the database for Active Record 12 | gem "sqlite3", "~> 1.4" 13 | 14 | # Use the Puma web server [https://github.com/puma/puma] 15 | gem "puma", ">= 5.0" 16 | 17 | # Use JavaScript with ESM import maps [https://github.com/rails/importmap-rails] 18 | gem "importmap-rails" 19 | 20 | # Hotwire's SPA-like page accelerator [https://turbo.hotwired.dev] 21 | gem "turbo-rails" 22 | 23 | # Hotwire's modest JavaScript framework [https://stimulus.hotwired.dev] 24 | gem "stimulus-rails" 25 | 26 | # Build JSON APIs with ease [https://github.com/rails/jbuilder] 27 | gem "jbuilder" 28 | 29 | # Use Redis adapter to run Action Cable in production 30 | gem "redis", ">= 4.0.1" 31 | 32 | # Use Kredis to get higher-level data types in Redis [https://github.com/rails/kredis] 33 | # gem "kredis" 34 | 35 | # Use Active Model has_secure_password [https://guides.rubyonrails.org/active_model_basics.html#securepassword] 36 | # gem "bcrypt", "~> 3.1.7" 37 | 38 | # Windows does not include zoneinfo files, so bundle the tzinfo-data gem 39 | gem "tzinfo-data", platforms: %i[ windows jruby ] 40 | 41 | # Reduces boot times through caching; required in config/boot.rb 42 | gem "bootsnap", require: false 43 | 44 | # Use Active Storage variants [https://guides.rubyonrails.org/active_storage_overview.html#transforming-images] 45 | # gem "image_processing", "~> 1.2" 46 | 47 | group :development, :test do 48 | # See https://guides.rubyonrails.org/debugging_rails_applications.html#debugging-with-the-debug-gem 49 | gem "debug", platforms: %i[ mri windows ] 50 | end 51 | 52 | group :development do 53 | # Use console on exceptions pages [https://github.com/rails/web-console] 54 | gem "web-console" 55 | 56 | # Add speed badges [https://github.com/MiniProfiler/rack-mini-profiler] 57 | # gem "rack-mini-profiler" 58 | 59 | # Speed up commands on slow machines / big apps [https://github.com/rails/spring] 60 | # gem "spring" 61 | end 62 | 63 | group :test do 64 | # Use system testing [https://guides.rubyonrails.org/testing.html#system-testing] 65 | gem "capybara" 66 | gem "selenium-webdriver" 67 | end 68 | -------------------------------------------------------------------------------- /spec/rails_applications/7.1.3/README.md: -------------------------------------------------------------------------------- 1 | # README 2 | 3 | This README would normally document whatever steps are necessary to get the 4 | application up and running. 5 | 6 | Things you may want to cover: 7 | 8 | * Ruby version 9 | 10 | * System dependencies 11 | 12 | * Configuration 13 | 14 | * Database creation 15 | 16 | * Database initialization 17 | 18 | * How to run the test suite 19 | 20 | * Services (job queues, cache servers, search engines, etc.) 21 | 22 | * Deployment instructions 23 | 24 | * ... 25 | -------------------------------------------------------------------------------- /spec/rails_applications/7.1.3/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/rails_applications/7.1.3/app/assets/config/manifest.js: -------------------------------------------------------------------------------- 1 | //= link_tree ../images 2 | //= link_directory ../stylesheets .css 3 | //= link_tree ../../javascript .js 4 | //= link_tree ../../../vendor/javascript .js 5 | -------------------------------------------------------------------------------- /spec/rails_applications/7.1.3/app/assets/images/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MindscapeHQ/raygun4ruby/5f6e26c34516ae09f9c1fac54e2a6f1df71030e4/spec/rails_applications/7.1.3/app/assets/images/.keep -------------------------------------------------------------------------------- /spec/rails_applications/7.1.3/app/assets/stylesheets/application.css: -------------------------------------------------------------------------------- 1 | /* 2 | * This is a manifest file that'll be compiled into application.css, which will include all the files 3 | * listed below. 4 | * 5 | * Any CSS (and SCSS, if configured) file within this directory, lib/assets/stylesheets, or any plugin's 6 | * vendor/assets/stylesheets directory can be referenced here using a relative path. 7 | * 8 | * You're free to add application-wide styles to this file and they'll appear at the bottom of the 9 | * compiled file so the styles you add here take precedence over styles defined in any other CSS 10 | * files in this directory. Styles in this file should be added after the last require_* statement. 11 | * It is generally better to create a new file per style scope. 12 | * 13 | *= require_tree . 14 | *= require_self 15 | */ 16 | -------------------------------------------------------------------------------- /spec/rails_applications/7.1.3/app/channels/application_cable/channel.rb: -------------------------------------------------------------------------------- 1 | module ApplicationCable 2 | class Channel < ActionCable::Channel::Base 3 | end 4 | end 5 | -------------------------------------------------------------------------------- /spec/rails_applications/7.1.3/app/channels/application_cable/connection.rb: -------------------------------------------------------------------------------- 1 | module ApplicationCable 2 | class Connection < ActionCable::Connection::Base 3 | end 4 | end 5 | -------------------------------------------------------------------------------- /spec/rails_applications/7.1.3/app/controllers/application_controller.rb: -------------------------------------------------------------------------------- 1 | class ApplicationController < ActionController::Base 2 | end 3 | -------------------------------------------------------------------------------- /spec/rails_applications/7.1.3/app/controllers/concerns/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MindscapeHQ/raygun4ruby/5f6e26c34516ae09f9c1fac54e2a6f1df71030e4/spec/rails_applications/7.1.3/app/controllers/concerns/.keep -------------------------------------------------------------------------------- /spec/rails_applications/7.1.3/app/controllers/home_controller.rb: -------------------------------------------------------------------------------- 1 | class HomeController < ApplicationController 2 | end 3 | -------------------------------------------------------------------------------- /spec/rails_applications/7.1.3/app/helpers/application_helper.rb: -------------------------------------------------------------------------------- 1 | module ApplicationHelper 2 | end 3 | -------------------------------------------------------------------------------- /spec/rails_applications/7.1.3/app/helpers/home_helper.rb: -------------------------------------------------------------------------------- 1 | module HomeHelper 2 | end 3 | -------------------------------------------------------------------------------- /spec/rails_applications/7.1.3/app/javascript/application.js: -------------------------------------------------------------------------------- 1 | // Configure your import map in config/importmap.rb. Read more: https://github.com/rails/importmap-rails 2 | import "@hotwired/turbo-rails" 3 | import "controllers" 4 | -------------------------------------------------------------------------------- /spec/rails_applications/7.1.3/app/javascript/controllers/application.js: -------------------------------------------------------------------------------- 1 | import { Application } from "@hotwired/stimulus" 2 | 3 | const application = Application.start() 4 | 5 | // Configure Stimulus development experience 6 | application.debug = false 7 | window.Stimulus = application 8 | 9 | export { application } 10 | -------------------------------------------------------------------------------- /spec/rails_applications/7.1.3/app/javascript/controllers/hello_controller.js: -------------------------------------------------------------------------------- 1 | import { Controller } from "@hotwired/stimulus" 2 | 3 | export default class extends Controller { 4 | connect() { 5 | this.element.textContent = "Hello World!" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /spec/rails_applications/7.1.3/app/javascript/controllers/index.js: -------------------------------------------------------------------------------- 1 | // Import and register all your controllers from the importmap under controllers/* 2 | 3 | import { application } from "controllers/application" 4 | 5 | // Eager load all controllers defined in the import map under controllers/**/*_controller 6 | import { eagerLoadControllersFrom } from "@hotwired/stimulus-loading" 7 | eagerLoadControllersFrom("controllers", application) 8 | 9 | // Lazy load controllers as they appear in the DOM (remember not to preload controllers in import map!) 10 | // import { lazyLoadControllersFrom } from "@hotwired/stimulus-loading" 11 | // lazyLoadControllersFrom("controllers", application) 12 | -------------------------------------------------------------------------------- /spec/rails_applications/7.1.3/app/jobs/application_job.rb: -------------------------------------------------------------------------------- 1 | class ApplicationJob < ActiveJob::Base 2 | # Automatically retry jobs that encountered a deadlock 3 | # retry_on ActiveRecord::Deadlocked 4 | 5 | # Most jobs are safe to ignore if the underlying records are no longer available 6 | # discard_on ActiveJob::DeserializationError 7 | end 8 | -------------------------------------------------------------------------------- /spec/rails_applications/7.1.3/app/mailers/application_mailer.rb: -------------------------------------------------------------------------------- 1 | class ApplicationMailer < ActionMailer::Base 2 | default from: "from@example.com" 3 | layout "mailer" 4 | end 5 | -------------------------------------------------------------------------------- /spec/rails_applications/7.1.3/app/models/application_record.rb: -------------------------------------------------------------------------------- 1 | class ApplicationRecord < ActiveRecord::Base 2 | primary_abstract_class 3 | end 4 | -------------------------------------------------------------------------------- /spec/rails_applications/7.1.3/app/models/concerns/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MindscapeHQ/raygun4ruby/5f6e26c34516ae09f9c1fac54e2a6f1df71030e4/spec/rails_applications/7.1.3/app/models/concerns/.keep -------------------------------------------------------------------------------- /spec/rails_applications/7.1.3/app/views/home/index.html.erb: -------------------------------------------------------------------------------- 1 |

Home#index

2 |

Find me in app/views/home/index.html.erb

3 |

<%= Raygun.configuration.js_api_key %>

4 | -------------------------------------------------------------------------------- /spec/rails_applications/7.1.3/app/views/home/index.json.erb: -------------------------------------------------------------------------------- 1 | {} -------------------------------------------------------------------------------- /spec/rails_applications/7.1.3/app/views/layouts/application.html.erb: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Dummy 5 | 6 | <%= csrf_meta_tags %> 7 | <%= csp_meta_tag %> 8 | 9 | <%= stylesheet_link_tag "application", "data-turbo-track": "reload" %> 10 | <%= javascript_importmap_tags %> 11 | 12 | 13 | 14 | <%= yield %> 15 | 16 | 17 | -------------------------------------------------------------------------------- /spec/rails_applications/7.1.3/app/views/layouts/mailer.html.erb: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 8 | 9 | 10 | 11 | <%= yield %> 12 | 13 | 14 | -------------------------------------------------------------------------------- /spec/rails_applications/7.1.3/app/views/layouts/mailer.text.erb: -------------------------------------------------------------------------------- 1 | <%= yield %> 2 | -------------------------------------------------------------------------------- /spec/rails_applications/7.1.3/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.match?(Gem::Version::ANCHORED_VERSION_PATTERN) 31 | bundler_version = a 32 | end 33 | next unless a =~ /\A--bundler(?:[= ](#{Gem::Version::VERSION_PATTERN}))?\z/ 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", __dir__) 45 | end 46 | 47 | def lockfile 48 | lockfile = 49 | case File.basename(gemfile) 50 | when "gems.rb" then gemfile.sub(/\.rb$/, ".locked") 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/ 60 | Regexp.last_match(1) 61 | end 62 | 63 | def bundler_requirement 64 | @bundler_requirement ||= 65 | env_var_version || 66 | cli_arg_version || 67 | bundler_requirement_for(lockfile_version) 68 | end 69 | 70 | def bundler_requirement_for(version) 71 | return "#{Gem::Requirement.default}.a" unless version 72 | 73 | bundler_gem_version = Gem::Version.new(version) 74 | 75 | bundler_gem_version.approximate_recommendation 76 | end 77 | 78 | def load_bundler! 79 | ENV["BUNDLE_GEMFILE"] ||= gemfile 80 | 81 | activate_bundler 82 | end 83 | 84 | def activate_bundler 85 | gem_error = activation_error_handling do 86 | gem "bundler", bundler_requirement 87 | end 88 | return if gem_error.nil? 89 | require_error = activation_error_handling do 90 | require "bundler/version" 91 | end 92 | return if require_error.nil? && Gem::Requirement.new(bundler_requirement).satisfied_by?(Gem::Version.new(Bundler::VERSION)) 93 | 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}'`" 94 | exit 42 95 | end 96 | 97 | def activation_error_handling 98 | yield 99 | nil 100 | rescue StandardError, LoadError => e 101 | e 102 | end 103 | end 104 | 105 | m.load_bundler! 106 | 107 | if m.invoked_as_script? 108 | load Gem.bin_path("bundler", "bundle") 109 | end 110 | -------------------------------------------------------------------------------- /spec/rails_applications/7.1.3/bin/docker-entrypoint: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | 3 | # If running the rails server then create or migrate existing database 4 | if [ "${1}" == "./bin/rails" ] && [ "${2}" == "server" ]; then 5 | ./bin/rails db:prepare 6 | fi 7 | 8 | exec "${@}" 9 | -------------------------------------------------------------------------------- /spec/rails_applications/7.1.3/bin/importmap: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | require_relative "../config/application" 4 | require "importmap/commands" 5 | -------------------------------------------------------------------------------- /spec/rails_applications/7.1.3/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/rails_applications/7.1.3/bin/rake: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require_relative "../config/boot" 3 | require "rake" 4 | Rake.application.run 5 | -------------------------------------------------------------------------------- /spec/rails_applications/7.1.3/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, exception: true) 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== Copying sample files ==" 21 | # unless File.exist?("config/database.yml") 22 | # FileUtils.cp "config/database.yml.sample", "config/database.yml" 23 | # end 24 | 25 | puts "\n== Preparing database ==" 26 | system! "bin/rails db:prepare" 27 | 28 | puts "\n== Removing old logs and tempfiles ==" 29 | system! "bin/rails log:clear tmp:clear" 30 | 31 | puts "\n== Restarting application server ==" 32 | system! "bin/rails restart" 33 | end 34 | -------------------------------------------------------------------------------- /spec/rails_applications/7.1.3/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/rails_applications/7.1.3/config/application.rb: -------------------------------------------------------------------------------- 1 | require_relative "boot" 2 | 3 | require "rails/all" 4 | 5 | # Require the gems listed in Gemfile, including any gems 6 | # you've limited to :test, :development, or :production. 7 | Bundler.require(*Rails.groups) 8 | 9 | module Dummy 10 | class Application < Rails::Application 11 | # Initialize configuration defaults for originally generated Rails version. 12 | config.load_defaults 7.1 13 | 14 | # Please, add to the `ignore` list any other `lib` subdirectories that do 15 | # not contain `.rb` files, or that should not be reloaded or eager loaded. 16 | # Common ones are `templates`, `generators`, or `middleware`, for example. 17 | config.autoload_lib(ignore: %w(assets tasks)) 18 | 19 | # Configuration for the application, engines, and railties goes here. 20 | # 21 | # These settings can be overridden in specific environments using the files 22 | # in config/environments, which are processed later. 23 | # 24 | # config.time_zone = "Central Time (US & Canada)" 25 | # config.eager_load_paths << Rails.root.join("extras") 26 | end 27 | end 28 | -------------------------------------------------------------------------------- /spec/rails_applications/7.1.3/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/rails_applications/7.1.3/config/cable.yml: -------------------------------------------------------------------------------- 1 | development: 2 | adapter: redis 3 | url: redis://localhost:6379/1 4 | 5 | test: 6 | adapter: test 7 | 8 | production: 9 | adapter: redis 10 | url: <%= ENV.fetch("REDIS_URL") { "redis://localhost:6379/1" } %> 11 | channel_prefix: dummy_production 12 | -------------------------------------------------------------------------------- /spec/rails_applications/7.1.3/config/credentials.yml.enc: -------------------------------------------------------------------------------- 1 | v+qpJS9dHtYdjpHPCRVcjajq+Tlb6ONmeul+eI9CFyFtJQMcejkgV8w8H0w90kwselljjrjD+YxZUq8zarwhrmWC+03M4JOwJGDE5C/Iaofa2pT5qtjZSP7/wL9v4G6/lFpKBvT+teCRhXs+6uvcWACyFotEKZq89v6ApMBgzF94sioz5LmY51gFSIk1EhaMuEut0lUWOYn/mzBRA/sdYymEM4ynOg5AglQ2Q1c34JIQtrWnGrtwMD9C/XnQ96vUZcQd4wUQUjYtF0xnJNx/MknaHMdbrS26zXMpmBveh/O8a67x/ozO/c8hjnYeMPMZ0lOdHnbyWsrdpCjhHkKA7foc3KuCkMEsHXvFbWnlip7doOaF4tKwTq9z79gxshYJTzQ2CXrIgDignUcNlecVj3Krkmpb--A0mHiuQO+RWqb84v--VvD6hXbRbSQZ5vYc2YVqjw== -------------------------------------------------------------------------------- /spec/rails_applications/7.1.3/config/database.yml: -------------------------------------------------------------------------------- 1 | # SQLite. Versions 3.8.0 and up are supported. 2 | # gem install sqlite3 3 | # 4 | # Ensure the SQLite 3 gem is defined in your Gemfile 5 | # gem "sqlite3" 6 | # 7 | default: &default 8 | adapter: sqlite3 9 | pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %> 10 | timeout: 5000 11 | 12 | development: 13 | <<: *default 14 | database: storage/development.sqlite3 15 | 16 | # Warning: The database defined as "test" will be erased and 17 | # re-generated from your development database when you run "rake". 18 | # Do not set this db to the same as development or production. 19 | test: 20 | <<: *default 21 | database: storage/test.sqlite3 22 | 23 | production: 24 | <<: *default 25 | database: storage/production.sqlite3 26 | -------------------------------------------------------------------------------- /spec/rails_applications/7.1.3/config/environment.rb: -------------------------------------------------------------------------------- 1 | # Load the Rails application. 2 | require_relative "application" 3 | 4 | # Initialize the Rails application. 5 | Rails.application.initialize! 6 | -------------------------------------------------------------------------------- /spec/rails_applications/7.1.3/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.enable_reloading = true 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 server timing 18 | config.server_timing = true 19 | 20 | # Enable/disable caching. By default caching is disabled. 21 | # Run rails dev:cache to toggle caching. 22 | if Rails.root.join("tmp/caching-dev.txt").exist? 23 | config.action_controller.perform_caching = true 24 | config.action_controller.enable_fragment_cache_logging = true 25 | 26 | config.cache_store = :memory_store 27 | config.public_file_server.headers = { 28 | "Cache-Control" => "public, max-age=#{2.days.to_i}" 29 | } 30 | else 31 | config.action_controller.perform_caching = false 32 | 33 | config.cache_store = :null_store 34 | end 35 | 36 | # Store uploaded files on the local file system (see config/storage.yml for options). 37 | config.active_storage.service = :local 38 | 39 | # Don't care if the mailer can't send. 40 | config.action_mailer.raise_delivery_errors = false 41 | 42 | config.action_mailer.perform_caching = false 43 | 44 | # Print deprecation notices to the Rails logger. 45 | config.active_support.deprecation = :log 46 | 47 | # Raise exceptions for disallowed deprecations. 48 | config.active_support.disallowed_deprecation = :raise 49 | 50 | # Tell Active Support which deprecation messages to disallow. 51 | config.active_support.disallowed_deprecation_warnings = [] 52 | 53 | # Raise an error on page load if there are pending migrations. 54 | config.active_record.migration_error = :page_load 55 | 56 | # Highlight code that triggered database queries in logs. 57 | config.active_record.verbose_query_logs = true 58 | 59 | # Highlight code that enqueued background job in logs. 60 | config.active_job.verbose_enqueue_logs = true 61 | 62 | # Suppress logger output for asset requests. 63 | config.assets.quiet = true 64 | 65 | # Raises error for missing translations. 66 | # config.i18n.raise_on_missing_translations = true 67 | 68 | # Annotate rendered view with file names. 69 | # config.action_view.annotate_rendered_view_with_filenames = true 70 | 71 | # Uncomment if you wish to allow Action Cable access from any origin. 72 | # config.action_cable.disable_request_forgery_protection = true 73 | 74 | # Raise error when a before_action's only/except options reference missing actions 75 | config.action_controller.raise_on_missing_callback_actions = true 76 | end 77 | -------------------------------------------------------------------------------- /spec/rails_applications/7.1.3/config/environments/production.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 | # Code is not reloaded between requests. 7 | config.enable_reloading = false 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 | # Ensures that a master key has been made available in ENV["RAILS_MASTER_KEY"], config/master.key, or an environment 20 | # key such as config/credentials/production.key. This key is used to decrypt credentials (and other encrypted files). 21 | # config.require_master_key = true 22 | 23 | # Disable serving static files from `public/`, relying on NGINX/Apache to do so instead. 24 | # config.public_file_server.enabled = false 25 | 26 | # Compress CSS using a preprocessor. 27 | # config.assets.css_compressor = :sass 28 | 29 | # Do not fall back to assets pipeline if a precompiled asset is missed. 30 | config.assets.compile = false 31 | 32 | # Enable serving of images, stylesheets, and JavaScripts from an asset server. 33 | # config.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 | # Store uploaded files on the local file system (see config/storage.yml for options). 40 | config.active_storage.service = :local 41 | 42 | # Mount Action Cable outside main process or domain. 43 | # config.action_cable.mount_path = nil 44 | # config.action_cable.url = "wss://example.com/cable" 45 | # config.action_cable.allowed_request_origins = [ "http://example.com", /http:\/\/example.*/ ] 46 | 47 | # Assume all access to the app is happening through a SSL-terminating reverse proxy. 48 | # Can be used together with config.force_ssl for Strict-Transport-Security and secure cookies. 49 | # config.assume_ssl = true 50 | 51 | # Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies. 52 | config.force_ssl = true 53 | 54 | # Log to STDOUT by default 55 | config.logger = ActiveSupport::Logger.new(STDOUT) 56 | .tap { |logger| logger.formatter = ::Logger::Formatter.new } 57 | .then { |logger| ActiveSupport::TaggedLogging.new(logger) } 58 | 59 | # Prepend all log lines with the following tags. 60 | config.log_tags = [ :request_id ] 61 | 62 | # "info" includes generic and useful information about system operation, but avoids logging too much 63 | # information to avoid inadvertent exposure of personally identifiable information (PII). If you 64 | # want to log everything, set the level to "debug". 65 | config.log_level = ENV.fetch("RAILS_LOG_LEVEL", "info") 66 | 67 | # Use a different cache store in production. 68 | # config.cache_store = :mem_cache_store 69 | 70 | # Use a real queuing backend for Active Job (and separate queues per environment). 71 | # config.active_job.queue_adapter = :resque 72 | # config.active_job.queue_name_prefix = "dummy_production" 73 | 74 | config.action_mailer.perform_caching = false 75 | 76 | # Ignore bad email addresses and do not raise email delivery errors. 77 | # Set this to true and configure the email server for immediate delivery to raise delivery errors. 78 | # config.action_mailer.raise_delivery_errors = false 79 | 80 | # Enable locale fallbacks for I18n (makes lookups for any locale fall back to 81 | # the I18n.default_locale when a translation cannot be found). 82 | config.i18n.fallbacks = true 83 | 84 | # Don't log any deprecations. 85 | config.active_support.report_deprecations = false 86 | 87 | # Do not dump schema after migrations. 88 | config.active_record.dump_schema_after_migration = false 89 | 90 | # Enable DNS rebinding protection and other `Host` header attacks. 91 | # config.hosts = [ 92 | # "example.com", # Allow requests from example.com 93 | # /.*\.example\.com/ # Allow requests from subdomains like `www.example.com` 94 | # ] 95 | # Skip DNS rebinding protection for the default health check endpoint. 96 | # config.host_authorization = { exclude: ->(request) { request.path == "/up" } } 97 | end 98 | -------------------------------------------------------------------------------- /spec/rails_applications/7.1.3/config/environments/test.rb: -------------------------------------------------------------------------------- 1 | require "active_support/core_ext/integer/time" 2 | 3 | # The test environment is used exclusively to run your application's 4 | # test suite. You never need to work with it otherwise. Remember that 5 | # your test database is "scratch space" for the test suite and is wiped 6 | # and recreated between test runs. Don't rely on the data there! 7 | 8 | Rails.application.configure do 9 | # Settings specified here will take precedence over those in config/application.rb. 10 | 11 | # While tests run files are not watched, reloading is not necessary. 12 | config.enable_reloading = false 13 | 14 | # Eager loading loads your entire application. When running a single test locally, 15 | # this is usually not necessary, and can slow down your test suite. However, it's 16 | # recommended that you enable it in continuous integration systems to ensure eager 17 | # loading is working properly before deploying your code. 18 | config.eager_load = ENV["CI"].present? 19 | 20 | # Configure public file server for tests with Cache-Control for performance. 21 | config.public_file_server.enabled = true 22 | config.public_file_server.headers = { 23 | "Cache-Control" => "public, max-age=#{1.hour.to_i}" 24 | } 25 | 26 | # Show full error reports and disable caching. 27 | config.consider_all_requests_local = true 28 | config.action_controller.perform_caching = false 29 | config.cache_store = :null_store 30 | 31 | # Render exception templates for rescuable exceptions and raise for other exceptions. 32 | config.action_dispatch.show_exceptions = :rescuable 33 | 34 | # Disable request forgery protection in test environment. 35 | config.action_controller.allow_forgery_protection = false 36 | 37 | # Store uploaded files on the local file system in a temporary directory. 38 | config.active_storage.service = :test 39 | 40 | config.action_mailer.perform_caching = false 41 | 42 | # Tell Action Mailer not to deliver emails to the real world. 43 | # The :test delivery method accumulates sent emails in the 44 | # ActionMailer::Base.deliveries array. 45 | config.action_mailer.delivery_method = :test 46 | 47 | # Print deprecation notices to the stderr. 48 | config.active_support.deprecation = :stderr 49 | 50 | # Raise exceptions for disallowed deprecations. 51 | config.active_support.disallowed_deprecation = :raise 52 | 53 | # Tell Active Support which deprecation messages to disallow. 54 | config.active_support.disallowed_deprecation_warnings = [] 55 | 56 | # Raises error for missing translations. 57 | # config.i18n.raise_on_missing_translations = true 58 | 59 | # Annotate rendered view with file names. 60 | # config.action_view.annotate_rendered_view_with_filenames = true 61 | 62 | # Raise error when a before_action's only/except options reference missing actions 63 | config.action_controller.raise_on_missing_callback_actions = true 64 | end 65 | -------------------------------------------------------------------------------- /spec/rails_applications/7.1.3/config/importmap.rb: -------------------------------------------------------------------------------- 1 | # Pin npm packages by running ./bin/importmap 2 | 3 | pin "application" 4 | pin "@hotwired/turbo-rails", to: "turbo.min.js" 5 | pin "@hotwired/stimulus", to: "stimulus.min.js" 6 | pin "@hotwired/stimulus-loading", to: "stimulus-loading.js" 7 | pin_all_from "app/javascript/controllers", under: "controllers" 8 | -------------------------------------------------------------------------------- /spec/rails_applications/7.1.3/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 | -------------------------------------------------------------------------------- /spec/rails_applications/7.1.3/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 | # See the Securing Rails Applications Guide for more information: 5 | # https://guides.rubyonrails.org/security.html#content-security-policy-header 6 | 7 | # Rails.application.configure do 8 | # config.content_security_policy do |policy| 9 | # policy.default_src :self, :https 10 | # policy.font_src :self, :https, :data 11 | # policy.img_src :self, :https, :data 12 | # policy.object_src :none 13 | # policy.script_src :self, :https 14 | # policy.style_src :self, :https 15 | # # Specify URI for violation reports 16 | # # policy.report_uri "/csp-violation-report-endpoint" 17 | # end 18 | # 19 | # # Generate session nonces for permitted importmap, inline scripts, and inline styles. 20 | # config.content_security_policy_nonce_generator = ->(request) { request.session.id.to_s } 21 | # config.content_security_policy_nonce_directives = %w(script-src style-src) 22 | # 23 | # # Report violations without enforcing the policy. 24 | # # config.content_security_policy_report_only = true 25 | # end 26 | -------------------------------------------------------------------------------- /spec/rails_applications/7.1.3/config/initializers/filter_parameter_logging.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Configure parameters to be partially matched (e.g. passw matches password) and filtered from the log file. 4 | # Use this to limit dissemination of sensitive information. 5 | # See the ActiveSupport::ParameterFilter documentation for supported notations and behaviors. 6 | Rails.application.config.filter_parameters += [ 7 | :passw, :secret, :token, :_key, :crypt, :salt, :certificate, :otp, :ssn 8 | ] 9 | -------------------------------------------------------------------------------- /spec/rails_applications/7.1.3/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/rails_applications/7.1.3/config/initializers/permissions_policy.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Define an application-wide HTTP permissions policy. For further 4 | # information see: https://developers.google.com/web/updates/2018/06/feature-policy 5 | 6 | # Rails.application.config.permissions_policy do |policy| 7 | # policy.camera :none 8 | # policy.gyroscope :none 9 | # policy.microphone :none 10 | # policy.usb :none 11 | # policy.fullscreen :self 12 | # policy.payment :self, "https://secure.example.com" 13 | # end 14 | -------------------------------------------------------------------------------- /spec/rails_applications/7.1.3/config/locales/en.yml: -------------------------------------------------------------------------------- 1 | # Files in the config/locales directory are used for internationalization and 2 | # are automatically loaded by Rails. If you want to use locales other than 3 | # 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 about the API, please read the Rails Internationalization guide 20 | # at https://guides.rubyonrails.org/i18n.html. 21 | # 22 | # Be aware that YAML interprets the following case-insensitive strings as 23 | # booleans: `true`, `false`, `on`, `off`, `yes`, `no`. Therefore, these strings 24 | # must be quoted to be interpreted as strings. For example: 25 | # 26 | # en: 27 | # "yes": yup 28 | # enabled: "ON" 29 | 30 | en: 31 | hello: "Hello world" 32 | -------------------------------------------------------------------------------- /spec/rails_applications/7.1.3/config/puma.rb: -------------------------------------------------------------------------------- 1 | # This configuration file will be evaluated by Puma. The top-level methods that 2 | # are invoked here are part of Puma's configuration DSL. For more information 3 | # about methods provided by the DSL, see https://puma.io/puma/Puma/DSL.html. 4 | 5 | # Puma can serve each request in a thread from an internal thread pool. 6 | # The `threads` method setting takes two numbers: a minimum and maximum. 7 | # Any libraries that use thread pools should be configured to match 8 | # the maximum value specified for Puma. Default is set to 5 threads for minimum 9 | # and maximum; this matches the default thread size of Active Record. 10 | max_threads_count = ENV.fetch("RAILS_MAX_THREADS") { 5 } 11 | min_threads_count = ENV.fetch("RAILS_MIN_THREADS") { max_threads_count } 12 | threads min_threads_count, max_threads_count 13 | 14 | # Specifies that the worker count should equal the number of processors in production. 15 | if ENV["RAILS_ENV"] == "production" 16 | require "concurrent-ruby" 17 | worker_count = Integer(ENV.fetch("WEB_CONCURRENCY") { Concurrent.physical_processor_count }) 18 | workers worker_count if worker_count > 1 19 | end 20 | 21 | # Specifies the `worker_timeout` threshold that Puma will use to wait before 22 | # terminating a worker in development environments. 23 | worker_timeout 3600 if ENV.fetch("RAILS_ENV", "development") == "development" 24 | 25 | # Specifies the `port` that Puma will listen on to receive requests; default is 3000. 26 | port ENV.fetch("PORT") { 3000 } 27 | 28 | # Specifies the `environment` that Puma will run in. 29 | environment ENV.fetch("RAILS_ENV") { "development" } 30 | 31 | # Specifies the `pidfile` that Puma will use. 32 | pidfile ENV.fetch("PIDFILE") { "tmp/pids/server.pid" } 33 | 34 | # Allow puma to be restarted by `bin/rails restart` command. 35 | plugin :tmp_restart 36 | -------------------------------------------------------------------------------- /spec/rails_applications/7.1.3/config/routes.rb: -------------------------------------------------------------------------------- 1 | Rails.application.routes.draw do 2 | # Define your application routes per the DSL in https://guides.rubyonrails.org/routing.html 3 | 4 | # Reveal health status on /up that returns 200 if the app boots with no exceptions, otherwise 500. 5 | # Can be used by load balancers and uptime monitors to verify that the app is live. 6 | get "up" => "rails/health#show", as: :rails_health_check 7 | 8 | # Defines the root path route ("/") 9 | # root "posts#index" 10 | root to: 'home#index' 11 | end 12 | -------------------------------------------------------------------------------- /spec/rails_applications/7.1.3/config/storage.yml: -------------------------------------------------------------------------------- 1 | test: 2 | service: Disk 3 | root: <%= Rails.root.join("tmp/storage") %> 4 | 5 | local: 6 | service: Disk 7 | root: <%= Rails.root.join("storage") %> 8 | 9 | # Use bin/rails credentials:edit to set the AWS secrets (as aws:access_key_id|secret_access_key) 10 | # amazon: 11 | # service: S3 12 | # access_key_id: <%= Rails.application.credentials.dig(:aws, :access_key_id) %> 13 | # secret_access_key: <%= Rails.application.credentials.dig(:aws, :secret_access_key) %> 14 | # region: us-east-1 15 | # bucket: your_own_bucket-<%= Rails.env %> 16 | 17 | # Remember not to checkin your GCS keyfile to a repository 18 | # google: 19 | # service: GCS 20 | # project: your_project 21 | # credentials: <%= Rails.root.join("path/to/gcs.keyfile") %> 22 | # bucket: your_own_bucket-<%= Rails.env %> 23 | 24 | # Use bin/rails credentials:edit to set the Azure Storage secret (as azure_storage:storage_access_key) 25 | # microsoft: 26 | # service: AzureStorage 27 | # storage_account_name: your_account_name 28 | # storage_access_key: <%= Rails.application.credentials.dig(:azure_storage, :storage_access_key) %> 29 | # container: your_container_name-<%= Rails.env %> 30 | 31 | # mirror: 32 | # service: Mirror 33 | # primary: local 34 | # mirrors: [ amazon, google, microsoft ] 35 | -------------------------------------------------------------------------------- /spec/rails_applications/7.1.3/db/seeds.rb: -------------------------------------------------------------------------------- 1 | # This file should ensure the existence of records required to run the application in every environment (production, 2 | # development, test). The code here should be idempotent so that it can be executed at any point in every environment. 3 | # The data can then be loaded with the bin/rails db:seed command (or created alongside the database with db:setup). 4 | # 5 | # Example: 6 | # 7 | # ["Action", "Comedy", "Drama", "Horror"].each do |genre_name| 8 | # MovieGenre.find_or_create_by!(name: genre_name) 9 | # end 10 | -------------------------------------------------------------------------------- /spec/rails_applications/7.1.3/lib/assets/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MindscapeHQ/raygun4ruby/5f6e26c34516ae09f9c1fac54e2a6f1df71030e4/spec/rails_applications/7.1.3/lib/assets/.keep -------------------------------------------------------------------------------- /spec/rails_applications/7.1.3/lib/tasks/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MindscapeHQ/raygun4ruby/5f6e26c34516ae09f9c1fac54e2a6f1df71030e4/spec/rails_applications/7.1.3/lib/tasks/.keep -------------------------------------------------------------------------------- /spec/rails_applications/7.1.3/public/404.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | The page you were looking for doesn't exist (404) 5 | 6 | 55 | 56 | 57 | 58 | 59 |
60 |
61 |

The page you were looking for doesn't exist.

62 |

You may have mistyped the address or the page may have moved.

63 |
64 |

If you are the application owner check the logs for more information.

65 |
66 | 67 | 68 | -------------------------------------------------------------------------------- /spec/rails_applications/7.1.3/public/422.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | The change you wanted was rejected (422) 5 | 6 | 55 | 56 | 57 | 58 | 59 |
60 |
61 |

The change you wanted was rejected.

62 |

Maybe you tried to change something you didn't have access to.

63 |
64 |

If you are the application owner check the logs for more information.

65 |
66 | 67 | 68 | -------------------------------------------------------------------------------- /spec/rails_applications/7.1.3/public/500.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | We're sorry, but something went wrong (500) 5 | 6 | 55 | 56 | 57 | 58 | 59 |
60 |
61 |

We're sorry, but something went wrong.

62 |
63 |

If you are the application owner check the logs for more information.

64 |
65 | 66 | 67 | -------------------------------------------------------------------------------- /spec/rails_applications/7.1.3/public/apple-touch-icon-precomposed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MindscapeHQ/raygun4ruby/5f6e26c34516ae09f9c1fac54e2a6f1df71030e4/spec/rails_applications/7.1.3/public/apple-touch-icon-precomposed.png -------------------------------------------------------------------------------- /spec/rails_applications/7.1.3/public/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MindscapeHQ/raygun4ruby/5f6e26c34516ae09f9c1fac54e2a6f1df71030e4/spec/rails_applications/7.1.3/public/apple-touch-icon.png -------------------------------------------------------------------------------- /spec/rails_applications/7.1.3/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MindscapeHQ/raygun4ruby/5f6e26c34516ae09f9c1fac54e2a6f1df71030e4/spec/rails_applications/7.1.3/public/favicon.ico -------------------------------------------------------------------------------- /spec/rails_applications/7.1.3/public/robots.txt: -------------------------------------------------------------------------------- 1 | # See https://www.robotstxt.org/robotstxt.html for documentation on how to use the robots.txt file 2 | -------------------------------------------------------------------------------- /spec/rails_applications/7.1.3/storage/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MindscapeHQ/raygun4ruby/5f6e26c34516ae09f9c1fac54e2a6f1df71030e4/spec/rails_applications/7.1.3/storage/.keep -------------------------------------------------------------------------------- /spec/rails_applications/7.1.3/test/application_system_test_case.rb: -------------------------------------------------------------------------------- 1 | require "test_helper" 2 | 3 | class ApplicationSystemTestCase < ActionDispatch::SystemTestCase 4 | driven_by :selenium, using: :chrome, screen_size: [1400, 1400] 5 | end 6 | -------------------------------------------------------------------------------- /spec/rails_applications/7.1.3/test/channels/application_cable/connection_test.rb: -------------------------------------------------------------------------------- 1 | require "test_helper" 2 | 3 | module ApplicationCable 4 | class ConnectionTest < ActionCable::Connection::TestCase 5 | # test "connects with cookies" do 6 | # cookies.signed[:user_id] = 42 7 | # 8 | # connect 9 | # 10 | # assert_equal connection.user_id, "42" 11 | # end 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /spec/rails_applications/7.1.3/test/controllers/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MindscapeHQ/raygun4ruby/5f6e26c34516ae09f9c1fac54e2a6f1df71030e4/spec/rails_applications/7.1.3/test/controllers/.keep -------------------------------------------------------------------------------- /spec/rails_applications/7.1.3/test/controllers/home_controller_test.rb: -------------------------------------------------------------------------------- 1 | require "test_helper" 2 | 3 | class HomeControllerTest < ActionDispatch::IntegrationTest 4 | # test "the truth" do 5 | # assert true 6 | # end 7 | end 8 | -------------------------------------------------------------------------------- /spec/rails_applications/7.1.3/test/fixtures/files/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MindscapeHQ/raygun4ruby/5f6e26c34516ae09f9c1fac54e2a6f1df71030e4/spec/rails_applications/7.1.3/test/fixtures/files/.keep -------------------------------------------------------------------------------- /spec/rails_applications/7.1.3/test/helpers/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MindscapeHQ/raygun4ruby/5f6e26c34516ae09f9c1fac54e2a6f1df71030e4/spec/rails_applications/7.1.3/test/helpers/.keep -------------------------------------------------------------------------------- /spec/rails_applications/7.1.3/test/integration/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MindscapeHQ/raygun4ruby/5f6e26c34516ae09f9c1fac54e2a6f1df71030e4/spec/rails_applications/7.1.3/test/integration/.keep -------------------------------------------------------------------------------- /spec/rails_applications/7.1.3/test/mailers/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MindscapeHQ/raygun4ruby/5f6e26c34516ae09f9c1fac54e2a6f1df71030e4/spec/rails_applications/7.1.3/test/mailers/.keep -------------------------------------------------------------------------------- /spec/rails_applications/7.1.3/test/models/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MindscapeHQ/raygun4ruby/5f6e26c34516ae09f9c1fac54e2a6f1df71030e4/spec/rails_applications/7.1.3/test/models/.keep -------------------------------------------------------------------------------- /spec/rails_applications/7.1.3/test/system/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MindscapeHQ/raygun4ruby/5f6e26c34516ae09f9c1fac54e2a6f1df71030e4/spec/rails_applications/7.1.3/test/system/.keep -------------------------------------------------------------------------------- /spec/rails_applications/7.1.3/test/test_helper.rb: -------------------------------------------------------------------------------- 1 | ENV["RAILS_ENV"] ||= "test" 2 | require_relative "../config/environment" 3 | require "rails/test_help" 4 | 5 | module ActiveSupport 6 | class TestCase 7 | # Run tests in parallel with specified workers 8 | parallelize(workers: :number_of_processors) 9 | 10 | # Setup all fixtures in test/fixtures/*.yml for all tests in alphabetical order. 11 | fixtures :all 12 | 13 | # Add more helper methods to be used by all tests here... 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /spec/rails_applications/7.1.3/vendor/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MindscapeHQ/raygun4ruby/5f6e26c34516ae09f9c1fac54e2a6f1df71030e4/spec/rails_applications/7.1.3/vendor/.keep -------------------------------------------------------------------------------- /spec/rails_applications/7.1.3/vendor/javascript/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MindscapeHQ/raygun4ruby/5f6e26c34516ae09f9c1fac54e2a6f1df71030e4/spec/rails_applications/7.1.3/vendor/javascript/.keep -------------------------------------------------------------------------------- /spec/rails_helper.rb: -------------------------------------------------------------------------------- 1 | ENV['RAILS_ENV'] ||= 'test' 2 | require "rails" 3 | 4 | major_minor_patch = Rails::VERSION::STRING.split(".").first(3).join(".") 5 | 6 | require "rails_applications/#{major_minor_patch}/config/environment" 7 | 8 | require "rspec/rails" 9 | -------------------------------------------------------------------------------- /spec/raygun/breadcrumbs/breadcrumb_spec.rb: -------------------------------------------------------------------------------- 1 | require "spec_helper" 2 | 3 | module Raygun 4 | module Breadcrumbs 5 | describe Breadcrumb do 6 | let(:subject) { Breadcrumb.new } 7 | context 'fields' do 8 | it 'has a message' do 9 | message = 'foo' 10 | 11 | subject.message = message 12 | 13 | expect(subject.message).to eq(message) 14 | end 15 | 16 | it 'has a category' do 17 | category = 'foo' 18 | 19 | subject.category = category 20 | 21 | expect(subject.category).to eq(category) 22 | end 23 | 24 | it 'has a level' do 25 | level = 'foo' 26 | 27 | subject.level = level 28 | 29 | expect(subject.level).to eq(level) 30 | end 31 | 32 | it 'has a timestamp' do 33 | timestamp = Time.now 34 | 35 | subject.timestamp = timestamp 36 | 37 | expect(subject.timestamp).to eq(timestamp) 38 | end 39 | 40 | it 'has metadata' do 41 | metadata = {foo: '1'} 42 | 43 | subject.metadata = metadata 44 | 45 | expect(subject.metadata).to eq(metadata) 46 | end 47 | 48 | it 'has a class_name' do 49 | class_name = 'foo' 50 | 51 | subject.class_name = class_name 52 | 53 | expect(subject.class_name).to eq(class_name) 54 | end 55 | 56 | it 'has a method_name' do 57 | method_name = 'foo' 58 | 59 | subject.method_name = method_name 60 | 61 | expect(subject.method_name).to eq(method_name) 62 | end 63 | 64 | it 'has a line_number' do 65 | line_number = 17 66 | 67 | subject.line_number = line_number 68 | 69 | expect(subject.line_number).to eq(line_number) 70 | end 71 | end 72 | 73 | describe "#build_payload" do 74 | before do 75 | Timecop.freeze 76 | Store.initialize 77 | end 78 | after do 79 | Timecop.return 80 | Store.clear 81 | end 82 | 83 | let(:breadcrumb) do 84 | Store.record( 85 | message: "test", 86 | category: "test", 87 | level: :info, 88 | class_name: "HomeController", 89 | method_name: "index", 90 | line_number: 17, 91 | metadata: { 92 | foo: 'bar' 93 | } 94 | ) 95 | 96 | Store.stored[0] 97 | end 98 | let(:payload) { breadcrumb.build_payload } 99 | 100 | it "joins the class name, method name and line number together" do 101 | expect(payload[:location]).to eq("HomeController:index:17") 102 | end 103 | 104 | it "does not include the method name and line number if the class name is missing" do 105 | breadcrumb.class_name = nil 106 | 107 | expect(payload.has_key?(:location)).to eq(false) 108 | end 109 | 110 | it "does not inlcude the line number if is it missing" do 111 | breadcrumb.line_number = nil 112 | 113 | expect(payload[:location]).to eq("HomeController:index") 114 | end 115 | 116 | it "does not include keys in payload with nil values" do 117 | breadcrumb.metadata = nil 118 | breadcrumb.category = nil 119 | 120 | expect(payload.key?(:CustomData)).to eq(false) 121 | expect(payload.key?(:category)).to eq(false) 122 | end 123 | 124 | it 'includes the rest of the fields' do 125 | expect(payload[:message]).to eq('test') 126 | expect(payload[:category]).to eq('test') 127 | expect(payload[:level]).to eq(1) 128 | expect(payload[:timestamp]).to_not eq(nil) 129 | expect(payload[:CustomData]).to eq(foo: 'bar') 130 | end 131 | end 132 | 133 | describe "#size" do 134 | before do 135 | Timecop.freeze 136 | Store.initialize 137 | end 138 | after do 139 | Timecop.return 140 | Store.clear 141 | end 142 | 143 | let(:message) { "This is a breadcrumb message" } 144 | 145 | let(:breadcrumb) do 146 | Store.record( 147 | message: message, 148 | category: "test", 149 | level: :info, 150 | class_name: "HomeController", 151 | method_name: "index", 152 | line_number: 17, 153 | metadata: { 154 | foo: 'bar' 155 | } 156 | ) 157 | 158 | Store.stored[0] 159 | end 160 | 161 | let(:size) { breadcrumb.size } 162 | 163 | it "returns the estimated size of the breadcrumb" do 164 | # Can't check all the fields but message so assume a standard 100 length for all of them 165 | # The message should be the bulk of large breadcrumbs anyway 166 | expect(size).to eq(message.length + 100) 167 | end 168 | end 169 | end 170 | end 171 | end 172 | -------------------------------------------------------------------------------- /spec/raygun/breadcrumbs/store_spec.rb: -------------------------------------------------------------------------------- 1 | require "spec_helper" 2 | 3 | module Raygun 4 | module Breadcrumbs 5 | describe Store do 6 | let(:subject) { Store } 7 | after { subject.clear } 8 | 9 | describe "#initialize" do 10 | before do 11 | expect(subject.stored).to eq(nil) 12 | 13 | subject.initialize 14 | end 15 | 16 | it "creates the store on the current Thread" do 17 | expect(subject.stored).to eq([]) 18 | end 19 | 20 | it "does not effect other threads" do 21 | Thread.new do 22 | expect(subject.stored).to eq(nil) 23 | end.join 24 | end 25 | end 26 | 27 | describe "#any?" do 28 | it "returns true if any breadcrumbs have been logged" do 29 | subject.initialize 30 | 31 | subject.record(message: "test") 32 | 33 | expect(subject.any?).to eq(true) 34 | end 35 | 36 | it "returns false if none have been logged" do 37 | subject.initialize 38 | 39 | expect(subject.any?).to eq(false) 40 | end 41 | 42 | it "returns false if the store is uninitialized" do 43 | expect(subject.any?).to eq(false) 44 | end 45 | end 46 | 47 | describe "#clear" do 48 | before do 49 | subject.initialize 50 | end 51 | 52 | it "resets the store back to nil" do 53 | subject.clear 54 | 55 | expect(subject.stored).to eq(nil) 56 | end 57 | end 58 | 59 | describe "#should_record?" do 60 | it "returns false when the log level is above the breadcrumbs level" do 61 | allow(Raygun.configuration).to receive(:breadcrumb_level).and_return(:error) 62 | 63 | crumb = Breadcrumb.new 64 | crumb.level = :warning 65 | 66 | expect(subject.send(:should_record?, crumb)).to eq(false) 67 | end 68 | end 69 | 70 | describe "#take_until_size" do 71 | before do 72 | subject.initialize 73 | end 74 | 75 | it "takes the most recent breadcrumbs until the size limit is reached" do 76 | subject.record(message: '1' * 100) 77 | subject.record(message: '2' * 100) 78 | subject.record(message: '3' * 100) 79 | 80 | crumbs = subject.take_until_size(500) 81 | 82 | expect(crumbs.length).to eq(2) 83 | expect(crumbs[0].message).to eq('2' * 100) 84 | expect(crumbs[1].message).to eq('3' * 100) 85 | end 86 | 87 | it "does not crash with no recorded breadcrumbs" do 88 | crumbs = subject.take_until_size(500) 89 | 90 | expect(crumbs).to eq([]) 91 | end 92 | end 93 | 94 | context "adding a breadcrumb" do 95 | class Foo 96 | include ::Raygun::Breadcrumbs 97 | 98 | def bar 99 | record_breadcrumb(message: "test") 100 | end 101 | end 102 | 103 | before do 104 | subject.clear 105 | subject.initialize 106 | end 107 | 108 | it "gets stored" do 109 | subject.record(message: "test") 110 | 111 | expect(subject.stored.length).to eq(1) 112 | expect(subject.stored[0].message).to eq("test") 113 | end 114 | 115 | it "automatically sets the class name" do 116 | Foo.new.bar 117 | 118 | bc = subject.stored[0] 119 | expect(bc.class_name).to eq("Raygun::Breadcrumbs::Foo") 120 | end 121 | 122 | it "automatically sets the method name" do 123 | Foo.new.bar 124 | 125 | bc = subject.stored[0] 126 | expect(bc.method_name).to eq("bar") 127 | end 128 | 129 | it "does not set the method name if it is already set" do 130 | subject.record(message: 'test', method_name: "foo") 131 | 132 | expect(subject.stored[0].method_name).to eq("foo") 133 | end 134 | 135 | 136 | it "automatically sets the timestamp" do 137 | Timecop.freeze do 138 | Foo.new.bar 139 | 140 | bc = subject.stored[0] 141 | expect(bc.timestamp).to eq(Time.now.utc.to_i) 142 | end 143 | end 144 | 145 | it "does not set the timestamp if it is already set" do 146 | time = Time.now.utc 147 | 148 | Timecop.freeze do 149 | subject.record(message: 'test', timestamp: time) 150 | 151 | expect(subject.stored[0].timestamp).to_not eq(Time.now.utc) 152 | end 153 | end 154 | 155 | it "sets the log level to :info if one is not supplied" do 156 | Foo.new.bar 157 | 158 | expect(subject.stored[0].level).to eq(:info) 159 | end 160 | 161 | it "does not record the breadcrumb if should_record? is false" do 162 | expect(subject).to receive(:should_record?).and_return(false) 163 | Foo.new.bar 164 | 165 | expect(subject.stored.length).to eq(0) 166 | end 167 | end 168 | end 169 | end 170 | end 171 | -------------------------------------------------------------------------------- /spec/services/apply_whitelist_filter_to_payload_spec.rb: -------------------------------------------------------------------------------- 1 | require "spec_helper" 2 | 3 | module Raygun 4 | module Services 5 | describe ApplyWhitelistFilterToPayload do 6 | let(:service) { ApplyWhitelistFilterToPayload.new } 7 | 8 | describe "top level keys" do 9 | let(:payload) do 10 | { foo: 1, bar: 2 } 11 | end 12 | let(:expected) do 13 | { foo: 1 , bar: '[FILTERED]'} 14 | end 15 | 16 | it "filters out keys that are not present in the shape" do 17 | shape = { 18 | foo: true 19 | } 20 | 21 | new_payload = service.call(shape, payload) 22 | 23 | expect(new_payload).to eq(expected) 24 | end 25 | 26 | it "filters out keys that are set to false" do 27 | shape = { 28 | foo: true, 29 | bar: false 30 | } 31 | 32 | new_payload = service.call(shape, payload) 33 | 34 | expect(new_payload).to eq(expected) 35 | end 36 | end 37 | 38 | describe "nested hashes" do 39 | let(:payload) {{ 40 | foo: 1, 41 | bar: { 42 | baz: 2, 43 | qux: 3 44 | } 45 | }} 46 | let(:expected) {{ 47 | foo: 1, 48 | bar: { 49 | baz: 2, 50 | qux: '[FILTERED]' 51 | } 52 | }} 53 | 54 | it "filters out keys in nested hashes" do 55 | shape = { 56 | foo: true, 57 | bar: { 58 | baz: true 59 | } 60 | } 61 | 62 | new_payload = service.call(shape, payload) 63 | 64 | expect(new_payload).to eq(expected) 65 | end 66 | 67 | it "filters out a nested hash if the whitelist does not contain it" do 68 | shape = { 69 | foo: true 70 | } 71 | expected[:bar] = "[FILTERED]" 72 | 73 | new_payload = service.call(shape, payload) 74 | 75 | expect(new_payload).to eq(expected) 76 | end 77 | 78 | it "handles nested hashes when the whitelist is set to allow the whole hash" do 79 | shape = { 80 | bar: true 81 | } 82 | expected = { 83 | foo: '[FILTERED]', 84 | bar: { 85 | baz: 2, 86 | qux: 3 87 | } 88 | } 89 | 90 | new_payload = service.call(shape, payload) 91 | 92 | expect(new_payload).to eq(expected) 93 | end 94 | 95 | it "handles nested hashes when the whitelist is set to not allow the whole hash" do 96 | shape = { 97 | foo: true, 98 | bar: false 99 | } 100 | expected = { 101 | foo: 1, 102 | bar: '[FILTERED]' 103 | } 104 | 105 | new_payload = service.call(shape, payload) 106 | 107 | expect(new_payload).to eq(expected) 108 | end 109 | end 110 | 111 | describe "string keys" do 112 | it "handles the case where a payload key is a string and a whitelist key is a symbol" do 113 | shape = { 114 | foo: true 115 | } 116 | payload = { 117 | "foo" => 1, 118 | "bar" => 2 119 | } 120 | expected = { 121 | "foo" => 1, 122 | "bar" => '[FILTERED]' 123 | } 124 | 125 | new_payload = service.call(shape, payload) 126 | 127 | expect(new_payload).to eq(expected) 128 | end 129 | end 130 | 131 | it "handles a very complex shape" do 132 | shape = { 133 | machineName: true, 134 | version: true, 135 | client: true, 136 | error: { 137 | className: true, 138 | message: true, 139 | stackTrace: true 140 | }, 141 | userCustomData: true, 142 | tags: true, 143 | request: { 144 | hostName: true, 145 | url: true, 146 | httpMethod: true, 147 | iPAddress: true, 148 | queryString: { 149 | param1: true, 150 | param2: true, 151 | }, 152 | headers: { 153 | "Host" => true, 154 | "Connection" => true, 155 | "Upgrade-Insecure_requests" => true, 156 | "User-Agent" => false, 157 | "Accept" => true, 158 | }, 159 | form: { 160 | controller: true, 161 | action: false 162 | }, 163 | rawData: { 164 | controller: true, 165 | action: false 166 | } 167 | }, 168 | user: false, 169 | } 170 | payload = { 171 | machineName: "mindscapes-MacBook-Pro.local", 172 | version: nil, 173 | client: {name: "Raygun4Ruby Gem", version: "1.1.12", clientUrl: "https://github.com/MindscapeHQ/raygun4ruby"}, 174 | error: {className: "Exception", message: "foo", stackTrace: []}, 175 | userCustomData: {}, 176 | tags: ["development"], 177 | request: { 178 | hostName: "localhost", 179 | url: "/make-me-an-error-charlie", 180 | httpMethod: "GET", 181 | iPAddress: "::1", 182 | queryString: { 183 | param1: "1", 184 | param2: "2", 185 | param3: "3", 186 | }, 187 | headers: { 188 | "Host"=>"localhost:3000", 189 | "Connection"=>"keep-alive", 190 | "Upgrade-Insecure_requests"=>"1", 191 | "User-Agent"=> "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36", 192 | "Accept"=>"text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8", 193 | "Accept-Encoding"=>"gzip, deflate, sdch, br", 194 | "Accept-Language"=>"en-US,en;q=0.8", 195 | "Version"=>"HTTP/1.1" 196 | }, 197 | form: { 198 | controller: "home", 199 | action: "raise_error" 200 | }, 201 | rawData: { 202 | controller: "home", 203 | action: "raise_error" 204 | } 205 | } 206 | } 207 | expected = { 208 | machineName: "mindscapes-MacBook-Pro.local", 209 | version: nil, 210 | client: {name: "Raygun4Ruby Gem", version: "1.1.12", clientUrl: "https://github.com/MindscapeHQ/raygun4ruby"}, 211 | error: {className: "Exception", message: "foo", stackTrace: []}, 212 | userCustomData: {}, 213 | tags: ["development"], 214 | request: { 215 | hostName: "localhost", 216 | url: "/make-me-an-error-charlie", 217 | httpMethod: "GET", 218 | iPAddress: "::1", 219 | queryString: { 220 | param1: "1", 221 | param2: "2", 222 | param3: '[FILTERED]' 223 | }, 224 | headers: { 225 | "Host"=>"localhost:3000", 226 | "Connection"=>"keep-alive", 227 | "Upgrade-Insecure_requests"=>"1", 228 | "User-Agent" => "[FILTERED]", 229 | "Accept"=>"text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8", 230 | "Accept-Encoding" => "[FILTERED]", 231 | "Accept-Language" => "[FILTERED]", 232 | "Version" => "[FILTERED]" 233 | }, 234 | form: { 235 | controller: "home", 236 | action: "[FILTERED]" 237 | }, 238 | rawData: { 239 | controller: "home", 240 | action: "[FILTERED]" 241 | } 242 | } 243 | } 244 | 245 | new_payload = service.call(shape, payload) 246 | 247 | expect(new_payload).to eq(expected) 248 | end 249 | end 250 | end 251 | end 252 | -------------------------------------------------------------------------------- /spec/spec_helper.rb: -------------------------------------------------------------------------------- 1 | require "bundler/setup" 2 | 3 | require "timecop" 4 | require "webmock/rspec" 5 | 6 | # Coverage 7 | require "simplecov" 8 | SimpleCov.start do 9 | add_filter "/spec/" 10 | end 11 | 12 | require "support/fake_logger" 13 | 14 | RSpec.configure do |config| 15 | # Enable flags like --only-failures and --next-failure 16 | # config.example_status_persistence_file_path = ".rspec_status" 17 | 18 | # Disable RSpec exposing methods globally on `Module` and `main` 19 | # config.disable_monkey_patching! 20 | 21 | config.expect_with :rspec do |c| 22 | c.syntax = :expect 23 | end 24 | end 25 | -------------------------------------------------------------------------------- /spec/support/fake_logger.rb: -------------------------------------------------------------------------------- 1 | class FakeLogger 2 | def initialize 3 | @logger = StringIO.new 4 | end 5 | 6 | def info(message) 7 | @logger.write(message) 8 | end 9 | 10 | def reset 11 | @logger.string = "" 12 | end 13 | 14 | def get 15 | @logger.string 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /test/integration/client_test.rb: -------------------------------------------------------------------------------- 1 | require_relative "../test_helper.rb" 2 | 3 | class ClientTest < Raygun::IntegrationTest 4 | 5 | class InnocentTestException < StandardError 6 | def message 7 | "I am nothing but a test exception" 8 | end 9 | end 10 | 11 | def test_sending_a_sample_exception 12 | begin 13 | raise InnocentTestException.new 14 | rescue InnocentTestException => e 15 | response = Raygun.track_exception(e) 16 | assert_equal 202, response.code, "Raygun Request Failed: #{response.inspect}" 17 | end 18 | end 19 | 20 | end -------------------------------------------------------------------------------- /test/rails_helper.rb: -------------------------------------------------------------------------------- 1 | ENV['RAILS_ENV'] ||= 'test' 2 | require "rails" 3 | 4 | major_minor_patch = Rails::VERSION::STRING.split(".").first(3).join(".") 5 | 6 | require_relative "../spec/rails_applications/#{major_minor_patch}/config/environment" -------------------------------------------------------------------------------- /test/test_helper.rb: -------------------------------------------------------------------------------- 1 | ENV['RACK_ENV'] = 'test' 2 | require "minitest/autorun" 3 | require "minitest/pride" 4 | require "timecop" 5 | require "mocha/minitest" 6 | require "stringio" 7 | require "webmock/minitest" 8 | 9 | require_relative "./rails_helper" 10 | require_relative "../lib/raygun.rb" 11 | 12 | # Ensure we start with a known state 13 | Raygun.reset_configuration 14 | 15 | class FakeLogger 16 | def initialize 17 | @logger = StringIO.new 18 | end 19 | 20 | def info(message) 21 | @logger.write(message) 22 | end 23 | 24 | def reset 25 | @logger.string = "" 26 | end 27 | 28 | def get 29 | @logger.string 30 | end 31 | end 32 | 33 | class NoApiKey < StandardError; end 34 | 35 | class Raygun::IntegrationTest < Minitest::Test 36 | 37 | def setup 38 | Raygun.setup do |config| 39 | config.api_key = File.open(File.expand_path("~/.raygun4ruby-test-key"), "rb").read 40 | config.version = Raygun::VERSION 41 | end 42 | 43 | rescue Errno::ENOENT 44 | raise NoApiKey.new("Place a valid Raygun API key into ~/.raygun4ruby-test-key to run integration tests") unless api_key 45 | end 46 | 47 | def teardown 48 | Raygun.wait_for_futures 49 | Raygun.reset_configuration 50 | end 51 | 52 | end 53 | 54 | class Raygun::UnitTest < Minitest::Test 55 | 56 | def setup 57 | Raygun.configuration.api_key = "test api key" 58 | end 59 | 60 | def teardown 61 | Raygun.wait_for_futures 62 | Raygun.reset_configuration 63 | end 64 | 65 | def fake_successful_entry 66 | stub_request(:post, 'https://api.raygun.com/entries').to_return(status: 202) 67 | end 68 | 69 | def setup_logging 70 | logger = FakeLogger.new 71 | Raygun.configuration.debug = true 72 | Raygun.configuration.logger = logger 73 | 74 | logger 75 | end 76 | end 77 | -------------------------------------------------------------------------------- /test/unit/affected_user_test.rb: -------------------------------------------------------------------------------- 1 | require_relative "../test_helper.rb" 2 | require 'ostruct' 3 | require 'raygun/middleware/rails_insert_affected_user' 4 | 5 | class AffectedUserTest < Raygun::UnitTest 6 | 7 | class TestException < StandardError; end 8 | 9 | class MockController 10 | 11 | def user_with_email 12 | OpenStruct.new(id: 123, email: "testemail@something.com") 13 | end 14 | 15 | def user_with_login 16 | OpenStruct.new(login: "topsecret") 17 | end 18 | 19 | def user_with_full_details 20 | OpenStruct.new(id: 123, email: "testemail@something.com", first_name: "Taylor", last_name: "Lodge") 21 | end 22 | 23 | def user_as_string 24 | "some-string-identifier" 25 | end 26 | 27 | def no_logged_in_user 28 | end 29 | 30 | private 31 | 32 | def private_current_user 33 | user_with_email 34 | end 35 | 36 | end 37 | 38 | class MockApp 39 | attr_accessor :env 40 | 41 | def call(env) 42 | @env = env 43 | raise TestException.new 44 | end 45 | end 46 | 47 | def setup 48 | super 49 | @client = Raygun::Client.new 50 | fake_successful_entry 51 | 52 | @app = MockApp.new 53 | @controller = MockController.new 54 | @middleware = Raygun::Middleware::RailsInsertAffectedUser.new(@app) 55 | end 56 | 57 | def test_inserting_user_object_with_email 58 | Raygun.configuration.affected_user_method = :user_with_email 59 | assert @controller.respond_to?(Raygun.configuration.affected_user_method) 60 | 61 | begin 62 | @middleware.call("action_controller.instance" => @controller) 63 | rescue TestException 64 | user_hash = { :identifier => 123, :email => "testemail@something.com", :isAnonymous => false } 65 | assert_equal user_hash, @app.env["raygun.affected_user"] 66 | end 67 | end 68 | 69 | def test_changing_method_mapping 70 | Raygun.configuration.affected_user_method = :user_with_login 71 | Raygun.configuration.affected_user_mapping = { 72 | identifier: :login 73 | } 74 | 75 | assert @controller.respond_to?(Raygun.configuration.affected_user_method) 76 | 77 | begin 78 | @middleware.call("action_controller.instance" => @controller) 79 | rescue TestException 80 | user_hash = { :identifier => "topsecret", :isAnonymous => false } 81 | assert_equal user_hash, @app.env["raygun.affected_user"] 82 | end 83 | end 84 | 85 | def test_inserting_user_as_plain_string 86 | Raygun.configuration.affected_user_method = :user_as_string 87 | assert @controller.respond_to?(Raygun.configuration.affected_user_method) 88 | 89 | begin 90 | @middleware.call("action_controller.instance" => @controller) 91 | rescue TestException 92 | user_hash = { :identifier => "some-string-identifier", :isAnonymous => true } 93 | assert_equal user_hash, @app.env["raygun.affected_user"] 94 | end 95 | end 96 | 97 | def test_with_a_nil_user 98 | Raygun.configuration.affected_user_method = :no_logged_in_user 99 | assert @controller.respond_to?(Raygun.configuration.affected_user_method) 100 | 101 | begin 102 | @middleware.call("action_controller.instance" => @controller) 103 | rescue TestException 104 | user_hash = { :isAnonymous => true } 105 | assert_equal user_hash, @app.env["raygun.affected_user"] 106 | end 107 | end 108 | 109 | def test_with_private_method 110 | Raygun.configuration.affected_user_method = :private_current_user 111 | assert @controller.respond_to?(Raygun.configuration.affected_user_method, true) 112 | 113 | begin 114 | @middleware.call("action_controller.instance" => @controller) 115 | rescue TestException 116 | user_hash = {:isAnonymous=>false, :identifier=>123, :email=>"testemail@something.com"} 117 | assert_equal user_hash, @app.env["raygun.affected_user"] 118 | end 119 | end 120 | 121 | def test_with_proc_for_mapping 122 | Raygun.configuration.affected_user_method = :user_with_full_details 123 | Raygun.configuration.affected_user_mapping = Raygun::AffectedUser::DEFAULT_MAPPING.merge({ 124 | full_name: ->(user) { "#{user.first_name} #{user.last_name}" } 125 | }) 126 | 127 | assert @controller.respond_to?(Raygun.configuration.affected_user_method, true) 128 | 129 | begin 130 | @middleware.call("action_controller.instance" => @controller) 131 | rescue TestException 132 | user_hash = {:isAnonymous=>false, :identifier=>123, :email=>"testemail@something.com", :fullName => "Taylor Lodge", :firstName => "Taylor"} 133 | assert_equal user_hash, @app.env["raygun.affected_user"] 134 | end 135 | end 136 | end 137 | -------------------------------------------------------------------------------- /test/unit/configuration_test.rb: -------------------------------------------------------------------------------- 1 | require_relative "../test_helper.rb" 2 | 3 | class ConfigurationTest < Raygun::UnitTest 4 | 5 | class TestException < StandardError; end 6 | class Test2Exception < StandardError; end 7 | 8 | def setup 9 | Raygun.setup do |config| 10 | config.api_key = "a test api key" 11 | config.version = 9.9 12 | end 13 | end 14 | 15 | def test_setting_api_key_and_version 16 | assert_equal 9.9, Raygun.configuration.version 17 | assert_equal "a test api key", Raygun.configuration.api_key 18 | end 19 | 20 | def test_hash_style_access 21 | assert_equal 9.9, Raygun.configuration[:version] 22 | end 23 | 24 | def test_set_js_api_key 25 | Raygun.configuration.js_api_key = "a test js api key" 26 | 27 | assert_equal "a test js api key", Raygun.configuration.js_api_key 28 | end 29 | 30 | def test_set_js_api_version 31 | Raygun.configuration.js_api_version = "a test js api version" 32 | 33 | assert_equal "a test js api version", Raygun.configuration.js_api_version 34 | end 35 | 36 | def test_enable_reporting 37 | Raygun.configuration.enable_reporting = false 38 | 39 | # should be no API call 40 | assert_nil Raygun.track_exception(TestException.new) 41 | end 42 | 43 | def test_silence_reporting 44 | Raygun.configuration.silence_reporting = true 45 | 46 | # nothing returned as there's no HTTP call 47 | assert_nil Raygun.track_exception(TestException.new) 48 | end 49 | 50 | def test_ignoring_exceptions 51 | Raygun.configuration.ignore << TestException.to_s 52 | 53 | assert_nil Raygun.track_exception(TestException.new) 54 | end 55 | 56 | def test_ignoring_multiple_exceptions 57 | Raygun.configuration.ignore << [TestException.to_s, Test2Exception.to_s] 58 | 59 | assert_nil Raygun.track_exception(TestException.new) 60 | assert_nil Raygun.track_exception(Test2Exception.new) 61 | end 62 | 63 | def test_default_values 64 | assert_equal({}, Raygun.configuration.custom_data) 65 | end 66 | 67 | def test_default_tags_set 68 | assert_equal([], Raygun.configuration.tags) 69 | end 70 | 71 | def test_overriding_defaults 72 | Raygun.default_configuration.custom_data = { robby: "robot" } 73 | assert_equal({ robby: "robot" }, Raygun.configuration.custom_data) 74 | 75 | Raygun.configuration.custom_data = { sally: "stegosaurus" } 76 | assert_equal({ sally: "stegosaurus" }, Raygun.configuration.custom_data) 77 | end 78 | 79 | def test_debug 80 | Raygun.setup do |config| 81 | config.debug = true 82 | end 83 | 84 | assert_equal Raygun.configuration.debug, true 85 | end 86 | 87 | def test_debug_default_set 88 | assert_equal false, Raygun.configuration.debug 89 | end 90 | 91 | def test_setting_filter_paramters_to_proc 92 | Raygun.setup do |config| 93 | config.filter_parameters do |hash| 94 | # Don't need to do anything :) 95 | end 96 | end 97 | 98 | assert Raygun.configuration.filter_parameters.is_a?(Proc) 99 | ensure 100 | Raygun.configuration.filter_parameters = nil 101 | end 102 | 103 | def test_filter_payload_with_whitelist_default 104 | assert_equal(false, Raygun.configuration.filter_payload_with_whitelist) 105 | end 106 | 107 | def test_setting_whitelist_payload_keys_to_proc 108 | Raygun.setup do |config| 109 | config.whitelist_payload_shape do |hash| 110 | # No-op 111 | end 112 | end 113 | 114 | assert Raygun.configuration.whitelist_payload_shape.is_a?(Proc) 115 | ensure 116 | Raygun.configuration.whitelist_payload_shape = nil 117 | end 118 | 119 | def test_setting_custom_data_to_proc 120 | Raygun.setup do |config| 121 | config.custom_data do |exception, env| 122 | # No-op 123 | end 124 | end 125 | 126 | assert Raygun.configuration.custom_data.is_a?(Proc) 127 | ensure 128 | Raygun.configuration.custom_data = nil 129 | end 130 | 131 | def test_setting_custom_data_to_hash 132 | Raygun.setup do |config| 133 | config.custom_data = {} 134 | end 135 | 136 | assert Raygun.configuration.custom_data.is_a?(Hash) 137 | ensure 138 | Raygun.configuration.custom_data = nil 139 | end 140 | 141 | def test_setting_tags_to_array 142 | Raygun.setup do |c| 143 | c.tags = ['test'] 144 | end 145 | 146 | assert_equal Raygun.configuration.tags, ['test'] 147 | end 148 | 149 | def test_setting_tags_to_proc 150 | Raygun.setup do |c| 151 | c.tags = ->(exception, env) {} 152 | end 153 | 154 | assert Raygun.configuration.tags.is_a?(Proc) 155 | end 156 | 157 | def test_api_url_default 158 | assert_equal "https://api.raygun.com/", Raygun.configuration.api_url 159 | end 160 | 161 | def test_setting_breadcrumb_level 162 | Raygun.setup do |config| 163 | config.breadcrumb_level = :info 164 | end 165 | 166 | assert_equal :info, Raygun.configuration.breadcrumb_level 167 | end 168 | 169 | def test_setting_breadcrumb_level_to_bad_value 170 | logger = setup_logging 171 | 172 | Raygun.setup do |config| 173 | config.breadcrumb_level = :invalid 174 | end 175 | 176 | assert_equal :info, Raygun.configuration.breadcrumb_level 177 | assert( 178 | logger.get.include?("unknown breadcrumb level"), 179 | "unknown breadcrumb level message was not logged" 180 | ) 181 | end 182 | 183 | def test_breadcrumb_level_default 184 | assert_equal :info, Raygun.configuration.breadcrumb_level 185 | end 186 | 187 | def test_record_raw_data_default 188 | assert_equal false, Raygun.configuration.record_raw_data 189 | end 190 | 191 | def test_send_in_background_default 192 | assert_equal false, Raygun.configuration.send_in_background 193 | end 194 | 195 | def test_error_report_send_timeout_default 196 | assert_equal 10, Raygun.configuration.error_report_send_timeout 197 | end 198 | 199 | def test_enable_reporting_default 200 | assert_equal true, Raygun.configuration.enable_reporting 201 | end 202 | end 203 | -------------------------------------------------------------------------------- /test/unit/error_subscriber_test.rb: -------------------------------------------------------------------------------- 1 | require_relative "../test_helper.rb" 2 | 3 | class ErrorSubscriberTest < Raygun::UnitTest 4 | 5 | def setup 6 | super 7 | Raygun.configuration.send_in_background = false 8 | end 9 | 10 | 11 | def test_tracking_exception_via_subscriber 12 | body_matcher = lambda do |body| 13 | json = JSON.parse(body) 14 | details = json["details"] 15 | 16 | details["userCustomData"] && 17 | details["userCustomData"]["rails.error"] && 18 | details["userCustomData"]["rails.error"]["handled"] == true && 19 | details["tags"] == ["rails_error_reporter", "test_tag", "test"] 20 | end 21 | 22 | request_stub = stub_request(:post, 'https://api.raygun.com/entries') 23 | .with( 24 | body: body_matcher 25 | ) 26 | .to_return(status: 202).times(1) 27 | 28 | result = Raygun::ErrorSubscriber.new.report( 29 | StandardError.new("test error"), 30 | handled: true, 31 | severity: "warning", 32 | context: { 33 | tags: ["test_tag"] 34 | }, 35 | source: "application" 36 | ) 37 | 38 | assert result && result.success?, "Expected success, got #{result.class}, #{result.inspect}" 39 | 40 | assert_requested request_stub 41 | end 42 | 43 | end -------------------------------------------------------------------------------- /test/unit/raygun_test.rb: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | require_relative "../test_helper.rb" 3 | 4 | class RaygunTest < Raygun::UnitTest 5 | def test_raygun_is_not_configured_with_no_api_key 6 | Raygun.configuration.api_key = nil 7 | assert !Raygun.configured? 8 | end 9 | 10 | def test_should_report_logs_silence_reporting_when_debug_is_on 11 | logger = setup_logging 12 | Raygun.configuration.silence_reporting = true 13 | Raygun.send(:should_report?, Exception.new) 14 | 15 | assert logger.get.include?("silence_reporting"), "silence_reporting was not logged" 16 | end 17 | 18 | def test_should_report_logs_ignored_exceptions_when_debug_is_on 19 | logger = setup_logging 20 | Raygun.configuration.ignore = ["Exception"] 21 | Raygun.send(:should_report?, Exception.new) 22 | 23 | assert logger.get =~ /skipping reporting of.*Exception.*/, "ignored exception was not logged" 24 | end 25 | 26 | class BackgroundSendTest < Raygun::UnitTest 27 | def setup 28 | @failsafe_logger = FakeLogger.new 29 | Raygun.setup do |c| 30 | c.silence_reporting = false 31 | c.send_in_background = true 32 | c.api_url = "http://example.api" 33 | c.api_key = "foo" 34 | c.debug = false 35 | c.failsafe_logger = @failsafe_logger 36 | end 37 | end 38 | 39 | def test_breadcrumb_context_passed 40 | Raygun::Breadcrumbs::Store.initialize 41 | Raygun.record_breadcrumb(message: "mmm crumbly") 42 | assert Raygun::Breadcrumbs::Store.any? 43 | 44 | stub_request(:post, "http://example.api/entries") 45 | .with(body: hash_including(breadcrumbs: [ hash_including(message: "mmm crumbly") ])) 46 | .to_return(status: 202) 47 | 48 | Raygun.track_exception(StandardError.new) 49 | Raygun.wait_for_futures 50 | ensure 51 | Raygun::Breadcrumbs::Store.clear 52 | end 53 | 54 | def test_failsafe_reported_on_timeout 55 | stub_request(:post, "http://example.api/entries").to_timeout 56 | 57 | error = StandardError.new 58 | 59 | Raygun.track_exception(error) 60 | 61 | Raygun.wait_for_futures 62 | assert_match(/Problem reporting exception to Raygun/, @failsafe_logger.get) 63 | end 64 | 65 | end 66 | 67 | class ErrorSubscriberTest < Raygun::UnitTest 68 | def setup 69 | Raygun.setup do |c| 70 | c.api_key = "test" 71 | c.silence_reporting = false 72 | c.debug = true 73 | c.register_rails_error_handler = true 74 | end 75 | 76 | Raygun::Railtie.setup_error_subscriber 77 | end 78 | 79 | def test_registers_with_rails 80 | if ::Rails.version.to_f >= 7.0 81 | assert Rails.error.instance_variable_get("@subscribers").any? { |s| s.is_a?(Raygun::ErrorSubscriber) } 82 | end 83 | end 84 | 85 | def test_reports_exceptions 86 | if ::Rails.version.to_f >= 7.0 87 | stub_request(:post, "https://api.raygun.com/entries").to_return(status: 202) 88 | 89 | Rails.error.handle do 90 | raise StandardError.new("test rails handling") 91 | end 92 | end 93 | end 94 | end 95 | 96 | def test_reset_configuration 97 | Raygun.setup do |c| 98 | c.api_url = "http://test.api" 99 | end 100 | 101 | original_api_url = Raygun.configuration.api_url 102 | Raygun.reset_configuration 103 | assert_equal Raygun.default_configuration.api_url, Raygun.configuration.api_url 104 | refute_equal original_api_url, Raygun.configuration.api_url 105 | end 106 | 107 | def test_retries 108 | failsafe_logger = FakeLogger.new 109 | Raygun.setup do |c| 110 | c.error_report_max_attempts = 3 111 | c.failsafe_logger = failsafe_logger 112 | end 113 | 114 | WebMock.reset! 115 | report_request = stub_request(:post, "https://api.raygun.com/entries").to_timeout 116 | 117 | error = StandardError.new 118 | Raygun.track_exception(error) 119 | 120 | assert_requested report_request, times: 3 121 | 122 | assert_match(/Gave up reporting exception to Raygun after 3 retries/, failsafe_logger.get) 123 | ensure 124 | Raygun.reset_configuration 125 | end 126 | 127 | def test_raising_on_retry_failure 128 | Raygun.setup do |c| 129 | c.error_report_max_attempts = 1 130 | c.raise_on_failed_error_report = true 131 | end 132 | 133 | report_request = stub_request(:post, "https://api.raygun.com/entries").to_timeout 134 | 135 | error = StandardError.new 136 | 137 | assert_raises(StandardError) do 138 | Raygun.track_exception(error) 139 | assert_requested report_request 140 | end 141 | 142 | ensure 143 | Raygun.reset_configuration 144 | end 145 | end 146 | -------------------------------------------------------------------------------- /test/unit/resque_failure_test.rb: -------------------------------------------------------------------------------- 1 | require_relative "../test_helper.rb" 2 | 3 | # Very simple test 4 | class ResqueFailureTest < Raygun::UnitTest 5 | 6 | require "resque/failure/raygun" 7 | 8 | def setup 9 | super 10 | Raygun.configuration.send_in_background = false 11 | 12 | stub_request(:post, 'https://api.raygun.com/entries').to_return(status: 202) 13 | fake_successful_entry 14 | end 15 | 16 | def test_failure_backend_appears_to_work 17 | result = Resque::Failure::Raygun.new( 18 | StandardError.new("Worker Problem"), 19 | "TestWorker PID 123", 20 | "super_important_jobs", 21 | class: "SendCookies", args: [ "nik" ] 22 | ).save 23 | 24 | assert result && result.success?, "Expected success, got #{result.inspect}" 25 | end 26 | 27 | end 28 | -------------------------------------------------------------------------------- /test/unit/sidekiq_failure_test.rb: -------------------------------------------------------------------------------- 1 | require_relative "../test_helper.rb" 2 | 3 | require "sidekiq" 4 | 5 | # Convince Sidekiq it's on a server :) 6 | module Sidekiq 7 | class << self 8 | undef server? 9 | def server? 10 | true 11 | end 12 | end 13 | end 14 | require "raygun/sidekiq" 15 | 16 | class SidekiqFailureTest < Raygun::UnitTest 17 | 18 | def setup 19 | require "sidekiq/job_retry" 20 | 21 | super 22 | Raygun.configuration.send_in_background = false 23 | 24 | stub_request(:post, 'https://api.raygun.com/entries').to_return(status: 202) 25 | fake_successful_entry 26 | end 27 | 28 | def test_failure_backend_appears_to_work 29 | response = Raygun::SidekiqReporter.call( 30 | StandardError.new("Oh no! Your Sidekiq has failed!"), 31 | { sidekick_name: "robin" }, 32 | {} # config 33 | ) 34 | 35 | assert response && response.success?, "Expected success, got #{response.class}: #{response.inspect}" 36 | end 37 | 38 | def test_failure_backend_unwraps_retries 39 | WebMock.reset! 40 | 41 | unwrapped_stub = stub_request(:post, 'https://api.raygun.com/entries'). 42 | with(body: /StandardError/). 43 | to_return(status: 202) 44 | 45 | begin 46 | raise StandardError.new("Some job in Sidekiq failed, oh dear!") 47 | rescue 48 | raise Sidekiq::JobRetry::Handled 49 | end 50 | 51 | rescue Sidekiq::JobRetry::Handled => e 52 | 53 | response = Raygun::SidekiqReporter.call( 54 | e, 55 | { sidekick_name: "robin" }, 56 | {} # config 57 | ) 58 | 59 | assert_requested unwrapped_stub 60 | assert response && response.success?, "Expected success, got #{response.class}: #{response.inspect}" 61 | end 62 | 63 | def test_failured_backend_ignores_retries_if_configured 64 | Raygun.configuration.track_retried_sidekiq_jobs = false 65 | 66 | begin 67 | raise StandardError.new("Some job in Sidekiq failed, oh dear!") 68 | rescue 69 | raise Sidekiq::JobRetry::Handled 70 | end 71 | 72 | rescue Sidekiq::JobRetry::Handled => e 73 | 74 | refute Raygun::SidekiqReporter.call(e, 75 | { sidekick_name: "robin" }, 76 | {} # config 77 | ) 78 | ensure 79 | Raygun.configuration.track_retried_sidekiq_jobs = true 80 | end 81 | 82 | # See https://github.com/MindscapeHQ/raygun4ruby/issues/183 83 | # (This is how Sidekiq pre 7.1.5 calls error handlers: https://github.com/sidekiq/sidekiq/blob/1ba89bbb22d2fd574b11702d8b6ed63ae59e2256/lib/sidekiq/config.rb#L269) 84 | def test_failure_backend_appears_to_work_without_config_argument 85 | response = Raygun::SidekiqReporter.call( 86 | StandardError.new("Oh no! Your Sidekiq has failed!"), 87 | { sidekick_name: "robin" } 88 | ) 89 | 90 | assert response && response.success?, "Expected success, got #{response.class}: #{response.inspect}" 91 | end 92 | 93 | def test_we_are_in_sidekiqs_list_of_error_handlers 94 | # Sidekiq 7.x stores error handlers inside a configuration object, while 6.x and below stores them directly against the Sidekiq module 95 | error_handlers = Sidekiq.respond_to?(:error_handlers) ? Sidekiq.error_handlers : Sidekiq.default_configuration.error_handlers 96 | 97 | assert error_handlers.include?(Raygun::SidekiqReporter) 98 | end 99 | 100 | def test_rails_error_reporter_uses_sidekiq_reporter 101 | WebMock.reset! 102 | 103 | tagged_request = stub_request(:post, 'https://api.raygun.com/entries'). 104 | with(body: /"sidekiq"/). # should have a sidekiq tag! 105 | to_return(status: 202) 106 | 107 | error = StandardError.new("Oh no! Your Sidekiq has failed!") 108 | 109 | response = Raygun::ErrorSubscriber.new.report( 110 | error, 111 | handled: true, 112 | severity: "error", 113 | context: { sidekick_name: "robin" }, 114 | source: "job.sidekiq" 115 | ) 116 | 117 | assert response && response.success?, "Expected success, got #{response.class}: #{response.inspect}" 118 | 119 | assert_requested tagged_request 120 | end 121 | 122 | end 123 | --------------------------------------------------------------------------------