From 4adf075bd0e01d2ce1ed195f7f5a992929b546c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maximilien=20Pressens=C3=A9?= Date: Fri, 22 Nov 2024 14:42:03 +0100 Subject: [PATCH] Add Standard configuration, and update various files for consistency --- .github/workflows/ci.yml | 56 +++++++------ .github/workflows/deploy.yml | 2 +- .standard.yml | 2 + Gemfile | 8 +- Gemfile.lock | 31 ++++--- app/controllers/application_controller.rb | 2 +- app/controllers/connections_controller.rb | 27 ++++-- .../email_verifications_controller.rb | 17 ++-- app/controllers/identity/emails_controller.rb | 33 ++++---- .../identity/password_resets_controller.rb | 27 +++--- app/controllers/passwords_controller.rb | 13 +-- app/controllers/registrations_controller.rb | 45 +++++----- app/controllers/sessions_controller.rb | 14 +++- app/models/concerns/otp.rb | 4 +- app/models/current.rb | 3 +- app/models/hotp.rb | 1 - app/models/user.rb | 6 +- config/environments/development.rb | 4 +- config/environments/production.rb | 14 ++-- config/environments/test.rb | 4 +- config/routes.rb | 8 +- ...0241114104529_create_accounts_migration.rb | 2 +- db/migrate/20241114104535_create_users.rb | 2 +- db/queue_schema.rb | 54 ++++++------ lib/account_middleware.rb | 17 ++-- spec/mailers/user_mailer_spec.rb | 4 +- spec/rails_helper.rb | 16 ++-- spec/requests/connections_spec.rb | 18 ++-- spec/requests/registrations_spec.rb | 12 +-- spec/requests/sessions_spec.rb | 12 +-- spec/spec_helper.rb | 82 +++++++++---------- spec/support/authentication_helpers.rb | 2 +- .../shared_examples/only_for_guests.rb | 2 +- .../shared_examples/require_authentication.rb | 2 +- test/application_system_test_case.rb | 4 +- .../email_verifications_controller_test.rb | 2 +- .../identity/emails_controller_test.rb | 5 +- .../password_resets_controller_test.rb | 12 +-- test/controllers/passwords_controller_test.rb | 4 +- test/mailers/user_mailer_test.rb | 4 +- test/test_helper.rb | 3 +- 41 files changed, 307 insertions(+), 273 deletions(-) create mode 100644 .standard.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e81c4da..03d8483 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -6,15 +6,34 @@ on: branches: [main] jobs: + lint_ruby: + runs-on: ubuntu-latest + permissions: + checks: write + contents: write + steps: + - name: Checkout code + uses: actions/checkout@v4.2.2 + + - name: Set up Ruby + uses: ruby/setup-ruby@v1.202.0 + with: + ruby-version: .ruby-version + bundler-cache: true + + - name: Run Standard Ruby + uses: standardrb/standard-ruby-action@v1 + scan_ruby: runs-on: ubuntu-latest + needs: standard_ruby steps: - name: Checkout code - uses: actions/checkout@v4 + uses: actions/checkout@v4.2.2 - name: Set up Ruby - uses: ruby/setup-ruby@v1 + uses: ruby/setup-ruby@v1.202.0 with: ruby-version: .ruby-version bundler-cache: true @@ -27,16 +46,10 @@ jobs: steps: - name: Checkout code - uses: actions/checkout@v4 - - # - name: Set up Ruby - # uses: ruby/setup-ruby@v1 - # with: - # ruby-version: .ruby-version - # bundler-cache: true + uses: actions/checkout@v4.2.2 - name: Setup node - uses: actions/setup-node@v4 + uses: actions/setup-node@v4.1.0 with: node-version: 20 @@ -50,10 +63,10 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout code - uses: actions/checkout@v4 + uses: actions/checkout@v4.2.2 - name: Set up Ruby - uses: ruby/setup-ruby@v1 + uses: ruby/setup-ruby@v1.202.0 with: ruby-version: .ruby-version bundler-cache: true @@ -64,27 +77,21 @@ jobs: test: runs-on: ubuntu-latest - # services: - # redis: - # image: redis - # ports: - # - 6379:6379 - # options: --health-cmd "redis-cli ping" --health-interval 10s --health-timeout 5s --health-retries 5 steps: - name: Install packages run: sudo apt-get update && sudo apt-get install --no-install-recommends -y google-chrome-stable curl libjemalloc2 libvips sqlite3 - name: Checkout code - uses: actions/checkout@v4 + uses: actions/checkout@v4.2.2 - name: Set up Ruby - uses: ruby/setup-ruby@v1 + uses: ruby/setup-ruby@v1.202.0 with: ruby-version: .ruby-version bundler-cache: true - name: Setup node - uses: actions/setup-node@v4 + uses: actions/setup-node@v4.1.0 with: node-version: 20 @@ -96,22 +103,19 @@ jobs: - name: Prepare db env: - # RAILS_MASTER_KEY: ${{ secrets.RAILS_MASTER_KEY }} RAILS_ENV: test - # REDIS_URL: redis://localhost:6379/0 run: bin/rails db:test:prepare - name: Run tests env: RAILS_MASTER_KEY: ${{ secrets.RAILS_MASTER_KEY }} - # RAILS_ENV: test - # REDIS_URL: redis://localhost:6379/0 run: bundle exec rspec - name: Keep screenshots from failed system tests - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v4.4.3 if: failure() with: name: screenshots path: ${{ github.workspace }}/tmp/screenshots if-no-files-found: ignore + diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 3274654..3c5cbbc 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -18,7 +18,7 @@ jobs: uses: actions/checkout@v4.2.2 - name: Set up Ruby - uses: ruby/setup-ruby@v1.201.0 + uses: ruby/setup-ruby@v1.202.0 with: ruby-version: .ruby-version bundler-cache: true diff --git a/.standard.yml b/.standard.yml new file mode 100644 index 0000000..fcd095b --- /dev/null +++ b/.standard.yml @@ -0,0 +1,2 @@ +plugins: + - standard-rails diff --git a/Gemfile b/Gemfile index 152824e..7ec6667 100644 --- a/Gemfile +++ b/Gemfile @@ -11,7 +11,7 @@ gem "puma", ">= 5.0" gem "bcrypt", "~> 3.1.7" # Windows does not include zoneinfo files, so bundle the tzinfo-data gem -gem "tzinfo-data", platforms: %i[ windows jruby ] +gem "tzinfo-data", platforms: %i[windows jruby] # Use the database-backed adapters for Rails.cache, Active Job, and Action Cable gem "solid_cache" @@ -32,15 +32,17 @@ gem "thruster", require: false group :development, :test do # See https://guides.rubyonrails.org/debugging_rails_applications.html#debugging-with-the-debug-gem - gem "debug", platforms: %i[ mri windows ], require: "debug/prelude" + gem "debug", platforms: %i[mri windows], require: "debug/prelude" # Static analysis for security vulnerabilities [https://brakemanscanner.org/] gem "brakeman", require: false # Omakase Ruby styling [https://github.com/rails/rubocop-rails-omakase/] - gem "rubocop-rails-omakase", require: false gem "rspec-rails" gem "factory_bot_rails" + + gem "standard" + gem "standard-rails" end group :development do diff --git a/Gemfile.lock b/Gemfile.lock index afff94d..fb850df 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -153,6 +153,7 @@ GEM thor (~> 1.3) zeitwerk (>= 2.6.18, < 3.0) language_server-protocol (3.17.0.3) + lint_roller (1.1.0) logger (1.6.1) loofah (2.23.1) crass (~> 1.0.2) @@ -299,22 +300,14 @@ GEM unicode-display_width (>= 2.4.0, < 3.0) rubocop-ast (1.36.1) parser (>= 3.3.1.0) - rubocop-minitest (0.36.0) - rubocop (>= 1.61, < 2.0) - rubocop-ast (>= 1.31.1, < 2.0) - rubocop-performance (1.23.0) + rubocop-performance (1.22.1) rubocop (>= 1.48.1, < 2.0) rubocop-ast (>= 1.31.1, < 2.0) - rubocop-rails (2.27.0) + rubocop-rails (2.26.2) activesupport (>= 4.2.0) rack (>= 1.1) rubocop (>= 1.52.0, < 2.0) rubocop-ast (>= 1.31.1, < 2.0) - rubocop-rails-omakase (1.0.0) - rubocop - rubocop-minitest - rubocop-performance - rubocop-rails ruby-lsp (0.21.3) language_server-protocol (~> 3.17.0) prism (>= 1.2, < 2.0) @@ -366,6 +359,21 @@ GEM net-sftp (>= 2.1.2) net-ssh (>= 2.8.0) ostruct + standard (1.42.1) + language_server-protocol (~> 3.17.0.2) + lint_roller (~> 1.0) + rubocop (~> 1.68.0) + standard-custom (~> 1.0.0) + standard-performance (~> 1.5) + standard-custom (1.0.2) + lint_roller (~> 1.0) + rubocop (~> 1.50) + standard-performance (1.5.0) + lint_roller (~> 1.1) + rubocop-performance (~> 1.22.0) + standard-rails (1.2.0) + lint_roller (~> 1.0) + rubocop-rails (~> 2.26.0) stringio (3.1.2) thor (1.3.2) thruster (0.1.9) @@ -435,7 +443,6 @@ DEPENDENCIES rails rotp (~> 6.3) rspec-rails - rubocop-rails-omakase ruby-lsp ruby-lsp-rails ruby-lsp-rspec @@ -444,6 +451,8 @@ DEPENDENCIES solid_cache solid_queue sqlite3 (>= 2.1) + standard + standard-rails thruster tzinfo-data vite_rails (~> 3.0) diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 03d076a..3e4d776 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -20,7 +20,7 @@ def set_current_request_details end def authenticate - if session_record = Session.find_by_id(cookies.signed[:session_token]) + if (session_record = Session.find_by_id(cookies.signed[:session_token])) Current.session = session_record end end diff --git a/app/controllers/connections_controller.rb b/app/controllers/connections_controller.rb index 23e230f..bac411e 100644 --- a/app/controllers/connections_controller.rb +++ b/app/controllers/connections_controller.rb @@ -2,12 +2,21 @@ class ConnectionsController < ApplicationController skip_before_action :require_authentication before_action :only_for_guests - rate_limit to: 10, - within: 1.minute, - only: :create, - by: -> { params[:email] }, - with: -> { redirect_to new_connection_path, error: "Le maximum de tentatives a été atteint." } - rate_limit to: 1, within: 1.minute, only: :resend_otp + rate_limit to: 5, + within: 1.minute, + only: :create, + by: -> { params[:email] }, + with: -> { + redirect_to new_connection_path, + error: "Le maximum de connexions a été atteint. Veuillez patienter." + } + rate_limit to: 1, + within: 1.minute, + only: :resend_otp, + with: -> { + redirect_to new_connection_path, + error: "Veuillez patienter." + } def new render inertia: "Auth/Connection" @@ -15,13 +24,13 @@ def new def create email = params[:email] - if user = User.find_by(email:) + if (user = User.find_by(email:)) user.send_otp_email redirect_to new_session_path else user = User.create(email:) # will always fail because missing mandatory fields if user.errors[:email].any? - redirect_to new_connection_path, inertia: { errors: user.errors } + redirect_to new_connection_path, inertia: {errors: user.errors} else redirect_to new_registration_path end @@ -29,7 +38,7 @@ def create end def resend_otp - if user = User.find_by(email: params[:email]) + if (user = User.find_by(email: params[:email])) user.send_otp_email(expiration_check: false) redirect_to new_session_path else diff --git a/app/controllers/identity/email_verifications_controller.rb b/app/controllers/identity/email_verifications_controller.rb index 813c286..b1e76ad 100644 --- a/app/controllers/identity/email_verifications_controller.rb +++ b/app/controllers/identity/email_verifications_controller.rb @@ -14,13 +14,14 @@ def create end private - def set_user - @user = User.find_by_token_for!(:email_verification, params[:sid]) - rescue StandardError - redirect_to edit_identity_email_path, error: "That email verification link is invalid" - end - def send_email_verification - UserMailer.with(user: Current.user).email_verification.deliver_later - end + def set_user + @user = User.find_by_token_for!(:email_verification, params[:sid]) + rescue + redirect_to edit_identity_email_path, error: "That email verification link is invalid" + end + + def send_email_verification + UserMailer.with(user: Current.user).email_verification.deliver_later + end end diff --git a/app/controllers/identity/emails_controller.rb b/app/controllers/identity/emails_controller.rb index 97b6a22..0ccacb0 100644 --- a/app/controllers/identity/emails_controller.rb +++ b/app/controllers/identity/emails_controller.rb @@ -13,24 +13,25 @@ def update end private - def set_user - @user = Current.user - end - def user_params - params.permit(:email, :password_challenge).with_defaults(password_challenge: "") - end + def set_user + @user = Current.user + end - def redirect_to_root - if @user.email_previously_changed? - resend_email_verification - redirect_to root_path, success: "Your email has been changed" - else - redirect_to root_path - end - end + def user_params + params.permit(:email, :password_challenge).with_defaults(password_challenge: "") + end - def resend_email_verification - UserMailer.with(user: @user).email_verification.deliver_later + def redirect_to_root + if @user.email_previously_changed? + resend_email_verification + redirect_to root_path, success: "Your email has been changed" + else + redirect_to root_path end + end + + def resend_email_verification + UserMailer.with(user: @user).email_verification.deliver_later + end end diff --git a/app/controllers/identity/password_resets_controller.rb b/app/controllers/identity/password_resets_controller.rb index 012f6f4..43b14e6 100644 --- a/app/controllers/identity/password_resets_controller.rb +++ b/app/controllers/identity/password_resets_controller.rb @@ -1,7 +1,7 @@ class Identity::PasswordResetsController < ApplicationController skip_before_action :require_authentication - before_action :set_user, only: %i[ edit update ] + before_action :set_user, only: %i[edit update] def new end @@ -10,7 +10,7 @@ def edit end def create - if @user = User.find_by(email: params[:email], verified: true) + if (@user = User.find_by(email: params[:email], verified: true)) send_password_reset_email redirect_to new_session_path, info: "Check your email for reset instructions" else @@ -27,17 +27,18 @@ def update end private - def set_user - @user = User.find_by_token_for!(:password_reset, params[:sid]) - rescue StandardError - redirect_to new_identity_password_reset_path, error: "That password reset link is invalid" - end - def user_params - params.permit(:password, :password_confirmation) - end + def set_user + @user = User.find_by_token_for!(:password_reset, params[:sid]) + rescue + redirect_to new_identity_password_reset_path, error: "That password reset link is invalid" + end - def send_password_reset_email - UserMailer.with(user: @user).password_reset.deliver_later - end + def user_params + params.permit(:password, :password_confirmation) + end + + def send_password_reset_email + UserMailer.with(user: @user).password_reset.deliver_later + end end diff --git a/app/controllers/passwords_controller.rb b/app/controllers/passwords_controller.rb index 0ca878b..e8a7c04 100644 --- a/app/controllers/passwords_controller.rb +++ b/app/controllers/passwords_controller.rb @@ -13,11 +13,12 @@ def update end private - def set_user - @user = Current.user - end - def user_params - params.permit(:password, :password_confirmation, :password_challenge).with_defaults(password_challenge: "") - end + def set_user + @user = Current.user + end + + def user_params + params.permit(:password, :password_confirmation, :password_challenge).with_defaults(password_challenge: "") + end end diff --git a/app/controllers/registrations_controller.rb b/app/controllers/registrations_controller.rb index 82bf905..e4fa764 100644 --- a/app/controllers/registrations_controller.rb +++ b/app/controllers/registrations_controller.rb @@ -2,10 +2,13 @@ class RegistrationsController < ApplicationController skip_before_action :require_authentication before_action :only_for_guests - before_action :verify_captcha, only: [ :create ] - before_action :add_terms_and_privacy_accepted_at, only: [ :create ] + before_action :verify_captcha, only: [:create] + before_action :add_terms_and_privacy_accepted_at, only: [:create] - rate_limit to: 100, within: 1.day, only: :create + rate_limit to: 100, within: 1.day, only: :create, with: -> { + redirect_to root_path, + error: "Le maximum d'inscriptions a été atteint. Veuillez nous contacter." + } def new render inertia: "Auth/SignUp" @@ -18,32 +21,32 @@ def create user.send_otp_email redirect_to new_session_path else - redirect_to new_registration_path, inertia: { errors: user.errors } + redirect_to new_registration_path, inertia: {errors: user.errors} end end private - def add_terms_and_privacy_accepted_at - params.delete(:terms_and_privacy_accepted_at) # avoid hacking of terms_and_privacy_accepted_at - if accepts_conditions? - params[:terms_and_privacy_accepted_at] = DateTime.current - end + def add_terms_and_privacy_accepted_at + params.delete(:terms_and_privacy_accepted_at) # avoid hacking of terms_and_privacy_accepted_at + if accepts_conditions? + params[:terms_and_privacy_accepted_at] = DateTime.current end + end - def verify_captcha - captcha = Captcha.new(params.delete(:recaptcha_token)) - unless captcha.valid? - redirect_to new_registration_path, error: "Erreur de validation du CAPTCHA. Veuillez réessayer." - end + def verify_captcha + captcha = Captcha.new(params.delete(:recaptcha_token)) + unless captcha.valid? + redirect_to new_registration_path, error: "Erreur de validation du CAPTCHA. Veuillez réessayer." end + end - def user_params - params.permit(:email, :first_name, :last_name, :terms_and_privacy_accepted_at) - end + def user_params + params.permit(:email, :first_name, :last_name, :terms_and_privacy_accepted_at) + end - def accepts_conditions? - # BUG : in test environment, the boolean true is received as a string 'true' - ActiveModel::Type::Boolean.new.cast(params[:accepts_conditions]) - end + def accepts_conditions? + # BUG : in test environment, the boolean true is received as a string 'true' + ActiveModel::Type::Boolean.new.cast(params[:accepts_conditions]) + end end diff --git a/app/controllers/sessions_controller.rb b/app/controllers/sessions_controller.rb index 4c3696a..393bd1c 100644 --- a/app/controllers/sessions_controller.rb +++ b/app/controllers/sessions_controller.rb @@ -2,8 +2,14 @@ class SessionsController < ApplicationController skip_before_action :require_authentication, only: %i[new create] before_action :only_for_guests, only: %i[new create] - # use a redirect to avoid a weird render - rate_limit to: 5, within: 1.minute, only: :create, by: -> { params[:email] } + rate_limit to: 5, + within: 1.minute, + only: :create, + by: -> { params[:email] }, + with: -> { + redirect_to new_session_path, + error: "Le maximum de tentatives a été atteint. Veuillez patienter." + } def new render inertia: "Auth/SignIn" @@ -21,7 +27,7 @@ def create sign_in(user) redirect_to root_path, success: "Vous êtes connecté." else - redirect_to new_session_path, inertia: { errors: hotp.errors } + redirect_to new_session_path, inertia: {errors: hotp.errors} end end @@ -35,6 +41,6 @@ def destroy def sign_in(user) session = user.sessions.create! - cookies.signed.permanent[:session_token] = { value: session.id, httponly: true } + cookies.signed.permanent[:session_token] = {value: session.id, httponly: true} end end diff --git a/app/models/concerns/otp.rb b/app/models/concerns/otp.rb index a1987cd..4ce7740 100644 --- a/app/models/concerns/otp.rb +++ b/app/models/concerns/otp.rb @@ -14,8 +14,8 @@ def send_otp_email(expiration_check: true) end def generate_new_otp - self.increment!(:otp_counter) - self.update!(otp_expires_at: DateTime.current + 10.minutes) + increment!(:otp_counter) + update!(otp_expires_at: DateTime.current + 10.minutes) otp end diff --git a/app/models/current.rb b/app/models/current.rb index a5f7439..ccf97b9 100644 --- a/app/models/current.rb +++ b/app/models/current.rb @@ -7,6 +7,7 @@ class Current < ActiveSupport::CurrentAttributes delegate :user, to: :session, allow_nil: true def session=(session) - super; self.account = session.user.account + super + self.account = session.user.account end end diff --git a/app/models/hotp.rb b/app/models/hotp.rb index b83f746..efe306b 100644 --- a/app/models/hotp.rb +++ b/app/models/hotp.rb @@ -9,7 +9,6 @@ class Hotp validates :code, presence: true validate :validate_code - private def validate_code diff --git a/app/models/user.rb b/app/models/user.rb index 5a692cc..6106de0 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -1,5 +1,6 @@ class User < ApplicationRecord include Otp + has_secure_password validations: false generates_token_for :email_verification, expires_in: 2.days do @@ -10,15 +11,14 @@ class User < ApplicationRecord password_salt.last(10) end - belongs_to :account has_many :sessions, dependent: :destroy validates :email, presence: true - validates :email, uniqueness: true, format: { with: URI::MailTo::EMAIL_REGEXP }, if: -> { email.present? } + validates :email, uniqueness: true, format: {with: URI::MailTo::EMAIL_REGEXP}, if: -> { email.present? } validates :first_name, :last_name, :terms_and_privacy_accepted_at, presence: true - validates :password, allow_nil: true, length: { minimum: 12 } + validates :password, allow_nil: true, length: {minimum: 12} normalizes :email, with: -> { _1.strip.downcase } diff --git a/config/environments/development.rb b/config/environments/development.rb index 4cc21c4..4ba93a0 100644 --- a/config/environments/development.rb +++ b/config/environments/development.rb @@ -20,7 +20,7 @@ if Rails.root.join("tmp/caching-dev.txt").exist? config.action_controller.perform_caching = true config.action_controller.enable_fragment_cache_logging = true - config.public_file_server.headers = { "cache-control" => "public, max-age=#{2.days.to_i}" } + config.public_file_server.headers = {"cache-control" => "public, max-age=#{2.days.to_i}"} else config.action_controller.perform_caching = false end @@ -38,7 +38,7 @@ config.action_mailer.perform_caching = false # Set localhost to be used by links generated in mailer templates. - config.action_mailer.default_url_options = { host: "localhost", port: 3000 } + config.action_mailer.default_url_options = {host: "localhost", port: 3000} # Print deprecation notices to the Rails logger. config.active_support.deprecation = :log diff --git a/config/environments/production.rb b/config/environments/production.rb index 7a7ecec..967dce0 100644 --- a/config/environments/production.rb +++ b/config/environments/production.rb @@ -16,7 +16,7 @@ config.action_controller.perform_caching = true # Cache assets for far-future expiry since they are all digest stamped. - config.public_file_server.headers = { "cache-control" => "public, max-age=#{1.year.to_i}" } + config.public_file_server.headers = {"cache-control" => "public, max-age=#{1.year.to_i}"} # Enable serving of images, stylesheets, and JavaScripts from an asset server. # config.asset_host = "http://assets.example.com" @@ -34,8 +34,8 @@ # config.ssl_options = { redirect: { exclude: ->(request) { request.path == "/up" } } } # Log to STDOUT with the current request id as a default log tag. - config.log_tags = [ :request_id ] - config.logger = ActiveSupport::TaggedLogging.logger(STDOUT) + config.log_tags = [:request_id] + config.logger = ActiveSupport::TaggedLogging.logger($stdout) # Change to "debug" to log everything (including potentially personally-identifiable information!) config.log_level = ENV.fetch("RAILS_LOG_LEVEL", "info") @@ -51,15 +51,14 @@ # Replace the default in-process and non-durable queuing backend for Active Job. config.active_job.queue_adapter = :solid_queue - config.solid_queue.connects_to = { database: { writing: :queue } } - + config.solid_queue.connects_to = {database: {writing: :queue}} # Ignore bad email addresses and do not raise email delivery errors. # Set this to true and configure the email server for immediate delivery to raise delivery errors. # config.action_mailer.raise_delivery_errors = false # Set host to be used by links generated in mailer templates. - config.action_mailer.default_url_options = { host: "benefactorum.org" } + config.action_mailer.default_url_options = {host: "benefactorum.org"} # Specify outgoing SMTP server. Remember to add smtp/* credentials via rails credentials:edit. # config.action_mailer.smtp_settings = { @@ -71,7 +70,6 @@ # } config.action_mailer.delivery_method = :mailjet_api - # Enable locale fallbacks for I18n (makes lookups for any locale fall back to # the I18n.default_locale when a translation cannot be found). config.i18n.fallbacks = true @@ -80,7 +78,7 @@ config.active_record.dump_schema_after_migration = false # Only use :id for inspections in production. - config.active_record.attributes_for_inspect = [ :id ] + config.active_record.attributes_for_inspect = [:id] # Enable DNS rebinding protection and other `Host` header attacks. # config.hosts = [ diff --git a/config/environments/test.rb b/config/environments/test.rb index 4d41fb1..35bb3bf 100644 --- a/config/environments/test.rb +++ b/config/environments/test.rb @@ -16,7 +16,7 @@ config.eager_load = ENV["CI"].present? # Configure public file server for tests with cache-control for performance. - config.public_file_server.headers = { "cache-control" => "public, max-age=3600" } + config.public_file_server.headers = {"cache-control" => "public, max-age=3600"} # Show full error reports. config.consider_all_requests_local = true @@ -41,7 +41,7 @@ # config.active_job.queue_adapter = :inline # Set host to be used by links generated in mailer templates. - config.action_mailer.default_url_options = { host: "example.com" } + config.action_mailer.default_url_options = {host: "example.com"} # Print deprecation notices to the stderr. config.active_support.deprecation = :stderr diff --git a/config/routes.rb b/config/routes.rb index f7086f0..420776e 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -1,17 +1,17 @@ Rails.application.routes.draw do # Define your application routes per the DSL in https://guides.rubyonrails.org/routing.html - resources :connections, only: [ :create ] do + resources :connections, only: [:create] do collection do post :resend_otp end end get "connexion", to: "connections#new", as: :new_connection - resources :registrations, only: [ :create ] + resources :registrations, only: [:create] get "s-inscrire", to: "registrations#new", as: :new_registration - resources :sessions, only: [ :create, :destroy ] + resources :sessions, only: [:create, :destroy] get "se-connecter", to: "sessions#new", as: :new_session # resource :password, only: [ :edit, :update ] @@ -34,7 +34,7 @@ # Reveal health status on /up that returns 200 if the app boots with no exceptions, otherwise 500. # Can be used by load balancers and uptime monitors to verify that the app is live. # is used by Kamal Deploy - get "up" => "rails/health#show", as: :rails_health_check + get "up" => "rails/health#show", :as => :rails_health_check # Render dynamic PWA files from app/views/pwa/* (remember to link manifest in application.html.erb) # get "manifest" => "rails/pwa#manifest", as: :pwa_manifest diff --git a/db/migrate/20241114104529_create_accounts_migration.rb b/db/migrate/20241114104529_create_accounts_migration.rb index 0196a84..0caffbf 100644 --- a/db/migrate/20241114104529_create_accounts_migration.rb +++ b/db/migrate/20241114104529_create_accounts_migration.rb @@ -1,5 +1,5 @@ class CreateAccountsMigration < ActiveRecord::Migration[8.0] def change - create_table :accounts + create_table :accounts # standard:disable Rails/CreateTableWithTimestamps end end diff --git a/db/migrate/20241114104535_create_users.rb b/db/migrate/20241114104535_create_users.rb index 9ff390c..df6e193 100644 --- a/db/migrate/20241114104535_create_users.rb +++ b/db/migrate/20241114104535_create_users.rb @@ -1,7 +1,7 @@ class CreateUsers < ActiveRecord::Migration[8.0] def change create_table :users do |t| - t.string :email, null: false, index: { unique: true } + t.string :email, null: false, index: {unique: true} t.string :password_digest t.boolean :verified, null: false, default: false diff --git a/db/queue_schema.rb b/db/queue_schema.rb index 85194b6..4b2cfdb 100644 --- a/db/queue_schema.rb +++ b/db/queue_schema.rb @@ -6,24 +6,24 @@ t.string "concurrency_key", null: false t.datetime "expires_at", null: false t.datetime "created_at", null: false - t.index [ "concurrency_key", "priority", "job_id" ], name: "index_solid_queue_blocked_executions_for_release" - t.index [ "expires_at", "concurrency_key" ], name: "index_solid_queue_blocked_executions_for_maintenance" - t.index [ "job_id" ], name: "index_solid_queue_blocked_executions_on_job_id", unique: true + t.index ["concurrency_key", "priority", "job_id"], name: "index_solid_queue_blocked_executions_for_release" + t.index ["expires_at", "concurrency_key"], name: "index_solid_queue_blocked_executions_for_maintenance" + t.index ["job_id"], name: "index_solid_queue_blocked_executions_on_job_id", unique: true end create_table "solid_queue_claimed_executions", force: :cascade do |t| t.bigint "job_id", null: false t.bigint "process_id" t.datetime "created_at", null: false - t.index [ "job_id" ], name: "index_solid_queue_claimed_executions_on_job_id", unique: true - t.index [ "process_id", "job_id" ], name: "index_solid_queue_claimed_executions_on_process_id_and_job_id" + t.index ["job_id"], name: "index_solid_queue_claimed_executions_on_job_id", unique: true + t.index ["process_id", "job_id"], name: "index_solid_queue_claimed_executions_on_process_id_and_job_id" end create_table "solid_queue_failed_executions", force: :cascade do |t| t.bigint "job_id", null: false t.text "error" t.datetime "created_at", null: false - t.index [ "job_id" ], name: "index_solid_queue_failed_executions_on_job_id", unique: true + t.index ["job_id"], name: "index_solid_queue_failed_executions_on_job_id", unique: true end create_table "solid_queue_jobs", force: :cascade do |t| @@ -37,17 +37,17 @@ t.string "concurrency_key" t.datetime "created_at", null: false t.datetime "updated_at", null: false - t.index [ "active_job_id" ], name: "index_solid_queue_jobs_on_active_job_id" - t.index [ "class_name" ], name: "index_solid_queue_jobs_on_class_name" - t.index [ "finished_at" ], name: "index_solid_queue_jobs_on_finished_at" - t.index [ "queue_name", "finished_at" ], name: "index_solid_queue_jobs_for_filtering" - t.index [ "scheduled_at", "finished_at" ], name: "index_solid_queue_jobs_for_alerting" + t.index ["active_job_id"], name: "index_solid_queue_jobs_on_active_job_id" + t.index ["class_name"], name: "index_solid_queue_jobs_on_class_name" + t.index ["finished_at"], name: "index_solid_queue_jobs_on_finished_at" + t.index ["queue_name", "finished_at"], name: "index_solid_queue_jobs_for_filtering" + t.index ["scheduled_at", "finished_at"], name: "index_solid_queue_jobs_for_alerting" end create_table "solid_queue_pauses", force: :cascade do |t| t.string "queue_name", null: false t.datetime "created_at", null: false - t.index [ "queue_name" ], name: "index_solid_queue_pauses_on_queue_name", unique: true + t.index ["queue_name"], name: "index_solid_queue_pauses_on_queue_name", unique: true end create_table "solid_queue_processes", force: :cascade do |t| @@ -59,9 +59,9 @@ t.text "metadata" t.datetime "created_at", null: false t.string "name", null: false - t.index [ "last_heartbeat_at" ], name: "index_solid_queue_processes_on_last_heartbeat_at" - t.index [ "name", "supervisor_id" ], name: "index_solid_queue_processes_on_name_and_supervisor_id", unique: true - t.index [ "supervisor_id" ], name: "index_solid_queue_processes_on_supervisor_id" + t.index ["last_heartbeat_at"], name: "index_solid_queue_processes_on_last_heartbeat_at" + t.index ["name", "supervisor_id"], name: "index_solid_queue_processes_on_name_and_supervisor_id", unique: true + t.index ["supervisor_id"], name: "index_solid_queue_processes_on_supervisor_id" end create_table "solid_queue_ready_executions", force: :cascade do |t| @@ -69,9 +69,9 @@ t.string "queue_name", null: false t.integer "priority", default: 0, null: false t.datetime "created_at", null: false - t.index [ "job_id" ], name: "index_solid_queue_ready_executions_on_job_id", unique: true - t.index [ "priority", "job_id" ], name: "index_solid_queue_poll_all" - t.index [ "queue_name", "priority", "job_id" ], name: "index_solid_queue_poll_by_queue" + t.index ["job_id"], name: "index_solid_queue_ready_executions_on_job_id", unique: true + t.index ["priority", "job_id"], name: "index_solid_queue_poll_all" + t.index ["queue_name", "priority", "job_id"], name: "index_solid_queue_poll_by_queue" end create_table "solid_queue_recurring_executions", force: :cascade do |t| @@ -79,8 +79,8 @@ t.string "task_key", null: false t.datetime "run_at", null: false t.datetime "created_at", null: false - t.index [ "job_id" ], name: "index_solid_queue_recurring_executions_on_job_id", unique: true - t.index [ "task_key", "run_at" ], name: "index_solid_queue_recurring_executions_on_task_key_and_run_at", unique: true + t.index ["job_id"], name: "index_solid_queue_recurring_executions_on_job_id", unique: true + t.index ["task_key", "run_at"], name: "index_solid_queue_recurring_executions_on_task_key_and_run_at", unique: true end create_table "solid_queue_recurring_tasks", force: :cascade do |t| @@ -95,8 +95,8 @@ t.text "description" t.datetime "created_at", null: false t.datetime "updated_at", null: false - t.index [ "key" ], name: "index_solid_queue_recurring_tasks_on_key", unique: true - t.index [ "static" ], name: "index_solid_queue_recurring_tasks_on_static" + t.index ["key"], name: "index_solid_queue_recurring_tasks_on_key", unique: true + t.index ["static"], name: "index_solid_queue_recurring_tasks_on_static" end create_table "solid_queue_scheduled_executions", force: :cascade do |t| @@ -105,8 +105,8 @@ t.integer "priority", default: 0, null: false t.datetime "scheduled_at", null: false t.datetime "created_at", null: false - t.index [ "job_id" ], name: "index_solid_queue_scheduled_executions_on_job_id", unique: true - t.index [ "scheduled_at", "priority", "job_id" ], name: "index_solid_queue_dispatch_all" + t.index ["job_id"], name: "index_solid_queue_scheduled_executions_on_job_id", unique: true + t.index ["scheduled_at", "priority", "job_id"], name: "index_solid_queue_dispatch_all" end create_table "solid_queue_semaphores", force: :cascade do |t| @@ -115,9 +115,9 @@ t.datetime "expires_at", null: false t.datetime "created_at", null: false t.datetime "updated_at", null: false - t.index [ "expires_at" ], name: "index_solid_queue_semaphores_on_expires_at" - t.index [ "key", "value" ], name: "index_solid_queue_semaphores_on_key_and_value" - t.index [ "key" ], name: "index_solid_queue_semaphores_on_key", unique: true + t.index ["expires_at"], name: "index_solid_queue_semaphores_on_expires_at" + t.index ["key", "value"], name: "index_solid_queue_semaphores_on_key_and_value" + t.index ["key"], name: "index_solid_queue_semaphores_on_key", unique: true end add_foreign_key "solid_queue_blocked_executions", "solid_queue_jobs", column: "job_id", on_delete: :cascade diff --git a/lib/account_middleware.rb b/lib/account_middleware.rb index e011375..7a3dc55 100644 --- a/lib/account_middleware.rb +++ b/lib/account_middleware.rb @@ -6,19 +6,18 @@ def initialize(app) def call(env) request = ActionDispatch::Request.new(env) - if m = /\A(\/(\d{1,}))/.match(request.path_info) - script_name, account_id, path_info = [ m[1], m[2], m.post_match ] + if (m = /\A(\/(\d{1,}))/.match(request.path_info)) + script_name, account_id, path_info = [m[1], m[2], m.post_match] request.script_name = script_name - request.path_info = path_info.presence || "/" + request.path_info = path_info.presence || "/" set_current_account(account_id) - @app.call(request.env) - else - @app.call(request.env) end + @app.call(request.env) end private - def set_current_account(account_id) - Current.account = Account.find(account_id) - end + + def set_current_account(account_id) + Current.account = Account.find(account_id) + end end diff --git a/spec/mailers/user_mailer_spec.rb b/spec/mailers/user_mailer_spec.rb index 1bf1375..3e95a1a 100644 --- a/spec/mailers/user_mailer_spec.rb +++ b/spec/mailers/user_mailer_spec.rb @@ -7,8 +7,8 @@ it "renders email" do expect(mail.subject).to eq("Benefactorum : Voici votre code de connexion") - expect(mail.to).to eq([ user.email ]) - expect(mail.from).to eq([ "contact@benefactorum.org" ]) + expect(mail.to).to eq([user.email]) + expect(mail.from).to eq(["contact@benefactorum.org"]) expect(mail.body.encoded).to include(user.otp) end end diff --git a/spec/rails_helper.rb b/spec/rails_helper.rb index 534260a..c199f85 100644 --- a/spec/rails_helper.rb +++ b/spec/rails_helper.rb @@ -1,17 +1,17 @@ # This file is copied to spec/ when you run 'rails generate rspec:install' -require 'spec_helper' -ENV['RAILS_ENV'] ||= 'test' -require_relative '../config/environment' +require "spec_helper" +ENV["RAILS_ENV"] ||= "test" +require_relative "../config/environment" # Prevent database truncation if the environment is production abort("The Rails environment is running in production mode!") if Rails.env.production? # Uncomment the line below in case you have `--require rails_helper` in the `.rspec` file # that will avoid rails generators crashing because migrations haven't been run yet # return unless Rails.env.test? -require 'rspec/rails' -require 'inertia_rails/rspec' -require 'support/factory_bot' +require "rspec/rails" +require "inertia_rails/rspec" +require "support/factory_bot" -Dir[Rails.root.join('spec/support/**/*.rb')].each { |f| require f } +Rails.root.glob("spec/support/**/*.rb").each { |f| require f } # Add additional requires below this line. Rails is not loaded until this point! @@ -40,7 +40,7 @@ RSpec.configure do |config| # Remove this line if you're not using ActiveRecord or ActiveRecord fixtures config.fixture_paths = [ - Rails.root.join('spec/fixtures') + Rails.root.join("spec/fixtures") ] # If you're not using ActiveRecord, or you'd prefer not to run each of your diff --git a/spec/requests/connections_spec.rb b/spec/requests/connections_spec.rb index 4c0adfa..78bc70c 100644 --- a/spec/requests/connections_spec.rb +++ b/spec/requests/connections_spec.rb @@ -1,4 +1,4 @@ -require 'rails_helper' +require "rails_helper" RSpec.describe "Connections", type: :request, inertia: true do describe "GET /connexion" do @@ -19,7 +19,7 @@ it_behaves_like "only_for_guests" context "when email is invalid" do - let(:params) { { email: "" } } + let(:params) { {email: ""} } it "redirects back with errors" do assert_no_emails do @@ -32,15 +32,15 @@ end context "when user is unknown" do - let(:params) { { email: "unknown@mail.com" } } + let(:params) { {email: "unknown@mail.com"} } xcontext "when rate limit is reached" do # can't get this test to pass, but feature works as expected it "rate_limit" do 9.times do - post connections_path, params: { email: "unknown@mail.com" } + post connections_path, params: {email: "unknown@mail.com"} end - post connections_path, params: { email: "unknown@mail.com" } + post connections_path, params: {email: "unknown@mail.com"} expect(response).to redirect_to(new_connection_path) follow_redirect! expect(inertia.props[:flash]).to be_present @@ -57,14 +57,14 @@ context "when user is known" do let(:user) { create(:user, otp_expires_at: DateTime.current) } - let(:params) { { email: user.email } } + let(:params) { {email: user.email} } it "redirects to /se-connecter and sends OTP email" do assert_enqueued_emails 1 do subject end otp = user.reload.otp - assert_enqueued_email_with UserMailer, :otp, params: { user:, otp: } + assert_enqueued_email_with UserMailer, :otp, params: {user:, otp:} expect(response).to redirect_to(new_session_path) end @@ -86,7 +86,7 @@ it_behaves_like "only_for_guests" context "when user is not found" do - let(:params) { { email: "unknown@mail.com" } } + let(:params) { {email: "unknown@mail.com"} } it "redirects to /connection and does not send email" do assert_no_emails do @@ -98,7 +98,7 @@ context "when user is known" do let(:user) { create(:user) } - let(:params) { { email: user.email } } + let(:params) { {email: user.email} } it "sends OTP email and redirects to /se-connecter" do assert_enqueued_emails 1 do diff --git a/spec/requests/registrations_spec.rb b/spec/requests/registrations_spec.rb index e9390c6..2621d94 100644 --- a/spec/requests/registrations_spec.rb +++ b/spec/requests/registrations_spec.rb @@ -1,4 +1,4 @@ -require 'rails_helper' +require "rails_helper" RSpec.describe "Registrations", type: :request, inertia: true do include ActiveSupport::Testing::TimeHelpers @@ -22,7 +22,7 @@ context "with invalid params" do let!(:user) { create(:user) } - let(:params) { { email: user.email, last_name: "", accepts_conditions: false } } + let(:params) { {email: user.email, last_name: "", accepts_conditions: false} } context "when captcha is invalid" do before do @@ -33,7 +33,7 @@ expect { subject }.not_to change(User, :count) expect(response).to redirect_to(new_registration_path) follow_redirect! - expect(inertia.props[:flash]['error']).to be_present + expect(inertia.props[:flash]["error"]).to be_present end end @@ -50,7 +50,7 @@ end context "when terms_and_privacy_accepted_at is hacked" do - let(:params) { { email: "new_user@mail.com", first_name: 'john', last_name: 'Doe', terms_and_privacy_accepted_at: 1.week.ago } } + let(:params) { {email: "new_user@mail.com", first_name: "john", last_name: "Doe", terms_and_privacy_accepted_at: 1.week.ago} } it "does not create a new user" do expect { subject }.not_to change(User, :count) @@ -63,7 +63,7 @@ end context "with valid params" do - let(:params) { { email: "lazaronixon@hey.com", first_name: "Lazaro", last_name: "Nixon", accepts_conditions: true } } + let(:params) { {email: "lazaronixon@hey.com", first_name: "Lazaro", last_name: "Nixon", accepts_conditions: true} } before do allow_any_instance_of(Captcha).to receive(:valid?).and_return(true) @@ -79,7 +79,7 @@ expect(user.terms_and_privacy_accepted_at).to eq(Time.current) otp = user.reload.otp - assert_enqueued_email_with UserMailer, :otp, params: { user:, otp: } + assert_enqueued_email_with UserMailer, :otp, params: {user:, otp:} expect(response).to redirect_to(new_session_path) end diff --git a/spec/requests/sessions_spec.rb b/spec/requests/sessions_spec.rb index ffc12bb..a5779bd 100644 --- a/spec/requests/sessions_spec.rb +++ b/spec/requests/sessions_spec.rb @@ -1,4 +1,4 @@ -require 'rails_helper' +require "rails_helper" RSpec.describe "Sessions", type: :request, inertia: true do describe "GET /se-connecter" do @@ -20,7 +20,7 @@ context "with invalid params" do context "when email is invalid" do - let(:params) { { email: "" } } + let(:params) { {email: ""} } it "returns not found status" do subject @@ -30,7 +30,7 @@ context "when code is invalid" do let!(:user) { create(:user) } - let(:params) { { email: user.email, code: "" } } + let(:params) { {email: user.email, code: ""} } it "redirects back with errors" do subject @@ -43,13 +43,13 @@ context "with valid params" do let(:user) { create(:user) } - let(:params) { { email: user.email, code: user.otp } } + let(:params) { {email: user.email, code: user.otp} } it "signs in the user" do subject expect(response).to redirect_to(root_path) follow_redirect! - expect(inertia.props[:flash]['success']).to be_present + expect(inertia.props[:flash]["success"]).to be_present end end end @@ -83,7 +83,7 @@ subject expect(response).to redirect_to(root_path) follow_redirect! - expect(inertia.props[:flash]['success']).to be_present + expect(inertia.props[:flash]["success"]).to be_present end end end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 1429dc5..2f9c515 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -49,46 +49,44 @@ # you configure your source control system to ignore this file. config.example_status_persistence_file_path = "spec/examples.txt" -# The settings below are suggested to provide a good initial experience -# with RSpec, but feel free to customize to your heart's content. -=begin - # This allows you to limit a spec run to individual examples or groups - # you care about by tagging them with `:focus` metadata. When nothing - # is tagged with `:focus`, all examples get run. RSpec also provides - # aliases for `it`, `describe`, and `context` that include `:focus` - # metadata: `fit`, `fdescribe` and `fcontext`, respectively. - config.filter_run_when_matching :focus - - # Limits the available syntax to the non-monkey patched syntax that is - # recommended. For more details, see: - # https://rspec.info/features/3-12/rspec-core/configuration/zero-monkey-patching-mode/ - config.disable_monkey_patching! - - # Many RSpec users commonly either run the entire suite or an individual - # file, and it's useful to allow more verbose output when running an - # individual spec file. - if config.files_to_run.one? - # Use the documentation formatter for detailed output, - # unless a formatter has already been configured - # (e.g. via a command-line flag). - config.default_formatter = "doc" - end - - # Print the 10 slowest examples and example groups at the - # end of the spec run, to help surface which specs are running - # particularly slow. - config.profile_examples = 10 - - # Run specs in random order to surface order dependencies. If you find an - # order dependency and want to debug it, you can fix the order by providing - # the seed, which is printed after each run. - # --seed 1234 - config.order = :random - - # Seed global randomization in this process using the `--seed` CLI option. - # Setting this allows you to use `--seed` to deterministically reproduce - # test failures related to randomization by passing the same `--seed` value - # as the one that triggered the failure. - Kernel.srand config.seed -=end + # The settings below are suggested to provide a good initial experience + # with RSpec, but feel free to customize to your heart's content. + # # This allows you to limit a spec run to individual examples or groups + # # you care about by tagging them with `:focus` metadata. When nothing + # # is tagged with `:focus`, all examples get run. RSpec also provides + # # aliases for `it`, `describe`, and `context` that include `:focus` + # # metadata: `fit`, `fdescribe` and `fcontext`, respectively. + # config.filter_run_when_matching :focus + # + # # Limits the available syntax to the non-monkey patched syntax that is + # # recommended. For more details, see: + # # https://rspec.info/features/3-12/rspec-core/configuration/zero-monkey-patching-mode/ + # config.disable_monkey_patching! + # + # # Many RSpec users commonly either run the entire suite or an individual + # # file, and it's useful to allow more verbose output when running an + # # individual spec file. + # if config.files_to_run.one? + # # Use the documentation formatter for detailed output, + # # unless a formatter has already been configured + # # (e.g. via a command-line flag). + # config.default_formatter = "doc" + # end + # + # # Print the 10 slowest examples and example groups at the + # # end of the spec run, to help surface which specs are running + # # particularly slow. + # config.profile_examples = 10 + # + # # Run specs in random order to surface order dependencies. If you find an + # # order dependency and want to debug it, you can fix the order by providing + # # the seed, which is printed after each run. + # # --seed 1234 + # config.order = :random + # + # # Seed global randomization in this process using the `--seed` CLI option. + # # Setting this allows you to use `--seed` to deterministically reproduce + # # test failures related to randomization by passing the same `--seed` value + # # as the one that triggered the failure. + # Kernel.srand config.seed end diff --git a/spec/support/authentication_helpers.rb b/spec/support/authentication_helpers.rb index 86c14b3..ef94289 100644 --- a/spec/support/authentication_helpers.rb +++ b/spec/support/authentication_helpers.rb @@ -1,5 +1,5 @@ RSpec.configure do def sign_in_as(user) - post sessions_path, params: { email: user.email, code: user.otp } + post sessions_path, params: {email: user.email, code: user.otp} end end diff --git a/spec/support/shared_examples/only_for_guests.rb b/spec/support/shared_examples/only_for_guests.rb index 6d47c26..8620315 100644 --- a/spec/support/shared_examples/only_for_guests.rb +++ b/spec/support/shared_examples/only_for_guests.rb @@ -8,7 +8,7 @@ subject expect(response).to redirect_to(root_path) follow_redirect! - expect(inertia.props[:flash]['info']).to be_present + expect(inertia.props[:flash]["info"]).to be_present end end end diff --git a/spec/support/shared_examples/require_authentication.rb b/spec/support/shared_examples/require_authentication.rb index d67102a..835095e 100644 --- a/spec/support/shared_examples/require_authentication.rb +++ b/spec/support/shared_examples/require_authentication.rb @@ -4,7 +4,7 @@ subject expect(response).to redirect_to(new_connection_path) follow_redirect! - expect(inertia.props[:flash]['info']).to be_present + expect(inertia.props[:flash]["info"]).to be_present end end end diff --git a/test/application_system_test_case.rb b/test/application_system_test_case.rb index 6e09319..ec82c46 100644 --- a/test/application_system_test_case.rb +++ b/test/application_system_test_case.rb @@ -4,11 +4,11 @@ class ApplicationSystemTestCase < ActionDispatch::SystemTestCase if ENV["CAPYBARA_SERVER_PORT"] served_by host: "rails-app", port: ENV["CAPYBARA_SERVER_PORT"] - driven_by :selenium, using: :headless_chrome, screen_size: [ 1400, 1400 ], options: { + driven_by :selenium, using: :headless_chrome, screen_size: [1400, 1400], options: { browser: :remote, url: "http://#{ENV["SELENIUM_HOST"]}:4444" } else - driven_by :selenium, using: :headless_chrome, screen_size: [ 1400, 1400 ] + driven_by :selenium, using: :headless_chrome, screen_size: [1400, 1400] end end diff --git a/test/controllers/identity/email_verifications_controller_test.rb b/test/controllers/identity/email_verifications_controller_test.rb index 488f7a6..52a9ca8 100644 --- a/test/controllers/identity/email_verifications_controller_test.rb +++ b/test/controllers/identity/email_verifications_controller_test.rb @@ -8,7 +8,7 @@ class Identity::EmailVerificationsControllerTest < ActionDispatch::IntegrationTe test "should send a verification email" do skip - assert_enqueued_email_with UserMailer, :email_verification, params: { user: @user } do + assert_enqueued_email_with UserMailer, :email_verification, params: {user: @user} do post identity_email_verification_url end diff --git a/test/controllers/identity/emails_controller_test.rb b/test/controllers/identity/emails_controller_test.rb index c46964d..929db82 100644 --- a/test/controllers/identity/emails_controller_test.rb +++ b/test/controllers/identity/emails_controller_test.rb @@ -13,14 +13,13 @@ class Identity::EmailsControllerTest < ActionDispatch::IntegrationTest test "should update email" do skip - patch identity_email_url, params: { email: "new_email@hey.com", password_challenge: "Secret1*3*5*" } + patch identity_email_url, params: {email: "new_email@hey.com", password_challenge: "Secret1*3*5*"} assert_redirected_to root_url end - test "should not update email with wrong password challenge" do skip - patch identity_email_url, params: { email: "new_email@hey.com", password_challenge: "SecretWrong1*3" } + patch identity_email_url, params: {email: "new_email@hey.com", password_challenge: "SecretWrong1*3"} assert_response :unprocessable_entity assert_select "li", /Password challenge is invalid/ diff --git a/test/controllers/identity/password_resets_controller_test.rb b/test/controllers/identity/password_resets_controller_test.rb index 0702ab0..37cb1f2 100644 --- a/test/controllers/identity/password_resets_controller_test.rb +++ b/test/controllers/identity/password_resets_controller_test.rb @@ -18,8 +18,8 @@ class Identity::PasswordResetsControllerTest < ActionDispatch::IntegrationTest end test "should send a password reset email" do - assert_enqueued_email_with UserMailer, :password_reset, params: { user: @user } do - post identity_password_reset_url, params: { email: @user.email } + assert_enqueued_email_with UserMailer, :password_reset, params: {user: @user} do + post identity_password_reset_url, params: {email: @user.email} end assert_redirected_to new_session_url @@ -27,7 +27,7 @@ class Identity::PasswordResetsControllerTest < ActionDispatch::IntegrationTest test "should not send a password reset email to a nonexistent email" do assert_no_enqueued_emails do - post identity_password_reset_url, params: { email: "invalid_email@hey.com" } + post identity_password_reset_url, params: {email: "invalid_email@hey.com"} end assert_redirected_to new_identity_password_reset_url @@ -38,7 +38,7 @@ class Identity::PasswordResetsControllerTest < ActionDispatch::IntegrationTest @user.update! verified: false assert_no_enqueued_emails do - post identity_password_reset_url, params: { email: @user.email } + post identity_password_reset_url, params: {email: @user.email} end assert_redirected_to new_identity_password_reset_url @@ -48,7 +48,7 @@ class Identity::PasswordResetsControllerTest < ActionDispatch::IntegrationTest test "should update password" do sid = @user.generate_token_for(:password_reset) - patch identity_password_reset_url, params: { sid: sid, password: "Secret6*4*2*", password_confirmation: "Secret6*4*2*" } + patch identity_password_reset_url, params: {sid: sid, password: "Secret6*4*2*", password_confirmation: "Secret6*4*2*"} assert_redirected_to new_session_url end @@ -57,7 +57,7 @@ class Identity::PasswordResetsControllerTest < ActionDispatch::IntegrationTest travel 30.minutes - patch identity_password_reset_url, params: { sid: sid, password: "Secret6*4*2*", password_confirmation: "Secret6*4*2*" } + patch identity_password_reset_url, params: {sid: sid, password: "Secret6*4*2*", password_confirmation: "Secret6*4*2*"} assert_redirected_to new_identity_password_reset_url assert_equal "That password reset link is invalid", flash[:error] diff --git a/test/controllers/passwords_controller_test.rb b/test/controllers/passwords_controller_test.rb index aa2e3b1..245800e 100644 --- a/test/controllers/passwords_controller_test.rb +++ b/test/controllers/passwords_controller_test.rb @@ -13,13 +13,13 @@ class PasswordsControllerTest < ActionDispatch::IntegrationTest test "should update password" do skip - patch password_url, params: { password_challenge: "Secret1*3*5*", password: "Secret6*4*2*", password_confirmation: "Secret6*4*2*" } + patch password_url, params: {password_challenge: "Secret1*3*5*", password: "Secret6*4*2*", password_confirmation: "Secret6*4*2*"} assert_redirected_to root_url end test "should not update password with wrong password challenge" do skip - patch password_url, params: { password_challenge: "SecretWrong1*3", password: "Secret6*4*2*", password_confirmation: "Secret6*4*2*" } + patch password_url, params: {password_challenge: "SecretWrong1*3", password: "Secret6*4*2*", password_confirmation: "Secret6*4*2*"} assert_response :unprocessable_entity assert_select "li", /Password challenge is invalid/ diff --git a/test/mailers/user_mailer_test.rb b/test/mailers/user_mailer_test.rb index ec7dcbe..b490fc7 100644 --- a/test/mailers/user_mailer_test.rb +++ b/test/mailers/user_mailer_test.rb @@ -10,12 +10,12 @@ class UserMailerTest < ActionMailer::TestCase test "password_reset" do mail = UserMailer.with(user: @user).password_reset assert_equal "Reset your password", mail.subject - assert_equal [ @user.email ], mail.to + assert_equal [@user.email], mail.to end test "email_verification" do mail = UserMailer.with(user: @user).email_verification assert_equal "Verify your email", mail.subject - assert_equal [ @user.email ], mail.to + assert_equal [@user.email], mail.to end end diff --git a/test/test_helper.rb b/test/test_helper.rb index 3b80eee..cd03746 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -11,6 +11,7 @@ class ActiveSupport::TestCase # Add more helper methods to be used by all tests here... def sign_in_as(user) - post(new_session_url, params: { email: user.email, password: "Secret1*3*5*" }); user + post(new_session_url, params: {email: user.email, password: "Secret1*3*5*"}) + user end end