diff --git a/.rubocop.yml b/.rubocop.yml index 7933b1521..127c7d926 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -1,16 +1,70 @@ +inherit_from: .rubocop_todo.yml + inherit_gem: rubocop-github: - - config/default.yml - - config/rails.yml + - config/default_edge.yml + - config/rails_edge.yml AllCops: - TargetRailsVersion: 4.2 - TargetRubyVersion: 2.3 + TargetRailsVersion: 5.0 + TargetRubyVersion: 2.7 + NewCops: disable Exclude: - 'db/**/*' - 'config/**/*' - 'bin/**/*' - 'vendor/**/*' + - 'features/**/*' + +# Handle cops not enabled by default +# Should probably be checked on rubocop version upgrades +# Last checked 02/09/21 +# Disables cops marked as unsafe in docs + +Layout/SpaceAroundMethodCallOperator: + Enabled: true + +Lint/RaiseException: + Enabled: true + +Lint/StructNewOverride: + Enabled: true + +Style/ExponentialNotation: + Enabled: true + +Style/HashEachMethods: + Enabled: false + +Style/HashTransformKeys: + Enabled: false + +Style/HashTransformValues: + Enabled: false + +Performance/AncestorsInclude: + Enabled: false + +Performance/BigDecimalWithNumericArgument: + Enabled: true + +Performance/RedundantSortBlock: + Enabled: true + +Performance/RedundantStringChars: + Enabled: true + +Performance/ReverseFirst: + Enabled: true + +Performance/SortReverse: + Enabled: true + +Performance/Squeeze: + Enabled: true + +Performance/StringInclude: + Enabled: true ### Override rubcop-github ### @@ -31,7 +85,7 @@ GitHub/RailsControllerRenderPathsExist: Enabled: false GitHub/RailsApplicationRecord: - # Doesn't apply to < Rails 5.0, and ignores TargetRailsVersion + # Rails/ApplicationRecord does the same thing Enabled: false Lint/Void: @@ -43,7 +97,7 @@ Lint/Debugger: Exclude: - 'features/step_definitions/debug_steps.rb' -Style/BlockComments: +Lint/AmbiguousBlockAssociation: Exclude: - 'spec/**/*' @@ -65,7 +119,30 @@ Layout/MultilineHashBraceLayout: Layout/SpaceAroundOperators: Enabled: true +Naming/PredicateName: + Exclude: + - 'spec/**/*' + Security/JSONLoad: Enabled: true Exclude: - 'spec/**/*' + +Rails/HttpStatus: + EnforcedStyle: 'numeric' + +Style/Alias: + Enabled: false + +Style/BlockComments: + Exclude: + - 'spec/**/*' + +Style/ClassAndModuleChildren: + EnforcedStyle: 'compact' + +Style/Documentation: + Enabled: false + +Style/NumericLiterals: + MinDigits: 6 diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml new file mode 100644 index 000000000..ccf6a115e --- /dev/null +++ b/.rubocop_todo.yml @@ -0,0 +1,186 @@ +# This configuration was generated by +# `rubocop --auto-gen-config --exclude-limit 100` +# on 2021-02-11 14:07:46 -0800 using RuboCop version 0.82.0. +# The point is for the user to remove these configuration records +# one by one as the offenses are removed from the code base. +# Note that changes in the inspected code, or installation of new +# versions of RuboCop, may require this file to be generated again. + +# Offense count: 3 +# Configuration parameters: NamePrefix, ForbiddenPrefixes, AllowedMethods, MethodDefinitionMacros. +# NamePrefix: is_, has_, have_ +# ForbiddenPrefixes: is_, has_, have_ +# AllowedMethods: is_a? +# MethodDefinitionMacros: define_method, define_singleton_method +Naming/PredicateName: + Exclude: + - 'spec/**/*' + +# Offense count: 45 +# Configuration parameters: EnforcedStyle. +# SupportedStyles: snake_case, camelCase +Naming/VariableName: + Exclude: + - 'app/controllers/action_page_controller.rb' + - 'app/controllers/admin/action_pages_controller.rb' + - 'app/controllers/admin/mailer_controller.rb' + - 'app/controllers/admin/petitions_controller.rb' + - 'app/controllers/congress_messages_controller.rb' + - 'app/controllers/tools_controller.rb' + - 'app/controllers/users_controller.rb' + - 'app/controllers/welcome_controller.rb' + - 'app/helpers/application_helper.rb' + - 'app/helpers/devise_helper.rb' + - 'app/mailers/user_mailer.rb' + - 'app/models/markdown_renderer.rb' + - 'app/views/action_page/index.atom.builder' + - 'app/views/action_page/index.json.jbuilder' + - 'spec/controllers/action_page_controller_spec.rb' + - 'spec/controllers/admin/institutions_controller_spec.rb' + +# Offense count: 2 +# Cop supports --auto-correct. +Rails/ApplicationController: + Exclude: + - 'app/controllers/exceptions_controller.rb' + - 'spec/controllers/concerns/request_origin_validation_spec.rb' + +# Offense count: 1 +# Cop supports --auto-correct. +Rails/ApplicationMailer: + Exclude: + - 'app/mailers/user_mailer.rb' + +# Offense count: 29 +# Cop supports --auto-correct. +Rails/ApplicationRecord: + Exclude: + - 'app/models/action_institution.rb' + - 'app/models/action_page.rb' + - 'app/models/affiliation.rb' + - 'app/models/affiliation_type.rb' + - 'app/models/ahoy/event.rb' + - 'app/models/bounce.rb' + - 'app/models/call_campaign.rb' + - 'app/models/category.rb' + - 'app/models/complaint.rb' + - 'app/models/congress_member.rb' + - 'app/models/congress_message_campaign.rb' + - 'app/models/congress_scorecard.rb' + - 'app/models/email_campaign.rb' + - 'app/models/featured_action_page.rb' + - 'app/models/institution.rb' + - 'app/models/partner.rb' + - 'app/models/partnership.rb' + - 'app/models/petition.rb' + - 'app/models/signature.rb' + - 'app/models/source_file.rb' + - 'app/models/subscription.rb' + - 'app/models/topic.rb' + - 'app/models/topic_category.rb' + - 'app/models/topic_set.rb' + - 'app/models/tweet.rb' + - 'app/models/tweet_target.rb' + - 'app/models/user.rb' + - 'app/models/user_preference.rb' + - 'app/models/visit.rb' + +# Offense count: 2 +# Configuration parameters: EnforcedStyle. +# SupportedStyles: slashes, arguments +Rails/FilePath: + Exclude: + - 'lib/tasks/webshims_asset_compile.rake' + +# Offense count: 25 +# Configuration parameters: Include. +# Include: app/models/**/*.rb +Rails/HasManyOrHasOneDependent: + Exclude: + - 'app/models/action_page.rb' + - 'app/models/affiliation_type.rb' + - 'app/models/call_campaign.rb' + - 'app/models/congress_message_campaign.rb' + - 'app/models/email_campaign.rb' + - 'app/models/institution.rb' + - 'app/models/partner.rb' + - 'app/models/petition.rb' + - 'app/models/signature.rb' + - 'app/models/topic_category.rb' + - 'app/models/tweet.rb' + - 'app/models/user.rb' + - 'app/models/visit.rb' + +# Offense count: 15 +# Configuration parameters: Include. +# Include: app/helpers/**/*.rb +Rails/HelperInstanceVariable: + Exclude: + - 'app/helpers/action_page_helper.rb' + - 'app/helpers/application_helper.rb' + - 'app/helpers/devise_helper.rb' + - 'app/helpers/petition_helper.rb' + +# Offense count: 6 +# Configuration parameters: Include. +# Include: app/controllers/**/*.rb +Rails/LexicallyScopedActionFilter: + Exclude: + - 'app/controllers/admin/action_pages_controller.rb' + - 'app/controllers/admin/partners_controller.rb' + - 'app/controllers/petition_controller.rb' + - 'app/controllers/sessions_controller.rb' + - 'app/controllers/tools_controller.rb' + +# Offense count: 3 +# Configuration parameters: Include. +# Include: app/models/**/*.rb +Rails/UniqueValidationWithoutIndex: + Exclude: + - 'app/models/congress_member.rb' + - 'app/models/institution.rb' + - 'app/models/partner.rb' + +# Offense count: 1 +Security/Open: + Exclude: + - 'lib/related_content.rb' + +# Offense count: 2 +# Cop supports --auto-correct. +# Configuration parameters: AutoCorrect, EnforcedStyle. +# SupportedStyles: nested, compact +Style/ClassAndModuleChildren: + Exclude: + - 'app/models/ahoy/event.rb' + - 'lib/monkey_patches/octet_stream_override.rb' + +# Offense count: 17 +# Configuration parameters: MinBodyLength. +Style/GuardClause: + Exclude: + - 'app/controllers/action_page_controller.rb' + - 'app/controllers/admin/action_pages_controller.rb' + - 'app/controllers/application_controller.rb' + - 'app/controllers/concerns/action_page_display.rb' + - 'app/controllers/concerns/request_origin_validation.rb' + - 'app/controllers/congress_messages_controller.rb' + - 'app/controllers/partners_controller.rb' + - 'app/controllers/registrations_controller.rb' + - 'app/controllers/sessions_controller.rb' + - 'app/controllers/tools_controller.rb' + - 'app/helpers/application_helper.rb' + - 'app/models/ahoy/event.rb' + - 'lib/call_tool.rb' + +# Offense count: 4 +# Cop supports --auto-correct. +# Configuration parameters: AutoCorrect, EnforcedStyle, IgnoredMethods. +# SupportedStyles: predicate, comparison +Style/NumericPredicate: + Exclude: + - 'spec/**/*' + - 'app/controllers/tools_controller.rb' + - 'app/helpers/application_helper.rb' + - 'app/models/action_page.rb' + - 'app/models/petition.rb' diff --git a/.ruby-version b/.ruby-version index 0cadbc1e3..37c2961c2 100644 --- a/.ruby-version +++ b/.ruby-version @@ -1 +1 @@ -2.5.5 +2.7.2 diff --git a/.travis.yml b/.travis.yml index b4a0ed27c..8ffc83c25 100644 --- a/.travis.yml +++ b/.travis.yml @@ -14,7 +14,7 @@ before_script: - npm install - cp config/database.yml.travis config/database.yml - psql -c 'create database travis_ci_test;' -U postgres - - RAILS_ENV=test bundle exec rails webdrivers:chromedriver:update + - google-chrome-stable --headless --disable-gpu --remote-debugging-port=9222 http://localhost & script: - bundle exec rubocop - $(npm bin)/sass-lint -vq diff --git a/Dockerfile b/Dockerfile index ea4308c07..590eaee50 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM ruby:2.5-stretch +FROM ruby:2.7-slim RUN mkdir /opt/actioncenter WORKDIR /opt/actioncenter @@ -66,7 +66,6 @@ RUN bundle exec rake assets:precompile \ devise_secret_key=noop \ amazon_region=noop \ DATABASE_URL=postgres://noop -RUN bundle exec rake webshims:update_public RUN mkdir /opt/actioncenter/log \ /var/www diff --git a/Gemfile b/Gemfile index e30d333e3..e0f4da434 100644 --- a/Gemfile +++ b/Gemfile @@ -1,17 +1,17 @@ source "https://rubygems.org" -gem "rails", "~> 5.0" +gem "rails", "~> 5.0.7" -#Database +# Database gem "pg", "~> 1.1" -gem "pg_search" +# Can upgrade after upgrading to rails 5.2 +gem "pg_search", "< 2.3.1" # Hosting-related -gem "aws-sdk", "~> 2.3" -gem "aws-sdk-rails", "~> 1" +gem "aws-sdk-rails", "~> 2" +gem "aws-sdk-s3", "~> 1" gem "dotenv-rails", "~> 2" gem "rack-attack", "~> 5" -gem "rails_12factor", group: :production # Loads "rails_serve_static_assets" and "rails_stdout_logging" gem "rails_response_headers", "~> 0" # Frontend/assets @@ -22,10 +22,9 @@ gem "bundler", ">= 1.8.4" # needed for rails-assets gem "fontello_rails_converter", "~> 0" gem "react-rails", "~> 1" gem "redcarpet", "~> 3" # Markdown -gem "sass-rails", "~> 5.0" +gem "sass-rails", "< 5.1" gem "select2-rails" # Autocomplete select menus gem "uglifier", ">= 1.3.0" # compressor for JavaScript assets -gem "webshims-rails", "~> 1" source "https://rails-assets.org" do gem "rails-assets-chartjs", "~> 2" gem "rails-assets-congress-images-102x125" @@ -44,17 +43,14 @@ source "https://rails-assets.org" do end # File upload -gem "paperclip", "~> 5.2" +gem "kt-paperclip", "~> 6" # Email preformatting gem "nokogiri", "~> 1" # Required for premailer-rails gem "premailer-rails", "~> 1" # Inline styles for emails -# Optimization -gem "sprockets-image_compressor", "~> 0" # Optimizes png/jpg - # Analytics -gem "ahoy_matey", "~> 1.6" # Analytics +gem "ahoy_matey", "~> 1.6" gem "chartkick", "~> 3" gem "eff_matomo", "~> 0.2.4", require: "matomo" gem "groupdate", "~> 2" @@ -71,9 +67,9 @@ gem "counter_culture", "~> 2.0" # Other gem "activerecord-session_store", "~> 1" -gem "acts_as_paranoid", git: "https://github.com/ActsAsParanoid/acts_as_paranoid.git" +# Can upgrade after upgrading to rails 5.2 +gem "acts_as_paranoid", "< 0.7" gem "cocoon", "~> 1" # Dynamically add and remove nested associations from forms -gem "descriptive_statistics", "~> 2" # Used for calculating percentiles gem "devise", "~> 4.7" gem "ejs", "~> 1" # Embedded javascript gem "email_validator", "~> 1" @@ -84,14 +80,14 @@ gem "gravatar-ultimate", "~> 2" gem "http_accept_language", "~> 2" # Detect HTTP language header gem "invisible_captcha", "~> 0" # Prevent form submissions by bots gem "iso_country_codes", "~> 0" -gem "jbuilder", "~> 1.2" # JSON APIs +gem "jbuilder", "~> 2" gem "oauth", "~> 0" gem "rest-client", "~> 2" gem "sanitize", "~> 4" # Sanitize user input gem "warden", "1.2.4" # This dep of devise has a bug in 1.2.5 so am avaoiding gem "whenever", "~> 0", require: false # Cron jobs gem "will_paginate", "~> 3.0" -gem "xmlrpc" +gem "xmlrpc", "~> 0.3" # For creating many records, quickly gem "fast_inserter", "~> 0.1" @@ -111,23 +107,22 @@ group :development do end group :test do - gem "webmock", "~> 2" + gem "apparition", "~> 0.6" + gem "webmock", "~> 3" end group :development, :test do gem "byebug" - gem "capybara", "~> 3.26" - gem "cucumber-rails", "1.6.0", require: false + gem "capybara", "~> 3" gem "database_cleaner", "~> 1" - gem "factory_girl_rails", "~> 4" - gem "poltergeist", "~> 1" + gem "factory_bot_rails", "~> 4" gem "rails-controller-testing" gem "rspec-core", "~> 3" gem "rspec-rails", "~> 3" - gem "rubocop", "0.52.0" - gem "rubocop-github", "0.9.0" - gem "selenium-webdriver", "~> 3" - gem "webdrivers", "~> 4" + gem "rubocop" + gem "rubocop-github", "~> 0.16" + gem "rubocop-performance", require: false + gem "rubocop-rails", require: false end group :production do diff --git a/Gemfile.lock b/Gemfile.lock index f70727cfc..bbbe5f7c7 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,11 +1,3 @@ -GIT - remote: https://github.com/ActsAsParanoid/acts_as_paranoid.git - revision: b58c5149d32f06ea729ad1c8bd3ac26d8cde50ce - specs: - acts_as_paranoid (0.6.0) - activerecord (>= 4.2, < 6.0) - activesupport (>= 4.2, < 6.0) - GEM remote: https://rubygems.org/ remote: https://rails-assets.org/ @@ -53,11 +45,11 @@ GEM i18n (>= 0.7, < 2) minitest (~> 5.1) tzinfo (~> 1.1) - addressable (2.6.0) - public_suffix (>= 2.0.2, < 4.0) - after_commit_action (1.1.0) - activerecord (>= 3.0.0) - activesupport (>= 3.0.0) + acts_as_paranoid (0.6.3) + activerecord (>= 4.2, < 7.0) + activesupport (>= 4.2, < 7.0) + addressable (2.7.0) + public_suffix (>= 2.0.2, < 5.0) ahoy_matey (1.6.1) addressable browser (~> 2.0) @@ -69,147 +61,133 @@ GEM safely_block (>= 0.1.1) user_agent_parser uuidtools + apparition (0.6.0) + capybara (~> 3.13, < 4) + websocket-driver (>= 0.6.5) arel (7.1.4) - ast (2.4.0) - autoprefixer-rails (9.5.1) + ast (2.4.2) + autoprefixer-rails (10.2.4.0) execjs - aws-eventstream (1.0.3) - aws-sdk (2.11.264) - aws-sdk-resources (= 2.11.264) - aws-sdk-core (2.11.264) - aws-sigv4 (~> 1.0) + aws-eventstream (1.1.0) + aws-partitions (1.426.0) + aws-sdk-core (3.112.0) + aws-eventstream (~> 1, >= 1.0.2) + aws-partitions (~> 1, >= 1.239.0) + aws-sigv4 (~> 1.1) jmespath (~> 1.0) - aws-sdk-rails (1.0.1) - aws-sdk-resources (~> 2) + aws-sdk-kms (1.42.0) + aws-sdk-core (~> 3, >= 3.112.0) + aws-sigv4 (~> 1.1) + aws-sdk-rails (2.1.0) + aws-sdk-ses (~> 1) railties (>= 3) - aws-sdk-resources (2.11.264) - aws-sdk-core (= 2.11.264) - aws-sigv4 (1.1.0) - aws-eventstream (~> 1.0, >= 1.0.2) + aws-sdk-s3 (1.88.0) + aws-sdk-core (~> 3, >= 3.112.0) + aws-sdk-kms (~> 1) + aws-sigv4 (~> 1.1) + aws-sdk-ses (1.37.0) + aws-sdk-core (~> 3, >= 3.112.0) + aws-sigv4 (~> 1.1) + aws-sigv4 (1.2.2) + aws-eventstream (~> 1, >= 1.0.2) babel-source (5.8.35) babel-transpiler (0.7.0) babel-source (>= 4.0, < 6) execjs (~> 2.0) - backports (3.14.0) - bcrypt (3.1.13) - better_errors (2.5.1) + bcrypt (3.1.16) + better_errors (2.9.1) coderay (>= 1.0.0) erubi (>= 1.0.0) rack (>= 0.9.0) binding_of_caller (0.8.0) debug_inspector (>= 0.0.1) - bootstrap-daterangepicker-rails (3.0.3) - railties (>= 4.0, < 5.3) + bootstrap-daterangepicker-rails (3.0.4) + railties (>= 4.0) bootstrap-sass (3.4.1) autoprefixer-rails (>= 5.2.1) sassc (>= 2.0.0) bourbon (3.2.4) sass (~> 3.2) thor - browser (2.5.3) - builder (3.2.3) - byebug (11.0.1) - capybara (3.26.0) + browser (2.7.1) + builder (3.2.4) + byebug (11.1.3) + capybara (3.35.3) addressable mini_mime (>= 0.1.3) nokogiri (~> 1.8) rack (>= 1.6.0) rack-test (>= 0.6.3) - regexp_parser (~> 1.5) + regexp_parser (>= 1.5, < 3.0) xpath (~> 3.2) - chartkick (3.3.0) - childprocess (2.0.0) - rake (< 13.0) + chartkick (3.4.2) chronic (0.10.2) climate_control (0.2.0) - cliver (0.3.2) - cocoon (1.2.12) - coderay (1.1.2) - concurrent-ruby (1.1.5) - connection_pool (2.2.2) - counter_culture (2.2.3) + cocoon (1.2.15) + coderay (1.1.3) + concurrent-ruby (1.1.8) + connection_pool (2.2.3) + counter_culture (2.7.0) activerecord (>= 4.2) activesupport (>= 4.2) - after_commit_action (~> 1.0) - crack (0.4.3) - safe_yaml (~> 1.0.0) - crass (1.0.5) - css_parser (1.7.0) + crack (0.4.5) + rexml + crass (1.0.6) + css_parser (1.9.0) addressable - cucumber (3.1.2) - builder (>= 2.1.2) - cucumber-core (~> 3.2.0) - cucumber-expressions (~> 6.0.1) - cucumber-wire (~> 0.0.1) - diff-lcs (~> 1.3) - gherkin (~> 5.1.0) - multi_json (>= 1.7.5, < 2.0) - multi_test (>= 0.1.2) - cucumber-core (3.2.1) - backports (>= 3.8.0) - cucumber-tag_expressions (~> 1.1.0) - gherkin (~> 5.0) - cucumber-expressions (6.0.1) - cucumber-rails (1.6.0) - capybara (>= 1.1.2, < 4) - cucumber (>= 3.0.2, < 4) - mime-types (>= 1.17, < 4) - nokogiri (~> 1.8) - railties (>= 4, < 6) - cucumber-tag_expressions (1.1.1) - cucumber-wire (0.0.1) daemons (1.3.1) - database_cleaner (1.7.0) - debug_inspector (0.0.3) - delayed_job (4.1.5) - activesupport (>= 3.0, < 5.3) - delayed_job_active_record (4.1.3) - activerecord (>= 3.0, < 5.3) + database_cleaner (1.99.0) + debug_inspector (1.0.0) + delayed_job (4.1.9) + activesupport (>= 3.0, < 6.2) + delayed_job_active_record (4.1.5) + activerecord (>= 3.0, < 6.2) delayed_job (>= 3.0, < 5) - descriptive_statistics (2.5.1) - devise (4.7.1) + devise (4.7.3) bcrypt (~> 3.0) orm_adapter (~> 0.1) railties (>= 4.1.0) responders warden (~> 1.2.3) - diff-lcs (1.3) - domain_name (0.5.20180417) + diff-lcs (1.4.4) + domain_name (0.5.20190701) unf (>= 0.0.5, < 1.0.0) - dotenv (2.7.2) - dotenv-rails (2.7.2) - dotenv (= 2.7.2) - railties (>= 3.2, < 6.1) + dotenv (2.7.6) + dotenv-rails (2.7.6) + dotenv (= 2.7.6) + railties (>= 3.2) eff_matomo (0.2.4) activesupport httparty ejs (1.1.1) email_validator (1.6.0) activemodel - errbase (0.1.1) - erubi (1.8.0) + errbase (0.2.1) + erubi (1.10.0) erubis (2.7.0) execjs (2.7.0) - factory_girl (4.9.0) + factory_bot (4.11.1) activesupport (>= 3.0.0) - factory_girl_rails (4.9.0) - factory_girl (~> 4.9.0) + factory_bot_rails (4.11.1) + factory_bot (~> 4.11.1) railties (>= 3.0.0) - faraday (0.15.4) + faraday (1.3.0) + faraday-net_http (~> 1.0) multipart-post (>= 1.2, < 3) + ruby2_keywords + faraday-net_http (1.0.1) fast_inserter (0.1.6) activerecord (>= 4.1.0) - fastly (2.3.0) - ffi (1.10.0) + fastly (2.5.3) + ffi (1.14.2) fontello_rails_converter (0.4.6) activesupport launchy rest-client rubyzip (~> 1.0) - friendly_id (5.2.5) + friendly_id (5.4.2) activerecord (>= 4.0.0) - geocoder (1.5.1) - gherkin (5.1.0) + geocoder (1.6.5) globalid (0.4.2) activesupport (>= 4.2.0) going_postal (0.1.6) @@ -218,78 +196,74 @@ GEM rack groupdate (2.5.3) activesupport (>= 3) - hashdiff (0.3.9) + hashdiff (1.0.1) htmlentities (4.3.4) + http-accept (1.7.0) http-cookie (1.0.3) domain_name (~> 0.5) http_accept_language (2.1.1) - httparty (0.17.0) + httparty (0.18.1) mime-types (~> 3.0) multi_xml (>= 0.5.2) - i18n (1.6.0) + i18n (1.8.9) concurrent-ruby (~> 1.0) - invisible_captcha (0.12.0) + invisible_captcha (0.13.0) rails (>= 3.2.0) iso_country_codes (0.7.8) - jbuilder (1.5.3) - activesupport (>= 3.0.0) - multi_json (>= 1.2.0) + jbuilder (2.11.2) + activesupport (>= 5.0.0) jmespath (1.4.0) - launchy (2.4.3) - addressable (~> 2.3) - loofah (2.3.1) + kt-paperclip (6.4.1) + activemodel (>= 4.2.0) + activesupport (>= 4.2.0) + mime-types + mimemagic (~> 0.3.0) + terrapin (~> 0.6.0) + launchy (2.5.0) + addressable (~> 2.7) + loofah (2.9.0) crass (~> 1.0.2) nokogiri (>= 1.5.9) mail (2.7.1) mini_mime (>= 0.1.1) - method_source (0.9.2) - mime-types (3.2.2) + method_source (1.0.0) + mime-types (3.3.1) mime-types-data (~> 3.2015) - mime-types-data (3.2019.0331) - mimemagic (0.3.3) + mime-types-data (3.2020.1104) + mimemagic (0.3.5) mini_mime (1.0.2) - mini_portile2 (2.4.0) - minitest (5.11.3) - multi_json (1.13.1) - multi_test (0.1.2) + mini_portile2 (2.5.0) + minitest (5.14.3) + multi_json (1.15.0) multi_xml (0.6.0) - multipart-post (2.0.0) + multipart-post (2.1.1) netrc (0.11.0) - nio4r (2.3.1) - nokogiri (1.10.8) - mini_portile2 (~> 2.4.0) + nio4r (2.5.5) + nokogiri (1.11.1) + mini_portile2 (~> 2.5.0) + racc (~> 1.4) nokogumbo (1.5.0) nokogiri - oauth (0.5.4) + oauth (0.5.5) orm_adapter (0.5.0) - paperclip (5.3.0) - activemodel (>= 4.2.0) - activesupport (>= 4.2.0) - mime-types - mimemagic (~> 0.3.0) - terrapin (~> 0.6.0) - parallel (1.17.0) - parser (2.6.3.0) - ast (~> 2.4.0) - pg (1.1.4) - pg_search (2.1.7) + parallel (1.20.1) + parser (3.0.0.0) + ast (~> 2.4.1) + pg (1.2.3) + pg_search (2.3.0) activerecord (>= 4.2) activesupport (>= 4.2) - poltergeist (1.18.1) - capybara (>= 2.1, < 4) - cliver (~> 0.3.1) - websocket-driver (>= 0.2.0) - powerpack (0.1.2) - premailer (1.11.1) + premailer (1.14.2) addressable css_parser (>= 1.6.0) htmlentities (>= 4.0.0) - premailer-rails (1.10.2) - actionmailer (>= 3, < 6) + premailer-rails (1.11.1) + actionmailer (>= 3) premailer (~> 1.7, >= 1.7.9) - public_suffix (3.1.1) - puma (3.12.4) - rack (2.0.8) + public_suffix (4.0.6) + puma (3.12.6) + racc (1.5.2) + rack (2.2.3) rack-attack (5.4.2) rack (>= 1.0, < 3) rack-test (0.6.3) @@ -323,24 +297,19 @@ GEM rails-assets-respond (1.4.2) rails-assets-roboto-webfont (0.1.1) rails-assets-sweetalert (1.0.1) - rails-controller-testing (1.0.4) - actionpack (>= 5.0.1.x) - actionview (>= 5.0.1.x) - activesupport (>= 5.0.1.x) + rails-controller-testing (1.0.5) + actionpack (>= 5.0.1.rc1) + actionview (>= 5.0.1.rc1) + activesupport (>= 5.0.1.rc1) rails-dev-tweaks (1.2.0) actionpack (>= 3.1) railties (>= 3.1) rails-dom-testing (2.0.3) activesupport (>= 4.2.0) nokogiri (>= 1.6) - rails-html-sanitizer (1.2.0) - loofah (~> 2.2, >= 2.2.2) - rails_12factor (0.0.3) - rails_serve_static_assets - rails_stdout_logging + rails-html-sanitizer (1.3.0) + loofah (~> 2.3) rails_response_headers (0.1.0) - rails_serve_static_assets (0.0.5) - rails_stdout_logging (0.0.5) railties (5.0.7.2) actionpack (= 5.0.7.2) activesupport (= 5.0.7.2) @@ -348,62 +317,76 @@ GEM rake (>= 0.8.7) thor (>= 0.18.1, < 2.0) rainbow (3.0.0) - rake (12.3.3) + rake (13.0.3) rb-fchange (0.0.6) ffi - rb-fsevent (0.10.3) - rb-inotify (0.10.0) + rb-fsevent (0.10.4) + rb-inotify (0.10.1) ffi (~> 1.0) - rdoc (6.1.1) + rdoc (6.3.0) react-rails (1.11.0) babel-transpiler (>= 0.7.0) connection_pool execjs railties (>= 3.2) tilt - redcarpet (3.4.0) + redcarpet (3.5.1) referer-parser (0.3.0) - regexp_parser (1.6.0) - request_store (1.4.1) + regexp_parser (2.0.3) + request_store (1.5.0) rack (>= 1.4) - responders (3.0.0) + responders (3.0.1) actionpack (>= 5.0) railties (>= 5.0) - rest-client (2.0.2) + rest-client (2.1.0) + http-accept (>= 1.7.0, < 2.0) http-cookie (>= 1.0.2, < 2.0) mime-types (>= 1.16, < 4.0) netrc (~> 0.8) - rspec-core (3.8.0) - rspec-support (~> 3.8.0) - rspec-expectations (3.8.3) + rexml (3.2.4) + rspec-core (3.9.3) + rspec-support (~> 3.9.3) + rspec-expectations (3.9.4) diff-lcs (>= 1.2.0, < 2.0) - rspec-support (~> 3.8.0) - rspec-mocks (3.8.0) + rspec-support (~> 3.9.0) + rspec-mocks (3.9.1) diff-lcs (>= 1.2.0, < 2.0) - rspec-support (~> 3.8.0) - rspec-rails (3.8.2) + rspec-support (~> 3.9.0) + rspec-rails (3.9.1) actionpack (>= 3.0) activesupport (>= 3.0) railties (>= 3.0) - rspec-core (~> 3.8.0) - rspec-expectations (~> 3.8.0) - rspec-mocks (~> 3.8.0) - rspec-support (~> 3.8.0) - rspec-support (3.8.0) - rubocop (0.52.0) + rspec-core (~> 3.9.0) + rspec-expectations (~> 3.9.0) + rspec-mocks (~> 3.9.0) + rspec-support (~> 3.9.0) + rspec-support (3.9.4) + rubocop (1.6.1) parallel (~> 1.10) - parser (>= 2.4.0.2, < 3.0) - powerpack (~> 0.1) + parser (>= 2.7.1.5) rainbow (>= 2.2.2, < 4.0) + regexp_parser (>= 1.8, < 3.0) + rexml + rubocop-ast (>= 1.2.0, < 2.0) ruby-progressbar (~> 1.7) - unicode-display_width (~> 1.0, >= 1.0.1) - rubocop-github (0.9.0) - rubocop (~> 0.51) - ruby-progressbar (1.10.0) + unicode-display_width (>= 1.4.0, < 2.0) + rubocop-ast (1.4.1) + parser (>= 2.7.1.5) + rubocop-github (0.16.1) + rubocop (<= 1.6.1) + rubocop-performance (<= 1.7.1) + rubocop-rails (<= 2.7.1) + rubocop-performance (1.7.1) + rubocop (>= 0.82.0) + rubocop-rails (2.7.1) + activesupport (>= 4.2.0) + rack (>= 1.1) + rubocop (>= 0.87.0) + ruby-progressbar (1.11.0) + ruby2_keywords (0.0.4) rubyzip (1.3.0) - safe_yaml (1.0.5) - safely_block (0.2.1) - errbase + safely_block (0.3.0) + errbase (>= 0.1.1) sanitize (4.6.6) crass (~> 1.0.2) nokogiri (>= 1.4.4) @@ -419,61 +402,50 @@ GEM sprockets (>= 2.8, < 4.0) sprockets-rails (>= 2.0, < 4.0) tilt (>= 1.1, < 3) - sassc (2.0.1) + sassc (2.4.0) ffi (~> 1.9) - rake - sdoc (1.0.0) + sdoc (2.0.3) rdoc (>= 5.0) - select2-rails (4.0.3) - thor (~> 0.14) - selenium-webdriver (3.142.4) - childprocess (>= 0.5, < 3.0) - rubyzip (~> 1.2, >= 1.2.2) + select2-rails (4.0.13) sentry-raven (0.15.6) faraday (>= 0.7.6) sprockets (3.7.2) concurrent-ruby (~> 1.0) rack (> 1, < 3) - sprockets-image_compressor (0.3.0) - sprockets - sprockets-rails (3.2.1) + sprockets-rails (3.2.2) actionpack (>= 4.0) activesupport (>= 4.0) sprockets (>= 3.0.0) terrapin (0.6.0) climate_control (>= 0.0.3, < 1.0) - thor (0.20.3) + thor (1.1.0) thread_safe (0.3.6) - tilt (2.0.9) - tzinfo (1.2.5) + tilt (2.0.10) + tzinfo (1.2.9) thread_safe (~> 0.1) - uglifier (4.1.20) + uglifier (4.2.0) execjs (>= 0.3.0, < 3) unf (0.1.4) unf_ext - unf_ext (0.0.7.6) - unicode-display_width (1.5.0) - user_agent_parser (2.6.0) - uuidtools (2.1.5) + unf_ext (0.0.7.7) + unicode-display_width (1.7.0) + user_agent_parser (2.7.0) + uuidtools (2.2.0) warden (1.2.4) rack (>= 1.0) - webdrivers (4.1.2) - nokogiri (~> 1.6) - rubyzip (~> 1.0) - selenium-webdriver (>= 3.0, < 4.0) - webmock (2.3.2) + webmock (3.11.2) addressable (>= 2.3.6) crack (>= 0.3.2) - hashdiff - webshims-rails (1.16.0) - rails (> 3.1.0) + hashdiff (>= 0.4.0, < 2.0.0) + webrick (1.7.0) websocket-driver (0.6.5) websocket-extensions (>= 0.1.0) - websocket-extensions (0.1.3) + websocket-extensions (0.1.5) whenever (0.11.0) chronic (>= 0.6.3) - will_paginate (3.1.7) - xmlrpc (0.3.0) + will_paginate (3.3.0) + xmlrpc (0.3.2) + webrick xpath (3.2.0) nokogiri (~> 1.8) @@ -482,10 +454,11 @@ PLATFORMS DEPENDENCIES activerecord-session_store (~> 1) - acts_as_paranoid! + acts_as_paranoid (< 0.7) ahoy_matey (~> 1.6) - aws-sdk (~> 2.3) - aws-sdk-rails (~> 1) + apparition (~> 0.6) + aws-sdk-rails (~> 2) + aws-sdk-s3 (~> 1) better_errors (~> 2) binding_of_caller (~> 0) bootstrap-daterangepicker-rails (~> 3) @@ -493,21 +466,19 @@ DEPENDENCIES bourbon (~> 3) bundler (>= 1.8.4) byebug - capybara (~> 3.26) + capybara (~> 3) chartkick (~> 3) cocoon (~> 1) counter_culture (~> 2.0) - cucumber-rails (= 1.6.0) daemons (~> 1) database_cleaner (~> 1) delayed_job_active_record (~> 4) - descriptive_statistics (~> 2) devise (~> 4.7) dotenv-rails (~> 2) eff_matomo (~> 0.2.4) ejs (~> 1) email_validator (~> 1) - factory_girl_rails (~> 4) + factory_bot_rails (~> 4) fast_inserter (~> 0.1) fastly (~> 2) fontello_rails_converter (~> 0) @@ -518,17 +489,16 @@ DEPENDENCIES http_accept_language (~> 2) invisible_captcha (~> 0) iso_country_codes (~> 0) - jbuilder (~> 1.2) + jbuilder (~> 2) + kt-paperclip (~> 6) nokogiri (~> 1) oauth (~> 0) - paperclip (~> 5.2) pg (~> 1.1) - pg_search - poltergeist (~> 1) + pg_search (< 2.3.1) premailer-rails (~> 1) puma (~> 3) rack-attack (~> 5) - rails (~> 5.0) + rails (~> 5.0.7) rails-assets-EpicEditor (~> 0)! rails-assets-chartjs (~> 2)! rails-assets-congress-images-102x125! @@ -545,7 +515,6 @@ DEPENDENCIES rails-assets-sweetalert (= 1.0.1)! rails-controller-testing rails-dev-tweaks (~> 1.1) - rails_12factor rails_response_headers (~> 0) rb-fchange (~> 0) rb-fsevent (~> 0) @@ -555,23 +524,21 @@ DEPENDENCIES rest-client (~> 2) rspec-core (~> 3) rspec-rails (~> 3) - rubocop (= 0.52.0) - rubocop-github (= 0.9.0) + rubocop + rubocop-github (~> 0.16) + rubocop-performance + rubocop-rails sanitize (~> 4) - sass-rails (~> 5.0) + sass-rails (< 5.1) sdoc select2-rails - selenium-webdriver (~> 3) sentry-raven (~> 0.15) - sprockets-image_compressor (~> 0) uglifier (>= 1.3.0) warden (= 1.2.4) - webdrivers (~> 4) - webmock (~> 2) - webshims-rails (~> 1) + webmock (~> 3) whenever (~> 0) will_paginate (~> 3.0) - xmlrpc + xmlrpc (~> 0.3) BUNDLED WITH - 2.0.1 + 2.1.4 diff --git a/Rakefile b/Rakefile index 506551c8a..4afe39994 100644 --- a/Rakefile +++ b/Rakefile @@ -1,14 +1,14 @@ # Add your own tasks in files placed in lib/tasks ending in .rake, # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake. -require File.expand_path("../config/application", __FILE__) +require File.expand_path("config/application", __dir__) Actioncenter::Application.load_tasks -if %w(development test).include? Rails.env +if %w[development test].include? Rails.env require "rubocop/rake_task" RuboCop::RakeTask.new task(:default).clear - task default: [:sass_lint, :rubocop, :spec, :cucumber] + task default: %i[sass_lint rubocop spec cucumber] end diff --git a/app/controllers/action_page_controller.rb b/app/controllers/action_page_controller.rb index 8daf812f5..fd6db0b6e 100644 --- a/app/controllers/action_page_controller.rb +++ b/app/controllers/action_page_controller.rb @@ -5,15 +5,15 @@ class ActionPageController < ApplicationController :protect_unpublished, :redirect_to_specified_url, :redirect_from_archived_to_active_action, - only: [:show, :show_by_institution, :embed_iframe, - :signature_count, :filter] + only: %i[show show_by_institution embed_iframe + signature_count filter] before_action :redirect_to_cannonical_slug, only: [:show] - before_action :set_institution, only: [:show_by_institution, :filter] - before_action :set_action_display_variables, only: [:show, - :show_by_institution, - :embed_iframe, - :signature_count, - :filter] + before_action :set_institution, only: %i[show_by_institution filter] + before_action :set_action_display_variables, only: %i[show + show_by_institution + embed_iframe + signature_count + filter] skip_before_action :verify_authenticity_token, only: :embed @@ -26,9 +26,9 @@ def show end def index - @actionPages = ActionPage.where(published: true, archived: false, victory: false). - paginate(page: params[:page], per_page: 9). - order(created_at: :desc) + @actionPages = ActionPage.where(published: true, archived: false, victory: false) + .paginate(page: params[:page], per_page: 9) + .order(created_at: :desc) @actionPages = @actionPages.categorized(params[:category]) if params[:category].present? @@ -51,8 +51,8 @@ def embed_iframe def signature_count @actionPage = ActionPage.friendly.find(params[:id]) - if petition = @actionPage.petition - render text: petition.signatures.count + if @actionPage.petition + render text: @actionPage.petition.signatures.count else render text: "0" end @@ -83,18 +83,14 @@ def protect_unpublished end def redirect_to_specified_url - if @actionPage.enable_redirect - redirect_to @actionPage.redirect_url, status: 301 - end + redirect_to @actionPage.redirect_url, status: 301 if @actionPage.enable_redirect end def redirect_from_archived_to_active_action - if @actionPage.redirect_from_archived_to_active_action? - # Users can access actions they've taken in the past as a historical record - unless current_user and (current_user.taken_action? @actionPage or current_user.admin?) - redirect_to @actionPage.active_action_page_for_redirect - end - end + return unless @actionPage.redirect_from_archived_to_active_action? + return if current_user&.can_view_archived?(@actionPage) + + redirect_to @actionPage.active_action_page_for_redirect end def redirect_to_cannonical_slug diff --git a/app/controllers/admin/action_pages_controller.rb b/app/controllers/admin/action_pages_controller.rb index 5045b8f7a..c6bbc3a1b 100644 --- a/app/controllers/admin/action_pages_controller.rb +++ b/app/controllers/admin/action_pages_controller.rb @@ -2,23 +2,23 @@ class Admin::ActionPagesController < Admin::ApplicationController include DateRange include ActionPageDisplay - before_action :set_action_page, only: [ - :edit, - :update, - :destroy, - :events, - :events_table, - :duplicate, - :preview, - :status, - :edit_partners + before_action :set_action_page, only: %i[ + edit + update + destroy + events + events_table + duplicate + preview + status + edit_partners ] - before_action :set_petition_targets, only: %i(new edit duplicate) - before_action :set_partners, only: %i(new edit duplicate) - before_action :set_source_files, only: %i(new edit create update duplicate) + before_action :set_petition_targets, only: %i[new edit duplicate] + before_action :set_partners, only: %i[new edit duplicate] + before_action :set_source_files, only: %i[new edit create update duplicate] - after_action :purge_cache, only: [:update, :publish] + after_action :purge_cache, only: %i[update publish] allow_collaborators_to :index, :edit @@ -27,9 +27,7 @@ def index @authors = User.authors.order(:last_name) @actionPages = filter_action_pages - if request.xhr? - render partial: "admin/action_pages/index" - end + render partial: "admin/action_pages/index" if request.xhr? end def new @@ -64,13 +62,10 @@ def edit @actionPage.email_campaign ||= EmailCampaign.new @actionPage.congress_message_campaign ||= CongressMessageCampaign.new 10.times { @actionPage.affiliation_types.build } - if @actionPage.enable_petition && @actionPage.petition.enable_affiliations - @target_category = @actionPage.institutions.first.category - end + @target_category = @actionPage.institutions.first.category if @actionPage.enable_petition && @actionPage.petition.enable_affiliations end - def status - end + def status; end def edit_partners @partners = Partner.order(name: :desc) @@ -81,9 +76,9 @@ def update @actionPage.featured_image = nil if params[:destroy_featured_image] @actionPage.og_image = nil if params[:destroy_og_image] - @actionPage.update_attributes(action_page_params) + @actionPage.update(action_page_params) if (institutions_params[:reset] && institutions_params[:reset] == "1") || - (institutions_params[:category] && @actionPage.institutions.empty?) + (institutions_params[:category] && @actionPage.institutions.empty?) ActionInstitution.add(action_page: @actionPage, **institutions_params.to_h.symbolize_keys) end @@ -96,12 +91,11 @@ def destroy redirect_to admin_action_pages_path, notice: "Deleted action page: #{@actionPage.title}" end - def preview @actionPage.attributes = action_page_params if @actionPage.enable_redirect - redirect_to @actionPage.redirect_url, status: 301 + redirect_to @actionPage.redirect_url, status: 301 return end @@ -132,9 +126,9 @@ def events end format.json do render json: @events.chart_data( - type: params[:type], - range: @start_date..@end_date - ) + type: params[:type], + range: @start_date..@end_date + ) end end end @@ -144,9 +138,7 @@ def events_table @events = @actionPage.events.in_range(@start_date, @end_date) @counts = @events.table_data @summary = @events.summary - if @actionPage.enable_congress_message? - @fills = @actionPage.congress_message_campaign.date_fills(@start_date, @end_date) - end + @fills = @actionPage.congress_message_campaign.date_fills(@start_date, @end_date) if @actionPage.enable_congress_message? end def homepage @@ -189,19 +181,19 @@ def action_page_params :call_campaign_id, :what_to_say, :redirect_url, :email_text, :enable_redirect, :victory, :victory_message, :archived_redirect_action_page_id, :archived, :status, partner_ids: [], - action_page_images_attributes: [:id, :action_page_image], - call_campaign_attributes: [:id, :title, :message, :call_campaign_id], - petition_attributes: [:id, :title, :description, :goal, :enable_affiliations], - affiliation_types_attributes: [:id, :name], + action_page_images_attributes: %i[id action_page_image], + call_campaign_attributes: %i[id title message call_campaign_id], + petition_attributes: %i[id title description goal enable_affiliations], + affiliation_types_attributes: %i[id name], tweet_attributes: [ :id, :target, :target_house, :target_senate, :message, :cta, :bioguide_id, - tweet_targets_attributes: [:id, :_destroy, :twitter_id, :image] + { tweet_targets_attributes: %i[id _destroy twitter_id image] } ], - email_campaign_attributes: [ - :id, :message, :subject, :target_house, :target_senate, :target_email, - :email_addresses, :target_bioguide_id, :bioguide_id, :alt_text_email_your_rep, - :alt_text_look_up_your_rep, :alt_text_extra_fields_explain, :topic_category_id, - :alt_text_look_up_helper, :alt_text_customize_message_helper, :campaign_tag + email_campaign_attributes: %i[ + id message subject target_house target_senate target_email + email_addresses target_bioguide_id bioguide_id alt_text_email_your_rep + alt_text_look_up_your_rep alt_text_extra_fields_explain topic_category_id + alt_text_look_up_helper alt_text_customize_message_helper campaign_tag ], congress_message_campaign_attributes: [ :id, :message, :subject, :target_house, :target_senate, { target_bioguide_list: [] }, @@ -210,18 +202,19 @@ def action_page_params :alt_text_customize_message_helper, :campaign_tag, :enable_customization_notice ], - partnerships_attributes: [:id, :enable_mailings] + partnerships_attributes: %i[id enable_mailings] ) end def institutions_params - return {} unless params.has_key? :institutions - params.require(:institutions).permit(%i(category reset)) + return {} unless params.key? :institutions + + params.require(:institutions).permit(%i[category reset]) end def filter_params params.permit(:q, :date_range, :utf8, - action_filters: %i(type status author category)) + action_filters: %i[type status author category]) end def purge_cache diff --git a/app/controllers/admin/application_controller.rb b/app/controllers/admin/application_controller.rb index 3eedde808..fee652024 100644 --- a/app/controllers/admin/application_controller.rb +++ b/app/controllers/admin/application_controller.rb @@ -6,25 +6,19 @@ def manifest self.class.manifest || "admin" end - protected - + # FLAG_AS_UNUSED def self.allow_collaborators_to(*actions) skip_before_action :must_be_admin, only: actions before_action :must_be_admin_or_collaborator, only: actions end def must_be_admin - unless user_signed_in? && current_user.admin? - raise ActiveRecord::RecordNotFound - end + raise ActiveRecord::RecordNotFound unless user_signed_in? && current_user.admin? end def must_be_admin_or_collaborator - unless user_signed_in? && (current_user.admin? || current_user.collaborator?) - raise ActiveRecord::RecordNotFound - end + raise ActiveRecord::RecordNotFound unless user_signed_in? && (current_user.admin? || current_user.collaborator?) end - def images - end + def images; end end diff --git a/app/controllers/admin/congress_message_campaigns_controller.rb b/app/controllers/admin/congress_message_campaigns_controller.rb index 492ac7fd0..78360652d 100644 --- a/app/controllers/admin/congress_message_campaigns_controller.rb +++ b/app/controllers/admin/congress_message_campaigns_controller.rb @@ -3,8 +3,7 @@ class Admin::CongressMessageCampaignsController < Admin::ApplicationController allow_collaborators_to :congress_tabulation, :staffer_report - def congress_tabulation - end + def congress_tabulation; end def staffer_report @bioguide_id = params[:bioguide_id] diff --git a/app/controllers/admin/events_controller.rb b/app/controllers/admin/events_controller.rb index 3bd605300..97b29d105 100644 --- a/app/controllers/admin/events_controller.rb +++ b/app/controllers/admin/events_controller.rb @@ -6,12 +6,12 @@ def index @events = Ahoy::Event.all.in_range(@start_date, @end_date) respond_to do |format| format.html { @summary = @events.summary } - format.json { + format.json do render json: @events.chart_data( - type: params[:type], - range: @start_date..@end_date - ) - } + type: params[:type], + range: @start_date..@end_date + ) + end end end end diff --git a/app/controllers/admin/images_controller.rb b/app/controllers/admin/images_controller.rb index d89edf4a7..774771fc9 100644 --- a/app/controllers/admin/images_controller.rb +++ b/app/controllers/admin/images_controller.rb @@ -1,4 +1,3 @@ class Admin::ImagesController < Admin::ApplicationController - def index - end + def index; end end diff --git a/app/controllers/admin/institutions_controller.rb b/app/controllers/admin/institutions_controller.rb index 6b6c0a563..924f8a656 100644 --- a/app/controllers/admin/institutions_controller.rb +++ b/app/controllers/admin/institutions_controller.rb @@ -1,13 +1,11 @@ class Admin::InstitutionsController < Admin::ApplicationController - before_action :set_institution, only: %i(destroy edit update) - before_action :set_categories, only: %i(new edit upload index) + before_action :set_institution, only: %i[destroy edit update] + before_action :set_categories, only: %i[new edit upload index] def index @institutions = Institution.includes(:action_pages).all.order(created_at: :desc) @institutions = @institutions.search(params[:q]) if params[:q].present? - if params[:category].present? && params[:category] != "All" - @institutions = @institutions.where(category: params[:category]) - end + @institutions = @institutions.where(category: params[:category]) if params[:category].present? && params[:category] != "All" @institutions = @institutions.paginate(page: params[:page], per_page: 20) end @@ -42,11 +40,7 @@ def import if names.empty? redirect_to action: "upload", notice: "Import failed. Please check CSV formatting" else - category = if import_params[:new_category].blank? - import_params[:category] - else - import_params[:new_category] - end + category = import_params[:new_category].presence || import_params[:category] Institution.delay.import(category, names) redirect_to action: "index", notice: "Successfully imported #{names.length} targets" end diff --git a/app/controllers/admin/partners_controller.rb b/app/controllers/admin/partners_controller.rb index d3bb7080b..3fce9ce28 100644 --- a/app/controllers/admin/partners_controller.rb +++ b/app/controllers/admin/partners_controller.rb @@ -1,7 +1,7 @@ class Admin::PartnersController < Admin::ApplicationController layout "admin" - before_action :set_partner, only: %i(edit update show destroy) + before_action :set_partner, only: %i[edit update show destroy] # GET /partners # GET /partners.json @@ -22,16 +22,15 @@ def create respond_to do |format| if @partner.save format.html { redirect_to @partner, notice: "Partner was successfully created." } - format.json { render "show", status: :created, location: @partner } + format.json { render "show", status: 201, location: @partner } else format.html { render "new" } - format.json { render json: @partner.errors, status: :unprocessable_entity } + format.json { render json: @partner.errors, status: 422 } end end end - def edit - end + def edit; end def update if @partner.update(partner_params) diff --git a/app/controllers/admin/petitions_controller.rb b/app/controllers/admin/petitions_controller.rb index 331e767dd..1fde4420d 100644 --- a/app/controllers/admin/petitions_controller.rb +++ b/app/controllers/admin/petitions_controller.rb @@ -1,5 +1,5 @@ -include PetitionHelper class Admin::PetitionsController < Admin::ApplicationController + include PetitionHelper before_action :set_petition allow_collaborators_to :show, :destroy_signatures @@ -25,8 +25,8 @@ def affiliation_csv signatures = @petition.signatures if params[:institution_id].present? - signatures = signatures.joins(affiliations: :institution). - where(institutions: { id: params[:institution_id] }) + signatures = signatures.joins(affiliations: :institution) + .where(institutions: { id: params[:institution_id] }) end send_data signatures.to_affiliation_csv, @@ -36,9 +36,7 @@ def affiliation_csv def destroy_signatures @petition.signatures.where(id: params[:signature_ids]).delete_all - if params[:page].to_i > filtered_signatures.total_pages - params[:page] = filtered_signatures.total_pages - end + params[:page] = filtered_signatures.total_pages if params[:page].to_i > filtered_signatures.total_pages redirect_to admin_action_page_petition_path(@petition.action_page, @petition, search_params) @@ -51,10 +49,10 @@ def set_petition end def filtered_signatures - @petition.signatures. - filter(params[:query]). - order(created_at: :desc). - paginate(page: params[:page], per_page: params[:per_page] || 10) + @petition.signatures + .search(params[:query]) + .order(created_at: :desc) + .paginate(page: params[:page], per_page: params[:per_page] || 10) end def search_params diff --git a/app/controllers/admin/s3_uploads_controller.rb b/app/controllers/admin/s3_uploads_controller.rb index 78bca4f4b..5e80050c1 100644 --- a/app/controllers/admin/s3_uploads_controller.rb +++ b/app/controllers/admin/s3_uploads_controller.rb @@ -2,11 +2,11 @@ class Admin::S3UploadsController < Admin::ApplicationController # GET /admin/source_files # GET /admin/source_files.json def index - if params[:f].present? - source_files = SourceFile.where("LOWER(file_name) LIKE ?", "%#{params[:f]}%".downcase) - else - source_files = SourceFile.limit(3) - end + source_files = if params[:f].present? + SourceFile.where("LOWER(file_name) LIKE ?", "%#{params[:f]}%".downcase) + else + SourceFile.limit(3) + end source_files = source_files.order(created_at: :desc) @@ -22,15 +22,15 @@ def create @source_file = SourceFile.new(parameters) respond_to do |format| if @source_file.save - format.html { + format.html do render json: @source_file.to_jq_upload, - content_type: "text/html", - layout: false - } - format.json { render json: @source_file.to_jq_upload, status: :created } + content_type: "text/html", + layout: false + end + format.json { render json: @source_file.to_jq_upload, status: 201 } else format.html { render "new" } - format.json { render json: @source_file.errors, status: :unprocessable_entity } + format.json { render json: @source_file.errors, status: 422 } end end end @@ -52,7 +52,7 @@ def destroy # for /admin/action_page/new # GET /admin/source_files/generate_key def generate_key - uid = SecureRandom.uuid.gsub(/-/, "") + uid = SecureRandom.uuid.delete("-") render json: { key: "uploads/#{uid}/#{params[:filename]}", diff --git a/app/controllers/admin/topic_categories_controller.rb b/app/controllers/admin/topic_categories_controller.rb index 7242e9818..e33b3883f 100644 --- a/app/controllers/admin/topic_categories_controller.rb +++ b/app/controllers/admin/topic_categories_controller.rb @@ -14,18 +14,16 @@ def create end def destroy - begin - TopicCategory.destroy(params[:id]) - render json: { id: params[:id] } - rescue => e - render text: e.message, status: 500 - end + TopicCategory.destroy(params[:id]) + render json: { id: params[:id] } + rescue StandardError => e + render text: e.message, status: 500 end def update topic_category = TopicCategory.find(params[:id]) - if topic_category.update_attributes(topic_category_params) + if topic_category.update(topic_category_params) render json: topic_category else render json: topic_category.errors, status: 500 diff --git a/app/controllers/admin/topic_sets_controller.rb b/app/controllers/admin/topic_sets_controller.rb index 6ca7cb6db..c3c7fca41 100644 --- a/app/controllers/admin/topic_sets_controller.rb +++ b/app/controllers/admin/topic_sets_controller.rb @@ -5,12 +5,10 @@ def index end def destroy - begin - TopicSet.destroy(params[:id]) - render json: { id: params[:id] } - rescue => e - render text: e.message, status: 500 - end + TopicSet.destroy(params[:id]) + render json: { id: params[:id] } + rescue StandardError => e + render text: e.message, status: 500 end def create @@ -28,7 +26,7 @@ def create def update topic_set = TopicSet.find(params[:id]) - if topic_set.update_attributes(topic_set_params) + if topic_set.update(topic_set_params) render json: topic_set else render json: topic_set.errors, status: 500 diff --git a/app/controllers/admin/topics_controller.rb b/app/controllers/admin/topics_controller.rb index a635cbb3f..1c3c4f7b1 100644 --- a/app/controllers/admin/topics_controller.rb +++ b/app/controllers/admin/topics_controller.rb @@ -2,12 +2,10 @@ class Admin::TopicsController < Admin::ApplicationController layout "admin" def destroy - begin - Topic.destroy(params[:id]) - render json: { id: params[:id] } - rescue => e - render text: e.message, status: 500 - end + Topic.destroy(params[:id]) + render json: { id: params[:id] } + rescue StandardError => e + render text: e.message, status: 500 end def create diff --git a/app/controllers/admin/users_controller.rb b/app/controllers/admin/users_controller.rb index eb37ff0bb..38453b79f 100644 --- a/app/controllers/admin/users_controller.rb +++ b/app/controllers/admin/users_controller.rb @@ -6,7 +6,7 @@ def index def update user = User.find(params[:id]) - if user.update_attributes(user_params) + if user.update(user_params) flash[:notice] = "#{user.email} was updated" else flash[:error] = "Could not update #{user.email}" diff --git a/app/controllers/ahoy_controller.rb b/app/controllers/ahoy_controller.rb index 83a56264c..24676ba15 100644 --- a/app/controllers/ahoy_controller.rb +++ b/app/controllers/ahoy_controller.rb @@ -8,8 +8,8 @@ def visit action_page_id = params.require(:action_page_id) ahoy.track "View", - { type: "action", actionType: action_type, actionPageId: action_page_id }, - action_page_id: action_page_id + { type: "action", actionType: action_type, actionPageId: action_page_id }, + action_page_id: action_page_id send_data image_asset, content_type: "image/gif" end diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 0c4c4f5c2..c0a057e3b 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -16,18 +16,14 @@ class ApplicationController < ActionController::Base skip_before_action :set_ahoy_request_store def user_conditional_logic - if user_signed_in? - lock_users_with_expired_passwords! unless user_is_being_told_to_reset_pass_or_is_resetting_pass? - end + lock_users_with_expired_passwords! if user_signed_in? && !user_is_being_told_to_reset_pass_or_is_resetting_pass? end # This method seems to check if the request is coming from a domain listed in # `cors_allowed_domains` in application.yml, and if it is, the response gets # a header allowing the requesting domain to use this app's CRUD def cors - if Actioncenter::Application.config.cors_allowed_domains.include? request.env["HTTP_ORIGIN"] or Actioncenter::Application.config.cors_allowed_domains.include? "*" - response.headers["Access-Control-Allow-Origin"] = request.env["HTTP_ORIGIN"] - end + response.headers["Access-Control-Allow-Origin"] = request.env["HTTP_ORIGIN"] if Actioncenter::Application.config.cors_allowed_domains.include?(request.env["HTTP_ORIGIN"]) || Actioncenter::Application.config.cors_allowed_domains.include?("*") end def self.manifest(value = nil) @@ -60,7 +56,7 @@ def user_is_being_told_to_reset_pass_or_is_resetting_pass? def configure_permitted_parameters devise_parameter_sanitizer.permit(:sign_up, - keys: [:record_activity, :subscribe]) + keys: %i[record_activity subscribe]) end def set_locale diff --git a/app/controllers/concerns/action_page_display.rb b/app/controllers/concerns/action_page_display.rb index f31507472..4c842bd2a 100644 --- a/app/controllers/concerns/action_page_display.rb +++ b/app/controllers/concerns/action_page_display.rb @@ -11,22 +11,20 @@ def set_action_display_variables @congress_message_campaign = @actionPage.congress_message_campaign # Shows a mailing list if no tools enabled - @no_tools = [:tweet, :petition, :call, :email, :congress_message].none? do |tool| + @no_tools = %i[tweet petition call email congress_message].none? do |tool| @actionPage.send "enable_#{tool}".to_sym end set_signatures - if @actionPage.petition and @actionPage.petition.enable_affiliations + if @actionPage.petition&.enable_affiliations @top_institutions = @actionPage.institutions.top(300, first: @institution.try(:id)) @institutions = @actionPage.institutions.order(:name) @institution_category = @institutions.first.category end @topic_category = nil - if @email_campaign and !@email_campaign.topic_category.nil? - @topic_category = @email_campaign.topic_category.as_2d_array - end + @topic_category = @email_campaign.topic_category.as_2d_array if @email_campaign && !@email_campaign.topic_category.nil? # Initialize a temporary signature object for form auto-population current_zipcode = params[:zipcode] || current_user.try(:zipcode) @@ -53,18 +51,17 @@ def set_signatures @institution_signature_count = @signatures.pretty_count elsif @petition.enable_affiliations @signatures = @petition.signatures - .includes(affiliations: [:institution, :affiliation_type]) + .includes(affiliations: %i[institution affiliation_type]) else @signatures = @petition.signatures end @signatures = @signatures - .paginate(page: params[:page], per_page: 9) - .order(created_at: :desc) + .paginate(page: params[:page], per_page: 9) + .order(created_at: :desc) @signature_count = @petition.signatures.pretty_count @require_location = !@petition.enable_affiliations end end - end diff --git a/app/controllers/concerns/date_range.rb b/app/controllers/concerns/date_range.rb index ccefc3f4f..eae82f3f3 100644 --- a/app/controllers/concerns/date_range.rb +++ b/app/controllers/concerns/date_range.rb @@ -7,10 +7,9 @@ def set_dates def process_dates(date_range_text: nil, date_text: nil, **_) return parse_date_range(date_range_text) if date_range_text.present? - return [1.month.ago, Time.zone.now] unless date_text.present? - if date_text == "Action lifetime" && @actionPage.present? - return [@actionPage.created_at, Time.zone.now] - end + return [1.month.ago, Time.zone.now] if date_text.blank? + return [@actionPage.created_at, Time.zone.now] if date_text == "Action lifetime" && @actionPage.present? + [parse_time_ago(date_text), Time.zone.now] end @@ -21,12 +20,14 @@ def parse_date_range(date_range_string) # Convert Last X (days|weeks|months) to a time def parse_time_ago(string) _, count, unit = string.split(" ") - return Time.zone.now - 1.month unless %w(days weeks months years).include? unit + return Time.zone.now - 1.month unless %w[days weeks months years].include? unit + Time.zone.now - count.to_i.send(unit) end def date_range_string return "" unless @start_date && @end_date + format = "%Y-%m-%d" "#{@start_date.strftime(format)} - #{@end_date.strftime(format)}" end diff --git a/app/controllers/concerns/tooling.rb b/app/controllers/concerns/tooling.rb index e7b0cbef3..cd4cf7040 100644 --- a/app/controllers/concerns/tooling.rb +++ b/app/controllers/concerns/tooling.rb @@ -5,6 +5,7 @@ module Tooling def create_partner_subscription return unless @action_page + @action_page.partners.each do |partner| if params["#{partner.code}_subscribe"] == "1" Subscription.create(partner_signup_params.merge(partner: partner)) @@ -14,8 +15,6 @@ def create_partner_subscription def deliver_thanks_message @email ||= current_user.try(:email) || params[:email] || params.dig(:subscription, :email) - if @email.present? - UserMailer.thanks_message(@email, @action_page, user: @user, name: @name).deliver_now - end + UserMailer.thanks_message(@email, @action_page, user: @user, name: @name).deliver_now if @email.present? end end diff --git a/app/controllers/congress_messages_controller.rb b/app/controllers/congress_messages_controller.rb index 0bc6ab8aa..6b8976753 100644 --- a/app/controllers/congress_messages_controller.rb +++ b/app/controllers/congress_messages_controller.rb @@ -22,7 +22,7 @@ def new end forms, @links = CongressForms::Form.find(bioguide_ids) @defunct_members, @members = @members.partition do |m| - @links.keys.include? m.bioguide_id + @links.key?(m.bioguide_id) end @message = CongressMessage.new_from_lookup(location, @campaign, forms) render partial: "form" @@ -37,16 +37,16 @@ def create else params[:forms][:bioguide_ids] end - @message.forms, _ = CongressForms::Form.find(bioguide_ids) + @message.forms, = CongressForms::Form.find(bioguide_ids) - if EmailValidator.valid?(user_params[:email]) && @message.background_submit(params[:test]) + if EmailValidator.valid?(user_params[:email]) && @message.background_submit(test: params[:test]) @name = user_params[:first_name] # for deliver_thanks_message @email = user_params[:email] # for deliver_thanks_message track_action unless params[:test] deliver_thanks_message unless subscribe_user render partial: "tools/share" else - render plain: I18n.t(:invalid_submission, scope: :congress_forms), status: :bad_request + render plain: I18n.t(:invalid_submission, scope: :congress_forms), status: 400 end end @@ -84,35 +84,33 @@ def partner_signup_params end def update_user - if params[:update_user_data] == "yes" - current_user.update(user_params.except(:email)) - end + current_user.update(user_params.except(:email)) if params[:update_user_data] == "yes" end def subscribe_user create_partner_subscription if params[:subscribe] == "1" - source = "action center congress message :: " + @action_page.title + source = "action center congress message :: #{@action_page.title}" user = User.find_or_initialize_by(email: user_params[:email]) user.attributes = user_params - user.subscribe!(opt_in = false, source = source)["requires_confirmation"] + user.subscribe!(opt_in: false, source: source)["requires_confirmation"] end end def track_action customized_message = params[:message] != @campaign.message ahoy.track "Action", - { type: "action", actionType: "congress_message", actionPageId: params[:action_id], - customizedMessage: customized_message }, - action_page: @action_page + { type: "action", actionType: "congress_message", actionPageId: params[:action_id], + customizedMessage: customized_message }, + action_page: @action_page end def address_not_found - render plain: I18n.t(:address_lookup_failed, scope: :congress_forms), status: :bad_request + render plain: I18n.t(:address_lookup_failed, scope: :congress_forms), status: 400 end def congress_forms_request_failed - render plain: I18n.t(:request_failed, scope: :congress_forms), status: :internal_server_error + render plain: I18n.t(:request_failed, scope: :congress_forms), status: 500 end end diff --git a/app/controllers/partners_controller.rb b/app/controllers/partners_controller.rb index 515f87f8b..ccb77b04d 100644 --- a/app/controllers/partners_controller.rb +++ b/app/controllers/partners_controller.rb @@ -6,9 +6,9 @@ class PartnersController < ApplicationController # GET /partners/1 # GET /partners/1.json def show - @subscriptions = @partner.subscriptions. - paginate(page: params[:page], per_page: 10). - order("id desc") + @subscriptions = @partner.subscriptions + .paginate(page: params[:page], per_page: 10) + .order("id desc") end def csv @@ -24,24 +24,22 @@ def update format.json { head :no_content } else format.html { render "edit" } - format.json { render json: @partner.errors, status: :unprocessable_entity } + format.json { render json: @partner.errors, status: 422 } end end end def add_user - user = User.find_by_email(params[:email]) + user = User.find_by(email: params[:email]) if user.nil? flash[:notice] = "Couldn't find a user by email #{params[:email]}" + elsif user.partner == @partner + flash[:notice] = "That user is already linked to #{@partner.name}" + elsif user.partner.nil? + user.partner = @partner + user.save else - if user.partner.nil? - user.partner = @partner - user.save - elsif user.partner == @partner - flash[:notice] = "That user is already linked to #{@partner.name}" - else - flash[:notice] = "That user is linked to another partner: #{user.partner.name}" - end + flash[:notice] = "That user is linked to another partner: #{user.partner.name}" end redirect_to @partner end @@ -66,9 +64,7 @@ def set_partner def authenticate authenticate_user! - unless current_user.admin? - raise ActiveRecord::RecordNotFound if current_user.partner != @partner - end + raise ActiveRecord::RecordNotFound if !current_user.admin? && (current_user.partner != @partner) end # Never trust parameters from the scary internet, only allow the white list through. diff --git a/app/controllers/registrations_controller.rb b/app/controllers/registrations_controller.rb index 1254ffa85..e2a0f2dba 100644 --- a/app/controllers/registrations_controller.rb +++ b/app/controllers/registrations_controller.rb @@ -24,16 +24,16 @@ def handle_nonunique_email resource.errors.delete(:email) if resource.errors.empty? - existing = User.find_by_email(resource.email) + existing = User.find_by(email: resource.email) existing.send_email_taken_notice # Allow unconfirmed users to set a new password by re-registering. - if !existing.confirmed? - existing.update_attributes(sign_up_params) - end + existing.update(sign_up_params) unless existing.confirmed? if resource.persisted? + # rubocop:todo Rails/SkipsModelValidations resource.update_attribute(:unconfirmed_email, account_update_params[:email]) + # rubocop:enable Rails/SkipsModelValidations flash[:notice] = I18n.t "devise.registrations.update_needs_confirmation" respond_with resource, location: after_update_path_for(resource) else diff --git a/app/controllers/robots_controller.rb b/app/controllers/robots_controller.rb index be90d584c..b50b571d3 100644 --- a/app/controllers/robots_controller.rb +++ b/app/controllers/robots_controller.rb @@ -1,6 +1,6 @@ class RobotsController < ApplicationController def show - if Rails.env.development? or Rails.application.secrets.enable_basic_auth == "true" + if Rails.env.development? || (Rails.application.secrets.enable_basic_auth == "true") render text: "User-agent: *\nDisallow: /" else render text: "" diff --git a/app/controllers/sessions_controller.rb b/app/controllers/sessions_controller.rb index c86631eb7..e2f0fc452 100644 --- a/app/controllers/sessions_controller.rb +++ b/app/controllers/sessions_controller.rb @@ -3,7 +3,7 @@ class SessionsController < Devise::SessionsController before_action :unset_logged_in, only: :destroy def set_logged_in - if (user_signed_in?) + if user_signed_in? # Sets a "permanent" cookie (which expires in 20 years from now). # This is exclusively used to never cache content for logged in users cookies.permanent[:logged_in] = "I <3 EFF" diff --git a/app/controllers/smarty_streets_controller.rb b/app/controllers/smarty_streets_controller.rb index 3377aed18..de6fcda85 100644 --- a/app/controllers/smarty_streets_controller.rb +++ b/app/controllers/smarty_streets_controller.rb @@ -38,10 +38,8 @@ def authorize_query(params) end def proxy_request(url) - begin - return RestClient.get url, accept: :json, 'X-Include-Invalid': "true" - rescue => e - logger.error e - end + RestClient.get url, accept: :json, 'X-Include-Invalid': "true" + rescue StandardError => e + logger.error e end end diff --git a/app/controllers/sns_controller.rb b/app/controllers/sns_controller.rb index 00eb8ffb5..191704e3c 100644 --- a/app/controllers/sns_controller.rb +++ b/app/controllers/sns_controller.rb @@ -40,7 +40,7 @@ def set_context def set_message body = JSON.parse(request.body.read) - return JSON.parse(body["Message"]) + JSON.parse(body["Message"]) end def log_request diff --git a/app/controllers/subscriptions_controller.rb b/app/controllers/subscriptions_controller.rb index 95dcbe585..5ed80bdd6 100644 --- a/app/controllers/subscriptions_controller.rb +++ b/app/controllers/subscriptions_controller.rb @@ -9,14 +9,14 @@ class SubscriptionsController < ApplicationController def create email = params[:subscription][:email] - if !EmailValidator.valid?(email) + unless EmailValidator.valid?(email) render json: { message: "Bad news, something went wrong with your email address. Please check it for typos and try again." }, status: 400 return end update_user_data(email: email) params[:subscription][:opt_in] = params[:subscription][:opt_in] || false - subscription = CiviCRM::subscribe params[:subscription] + subscription = CiviCRM.subscribe params[:subscription] if subscription["error"] render json: { message: subscription["error_message"] }, status: 500 else diff --git a/app/controllers/tools_controller.rb b/app/controllers/tools_controller.rb index d5fe9158d..a0faec35a 100644 --- a/app/controllers/tools_controller.rb +++ b/app/controllers/tools_controller.rb @@ -10,10 +10,10 @@ class ToolsController < ApplicationController # Put an invisible captcha on forms are easy to submit programmatically and # create email subscriptions. - invisible_captcha only: [:email, :petition] - before_action :create_newsletter_subscription, only: [:email, :call] - before_action :create_partner_subscription, only: [:email, :call, :petition, :message_congress] - after_action :deliver_thanks_message, only: [:email, :call, :petition, :message_congress] + invisible_captcha only: %i[email petition] + before_action :create_newsletter_subscription, only: %i[email call] + before_action :create_partner_subscription, only: %i[email call petition message_congress] + after_action :deliver_thanks_message, only: %i[email call petition message_congress] skip_after_action :deliver_thanks_message, if: :signature_has_errors # See https://github.com/EFForg/action-center-platform/wiki/Deployment-Notes#csrf-protection @@ -22,14 +22,12 @@ class ToolsController < ApplicationController def call ahoy.track "Action", - { type: "action", actionType: "call", actionPageId: params[:action_id] }, - action_page: @action_page + { type: "action", actionType: "call", actionPageId: params[:action_id] }, + action_page: @action_page @name = current_user.try :name - if params[:update_user_data] == "yes" - update_user_data(call_params) - end + update_user_data(call_params) if params[:update_user_data] == "yes" CallTool.campaign_call(params[:call_campaign_id], phone: params[:phone], @@ -56,12 +54,11 @@ def petition @action_page = Petition.find(params[:signature][:petition_id]).action_page @signature = Signature.new(signature_params.merge(user_id: @user.id)) - if @signature.zipcode.present? && @signature.country_code.blank? - @signature.country_code = "US" - end + @signature.country_code = "US" if @signature.zipcode.present? && @signature.country_code.blank? if @signature.country_code == "US" && !Rails.application.secrets.smarty_streets_id.nil? - if city_state = SmartyStreets.get_city_state(@signature.zipcode) + city_state = SmartyStreets.get_city_state(@signature.zipcode) + if city_state @signature.city = city_state["city"] @signature.state = city_state["state"] end @@ -76,28 +73,24 @@ def petition :zipcode, :country_code, :phone ) - @source = "action center petition :: " + @action_page.title - @user.subscribe!(opt_in = true, source = @source) + @source = "action center petition :: #{@action_page.title}" + @user.subscribe!(opt_in: true, source: @source) end - if params[:update_user_data] - update_user_data(signature_params) - end + update_user_data(signature_params) if params[:update_user_data] ahoy.track "Action", - { type: "action", actionType: "signature", actionPageId: @action_page.id }, - action_page: @action_page + { type: "action", actionType: "signature", actionPageId: @action_page.id }, + action_page: @action_page respond_to do |format| format.json { render json: { success: true }, status: 200 } format.html do - begin - url = URI.parse(request.referrer) - url.query = [url.query.presence, "thankyou=1"].join("&") - redirect_to url.to_s - rescue - redirect_to welcome_index_path - end + url = URI.parse(request.referrer) + url.query = [url.query.presence, "thankyou=1"].join("&") + redirect_to url.to_s + rescue StandardError + redirect_to welcome_index_path end end else @@ -107,16 +100,16 @@ def petition def tweet ahoy.track "Action", - { type: "action", actionType: "tweet", actionPageId: params[:action_id] }, - action_page: @action_page + { type: "action", actionType: "tweet", actionPageId: params[:action_id] }, + action_page: @action_page render json: { success: true }, status: 200 end def email - unless (@user and @user.events.emails.find_by_action_page_id(params[:action_id])) or params[:dnt] == "true" + unless (@user && @user.events.emails.find_by(action_page_id: params[:action_id])) || (params[:dnt] == "true") ahoy.track "Action", - { type: "action", actionType: "email", actionPageId: params[:action_id] }, - action_page: @action_page + { type: "action", actionType: "email", actionPageId: params[:action_id] }, + action_page: @action_page end if params[:service] == "copy" @@ -161,16 +154,18 @@ def set_user @user = current_user end + # rubocop:todo Naming/MemoizedInstanceVariableName def set_action_page - @action_page ||= ActionPage.find_by_id(params[:action_id]) + @action_page ||= ActionPage.find_by(id: params[:action_id]) end + # rubocop:enable Naming/MemoizedInstanceVariableName def create_newsletter_subscription if params[:subscribe] && EmailValidator.valid?(params[:subscription][:email]) source = "action center #{@action_page.class.name.downcase} :: " + @action_page.title params[:subscription][:opt_in] = true params[:subscription][:source] = source - CiviCRM::subscribe params[:subscription] + CiviCRM.subscribe params[:subscription] end end @@ -179,9 +174,9 @@ def signature_has_errors end def partner_signup_params - attributes = %i(first_name last_name email) + attributes = %i[first_name last_name email] # Partner signup params might come through the main form or a nested subscription form. - %i(signature subscription).each do |model| + %i[signature subscription].each do |model| return params.require(model).permit(*attributes) if params[model].present? end params.permit(*attributes) @@ -191,8 +186,8 @@ def signature_params params.require(:signature).permit( :first_name, :last_name, :email, :petition_id, :user_id, :street_address, :city, :state, :country_code, :zipcode, :anonymous, - affiliations_attributes: [ - :id, :institution_id, :affiliation_type_id + affiliations_attributes: %i[ + id institution_id affiliation_type_id ] ) end diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index 38f7c87f2..4f1a3b3d1 100644 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -7,11 +7,11 @@ def show end def update - if current_user.update_attributes(user_params) - flash[:notice] = "You updated your account successfully." - else - flash[:notice] = "Could not update your account." - end + flash[:notice] = if current_user.update(user_params) + "You updated your account successfully." + else + "Could not update your account." + end if request.xhr? render json: {}, status: 200 @@ -21,7 +21,9 @@ def update end def clear_activity + # rubocop:todo Rails/SkipsModelValidations current_user.events.update_all(user_id: nil) + # rubocop:enable Rails/SkipsModelValidations redirect_to user_path end diff --git a/app/controllers/welcome_controller.rb b/app/controllers/welcome_controller.rb index 8e018e532..269572d32 100644 --- a/app/controllers/welcome_controller.rb +++ b/app/controllers/welcome_controller.rb @@ -1,10 +1,10 @@ class WelcomeController < ApplicationController manifest :welcome def index - @actionPages = FeaturedActionPage.includes(:action_page). - order("weight desc"). - map(&:action_page). - compact + @actionPages = FeaturedActionPage.includes(:action_page) + .order("weight desc") + .map(&:action_page) + .compact @featuredActionPage = @actionPages.pop @actionPages = @actionPages.reverse end diff --git a/app/helpers/action_page_helper.rb b/app/helpers/action_page_helper.rb index 1e78245f3..aba5e4848 100644 --- a/app/helpers/action_page_helper.rb +++ b/app/helpers/action_page_helper.rb @@ -4,9 +4,7 @@ def twitter_share_url(action_page) action_page.share_message, action_page_url(action_page) ].map(&:presence).compact.join(" ") - suffix = if Rails.application.config.twitter_handle - " via @#{Rails.application.config.twitter_handle}" - end + suffix = (" via @#{Rails.application.config.twitter_handle}" if Rails.application.config.twitter_handle) message += suffix if action_page.share_message.to_s.length + suffix.length <= 117 related = Rails.application.config.twitter_related.to_a.join(",") @@ -14,7 +12,6 @@ def twitter_share_url(action_page) "https://twitter.com/intent/tweet?text=#{u message}&related=#{related}" end - def tweet_url(target, message) message = [target, message].compact.join(" ") related = Rails.application.config.twitter_related.to_a.join(",") @@ -22,10 +19,8 @@ def tweet_url(target, message) end def facebook_share_url(action_page) - "https://www.facebook.com/sharer/sharer.php?" + { - u: action_page_url(action_page), - display: "popup" - }.to_param + fb_params = { u: action_page_url(action_page), display: "popup" }.to_param + "https://www.facebook.com/sharer/sharer.php?#{fb_params}" end def email_friends_url(action_page) @@ -70,16 +65,17 @@ def parse_email_text(options = {}) title = @actionPage.title name = html_escape(options[:name]) - email_text. - gsub(/\$TITLE/, title). - gsub(/\$URL/, url). - gsub(/\$NAME/, name) + email_text + .gsub(/\$TITLE/, title) + .gsub(/\$URL/, url) + .gsub(/\$NAME/, name) end def visible_partners mailings_enabled = @actionPage.partners.includes(:partnerships) .where(partnerships: { enable_mailings: true }) return mailings_enabled if params[:partner].blank? + mailings_enabled.where(code: params[:partner]) end end diff --git a/app/helpers/admin/action_pages_helper.rb b/app/helpers/admin/action_pages_helper.rb index dfc8b35dc..d10cd02a5 100644 --- a/app/helpers/admin/action_pages_helper.rb +++ b/app/helpers/admin/action_pages_helper.rb @@ -1,47 +1,43 @@ -module Admin - module ActionPagesHelper - def call_campaign_options_for_select - if CallTool.enabled? - CallTool.campaigns.map do |campaign| - ["#{campaign['name']} (#{campaign['status']})", campaign["id"]] - end.sort_by(&:last).reverse - else - [] - end - rescue SystemCallError, RestClient::Exception +module Admin::ActionPagesHelper + def call_campaign_options_for_select + if CallTool.enabled? + CallTool.campaigns.map do |campaign| + ["#{campaign['name']} (#{campaign['status']})", campaign["id"]] + end.sort_by(&:last).reverse + else [] end + rescue SystemCallError, RestClient::Exception + [] + end - def congress_member_options_for_select(campaign) - selected = (campaign.target_bioguide_ids || "").split(/\s*,\s*/) + def congress_member_options_for_select(campaign) + selected = (campaign.target_bioguide_ids || "").split(/\s*,\s*/) - state_names = Places.us_state_codes.invert + state_names = Places.us_state_codes.invert - congressional_bioguides = [] - grouped_reps = CongressMember.all.group_by do |rep| - congressional_bioguides << rep.bioguide_id - state_names[rep.state] - end + congressional_bioguides = [] + grouped_reps = CongressMember.all.group_by do |rep| + congressional_bioguides << rep.bioguide_id + state_names[rep.state] + end - grouped_reps.each do |state, state_reps| - grouped_reps[state] = state_reps.sort_by(&:last_name).map do |rep| - label = "#{rep.full_name} (#{rep.bioguide_id})" - [label, rep.bioguide_id] - end + grouped_reps.each do |state, state_reps| + grouped_reps[state] = state_reps.sort_by(&:last_name).map do |rep| + label = "#{rep.full_name} (#{rep.bioguide_id})" + [label, rep.bioguide_id] end + end - grouped_reps = grouped_reps.keys.sort.map { |k| [k, grouped_reps[k]] } + grouped_reps = grouped_reps.keys.sort.map { |k| [k, grouped_reps[k]] } - non_congressional_bioguides = [] - CongressMessageCampaign.targets_bioguide_ids.pluck(:target_bioguide_ids).each do |targets| - non_congressional_bioguides.concat(targets.split(/\s*,\s*/) - congressional_bioguides) - end + non_congressional_bioguides = [] + CongressMessageCampaign.targets_bioguide_ids.pluck(:target_bioguide_ids).each do |targets| + non_congressional_bioguides.concat(targets.split(/\s*,\s*/) - congressional_bioguides) + end - if non_congressional_bioguides.present? - grouped_reps.unshift(["Non-congressional", non_congressional_bioguides.sort]) - end + grouped_reps.unshift(["Non-congressional", non_congressional_bioguides.sort]) if non_congressional_bioguides.present? - grouped_options_for_select(grouped_reps, selected) - end + grouped_options_for_select(grouped_reps, selected) end end diff --git a/app/helpers/admin/topics_helper.rb b/app/helpers/admin/topics_helper.rb index cb93a029c..9308f1c89 100644 --- a/app/helpers/admin/topics_helper.rb +++ b/app/helpers/admin/topics_helper.rb @@ -1,19 +1,17 @@ -module Admin - module TopicsHelper - def topic_category_props(topic_category) - topic_sets = topic_category.topic_sets.map do |topic_set| - { - id: topic_set.id, - tier: topic_set.tier, - topics: topic_set.topics.map { |topic| topic.attributes.slice("id", "name") } - } - end - +module Admin::TopicsHelper + def topic_category_props(topic_category) + topic_sets = topic_category.topic_sets.map do |topic_set| { - topicCategoryId: topic_category.id, - topicCategoryName: topic_category.name, - topicSets: topic_sets + id: topic_set.id, + tier: topic_set.tier, + topics: topic_set.topics.map { |topic| topic.attributes.slice("id", "name") } } end + + { + topicCategoryId: topic_category.id, + topicCategoryName: topic_category.name, + topicSets: topic_sets + } end end diff --git a/app/helpers/ahoy_helper.rb b/app/helpers/ahoy_helper.rb index 2bc4f3676..b1ef23a17 100644 --- a/app/helpers/ahoy_helper.rb +++ b/app/helpers/ahoy_helper.rb @@ -1,8 +1,8 @@ module AhoyHelper def ahoy_track_tag(action_type, action_page_id) - content_tag(:div, style: "height: 0; overflow: hidden") { + content_tag(:div, style: "height: 0; overflow: hidden") do params = { action_type: action_type, action_page_id: action_page_id, format: :gif } image_tag(ahoy_visit_url(params), style: "border: 0", alt: "") - } + end end end diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 12ff78db6..740af86b6 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -1,15 +1,15 @@ module ApplicationHelper def page_title - t("page_title", scope: [controller_path.gsub("/", "_"), action_name], - default: [@title, I18n.t("site_title")].compact.join(" | ")) + t("page_title", scope: [controller_path.tr("/", "_"), action_name], + default: [@title, I18n.t("site_title")].compact.join(" | ")) end def escape_page_title - URI.escape(page_title , Regexp.new("[^#{URI::PATTERN::UNRESERVED}]")) + ERB::Util.url_encode page_title end def twitter_handle - "@" + Rails.application.config.twitter_handle.to_s + "@#{Rails.application.config.twitter_handle}" end def markdown(blogtext) @@ -21,7 +21,7 @@ def markdown(blogtext) end def substitute_keywords(blogtext) - if @actionPage and @actionPage.description and @petition + if @actionPage&.description && @petition blogtext.gsub("$SIGNATURECOUNT", @petition.signatures.pretty_count) else blogtext @@ -71,24 +71,26 @@ def update_user_data(params = {}) if user_signed_in? p = params.clone p.delete(:email) - current_user.update_attributes p + current_user.update p end end + # REFACTOR_FLAG + # use ActiveStorage::Filename#sanitized after upgrading to 5.2 def sanitize_filename(filename) # Split the name when finding a period which is preceded by some # character, and is followed by some character other than a period, # if there is no following period that is followed by something # other than a period (yeah, confusing, I know) - fn = filename.split /(?<=.)\.(?=[^.])(?!.*\.[^.])/m + fn = filename.split(/(?<=.)\.(?=[^.])(?!.*\.[^.])/m) # We now have one or two parts (depending on whether we could find # a suitable period). For each of these parts, replace any unwanted # sequence of characters with an underscore - fn.map! { |s| s.gsub /[^a-z0-9\-]+/i, "_" } + fn.map! { |s| s.gsub(/[^a-z0-9\-]+/i, "_") } # Finally, join the parts with a period and return the result - return fn.join "." + fn.join "." end def can?(ability) @@ -108,20 +110,22 @@ def messages safe_join(messages) end - def percentage(x, y, precision: 0) + def percentage(x, y, precision: 0) # rubocop:todo Naming/MethodParameterName return "-" unless y > 0 + number_to_percentage((x / y.to_f) * 100, precision: precision) end private def user_session_data_whitelist - [:email, :last_name, :first_name, :street_address, :city, :state, :zipcode, - :country_code, :phone] + %i[email last_name first_name street_address city state zipcode + country_code phone] end def current_user_data(field) return nil unless user_session_data_whitelist.include? field + current_user.try(field) end end diff --git a/app/helpers/congress_message_helper.rb b/app/helpers/congress_message_helper.rb index 12659b644..7fb8e7497 100644 --- a/app/helpers/congress_message_helper.rb +++ b/app/helpers/congress_message_helper.rb @@ -1,8 +1,7 @@ module CongressMessageHelper def congress_forms_prefills(campaign, field) - if field.value == "$TOPIC" && campaign.topic_category.present? - return campaign.topic_category.best_match(field.options_hash) - end + return campaign.topic_category.best_match(field.options_hash) if field.value == "$TOPIC" && campaign.topic_category.present? + { "$NAME_FIRST" => current_first_name, "$NAME_LAST" => current_last_name, @@ -10,16 +9,16 @@ def congress_forms_prefills(campaign, field) "$PHONE" => number_to_phone(current_user.try(:phone)), "$ADDRESS_STREET" => current_street_address, "$ADDRESS_CITY" => current_city, - "$SUBJECT" => campaign.subject, + "$SUBJECT" => campaign.subject }[field.value] end def congress_forms_field(field, campaign, message_attributes, bioguide_id = nil) - if bioguide_id - name = "member_attributes[#{bioguide_id}][#{field.value}]" - else - name = "common_attributes[#{field.value}]" - end + name = if bioguide_id + "member_attributes[#{bioguide_id}][#{field.value}]" + else + "common_attributes[#{field.value}]" + end # Try to guess the input based on saved info about the campaign + user. prefill = congress_forms_prefills(campaign, field) @@ -30,11 +29,11 @@ def congress_forms_field(field, campaign, message_attributes, bioguide_id = nil) elsif field.value == "$PHONE" telephone_field_tag name, prefill, congress_forms_field_defaults(field) .merge({ - class: "form-control bfh-phone", - "data-format": "ddd-ddd-dddd", - pattern: "^((5\\d[123467890])|(5[123467890]\\d)|([2346789]\\d\\d))-\\d\\d\\d-\\d\\d\\d\\d$", - title: "Must be a valid US phone number entered in 555-555-5555 format" - }) + class: "form-control bfh-phone", + "data-format": "ddd-ddd-dddd", + pattern: "^((5\\d[123467890])|(5[123467890]\\d)|([2346789]\\d\\d))-\\d\\d\\d-\\d\\d\\d\\d$", + title: "Must be a valid US phone number entered in 555-555-5555 format" + }) elsif field.value == "$EMAIL" email_field_tag name, prefill, congress_forms_field_defaults(field) elsif field.value.include?("ADDRESS") && !field.is_select? @@ -44,7 +43,7 @@ def congress_forms_field(field, campaign, message_attributes, bioguide_id = nil) text_field_tag name, prefill, congress_forms_field_defaults(field, placeholder: address_label, "aria-label": address_label) elsif field.is_select? select_tag name, options_for_select(field.options_hash, prefill), - class: "form-control", "aria-label": field.label, include_blank: field.label, required: true + class: "form-control", "aria-label": field.label, include_blank: field.label, required: true else text_field_tag name, prefill, congress_forms_field_defaults(field) end diff --git a/app/helpers/devise_helper.rb b/app/helpers/devise_helper.rb index ff4a7e3ce..c4bfed8b0 100644 --- a/app/helpers/devise_helper.rb +++ b/app/helpers/devise_helper.rb @@ -2,28 +2,22 @@ module DeviseHelper # Customized to add model error instead of flashing the error. def devise_error_messages! flash_alerts = [] - error_key = "errors.messages.not_saved" flash_alerts.push("This account was locked due to too many failed login attempts. Check your email for a link to unlock.") if locked_account? - if !flash.empty? + unless flash.empty? flash_alerts.push(flash[:error]) if flash[:error] flash_alerts.push(flash[:alert]) if flash[:alert] flash_alerts.push(flash[:notice]) if flash[:notice] - error_key = "devise.failure.invalid" end return "" if resource.errors.empty? && flash_alerts.empty? + @hasErrorMessages = true errors = resource.errors.empty? ? flash_alerts : resource.errors.full_messages messages = errors.map { |msg| content_tag(:p, msg) }.join - sentence = I18n.t(error_key, count: errors.count, - resource: resource.class.model_name.human.downcase) - - if !flash[:notice] | flash[:alert] - panel_title = "
You are in the <%= current_user.percentile_rank.ordinalize %> percentile of users.
-Actions you've taken so far: