diff --git a/.rubocop.yml b/.rubocop.yml index 2a7de6ec9..4be43860a 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -87,8 +87,7 @@ Metrics/ClassLength: - 'db/migrate/*' # Weird failures on this, disabled for now. Layout/LineLength: - Enabled: false - # Max: 79 + Max: 132 # Exclude: # - 'db/migrate/*' Metrics/MethodLength: @@ -233,3 +232,29 @@ Rails/WhereNot: Enabled: false Rails/NegateInclude: Enabled: false +Layout/RedundantLineBreak: + Enabled: false +Naming/VariableNumber: + Enabled: false +Layout/LineContinuationLeadingSpace: + Enabled: false +Style/TopLevelMethodDefinition: + Enabled: false +Naming/InclusiveLanguage: + Enabled: false +Bundler/GemVersion: + Enabled: false +Lint/EmptyBlock: + Enabled: false +Lint/OrAssignmentToConstant: + Enabled: false +Rails/EnvironmentVariableAccess: + Enabled: false +Rails/DuplicateScope: + Enabled: false +Rails/I18nLocaleTexts: + Enabled: false +Rails/RedundantPresenceValidationOnBelongsTo: + Enabled: false +Style/RequireOrder: + Enabled: false diff --git a/Gemfile b/Gemfile index e6bb86546..37dd73cb9 100644 --- a/Gemfile +++ b/Gemfile @@ -110,9 +110,9 @@ group :development, :test do gem 'pronto-rails_best_practices', '0.11.0' gem 'pronto-rubocop', '0.11.3' # gem 'railroader', '4.3.8' # Security static analyzer. OSS fork of Brakeman - gem 'rubocop', '1.0.0', require: false # Style checker - gem 'rubocop-performance', '1.10.2', require: false # Performance cops - gem 'rubocop-rails', '2.8.0', require: false # Rails-specific cops + gem 'rubocop', '1.41.1', require: false # Style checker + gem 'rubocop-performance', '1.15.1', require: false # Performance cops + gem 'rubocop-rails', '2.17.3', require: false # Rails-specific cops gem 'ruby-graphviz', '1.2.5' # This is used for bundle viz gem 'spring', '4.0.0' # Preloads app so console, rake, and tests run faster # Do NOT upgrade to vcr 6.*, as that is not OSS: diff --git a/Gemfile.lock b/Gemfile.lock index 99955923d..c58ace564 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -363,24 +363,25 @@ GEM rack (>= 1.4) require_all (3.0.0) rexml (3.2.5) - rubocop (1.0.0) + rubocop (1.41.1) + json (~> 2.3) parallel (~> 1.10) - parser (>= 2.7.1.5) + parser (>= 3.1.2.1) rainbow (>= 2.2.2, < 4.0) - regexp_parser (>= 1.8) - rexml - rubocop-ast (>= 0.6.0) + regexp_parser (>= 1.8, < 3.0) + rexml (>= 3.2.5, < 4.0) + rubocop-ast (>= 1.23.0, < 2.0) ruby-progressbar (~> 1.7) - unicode-display_width (>= 1.4.0, < 2.0) - rubocop-ast (1.23.0) + unicode-display_width (>= 1.4.0, < 3.0) + rubocop-ast (1.24.1) parser (>= 3.1.1.0) - rubocop-performance (1.10.2) - rubocop (>= 0.90.0, < 2.0) + rubocop-performance (1.15.1) + rubocop (>= 1.7.0, < 2.0) rubocop-ast (>= 0.4.0) - rubocop-rails (2.8.0) + rubocop-rails (2.17.3) activesupport (>= 4.2.0) rack (>= 1.1) - rubocop (>= 0.87.0) + rubocop (>= 1.33.0, < 2.0) ruby-graphviz (1.2.5) rexml ruby-progressbar (1.11.0) @@ -532,9 +533,9 @@ DEPENDENCIES rails_12factor (= 0.0.3) railties (= 6.1.7) redcarpet (= 3.5.1) - rubocop (= 1.0.0) - rubocop-performance (= 1.10.2) - rubocop-rails (= 2.8.0) + rubocop (= 1.41.1) + rubocop-performance (= 1.15.1) + rubocop-rails (= 2.17.3) ruby-graphviz (= 1.2.5) sass-rails (= 5.1.0) scout_apm (= 4.1.2) diff --git a/app/controllers/password_resets_controller.rb b/app/controllers/password_resets_controller.rb index 58415004d..fcab10e96 100644 --- a/app/controllers/password_resets_controller.rb +++ b/app/controllers/password_resets_controller.rb @@ -12,6 +12,8 @@ class PasswordResetsController < ApplicationController def new; end + def edit; end + # NOTE: password resets *always* reply with the same message, in all cases. # At one time we replied with error reports if there was no account or if # there was a GitHub account (not a local account) with the email address. @@ -40,8 +42,6 @@ def create redirect_to root_url end - def edit; end - def update new_password = nested_params(:user, :password) if new_password.nil? || new_password == '' diff --git a/app/controllers/project_stats_controller.rb b/app/controllers/project_stats_controller.rb index c289a8e40..27cafea0b 100644 --- a/app/controllers/project_stats_controller.rb +++ b/app/controllers/project_stats_controller.rb @@ -288,7 +288,7 @@ def daily_activity data: series_dataset } # Calculate moving average over ndays - series_counts = stat_data.map { |e| e[desired_field] } + series_counts = stat_data.pluck(desired_field) series_moving_average = series_counts.each_cons(ndays).map do |e| e.sum.to_f / ndays diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb index 9fd3e8d21..1b8022528 100644 --- a/app/controllers/projects_controller.rb +++ b/app/controllers/projects_controller.rb @@ -215,7 +215,7 @@ def new def edit return unless @project.notify_for_static_analysis?('0') - message = t('projects.edit.static_analysis_updated_html') + message = t('.static_analysis_updated_html') flash.now[:danger] = message end @@ -327,7 +327,7 @@ def destroy @project.homepage_url ||= project_find_default_url format.html do redirect_to projects_path - flash[:success] = t('projects.delete.done') + flash.now[:success] = t('projects.delete.done') end format.json { head :no_content } end @@ -678,9 +678,9 @@ def retrieve_projects # This will NOT match full URLs, but will match partial URLs. @projects = @projects.search_for(params[:q]) if params[:q].present? if params[:ids].present? - @projects = @projects.where( - 'id in (?)', params[:ids].split(',').map { |x| Integer(x) } - ) + @projects = @projects.where(id: params[:ids].split(',').map do |x| + Integer(x) + end) end @projects end diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index 71f4f4121..24a6ab348 100644 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -16,10 +16,6 @@ class UsersController < ApplicationController before_action :enable_maximum_privacy_headers include SessionsHelper - def new - @user = User.new - end - def index @pagy, @users = pagy(User.all) @pagy_locale = I18n.locale.to_s # Pagy requires a string version @@ -38,7 +34,7 @@ def show # we practically never have that many and the interface would be confusing. @projects_additional_rights = select_needed(Project.includes(:user).joins(:additional_rights) - .where('additional_rights.user_id = ?', @user.id)) + .where(additional_rights: { user_id: @user.id })) # *Separately* list edit_projects from projects_additional_rights. # Jason Dossett thinks they should be combined, but David A. Wheeler # thinks these are important to keep separate because how to *change* @@ -50,8 +46,21 @@ def show Project.includes(:user).where(repo_url: github_user_projects) ) - @projects end + + def new + @user = User.new + end + # rubocop: enable Metrics/MethodLength, Metrics/AbcSize + def edit + @user = User.find(params[:id]) + # Force redirect if current_user cannot edit. Otherwise, the process + # of displaying the edit fields (with their defaults) could cause an + # unauthorized exposure of an email address. + redirect_to @user unless current_user_can_edit(@user) + end + # rubocop: disable Metrics/MethodLength, Metrics/AbcSize def create if Rails.application.config.deny_login @@ -79,15 +88,6 @@ def create flash[:info] = t('users.new_activation_link_created') redirect_to root_path, status: :found end - # rubocop: enable Metrics/MethodLength, Metrics/AbcSize - - def edit - @user = User.find(params[:id]) - # Force redirect if current_user cannot edit. Otherwise, the process - # of displaying the edit fields (with their defaults) could cause an - # unauthorized exposure of an email address. - redirect_to @user unless current_user_can_edit(@user) - end # Produce a cleaned-up hash of changes. # The key is the field that was changed, the value is [old, new] diff --git a/app/helpers/sessions_helper.rb b/app/helpers/sessions_helper.rb index aea914f13..e18cd21ae 100644 --- a/app/helpers/sessions_helper.rb +++ b/app/helpers/sessions_helper.rb @@ -142,7 +142,7 @@ def current_user_is_github_owner?(url) def github_user_projects github = Octokit::Client.new access_token: session[:user_token] github.auto_paginate = true - github.repos.map(&:html_url).reject(&:blank?) + github.repos.map(&:html_url).compact_blank end # Logs out the current user. @@ -190,7 +190,7 @@ def can_current_user_edit_on_github?(url) # Returns true iff this is not the REAL final production system, # including the master/main and staging systems. # It only returns false if we are "truly in production" - def in_development?(hostname = ENV['PUBLIC_HOSTNAME']) + def in_development?(hostname = ENV.fetch('PUBLIC_HOSTNAME', nil)) return true if hostname.nil? hostname != PRODUCTION_HOSTNAME diff --git a/app/lib/chief.rb b/app/lib/chief.rb index ecea5f0f5..d30bee49e 100644 --- a/app/lib/chief.rb +++ b/app/lib/chief.rb @@ -69,9 +69,7 @@ def merge_changeset(c1, c2) def update_value?(project, key, changeset_data) if changeset_data.blank? false - elsif !project.attribute_present?(key) || project[key].blank? - true - elsif project[key] == '?' + elsif !project.attribute_present?(key) || project[key].blank? || project[key] == '?' true else changeset_data[:confidence].present? && diff --git a/app/lib/hardened_sites_detective.rb b/app/lib/hardened_sites_detective.rb index f6b7ce0d2..d12e7d7f9 100644 --- a/app/lib/hardened_sites_detective.rb +++ b/app/lib/hardened_sites_detective.rb @@ -29,7 +29,7 @@ class HardenedSitesDetective < Detective UNMET_MISSING = { value: 'Unmet', confidence: 5, - explanation: '// One or more of the required security hardening headers '\ + explanation: '// One or more of the required security hardening headers ' \ 'is missing.' }.freeze UNMET_NOSNIFF = diff --git a/app/mailers/report_mailer.rb b/app/mailers/report_mailer.rb index 70fbd4964..bb4605ec3 100644 --- a/app/mailers/report_mailer.rb +++ b/app/mailers/report_mailer.rb @@ -131,10 +131,12 @@ def report_reminder_summary(projects) # We currently only send these out in English, so it's not internationalized # (no point in asking the translators to do unnecessary work). def report_monthly_announcement( - projects, month_display, - last_stat_in_prev_month, last_stat_in_prev_prev_month + projects, + month_display, + last_stat_in_prev_month, + last_stat_in_prev_prev_month ) - @report_destination = ENV['REPORT_MONTHLY_EMAIL'] + @report_destination = ENV.fetch('REPORT_MONTHLY_EMAIL', nil) return if @report_destination.blank? @projects = projects diff --git a/app/models/badge.rb b/app/models/badge.rb index 58222a1a4..850beacdf 100644 --- a/app/models/badge.rb +++ b/app/models/badge.rb @@ -21,6 +21,7 @@ class Badge # We very rarely change the static images in a way that affects widths, # so it's simpler to just copy the information into the source code here. # As a style recommendation remove the comma from the last entry. + # rubocop:disable Lint/SymbolConversion BADGE_WIDTHS = { 'passing': 184, 'silver': 172, @@ -126,6 +127,7 @@ class Badge '98': 234, '99': 234 }.freeze + # rubocop:enable Lint/SymbolConversion attr_accessor :svg diff --git a/app/models/translations.rb b/app/models/translations.rb index 759ef1c01..8ebf8ead7 100644 --- a/app/models/translations.rb +++ b/app/models/translations.rb @@ -4,12 +4,14 @@ # OpenSSF Best Practices badge contributors # SPDX-License-Identifier: MIT -class Translations +module Translations + module_function + # This class is a used to gather sets of translations which will commonly # be called in bulk. For example, there are translations we would like # to export to JavaScript. We can use a method here to do that quickly. - def self.for_js + def for_js js_translations = I18n.available_locales.map do |locale| locale_t = diff --git a/config.ru b/config.ru index 61c04e13f..9db84a817 100644 --- a/config.ru +++ b/config.ru @@ -2,5 +2,5 @@ # This file is used by Rack-based servers to start the application. -require ::File.expand_path('../config/environment', __FILE__) +require File.expand_path('../config/environment', __FILE__) run Rails.application diff --git a/config/environments/production.rb b/config/environments/production.rb index 693dcdfd7..fc36decde 100644 --- a/config/environments/production.rb +++ b/config/environments/production.rb @@ -108,8 +108,8 @@ address: 'smtp.sendgrid.net', port: '587', authentication: :plain, - user_name: ENV['SENDGRID_USERNAME'], - password: ENV['SENDGRID_PASSWORD'], + user_name: ENV.fetch('SENDGRID_USERNAME', nil), + password: ENV.fetch('SENDGRID_PASSWORD', nil), domain: 'heroku.com', enable_starttls_auto: true } @@ -123,7 +123,7 @@ config.active_support.deprecation = :notify # Use default logging formatter so that PID and timestamp are not suppressed. - config.log_formatter = ::Logger::Formatter.new + config.log_formatter = Logger::Formatter.new # Do not dump schema after migrations. config.active_record.dump_schema_after_migration = false diff --git a/config/initializers/octokit.rb b/config/initializers/octokit.rb index 6e516090f..2900c7301 100644 --- a/config/initializers/octokit.rb +++ b/config/initializers/octokit.rb @@ -7,10 +7,10 @@ Octokit.configure do |c| if Rails.env.test? # Test app OAuth returns to a different port - ENV['GITHUB_KEY'] = ENV['TEST_GITHUB_KEY'] - ENV['GITHUB_SECRET'] = ENV['TEST_GITHUB_SECRET'] + ENV['GITHUB_KEY'] = ENV.fetch('TEST_GITHUB_KEY', nil) + ENV['GITHUB_SECRET'] = ENV.fetch('TEST_GITHUB_SECRET', nil) end - c.client_id = ENV['GITHUB_KEY'] - c.client_secret = ENV['GITHUB_SECRET'] + c.client_id = ENV.fetch('GITHUB_KEY', nil) + c.client_secret = ENV.fetch('GITHUB_SECRET', nil) c.auto_paginate = true end diff --git a/config/initializers/omniauth.rb b/config/initializers/omniauth.rb index ae11df7c7..fe8e89ad6 100644 --- a/config/initializers/omniauth.rb +++ b/config/initializers/omniauth.rb @@ -7,10 +7,10 @@ Rails.application.config.middleware.use OmniAuth::Builder do if Rails.env.test? # Test app OAuth returns to a different port - ENV['GITHUB_KEY'] = ENV['TEST_GITHUB_KEY'] - ENV['GITHUB_SECRET'] = ENV['TEST_GITHUB_SECRET'] + ENV['GITHUB_KEY'] = ENV.fetch('TEST_GITHUB_KEY', nil) + ENV['GITHUB_SECRET'] = ENV.fetch('TEST_GITHUB_SECRET', nil) end - provider :github, ENV['GITHUB_KEY'], ENV['GITHUB_SECRET'], + provider :github, ENV.fetch('GITHUB_KEY', nil), ENV.fetch('GITHUB_SECRET', nil), scope: 'user:email, read:org' Hashie.logger = Rails.logger end diff --git a/db/schema.rb b/db/schema.rb index 9d019c420..15544be64 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -34,8 +34,8 @@ create_table "pg_search_documents", id: :serial, force: :cascade do |t| t.text "content" - t.integer "searchable_id" t.string "searchable_type" + t.integer "searchable_id" t.datetime "created_at", null: false t.datetime "updated_at", null: false t.index ["searchable_type", "searchable_id"], name: "index_pg_search_documents_on_searchable_type_and_searchable_id" diff --git a/doc/send-translations.rb b/doc/send-translations.rb index a412ebeda..1633cc220 100755 --- a/doc/send-translations.rb +++ b/doc/send-translations.rb @@ -54,7 +54,7 @@ $SOURCE = {} # Get API key - warn very early if we can't get it! -$API_KEY = ENV['API_KEY'] +$API_KEY = ENV.fetch('API_KEY', nil) if $API_KEY.nil? || $API_KEY == '' STDERR.puts 'Error: Need API_KEY environment variable' exit 1 @@ -189,8 +189,7 @@ def process_data(lang, key, data) elsif data.is_a?(String) if $CURRENT_TRANSLATIONS[lang].key?(key) # Potential change to an existing translation - this_current_translation = $CURRENT_TRANSLATIONS[lang][key]['target'] - .rstrip + this_current_translation = $CURRENT_TRANSLATIONS[lang][key]['target'].rstrip new_translation = data.rstrip if this_current_translation != new_translation # Translation has changed! diff --git a/gen_markdown.rb b/gen_markdown.rb index d3cd6ff3f..e488263cb 100755 --- a/gen_markdown.rb +++ b/gen_markdown.rb @@ -49,7 +49,7 @@ def puts_criterion(key, criterion) print ' (Justification required for "N/A".)' end print ' (URL required for "met".)' if criterion.key?('met_url_required') - print " [#{key}]" + print " [#{key}]" if CriteriaText[key].key?('details') || criterion.key?('rationale') print '
' # Put details and rationale in a detail list show_details(key) diff --git a/lib/tasks/default.rake b/lib/tasks/default.rake index aeab6b82b..722c26448 100644 --- a/lib/tasks/default.rake +++ b/lib/tasks/default.rake @@ -51,7 +51,7 @@ task(:ci).clear.enhance %w[ # Simple smoke test to avoid development environment misconfiguration desc 'Ensure that rbenv or rvm are set up in PATH' task :rbenv_rvm_setup do - path = ENV['PATH'] + path = ENV.fetch('PATH', nil) if !path.include?('.rbenv') && !path.include?('.rvm') raise RuntimeError 'Must have rbenv or rvm in PATH' end @@ -64,8 +64,7 @@ end desc 'Run rails_best_practices with options' task :rails_best_practices do - sh 'bundle exec rails_best_practices ' \ - '--features --spec --without-color --exclude railroader/' + sh 'bundle exec rails_best_practices --features --spec --without-color --exclude railroader/' end desc 'Setup railroader if needed' @@ -85,8 +84,7 @@ task railroader: %w[railroader/bin/railroader] do # sh 'bundle exec railroader --quiet --no-pager' # Workaround to run correct version of railroader & its dependencies. # We have to set BUNDLE_GEMFILE so bundle works inside the rake task - sh 'cd railroader; BUNDLE_GEMFILE=$(pwd)/Gemfile ' \ - 'bundle exec bin/railroader --quiet --no-pager $(dirname $(pwd))' + sh 'cd railroader; BUNDLE_GEMFILE=$(pwd)/Gemfile bundle exec bin/railroader --quiet --no-pager $(dirname $(pwd))' end desc 'Run bundle if needed' @@ -175,8 +173,8 @@ end desc 'Load current self.json' task :load_self_json do - require 'open-uri' require 'json' + require 'open-uri' url = 'https://master.bestpractices.coreinfrastructure.org/projects/1.json' contents = URI.parse(url).open.read pretty_contents = JSON.pretty_generate(JSON.parse(contents)) @@ -192,14 +190,15 @@ file 'license_okay' => ['Gemfile.lock', 'doc/dependency_decisions.yml'] do end desc 'Create license report' -file 'license_finder_report.html' => - ['Gemfile.lock', 'doc/dependency_decisions.yml'] do - sh 'bundle exec license_finder report --format html ' \ - '> license_finder_report.html' +file 'license_finder_report.html' => [ + 'Gemfile.lock', + 'doc/dependency_decisions.yml' +] do + sh 'bundle exec license_finder report --format html > license_finder_report.html' end # Don't do whitespace checks on these YAML files: -YAML_WS_EXCEPTIONS ||= ':!test/vcr_cassettes/*.yml' +YAML_WS_EXCEPTIONS = ':!test/vcr_cassettes/*.yml' desc 'Check for trailing whitespace in latest proposed (git) patch.' task :whitespace_check do @@ -215,7 +214,7 @@ task :yaml_syntax_check do # Don't check "project.yml" - it's not a straight YAML file, but instead # it's processed by ERB (even though the filename doesn't admit it). sh "find . -name '*.yml' ! -name 'projects.yml' ! -path './railroader/*' " \ - "! -path './vendor/*' -exec bundle exec yaml-lint {} + \;" + "! -path './vendor/*' -exec bundle exec yaml-lint {} + ;" end # The following are invoked as needed. @@ -227,14 +226,12 @@ end desc 'Deploy current origin/main to staging' task deploy_staging: :production_to_staging do - sh 'git checkout staging && git pull && ' \ - 'git merge --ff-only origin/main && git push && git checkout main' + sh 'git checkout staging && git pull && git merge --ff-only origin/main && git push && git checkout main' end desc 'Deploy current origin/staging to production' task :deploy_production do - sh 'git checkout production && git pull && ' \ - 'git merge --ff-only origin/staging && git push && git checkout main' + sh 'git checkout production && git pull && git merge --ff-only origin/staging && git push && git checkout main' end rule '.html' => '.md' do |t| @@ -293,8 +290,7 @@ namespace :fastly do desc 'Test Fastly Caching' task :test, [:site_name] do |_t, args| - args.with_defaults site_name: - 'https://master.bestpractices.coreinfrastructure.org/projects/1/badge' + args.with_defaults site_name: 'https://master.bestpractices.coreinfrastructure.org/projects/1/badge' puts 'Starting test of Fastly caching' verbose(false) do sh "script/fastly_test #{args.site_name}" @@ -353,8 +349,7 @@ desc 'Copy production database backup to main stage, overwriting main database' task :production_to_main do sh 'heroku pg:backups:restore $(heroku pg:backups:public-url ' \ '--app production-bestpractices) DATABASE_URL --app master-bestpractices' - sh 'heroku run:detached bundle exec rake db:migrate ' \ - '--app master-bestpractices' + sh 'heroku run:detached bundle exec rake db:migrate --app master-bestpractices' end desc 'Copy production database backup to staging, overwriting staging database' @@ -362,8 +357,7 @@ task :production_to_staging do sh 'heroku pg:backups:restore $(heroku pg:backups:public-url ' \ '--app production-bestpractices) DATABASE_URL ' \ '--app staging-bestpractices --confirm staging-bestpractices' - sh 'heroku run:detached bundle exec rake db:migrate ' \ - '--app staging-bestpractices' + sh 'heroku run:detached bundle exec rake db:migrate --app staging-bestpractices' end # require 'rails/testtask.rb' @@ -444,7 +438,7 @@ def normalize_string(value, locale) .gsub(/target="_blank" *>/, 'target="_blank" rel="noopener">') .gsub(%r{https: // }, 'https://') .gsub(%r{href="/en/}, "href=\"/#{locale}/") - .gsub(%r{href='/en/}, "href=\'/#{locale}/") + .gsub(%r{href='/en/}, "href='/#{locale}/") end # rubocop:enable Metrics/MethodLength @@ -456,7 +450,7 @@ def normalize_yaml(path) # Compute locale from filename (it must be before the last period) locale = filename.split('.')[-2] normalized = normalize_values(YAML.load_file(filename), locale) - IO.write(filename, normalized.to_yaml(line_width: 60).gsub(/\s+$/, '')) + File.write(filename, normalized.to_yaml(line_width: 60).gsub(/\s+$/, '')) end end @@ -615,8 +609,7 @@ task :create_project_insertion_command do puts "Inserting project id #{project_id}" # Escape JSON using SQL escape ' -> '', so we can use it in a SQL command escaped_json = "'" + file_contents.gsub(/'/, "''") + "'" - sql_command = 'insert into projects select * from ' \ - "json_populate_record(NULL::projects, #{escaped_json});" + sql_command = 'insert into projects select * from ' + "json_populate_record(NULL::projects, #{escaped_json});" File.write('project.sql', sql_command) puts 'File project.sql created. To use this, do the following (examples):' puts 'Local: rails db < project.sql' @@ -683,7 +676,7 @@ end # we loop over all users, but ignore users where the rekey doesn't work. desc 'Rekey (change keys) of email addresses' task rekey: :environment do - old_key = [ENV['EMAIL_ENCRYPTION_KEY_OLD']].pack('H*') + old_key = [ENV.fetch('EMAIL_ENCRYPTION_KEY_OLD', nil)].pack('H*') User.find_each do |u| # rubocop:disable Style/RedundantBegin begin @@ -745,8 +738,8 @@ end # We do *NOT* try to localize, for speed. desc 'Send a mass email (e.g., a required GDPR notification)' task :mass_email do - subject = ENV['MASS_EMAIL_SUBJECT'] - body = ENV['MASS_EMAIL_BODY'] + subject = ENV.fetch('MASS_EMAIL_SUBJECT', nil) + body = ENV.fetch('MASS_EMAIL_BODY', nil) where_condition = ENV['MASS_EMAIL_WHERE'] || 'true' raise if !subject || !body @@ -815,9 +808,9 @@ def real_search_email(email) # to prevent swapping the email & name fields when calling search_user. raise ArgumentError unless /.+@.+/.match?(email) - results = User.where(email: email) - .select('id, name, encrypted_email, encrypted_email_iv') - .pluck(:id, :name) + results = User.where(email: email).select('id, name, encrypted_email, encrypted_email_iv').pluck( + :id, :name + ) puts results end @@ -887,9 +880,8 @@ task :update_badge_images do 'https://img.shields.io/badge/openssf_best_practices-passing-4c1' sh 'curl -o app/assets/images/badge_static_silver.svg ' \ 'https://img.shields.io/badge/openssf_best_practices-silver-c0c0c0' - sh 'curl -o app/assets/images/badge_static_gold.svg ' \ - 'https://img.shields.io/badge/openssf_best_practices-gold-ffd700' - (0..99).each do |percent| + sh 'curl -o app/assets/images/badge_static_gold.svg https://img.shields.io/badge/openssf_best_practices-gold-ffd700' + 100.times do |percent| # scale "color" to be greener as we approach passing, to provide a # visual indication of progress for those who can see color color = Paleta::Color.new(:hsl, (percent * 0.45) + 15, 85, 43).hex diff --git a/test/controllers/project_stats_controller_test.rb b/test/controllers/project_stats_controller_test.rb index 85b3c7a66..65640da96 100644 --- a/test/controllers/project_stats_controller_test.rb +++ b/test/controllers/project_stats_controller_test.rb @@ -165,7 +165,7 @@ class ProjectStatsControllerTest < ActionDispatch::IntegrationTest nontrivial_projects_project_stats_path(format: :json, locale: nil) get nontrivial_projects_project_stats_path(format: :json) contents = JSON.parse(@response.body) - levels = contents.map { |entry| entry['name'] } # levels reported + levels = contents.pluck('name') # levels reported assert_equal ['>=25%', '>=50%', '>=75%', '>=90%', '>=100%'], levels assert_equal '>=25%', contents[0]['name'] assert_equal 18, contents[0]['data']['2013-05-19 17:44:18 UTC'] @@ -195,6 +195,8 @@ class ProjectStatsControllerTest < ActionDispatch::IntegrationTest assert_equal 4, contents.length assert_equal 'projects created since day before', contents[0]['name'] assert_equal 2, contents[0]['data']['2013-05-19 17:44:18 UTC'] + assert_equal 0.8571428571428571, contents[1]['data']['2014-05-25 23:30:19 UTC'] + assert_equal 0.14285714285714285, contents[3]['data']['2014-05-25 23:30:19 UTC'] end test 'Test /en/project_stats/reminders.json' do diff --git a/test/test_helper.rb b/test/test_helper.rb index c54db600a..a0c79f856 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -136,7 +136,7 @@ def configure_omniauth_mock(cassette = 'github_login') end def contents(file_name) - IO.read "test/fixtures/files/#{file_name}" + File.read "test/fixtures/files/#{file_name}" end # rubocop:disable Metrics/MethodLength @@ -163,7 +163,10 @@ def kill_sticky_headers # Using "password" helps test that users can log in to their # existing accounts, even if we make the password rules harsher later. def log_in_as( - user, password: 'password', provider: 'local', remember_me: '1', + user, + password: 'password', + provider: 'local', + remember_me: '1', make_old: false ) # This is based on "Ruby on Rails Tutorial" by Michael Hargle, chapter 8, diff --git a/test/unit/lib/chief_test.rb b/test/unit/lib/chief_test.rb index c8bcc6cb1..726fec322 100644 --- a/test/unit/lib/chief_test.rb +++ b/test/unit/lib/chief_test.rb @@ -67,7 +67,7 @@ def analyze(_, _) end test 'Fatal exceptions in a Detective will not crash production system' do - old_environment = ENV['RAILS_ENV'] + old_environment = ENV.fetch('RAILS_ENV', nil) # TEMPORARILY make this a 'production' environment (it isn't really) ENV['RAILS_ENV'] = 'production' @@ -115,7 +115,7 @@ def analyze(_, _) # but not in this way. Thus, we must more carefully test the alternatives, # to ensure that both behaviors occur. - old_environment = ENV['RAILS_ENV'] + old_environment = ENV.fetch('RAILS_ENV', nil) # TEMPORARILY make this a 'test' environment (it probably is anyway) ENV['RAILS_ENV'] = 'test'