From ca3e7c7141a95d2f65cdc79b7d3ab2460f1a1acc Mon Sep 17 00:00:00 2001 From: Sebastian Zaremba <1636476+vassyz@users.noreply.github.com> Date: Tue, 18 Oct 2022 13:50:17 +0100 Subject: [PATCH] Upgrade Ruby to 3.0.4 and Rails to 6.1.7 (#2233) * Upgrade Ruby to 3.0.4 and Rails to 6.1.7 * Enable a few default configs * Keep the JS compressor Co-authored-by: Steven Lorek --- .ruby-version | 2 +- Dockerfile | 2 +- Gemfile | 9 +- Gemfile.lock | 207 ++++++++++-------- app/models/concerns/eligibility_checkable.rb | 2 +- app/models/current_claim.rb | 14 +- .../early_career_payments/dqt_record.rb | 2 +- .../early_career_payments/eligibility.rb | 6 +- .../eligibility.rb | 4 +- app/models/policy_configuration.rb | 2 +- app/views/shared/_error_summary.html.erb | 4 +- bin/rails | 12 +- bin/rake | 5 +- bin/setup | 16 +- bin/spring | 21 +- bin/yarn | 12 +- config.ru | 1 + config/application.rb | 10 +- config/environments/development.rb | 23 +- config/environments/production.rb | 51 ++++- config/environments/test.rb | 26 ++- config/initializers/backtrace_silencers.rb | 11 +- .../initializers/content_security_policy.rb | 6 +- .../new_framework_defaults_6_1.rb | 67 ++++++ config/initializers/permissions_policy.rb | 11 + config/locales/en.yml | 2 +- config/puma.rb | 17 +- .../combined_teacher_claim_journey_spec.rb | 2 +- .../early_career_payments_claim_spec.rb | 2 +- .../levelling_up_premium_payments_spec.rb | 2 +- spec/models/amendment_spec.rb | 8 +- spec/models/claim_spec.rb | 4 +- 32 files changed, 367 insertions(+), 196 deletions(-) create mode 100644 config/initializers/new_framework_defaults_6_1.rb create mode 100644 config/initializers/permissions_policy.rb diff --git a/.ruby-version b/.ruby-version index 49cdd668e1..b0f2dcb32f 100644 --- a/.ruby-version +++ b/.ruby-version @@ -1 +1 @@ -2.7.6 +3.0.4 diff --git a/Dockerfile b/Dockerfile index 448530cdec..f24904340b 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,7 +1,7 @@ # ------------------------------------------------------------------------------ # base # ------------------------------------------------------------------------------ -FROM ruby:2.7.6-alpine AS base +FROM ruby:3.0.4-alpine AS base RUN addgroup -S appgroup && adduser -S appuser -G appgroup diff --git a/Gemfile b/Gemfile index 5a30707245..f4da1ec137 100644 --- a/Gemfile +++ b/Gemfile @@ -1,10 +1,10 @@ source "https://rubygems.org" git_source(:github) { |repo| "https://github.com/#{repo}.git" } -ruby "2.7.6" +ruby "3.0.4" # Bundle edge Rails instead: gem 'rails', github: 'rails/rails' -gem "rails", "6.0.6" +gem "rails", "6.1.7" # Use postgresql as the database for Active Record gem "pg", ">= 0.18", "< 2.0" # Use Puma as the app server @@ -64,7 +64,7 @@ gem "httpclient" gem "daemons" # Gov form builder to structure claims -gem "govuk_design_system_formbuilder" +gem "govuk_design_system_formbuilder", "~> 2.8.0" # See https://github.com/typhoeus/ethon/issues/185 gem "ethon", "~> 0.15.0" @@ -91,8 +91,7 @@ gem "activerecord-copy", require: false gem "pagy" group :development, :test do - gem "amazing_print" - gem "byebug", platforms: [:mri, :mingw, :x64_mingw] + gem "debug" gem "rspec-rails" gem "capybara" gem "brakeman", require: false diff --git a/Gemfile.lock b/Gemfile.lock index 13e6156865..9f97f2d1d5 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -17,70 +17,73 @@ GIT GEM remote: https://rubygems.org/ specs: - actioncable (6.0.6) - actionpack (= 6.0.6) + actioncable (6.1.7) + actionpack (= 6.1.7) + activesupport (= 6.1.7) nio4r (~> 2.0) websocket-driver (>= 0.6.1) - actionmailbox (6.0.6) - actionpack (= 6.0.6) - activejob (= 6.0.6) - activerecord (= 6.0.6) - activestorage (= 6.0.6) - activesupport (= 6.0.6) + actionmailbox (6.1.7) + actionpack (= 6.1.7) + activejob (= 6.1.7) + activerecord (= 6.1.7) + activestorage (= 6.1.7) + activesupport (= 6.1.7) mail (>= 2.7.1) - actionmailer (6.0.6) - actionpack (= 6.0.6) - actionview (= 6.0.6) - activejob (= 6.0.6) + actionmailer (6.1.7) + actionpack (= 6.1.7) + actionview (= 6.1.7) + activejob (= 6.1.7) + activesupport (= 6.1.7) mail (~> 2.5, >= 2.5.4) rails-dom-testing (~> 2.0) - actionpack (6.0.6) - actionview (= 6.0.6) - activesupport (= 6.0.6) - rack (~> 2.0, >= 2.0.8) + actionpack (6.1.7) + actionview (= 6.1.7) + activesupport (= 6.1.7) + rack (~> 2.0, >= 2.0.9) rack-test (>= 0.6.3) rails-dom-testing (~> 2.0) rails-html-sanitizer (~> 1.0, >= 1.2.0) - actiontext (6.0.6) - actionpack (= 6.0.6) - activerecord (= 6.0.6) - activestorage (= 6.0.6) - activesupport (= 6.0.6) + actiontext (6.1.7) + actionpack (= 6.1.7) + activerecord (= 6.1.7) + activestorage (= 6.1.7) + activesupport (= 6.1.7) nokogiri (>= 1.8.5) - actionview (6.0.6) - activesupport (= 6.0.6) + actionview (6.1.7) + activesupport (= 6.1.7) builder (~> 3.1) erubi (~> 1.4) rails-dom-testing (~> 2.0) rails-html-sanitizer (~> 1.1, >= 1.2.0) - activejob (6.0.6) - activesupport (= 6.0.6) + activejob (6.1.7) + activesupport (= 6.1.7) globalid (>= 0.3.6) - activemodel (6.0.6) - activesupport (= 6.0.6) - activerecord (6.0.6) - activemodel (= 6.0.6) - activesupport (= 6.0.6) + activemodel (6.1.7) + activesupport (= 6.1.7) + activerecord (6.1.7) + activemodel (= 6.1.7) + activesupport (= 6.1.7) activerecord-copy (1.1.0) activerecord (>= 3.1) - activestorage (6.0.6) - actionpack (= 6.0.6) - activejob (= 6.0.6) - activerecord (= 6.0.6) + activestorage (6.1.7) + actionpack (= 6.1.7) + activejob (= 6.1.7) + activerecord (= 6.1.7) + activesupport (= 6.1.7) marcel (~> 1.0) - activesupport (6.0.6) + mini_mime (>= 1.1.0) + activesupport (6.1.7) concurrent-ruby (~> 1.0, >= 1.0.2) - i18n (>= 0.7, < 2) - minitest (~> 5.1) - tzinfo (~> 1.1) - zeitwerk (~> 2.2, >= 2.2.2) + i18n (>= 1.6, < 2) + minitest (>= 5.1) + tzinfo (~> 2.0) + zeitwerk (~> 2.3) addressable (2.8.1) public_suffix (>= 2.0.2, < 6.0) aes_key_wrap (1.1.0) - amazing_print (1.4.0) ast (2.4.2) attr_required (1.0.1) - bindata (2.4.10) + bindata (2.4.12) bindex (0.8.1) bootsnap (1.13.0) msgpack (~> 1.2) @@ -89,7 +92,6 @@ GEM bullet (7.0.3) activesupport (>= 3.0.0) uniform_notifier (~> 1.11) - byebug (11.1.3) capybara (3.37.1) addressable matrix @@ -105,11 +107,14 @@ GEM rexml crass (1.0.6) daemons (1.4.1) + debug (1.6.2) + irb (>= 1.3.6) + reline (>= 0.3.1) declarative (0.0.20) deep_merge (1.2.2) delayed_cron_job (0.9.0) fugit (>= 1.5) - delayed_job (4.1.10) + delayed_job (4.1.11) activesupport (>= 3.0, < 8.0) delayed_job_active_record (4.1.7) activerecord (>= 3.0, < 8.0) @@ -162,7 +167,7 @@ GEM faraday (~> 1.0) ffi (1.15.5) foreman (0.87.2) - fugit (1.5.3) + fugit (1.7.1) et-orbi (~> 1, >= 1.2.7) raabro (~> 1.4) globalid (1.0.0) @@ -219,21 +224,25 @@ GEM httpclient (2.8.3) i18n (1.12.0) concurrent-ruby (~> 1.0) + io-console (0.5.11) + irb (1.4.2) + reline (>= 0.3.0) jbuilder (2.11.5) actionview (>= 5.0.0) activesupport (>= 5.0.0) json (2.6.2) - json-jwt (1.13.0) + json-jwt (1.15.3) activesupport (>= 4.2) aes_key_wrap bindata + httpclient jwt (2.5.0) launchy (2.5.0) addressable (~> 2.7) listen (3.7.1) rb-fsevent (~> 0.10, >= 0.10.3) rb-inotify (~> 0.9, >= 0.9.10) - loofah (2.18.0) + loofah (2.19.0) crass (~> 1.0.2) nokogiri (>= 1.5.9) mail (2.7.1) @@ -252,17 +261,21 @@ GEM mini_mime (1.1.2) mini_portile2 (2.8.0) minitest (5.16.3) - msgpack (1.5.4) + msgpack (1.6.0) multi_json (1.15.0) multipart-post (2.2.3) nanoid (2.0.0) + net-protocol (0.1.3) + timeout + net-smtp (0.3.2) + net-protocol nio4r (2.5.8) nokogiri (1.13.8) mini_portile2 (~> 2.8.0) racc (~> 1.4) nokogiri (1.13.8-x86_64-darwin) racc (~> 1.4) - notifications-ruby-client (5.3.0) + notifications-ruby-client (5.4.0) jwt (>= 1.5, < 3) omniauth (2.1.0) hashie (>= 3.4.6) @@ -275,16 +288,17 @@ GEM addressable (~> 2.5) omniauth (>= 1.9, < 3) openid_connect (~> 1.1) - openid_connect (1.3.0) + openid_connect (1.4.2) activemodel attr_required (>= 1.0.0) - json-jwt (>= 1.5.0) - rack-oauth2 (>= 1.6.1) - swd (>= 1.0.0) + json-jwt (>= 1.15.0) + net-smtp + rack-oauth2 (~> 1.21) + swd (~> 1.3) tzinfo validate_email validate_url - webfinger (>= 1.0.1) + webfinger (~> 1.2) os (1.1.4) pagy (5.10.1) activesupport @@ -298,30 +312,30 @@ GEM raabro (1.4.0) racc (1.6.0) rack (2.2.4) - rack-oauth2 (1.19.0) + rack-oauth2 (1.21.3) activesupport attr_required httpclient json-jwt (>= 1.11.0) rack (>= 2.1.0) - rack-protection (2.2.2) + rack-protection (3.0.2) rack rack-test (2.0.2) rack (>= 1.3) - rails (6.0.6) - actioncable (= 6.0.6) - actionmailbox (= 6.0.6) - actionmailer (= 6.0.6) - actionpack (= 6.0.6) - actiontext (= 6.0.6) - actionview (= 6.0.6) - activejob (= 6.0.6) - activemodel (= 6.0.6) - activerecord (= 6.0.6) - activestorage (= 6.0.6) - activesupport (= 6.0.6) - bundler (>= 1.3.0) - railties (= 6.0.6) + rails (6.1.7) + actioncable (= 6.1.7) + actionmailbox (= 6.1.7) + actionmailer (= 6.1.7) + actionpack (= 6.1.7) + actiontext (= 6.1.7) + actionview (= 6.1.7) + activejob (= 6.1.7) + activemodel (= 6.1.7) + activerecord (= 6.1.7) + activestorage (= 6.1.7) + activesupport (= 6.1.7) + bundler (>= 1.15.0) + railties (= 6.1.7) sprockets-rails (>= 2.0.0) rails-dom-testing (2.0.3) activesupport (>= 4.2.0) @@ -332,18 +346,20 @@ GEM rack railties (>= 5.1) semantic_logger (~> 4.9) - railties (6.0.6) - actionpack (= 6.0.6) - activesupport (= 6.0.6) + railties (6.1.7) + actionpack (= 6.1.7) + activesupport (= 6.1.7) method_source - rake (>= 0.8.7) - thor (>= 0.20.3, < 2.0) + rake (>= 12.2) + thor (~> 1.0) rainbow (3.1.1) rake (13.0.6) rb-fsevent (0.11.2) rb-inotify (0.10.1) ffi (~> 1.0) - regexp_parser (2.5.0) + regexp_parser (2.6.0) + reline (0.3.1) + io-console (~> 0.5) representable (3.2.0) declarative (< 0.1.0) trailblazer-option (>= 0.1.1, < 0.2.0) @@ -356,21 +372,21 @@ GEM rotp (6.2.0) rspec-core (3.11.0) rspec-support (~> 3.11.0) - rspec-expectations (3.11.0) + rspec-expectations (3.11.1) diff-lcs (>= 1.2.0, < 2.0) rspec-support (~> 3.11.0) rspec-mocks (3.11.1) diff-lcs (>= 1.2.0, < 2.0) rspec-support (~> 3.11.0) - rspec-rails (5.1.2) - actionpack (>= 5.2) - activesupport (>= 5.2) - railties (>= 5.2) - rspec-core (~> 3.10) - rspec-expectations (~> 3.10) - rspec-mocks (~> 3.10) - rspec-support (~> 3.10) - rspec-support (3.11.0) + rspec-rails (6.0.0) + actionpack (>= 6.1) + activesupport (>= 6.1) + railties (>= 6.1) + rspec-core (~> 3.11) + rspec-expectations (~> 3.11) + rspec-mocks (~> 3.11) + rspec-support (~> 3.11) + rspec-support (3.11.1) rubocop (1.35.1) json (~> 2.3) parallel (~> 1.10) @@ -441,18 +457,18 @@ GEM attr_required (>= 0.0.5) httpclient (>= 2.4) thor (1.2.1) - thread_safe (0.3.6) tilt (2.0.11) + timeout (0.3.0) trailblazer-option (0.1.2) typhoeus (1.4.0) ethon (>= 0.9.0) - tzinfo (1.2.10) - thread_safe (~> 0.1) + tzinfo (2.0.5) + concurrent-ruby (~> 1.0) uber (0.1.0) uglifier (4.2.0) execjs (>= 0.3.0, < 3) uk_postcode (2.1.8) - unicode-display_width (2.2.0) + unicode-display_width (2.3.0) uniform_notifier (1.16.0) validate_email (0.1.6) activemodel (>= 3.0) @@ -483,7 +499,7 @@ GEM websocket-extensions (0.1.5) xpath (3.2.0) nokogiri (~> 1.8) - zeitwerk (2.6.0) + zeitwerk (2.6.1) PLATFORMS ruby @@ -492,14 +508,13 @@ PLATFORMS DEPENDENCIES activerecord-copy - amazing_print application_insights! bootsnap (>= 1.1.0) brakeman bullet - byebug capybara daemons + debug delayed_cron_job delayed_job_active_record dfe-analytics! @@ -510,7 +525,7 @@ DEPENDENCIES faraday_middleware foreman google-cloud-storage - govuk_design_system_formbuilder + govuk_design_system_formbuilder (~> 2.8.0) httpclient jbuilder (~> 2.11) jwt @@ -524,7 +539,7 @@ DEPENDENCIES pagy pg (>= 0.18, < 2.0) puma (~> 5.6) - rails (= 6.0.6) + rails (= 6.1.7) rails_semantic_logger rollbar rotp @@ -546,7 +561,7 @@ DEPENDENCIES webmock RUBY VERSION - ruby 2.7.6p219 + ruby 3.0.4p208 BUNDLED WITH - 2.3.20 + 2.3.23 diff --git a/app/models/concerns/eligibility_checkable.rb b/app/models/concerns/eligibility_checkable.rb index 97bbdc0063..b2c6241de7 100644 --- a/app/models/concerns/eligibility_checkable.rb +++ b/app/models/concerns/eligibility_checkable.rb @@ -70,7 +70,7 @@ def no_selectable_subjects? if args.values.any?(&:blank?) false else - JourneySubjectEligibilityChecker.new(args).current_and_future_subject_symbols(policy).empty? + JourneySubjectEligibilityChecker.new(**args).current_and_future_subject_symbols(policy).empty? end end diff --git a/app/models/current_claim.rb b/app/models/current_claim.rb index 0a1954a4a6..b1a1562f95 100644 --- a/app/models/current_claim.rb +++ b/app/models/current_claim.rb @@ -58,22 +58,22 @@ def submit!(policy) end end - def method_missing(method_name, *args, &block) + def method_missing(method_name, *args, **kwargs, &block) if [:attributes=, :save!, :update, :update!, :reset_dependent_answers].include?(method_name) claims.each do |c| - c.send(method_name, *args, &block) unless c == main_claim + c.send(method_name, *args, **kwargs, &block) unless c == main_claim end end - main_claim.send(method_name, *args, &block) + main_claim.send(method_name, *args, **kwargs, &block) end - def save(*args) - claims.map { |c| c.save(*args) }.all? + def save(*args, **kwargs) + claims.map { |c| c.save(*args, **kwargs) }.all? end - def respond_to_missing?(method_name, *args) - main_claim.respond_to?(method_name, *args) + def respond_to_missing?(method_name, *args, **kwargs) + main_claim.respond_to?(method_name, *args, **kwargs) end # Always give precedence to returning `:eligible_now` over `:eligible_later` diff --git a/app/models/early_career_payments/dqt_record.rb b/app/models/early_career_payments/dqt_record.rb index 6d60dbdd8b..61b9cc0a32 100644 --- a/app/models/early_career_payments/dqt_record.rb +++ b/app/models/early_career_payments/dqt_record.rb @@ -29,7 +29,7 @@ def eligible? if award_args.values.any?(&:blank?) false else - AwardAmountCalculator.award?(award_args) + AwardAmountCalculator.award?(**award_args) end end diff --git a/app/models/early_career_payments/eligibility.rb b/app/models/early_career_payments/eligibility.rb index 198664db15..d8b2dee980 100644 --- a/app/models/early_career_payments/eligibility.rb +++ b/app/models/early_career_payments/eligibility.rb @@ -90,7 +90,7 @@ def policy # Rescues from errors for assignments coming from LUP-only fields # eg. `claim.eligibility.eligible_degree_subject = true` will get ignored - def assign_attributes(*args) + def assign_attributes(*args, **kwargs) super rescue ActiveRecord::UnknownAttributeError all_attributes_ignored = (args.first.keys - IGNORED_ATTRIBUTES).empty? @@ -140,7 +140,7 @@ def calculate_award_amount if args.values.any?(&:blank?) 0 else - AwardAmountCalculator.new(args).amount_in_pounds + AwardAmountCalculator.new(**args).amount_in_pounds end end @@ -199,7 +199,7 @@ def itt_subject_other_than_those_eligible_now_or_in_the_future? # can still rule some out itt_subject_none_of_the_above? else - itt_subject_checker = JourneySubjectEligibilityChecker.new(args) + itt_subject_checker = JourneySubjectEligibilityChecker.new(**args) itt_subject_symbol = itt_subject.to_sym !itt_subject_symbol.in?(itt_subject_checker.current_and_future_subject_symbols(policy)) end diff --git a/app/models/levelling_up_premium_payments/eligibility.rb b/app/models/levelling_up_premium_payments/eligibility.rb index f5eeb02687..969ee3b36e 100644 --- a/app/models/levelling_up_premium_payments/eligibility.rb +++ b/app/models/levelling_up_premium_payments/eligibility.rb @@ -99,7 +99,7 @@ def indicated_ineligible_itt_subject? # trainee teacher who won't have given their ITT year eligible_itt_subject.present? && !eligible_itt_subject.to_sym.in?(JourneySubjectEligibilityChecker.fixed_lup_subject_symbols) else - itt_subject_checker = JourneySubjectEligibilityChecker.new(args) + itt_subject_checker = JourneySubjectEligibilityChecker.new(**args) eligible_itt_subject.present? && !eligible_itt_subject.to_sym.in?(itt_subject_checker.current_subject_symbols(policy)) end end @@ -127,7 +127,7 @@ def good_itt_subject? # trainee teacher who won't have given their ITT year eligible_itt_subject.present? && eligible_itt_subject.to_sym.in?(JourneySubjectEligibilityChecker.fixed_lup_subject_symbols) else - itt_subject_checker = JourneySubjectEligibilityChecker.new(args) + itt_subject_checker = JourneySubjectEligibilityChecker.new(**args) eligible_itt_subject.to_sym.in?(itt_subject_checker.current_subject_symbols(policy)) end end diff --git a/app/models/policy_configuration.rb b/app/models/policy_configuration.rb index d31d54aad2..fb786fb6bd 100644 --- a/app/models/policy_configuration.rb +++ b/app/models/policy_configuration.rb @@ -10,7 +10,7 @@ # * current_academic_year: the academic year the service is currently accepting # claims for. class PolicyConfiguration < ApplicationRecord - ACADEMIC_YEAR_REGEXP = /\A20\d{2}\/20\d{2}\z/.freeze + ACADEMIC_YEAR_REGEXP = /\A20\d{2}\/20\d{2}\z/ SERVICES = [ { diff --git a/app/views/shared/_error_summary.html.erb b/app/views/shared/_error_summary.html.erb index 7ff009fcf3..c4988b6910 100644 --- a/app/views/shared/_error_summary.html.erb +++ b/app/views/shared/_error_summary.html.erb @@ -4,9 +4,9 @@
diff --git a/bin/rails b/bin/rails index 0901824763..6809d57676 100755 --- a/bin/rails +++ b/bin/rails @@ -1,10 +1,12 @@ #!/usr/bin/env ruby -if ENV['RAILS_ENV'] == 'test' - require 'simplecov' - SimpleCov.start 'rails' +load File.expand_path("spring", __dir__) + +if ENV["RAILS_ENV"] == "test" + require "simplecov" + SimpleCov.start "rails" puts "required simplecov" end APP_PATH = File.expand_path('../config/application', __dir__) -require_relative '../config/boot' -require 'rails/commands' +require_relative "../config/boot" +require "rails/commands" diff --git a/bin/rake b/bin/rake index 17240489f6..7327f471e4 100755 --- a/bin/rake +++ b/bin/rake @@ -1,4 +1,5 @@ #!/usr/bin/env ruby -require_relative '../config/boot' -require 'rake' +load File.expand_path("spring", __dir__) +require_relative "../config/boot" +require "rake" Rake.application.run diff --git a/bin/setup b/bin/setup index 94fd4d7977..90700ac4f9 100755 --- a/bin/setup +++ b/bin/setup @@ -1,6 +1,5 @@ #!/usr/bin/env ruby -require 'fileutils' -include FileUtils +require "fileutils" # path to your application root. APP_ROOT = File.expand_path('..', __dir__) @@ -9,24 +8,25 @@ def system!(*args) system(*args) || abort("\n== Command #{args} failed ==") end -chdir APP_ROOT do - # This script is a starting point to setup your application. +FileUtils.chdir APP_ROOT do + # This script is a way to set up or update your development environment automatically. + # This script is idempotent, so that you can run it at any time and get an expectable outcome. # Add necessary setup steps to this file. puts '== Installing dependencies ==' system! 'gem install bundler --conservative' system('bundle check') || system!('bundle install') - # Install JavaScript dependencies if using Yarn - # system('bin/yarn') + # Install JavaScript dependencies + system! 'bin/yarn' # puts "\n== Copying sample files ==" # unless File.exist?('config/database.yml') - # cp 'config/database.yml.sample', 'config/database.yml' + # FileUtils.cp 'config/database.yml.sample', 'config/database.yml' # end puts "\n== Preparing database ==" - system! 'bin/rails db:setup' + system! 'bin/rails db:prepare' puts "\n== Removing old logs and tempfiles ==" system! 'bin/rails log:clear tmp:clear' diff --git a/bin/spring b/bin/spring index fb2ec2ebb4..b4147e8437 100755 --- a/bin/spring +++ b/bin/spring @@ -1,17 +1,14 @@ #!/usr/bin/env ruby +if !defined?(Spring) && [nil, "development", "test"].include?(ENV["RAILS_ENV"]) + gem "bundler" + require "bundler" -# This file loads spring without using Bundler, in order to be fast. -# It gets overwritten when you run the `spring binstub` command. - -unless defined?(Spring) - require 'rubygems' - require 'bundler' - - lockfile = Bundler::LockfileParser.new(Bundler.default_lockfile.read) - spring = lockfile.specs.detect { |spec| spec.name == "spring" } - if spring + # Load Spring without loading other gems in the Gemfile, for speed. + Bundler.locked_gems&.specs&.find { |spec| spec.name == "spring" }&.tap do |spring| Gem.use_paths Gem.dir, Bundler.bundle_path.to_s, *Gem.path - gem 'spring', spring.version - require 'spring/binstub' + gem "spring", spring.version + require "spring/binstub" + rescue Gem::LoadError + # Ignore when Spring is not installed. end end diff --git a/bin/yarn b/bin/yarn index 460dd565b4..9fab2c3507 100755 --- a/bin/yarn +++ b/bin/yarn @@ -1,9 +1,15 @@ #!/usr/bin/env ruby APP_ROOT = File.expand_path('..', __dir__) Dir.chdir(APP_ROOT) do - begin - exec "yarnpkg", *ARGV - rescue Errno::ENOENT + yarn = ENV["PATH"].split(File::PATH_SEPARATOR). + select { |dir| File.expand_path(dir) != __dir__ }. + product(["yarn", "yarn.cmd", "yarn.ps1"]). + map { |dir, file| File.expand_path(file, dir) }. + find { |file| File.executable?(file) } + + if yarn + exec yarn, *ARGV + else $stderr.puts "Yarn executable was not detected in the system." $stderr.puts "Download Yarn at https://yarnpkg.com/en/docs/install" exit 1 diff --git a/config.ru b/config.ru index 441e6ff0c3..4a3c09a688 100644 --- a/config.ru +++ b/config.ru @@ -3,3 +3,4 @@ require_relative "config/environment" run Rails.application +Rails.application.load_server diff --git a/config/application.rb b/config/application.rb index 11095e05c9..79083f5edb 100644 --- a/config/application.rb +++ b/config/application.rb @@ -30,10 +30,12 @@ class Application < Rails::Application # Initialize configuration defaults for originally generated Rails version. config.load_defaults 6.0 - # Settings in config/environments/* take precedence over those specified here. - # Application configuration can go into files in config/initializers - # -- all .rb files in that directory are automatically loaded after loading - # the framework and any gems in your application. + # Configuration for the application, engines, and railties goes here. + # + # These settings can be overridden in specific environments using the files + # in config/environments, which are processed later. + # + # config.eager_load_paths << Rails.root.join("extras") # Don't generate system test files. config.generators.system_tests = nil diff --git a/config/environments/development.rb b/config/environments/development.rb index 7c6d64c545..23f489b979 100644 --- a/config/environments/development.rb +++ b/config/environments/development.rb @@ -1,8 +1,10 @@ +require "active_support/core_ext/integer/time" + Rails.application.configure do # Settings specified here will take precedence over those in config/application.rb. - # In the development environment your application's code is reloaded on - # every request. This slows down response time but is perfect for development + # In the development environment your application's code is reloaded any time + # it changes. This slows down response time but is perfect for development # since you don't have to restart the web server when you make code changes. config.cache_classes = false @@ -16,6 +18,7 @@ # Run rails dev:cache to toggle caching. if Rails.root.join("tmp", "caching-dev.txt").exist? config.action_controller.perform_caching = true + config.action_controller.enable_fragment_cache_logging = true config.cache_store = :memory_store config.public_file_server.headers = { @@ -42,6 +45,12 @@ # Print deprecation notices to the Rails logger. config.active_support.deprecation = :log + # Raise exceptions for disallowed deprecations. + config.active_support.disallowed_deprecation = :raise + + # Tell Active Support which deprecation messages to disallow. + config.active_support.disallowed_deprecation_warnings = [] + # Raise an error on page load if there are pending migrations. config.active_record.migration_error = :page_load @@ -59,13 +68,19 @@ # Suppress logger output for asset requests. config.assets.quiet = true - # Raises error for missing translations - # config.action_view.raise_on_missing_translations = true + # Raises error for missing translations. + # config.i18n.raise_on_missing_translations = true + + # Annotate rendered view with file names. + # config.action_view.annotate_rendered_view_with_filenames = true # Use an evented file watcher to asynchronously detect changes in source code, # routes, locales, etc. This feature depends on the listen gem. config.file_watcher = ActiveSupport::EventedFileUpdateChecker + # Uncomment if you wish to allow Action Cable access from any origin. + # config.action_cable.disable_request_forgery_protection = true + # Add '127.0.0.1 ecp.test' to your /etc/hosts to use this over localhost. # This allows you to use https://ecp.test:3000/ in your browser. config.hosts << "ecp.test" diff --git a/config/environments/production.rb b/config/environments/production.rb index e8384c3aa3..50b1739104 100644 --- a/config/environments/production.rb +++ b/config/environments/production.rb @@ -1,3 +1,5 @@ +require "active_support/core_ext/integer/time" + Rails.application.configure do # Settings specified here will take precedence over those in config/application.rb. @@ -22,17 +24,16 @@ # Apache or NGINX already handles this. config.public_file_server.enabled = ENV["RAILS_SERVE_STATIC_FILES"].present? - # Compress JavaScripts and CSS. + # Compress CSS using a preprocessor. + # config.assets.css_compressor = :sass + config.assets.js_compressor = :uglifier # Do not fallback to assets pipeline if a precompiled asset is missed. config.assets.compile = false - # `config.assets.precompile` and `config.assets.version` have moved - # to config/initializers/assets.rb - # Enable serving of images, stylesheets, and JavaScripts from an asset server. - # config.action_controller.asset_host = 'http://assets.example.com' + # config.asset_host = 'http://assets.example.com' # Specifies the header that your server uses for sending files. # config.action_dispatch.x_sendfile_header = 'X-Sendfile' # for Apache @@ -41,16 +42,19 @@ # Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies. config.force_ssl = true - # Use the lowest log level to ensure availability of diagnostic information - # when problems arise. + # Include generic and useful information about system operation, but avoid logging too much + # information to avoid inadvertent exposure of personally identifiable information (PII). config.log_level = :info + # Prepend all log lines with the following tags. + config.log_tags = [:request_id] + # Use a different cache store in production. # config.cache_store = :mem_cache_store - # Use a real queuing backend for Active Job (and separate queues per environment) + # Use a real queuing backend for Active Job (and separate queues per environment). # config.active_job.queue_adapter = :resque - # config.active_job.queue_name_prefix = "dfe-teachers-payment-service_#{Rails.env}" + # config.active_job.queue_name_prefix = "dfe_teachers_payment_service_production" config.action_mailer.perform_caching = false @@ -71,11 +75,17 @@ # Send deprecation notices to registered listeners. config.active_support.deprecation = :notify + # Log disallowed deprecations. + config.active_support.disallowed_deprecation = :log + + # Tell Active Support which deprecation messages to disallow. + config.active_support.disallowed_deprecation_warnings = [] + # Use default logging formatter so that PID and timestamp are not suppressed. config.log_formatter = ::Logger::Formatter.new # Use a different logger for distributed setups. - # require 'syslog/logger' + # require "syslog/logger" # config.logger = ActiveSupport::TaggedLogging.new(Syslog::Logger.new 'app-name') if ENV["RAILS_LOG_TO_STDOUT"].present? @@ -86,4 +96,25 @@ # Do not dump schema after migrations. config.active_record.dump_schema_after_migration = false + + # Inserts middleware to perform automatic connection switching. + # The `database_selector` hash is used to pass options to the DatabaseSelector + # middleware. The `delay` is used to determine how long to wait after a write + # to send a subsequent read to the primary. + # + # The `database_resolver` class is used by the middleware to determine which + # database is appropriate to use based on the time delay. + # + # The `database_resolver_context` class is used by the middleware to set + # timestamps for the last write to the primary. The resolver uses the context + # class timestamps to determine how long to wait before reading from the + # replica. + # + # By default Rails will store a last write timestamp in the session. The + # DatabaseSelector middleware is designed as such you can define your own + # strategy for connection switching and pass that into the middleware through + # these configuration options. + # config.active_record.database_selector = { delay: 2.seconds } + # config.active_record.database_resolver = ActiveRecord::Middleware::DatabaseSelector::Resolver + # config.active_record.database_resolver_context = ActiveRecord::Middleware::DatabaseSelector::Resolver::Session end diff --git a/config/environments/test.rb b/config/environments/test.rb index 9af0167fdb..986ec71f95 100644 --- a/config/environments/test.rb +++ b/config/environments/test.rb @@ -1,11 +1,15 @@ +require "active_support/core_ext/integer/time" + +# The test environment is used exclusively to run your application's +# test suite. You never need to work with it otherwise. Remember that +# your test database is "scratch space" for the test suite and is wiped +# and recreated between test runs. Don't rely on the data there! + Rails.application.configure do # Settings specified here will take precedence over those in config/application.rb. - # The test environment is used exclusively to run your application's - # test suite. You never need to work with it otherwise. Remember that - # your test database is "scratch space" for the test suite and is wiped - # and recreated between test runs. Don't rely on the data there! config.cache_classes = true + config.action_view.cache_template_loading = true # Do not eager load code on boot. This avoids loading your whole application # just for the purpose of running a single test. If you are using a tool that @@ -21,6 +25,7 @@ # Show full error reports and disable caching. config.consider_all_requests_local = true config.action_controller.perform_caching = false + config.cache_store = :null_store # Raise exceptions instead of rendering exception templates. config.action_dispatch.show_exceptions = false @@ -44,11 +49,20 @@ # Print deprecation notices to the stderr. config.active_support.deprecation = :stderr - # Raises error for missing translations - config.action_view.raise_on_missing_translations = true + # Raise exceptions for disallowed deprecations. + config.active_support.disallowed_deprecation = :raise + + # Tell Active Support which deprecation messages to disallow. + config.active_support.disallowed_deprecation_warnings = [] + + # Raises error for missing translations. + config.i18n.raise_on_missing_translations = true config.active_job.queue_adapter = :test + # Annotate rendered view with file names. + # config.action_view.annotate_rendered_view_with_filenames = true + config.after_initialize do Bullet.enable = true Bullet.bullet_logger = true diff --git a/config/initializers/backtrace_silencers.rb b/config/initializers/backtrace_silencers.rb index 78c4f58afc..33699c3091 100644 --- a/config/initializers/backtrace_silencers.rb +++ b/config/initializers/backtrace_silencers.rb @@ -1,9 +1,8 @@ # Be sure to restart your server when you modify this file. -# You can add backtrace silencers for libraries that you're using but don't wish to see in your -# backtraces. -# Rails.backtrace_cleaner.add_silencer { |line| line =~ /my_noisy_library/ } +# You can add backtrace silencers for libraries that you're using but don't wish to see in your backtraces. +# Rails.backtrace_cleaner.add_silencer { |line| /my_noisy_library/.match?(line) } -# You can also remove all the silencers if you're trying to debug a problem that might stem from -# framework code. -# Rails.backtrace_cleaner.remove_silencers! +# You can also remove all the silencers if you're trying to debug a problem that might stem from framework code +# by setting BACKTRACE=1 before calling your invocation, like "BACKTRACE=1 ./bin/rails runner 'MyClass.perform'". +Rails.backtrace_cleaner.remove_silencers! if ENV["BACKTRACE"] diff --git a/config/initializers/content_security_policy.rb b/config/initializers/content_security_policy.rb index 78bb5cd44a..9586d0278b 100644 --- a/config/initializers/content_security_policy.rb +++ b/config/initializers/content_security_policy.rb @@ -18,8 +18,10 @@ end # If you are using UJS then enable automatic nonce generation -# Rails.application.config.content_security_policy_nonce_generator = -# -> request { SecureRandom.base64(16) } +# Rails.application.config.content_security_policy_nonce_generator = -> request { SecureRandom.base64(16) } + +# Set the nonce only to specific directives +# Rails.application.config.content_security_policy_nonce_directives = %w(script-src) # Report CSP violations to a specified URI # For further information see the following documentation: diff --git a/config/initializers/new_framework_defaults_6_1.rb b/config/initializers/new_framework_defaults_6_1.rb new file mode 100644 index 0000000000..97c9e62b76 --- /dev/null +++ b/config/initializers/new_framework_defaults_6_1.rb @@ -0,0 +1,67 @@ +# Be sure to restart your server when you modify this file. +# +# This file contains migration options to ease your Rails 6.1 upgrade. +# +# Once upgraded flip defaults one by one to migrate to the new default. +# +# Read the Guide for Upgrading Ruby on Rails for more info on each option. + +# Support for inversing belongs_to -> has_many Active Record associations. +Rails.application.config.active_record.has_many_inversing = true + +# Track Active Storage variants in the database. +# Rails.application.config.active_storage.track_variants = true + +# Apply random variation to the delay when retrying failed jobs. +Rails.application.config.active_job.retry_jitter = 0.15 + +# Stop executing `after_enqueue`/`after_perform` callbacks if +# `before_enqueue`/`before_perform` respectively halts with `throw :abort`. +Rails.application.config.active_job.skip_after_callbacks_if_terminated = true + +# Specify cookies SameSite protection level: either :none, :lax, or :strict. +# +# This change is not backwards compatible with earlier Rails versions. +# It's best enabled when your entire app is migrated and stable on 6.1. +# Rails.application.config.action_dispatch.cookies_same_site_protection = :lax + +# Generate CSRF tokens that are encoded in URL-safe Base64. +# +# This change is not backwards compatible with earlier Rails versions. +# It's best enabled when your entire app is migrated and stable on 6.1. +# Rails.application.config.action_controller.urlsafe_csrf_tokens = true + +# Specify whether `ActiveSupport::TimeZone.utc_to_local` returns a time with an +# UTC offset or a UTC time. +ActiveSupport.utc_to_local_returns_utc_offset_times = true + +# Change the default HTTP status code to `308` when redirecting non-GET/HEAD +# requests to HTTPS in `ActionDispatch::SSL` middleware. +Rails.application.config.action_dispatch.ssl_default_redirect_status = 308 + +# Use new connection handling API. For most applications this won't have any +# effect. For applications using multiple databases, this new API provides +# support for granular connection swapping. +Rails.application.config.active_record.legacy_connection_handling = false + +# Make `form_with` generate non-remote forms by default. +Rails.application.config.action_view.form_with_generates_remote_forms = false + +# Set the default queue name for the analysis job to the queue adapter default. +# Rails.application.config.active_storage.queues.analysis = nil + +# Set the default queue name for the purge job to the queue adapter default. +# Rails.application.config.active_storage.queues.purge = nil + +# Set the default queue name for the incineration job to the queue adapter default. +# Rails.application.config.action_mailbox.queues.incineration = nil + +# Set the default queue name for the routing job to the queue adapter default. +# Rails.application.config.action_mailbox.queues.routing = nil + +# Set the default queue name for the mail deliver job to the queue adapter default. +# Rails.application.config.action_mailer.deliver_later_queue_name = nil + +# Generate a `Link` header that gives a hint to modern browsers about +# preloading assets when using `javascript_include_tag` and `stylesheet_link_tag`. +Rails.application.config.action_view.preload_links_header = true diff --git a/config/initializers/permissions_policy.rb b/config/initializers/permissions_policy.rb new file mode 100644 index 0000000000..00f64d71b0 --- /dev/null +++ b/config/initializers/permissions_policy.rb @@ -0,0 +1,11 @@ +# Define an application-wide HTTP permissions policy. For further +# information see https://developers.google.com/web/updates/2018/06/feature-policy +# +# Rails.application.config.permissions_policy do |f| +# f.camera :none +# f.gyroscope :none +# f.microphone :none +# f.usb :none +# f.fullscreen :self +# f.payment :self, "https://secure.example.com" +# end diff --git a/config/locales/en.yml b/config/locales/en.yml index f3157241b7..0227091416 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -27,7 +27,7 @@ # 'true': 'foo' # # To learn more, please read the Rails Internationalization guide -# available at http://guides.rubyonrails.org/i18n.html. +# available at https://guides.rubyonrails.org/i18n.html. en: date: diff --git a/config/puma.rb b/config/puma.rb index fbb0501404..3e5b9042c0 100644 --- a/config/puma.rb +++ b/config/puma.rb @@ -4,8 +4,14 @@ # the maximum value specified for Puma. Default is set to 5 threads for minimum # and maximum; this matches the default thread size of Active Record. # -threads_count = ENV.fetch("RAILS_MAX_THREADS", 5) -threads threads_count, threads_count +max_threads_count = ENV.fetch("RAILS_MAX_THREADS", 5) +min_threads_count = ENV.fetch("RAILS_MIN_THREADS") { max_threads_count } +threads min_threads_count, max_threads_count + +# Specifies the `worker_timeout` threshold that Puma will use to wait before +# terminating a worker in development environments. +# +worker_timeout 3600 if ENV.fetch("RAILS_ENV", "development") == "development" # Specifies the `port` that Puma will listen on to receive requests; default is 3000. # @@ -13,10 +19,13 @@ # Specifies the `environment` that Puma will run in. # -environment ENV.fetch("RAILS_ENV", "development") +environment ENV.fetch("RAILS_ENV") { "development" } + +# Specifies the `pidfile` that Puma will use. +pidfile ENV.fetch("PIDFILE") { "tmp/pids/server.pid" } # Specifies the number of `workers` to boot in clustered mode. -# Workers are forked webserver processes. If using threads and workers together +# Workers are forked web server processes. If using threads and workers together # the concurrency of the application would be max `threads` * `workers`. # Workers do not work on JRuby or Windows (both of which do not support # processes). diff --git a/spec/features/combined_teacher_claim_journey_spec.rb b/spec/features/combined_teacher_claim_journey_spec.rb index d1528e37df..e8cfe8eb3e 100644 --- a/spec/features/combined_teacher_claim_journey_spec.rb +++ b/spec/features/combined_teacher_claim_journey_spec.rb @@ -132,7 +132,7 @@ expect(page).to have_text("Enter a valid passcode") # - clear and enter correct OTP - fill_in "claim_one_time_password", with: otp_in_mail_sent, fill_options: {clear: :backspace} + fill_in "claim_one_time_password", with: otp_in_mail_sent click_on "Confirm" # - Provide mobile number diff --git a/spec/features/early_career_payments_claim_spec.rb b/spec/features/early_career_payments_claim_spec.rb index ae5fbde865..a2595d6fe3 100644 --- a/spec/features/early_career_payments_claim_spec.rb +++ b/spec/features/early_career_payments_claim_spec.rb @@ -191,7 +191,7 @@ expect(page).to have_text("Enter a valid passcode") # - clear and enter correct OTP - fill_in "claim_one_time_password", with: otp_in_mail_sent, fill_options: {clear: :backspace} + fill_in "claim_one_time_password", with: otp_in_mail_sent click_on "Confirm" # - Provide mobile number diff --git a/spec/features/levelling_up_premium_payments_spec.rb b/spec/features/levelling_up_premium_payments_spec.rb index 66179fdfe1..a75e675a61 100644 --- a/spec/features/levelling_up_premium_payments_spec.rb +++ b/spec/features/levelling_up_premium_payments_spec.rb @@ -154,7 +154,7 @@ def claim_up_to_itt_subject expect(page).to have_text("Enter a valid passcode") # - clear and enter correct OTP - fill_in "claim_one_time_password", with: otp_in_mail_sent, fill_options: {clear: :backspace} + fill_in "claim_one_time_password", with: otp_in_mail_sent click_on "Confirm" # - Provide mobile number diff --git a/spec/models/amendment_spec.rb b/spec/models/amendment_spec.rb index 40d767d1ea..87fe04f037 100644 --- a/spec/models/amendment_spec.rb +++ b/spec/models/amendment_spec.rb @@ -89,7 +89,7 @@ expect(claim.teacher_reference_number).to eq("1234567") expect(claim.bank_account_number).to eq("12345678") - expect(amendment.errors.keys).to eq([:notes]) + expect(amendment.errors.attribute_names).to eq([:notes]) end end @@ -120,7 +120,7 @@ expect(claim.teacher_reference_number).to eq("1234567") expect(claim.bank_account_number).to eq("12345678") - expect(amendment.errors.keys).to match_array([:teacher_reference_number]) + expect(amendment.errors.attribute_names).to match_array([:teacher_reference_number]) end end @@ -150,7 +150,7 @@ expect(claim.teacher_reference_number).to eq("1234567") expect(claim.bank_account_number).to eq("12345678") - expect(amendment.errors.keys).to match_array([:notes, :teacher_reference_number]) + expect(amendment.errors.attribute_names).to match_array([:notes, :teacher_reference_number]) end end @@ -173,7 +173,7 @@ expect(amendment).to_not be_persisted expect(claim.reload.amendments).to be_empty - expect(amendment.errors.keys).to eq([:claim_changes]) + expect(amendment.errors.attribute_names).to eq([:claim_changes]) end end diff --git a/spec/models/claim_spec.rb b/spec/models/claim_spec.rb index bdd6d8a932..f419729fe4 100644 --- a/spec/models/claim_spec.rb +++ b/spec/models/claim_spec.rb @@ -164,7 +164,7 @@ # Tests a single attribute, possibly should test multiple attributes it "validates eligibility" do expect(claim).not_to be_valid(:"qts-year") - expect(claim.errors.values).to include(["Select when you completed your initial teacher training"]) + expect(claim.errors.first.message).to eq("Select when you completed your initial teacher training") end end @@ -174,7 +174,7 @@ # Tests a single attribute, possibly should test multiple attributes it "validates eligibility" do expect(claim).not_to be_valid(:"nqt-in-academic-year-after-itt") - expect(claim.errors.values).to include(["Select yes if you are currently teaching as a qualified teacher"]) + expect(claim.errors.first.message).to eq("Select yes if you are currently teaching as a qualified teacher") end end