diff --git a/Guardfile.rb b/Guardfile.rb index 7450267..25aa1cf 100644 --- a/Guardfile.rb +++ b/Guardfile.rb @@ -3,7 +3,7 @@ # TODO: Check this, just copied from Engine -guard 'rspec', :version => 2 do +guard 'rspec', version: 2 do watch(%r{^spec/.+_spec\.rb$}) watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" } watch('spec/spec_helper.rb') { "spec" } @@ -13,7 +13,9 @@ watch(%r{^app/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" } watch(%r{^app/(.*)(\.erb|\.haml)$}) { |m| "spec/#{m[1]}#{m[2]}_spec.rb" } watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" } - watch(%r{^app/controllers/(.+)_(controller)\.rb$}) { |m| ["spec/routing/#{m[1]}_routing_spec.rb", "spec/#{m[2]}s/#{m[1]}_#{m[2]}_spec.rb", "spec/acceptance/#{m[1]}_spec.rb"] } + watch(%r{^app/controllers/(.+)_(controller)\.rb$}) { |m| + [ "spec/routing/#{m[1]}_routing_spec.rb", "spec/#{m[2]}s/#{m[1]}_#{m[2]}_spec.rb", +"spec/acceptance/#{m[1]}_spec.rb" ] } watch(%r{^spec/support/(.+)\.rb$}) { "spec" } watch('spec/spec_helper.rb') { "spec" } watch('config/routes.rb') { "spec/routing" } diff --git a/app/components/css_classes.rb b/app/components/css_classes.rb index 121bb74..ad0f7e1 100644 --- a/app/components/css_classes.rb +++ b/app/components/css_classes.rb @@ -4,6 +4,6 @@ module CssClasses private def merge_attributes(attributes) - attributes.merge(class: [attributes[:class], *self.class::DEFAULT_CLASSES].compact.join(' ')) + attributes.merge(class: [ attributes[:class], *self.class::DEFAULT_CLASSES ].compact.join(" ")) end end diff --git a/app/components/hovercard/component.rb b/app/components/hovercard/component.rb index 70c5817..690d0f9 100644 --- a/app/components/hovercard/component.rb +++ b/app/components/hovercard/component.rb @@ -4,6 +4,6 @@ module Hovercard class Component < ApplicationComponent option :path option :text, default: proc { "" } - option :placement_class, default: proc { 'right-2' } + option :placement_class, default: proc { "right-2" } end end diff --git a/app/components/identity/sidebar_item_component.rb b/app/components/identity/sidebar_item_component.rb index 398da6d..1dd5c5b 100644 --- a/app/components/identity/sidebar_item_component.rb +++ b/app/components/identity/sidebar_item_component.rb @@ -5,7 +5,7 @@ class Identity::SidebarItemComponent < ApplicationComponent option :title option :explanation option :active, default: proc { false } - option :icon, default: proc { 'identification' } + option :icon, default: proc { "identification" } def css_classes if @active diff --git a/app/components/identity/token_component.rb b/app/components/identity/token_component.rb index b3719df..5d70f55 100644 --- a/app/components/identity/token_component.rb +++ b/app/components/identity/token_component.rb @@ -5,7 +5,7 @@ class Identity::TokenComponent < ApplicationComponent include Turbo::FramesHelper # TODO: this should not be here - TOKEN_PREFIX = Rails.env.staging? ? 'etm_beta_' : 'etm_' + TOKEN_PREFIX = Rails.env.staging? ? "etm_beta_" : "etm_" def initialize(token:) @token = token diff --git a/app/components/login/action_arrow_component.rb b/app/components/login/action_arrow_component.rb index 68a358d..ec4527f 100644 --- a/app/components/login/action_arrow_component.rb +++ b/app/components/login/action_arrow_component.rb @@ -3,7 +3,7 @@ module Login class ActionArrowComponent < ApplicationComponent def call - heroicon @icon, options: { class: 'flex-shrink-0 ml-1 mt-px group-hover:translate-x-1 group-active:translate-x-1 transition duration-300', aria_hidden: true } + heroicon(@icon, options: { class: "flex-shrink-0 ml-1 mt-px group-hover:translate-x-1 group-active:translate-x-1 transition duration-300", aria_hidden: true }) end end end diff --git a/app/components/login/action_button_component.rb b/app/components/login/action_button_component.rb index 6664a5c..c67036d 100644 --- a/app/components/login/action_button_component.rb +++ b/app/components/login/action_button_component.rb @@ -4,16 +4,16 @@ module Login class ActionButtonComponent < ApplicationComponent include ButtonHelper - BASE_CLASSES = 'text-base flex items-center justify-center group' + BASE_CLASSES = "text-base flex items-center justify-center group" def initialize(form:, color: :default, size: :base, **attributes) @form = form - additional_classes = [BASE_CLASSES, attributes.delete(:class)].compact.join(' ') + additional_classes = [ BASE_CLASSES, attributes.delete(:class) ].compact.join(" ") @attributes = attributes.merge( class: button_classes(additional_classes, color:, size:), - type: attributes[:type] || 'submit' + type: attributes[:type] || "submit" ) end end diff --git a/app/components/login/button_component.rb b/app/components/login/button_component.rb index a385226..b6e88cf 100644 --- a/app/components/login/button_component.rb +++ b/app/components/login/button_component.rb @@ -3,7 +3,7 @@ module Login class ButtonComponent < ActionButtonComponent def initialize(form:) - super(form:, type: :submit, color: :primary, size: :lg, class: 'w-full !py-3 mt-5 bg-midnight-600') + super(form:, type: :submit, color: :primary, size: :lg, class: "w-full !py-3 mt-5 bg-midnight-600") end end end diff --git a/app/components/modal_component.rb b/app/components/modal_component.rb index 676bef4..0870c81 100644 --- a/app/components/modal_component.rb +++ b/app/components/modal_component.rb @@ -22,11 +22,11 @@ def stimulus @stimulus ||= if turbo_modal? StimulusConfig.new( - controller: 'modal', + controller: "modal", turbo_frame_id: :modal, - button_close_action: 'click->modal#close', - backdrop_close_action: 'mousedown->modal#closeWithBackdrop', - keyboard_close_action: 'keyup@window->modal#closeWithKeyboard' + button_close_action: "click->modal#close", + backdrop_close_action: "mousedown->modal#closeWithBackdrop", + keyboard_close_action: "keyup@window->modal#closeWithKeyboard" ) else StimulusConfig.new(turbo_frame_id: :static_modal) @@ -44,6 +44,6 @@ def close_link(inline_content, url = nil, **kwargs) private def turbo_modal? - request.headers['Turbo-Frame'] == 'modal' + request.headers["Turbo-Frame"] == "modal" end end diff --git a/app/components/notice_banner/component.rb b/app/components/notice_banner/component.rb index ec45f25..91dfe11 100644 --- a/app/components/notice_banner/component.rb +++ b/app/components/notice_banner/component.rb @@ -3,6 +3,6 @@ class Component < ApplicationComponent option :text option :path, default: proc { "" } option :button_text, default: proc { "" } - option :icon, default: proc { 'information-circle' } + option :icon, default: proc { "information-circle" } end end diff --git a/app/components/saved_scenario_user/user_row/component.rb b/app/components/saved_scenario_user/user_row/component.rb index 43f0e77..354d42e 100644 --- a/app/components/saved_scenario_user/user_row/component.rb +++ b/app/components/saved_scenario_user/user_row/component.rb @@ -28,9 +28,9 @@ def destroy_classes def destroy_text if @destroyable - t('saved_scenario_users.confirm_destroy.button') + t("saved_scenario_users.confirm_destroy.button") else - t('saved_scenario_users.confirm_destroy.not_possible') + t("saved_scenario_users.confirm_destroy.not_possible") end end end diff --git a/app/components/toast_component.rb b/app/components/toast_component.rb index bc11b03..ab5599b 100644 --- a/app/components/toast_component.rb +++ b/app/components/toast_component.rb @@ -5,8 +5,8 @@ def initialize(message:, type: :notice) @type = type if message.is_a?(Hash) - @title = no_break_on_hyphen(message[:title] || message['title']) - @message = no_break_on_hyphen(message[:message] || message['message']) + @title = no_break_on_hyphen(message[:title] || message["title"]) + @message = no_break_on_hyphen(message[:message] || message["message"]) else @message = no_break_on_hyphen(message) end @@ -16,6 +16,6 @@ def initialize(message:, type: :notice) # Replaces any hyphen in the message with a character taht won't trigger line breaks. def no_break_on_hyphen(string) - string.tr('-', '‑') + string.tr("-", "‑") end end diff --git a/app/controllers/admin/saved_scenarios_controller.rb b/app/controllers/admin/saved_scenarios_controller.rb index 2647f8f..610c18b 100644 --- a/app/controllers/admin/saved_scenarios_controller.rb +++ b/app/controllers/admin/saved_scenarios_controller.rb @@ -5,7 +5,7 @@ class SavedScenariosController < ApplicationController def index @saved_scenarios = SavedScenario.available .includes(:featured_scenario, :users) - .order('updated_at DESC') + .order("updated_at DESC") end end end diff --git a/app/controllers/admin/staff_applications_controller.rb b/app/controllers/admin/staff_applications_controller.rb index f611048..61b6831 100644 --- a/app/controllers/admin/staff_applications_controller.rb +++ b/app/controllers/admin/staff_applications_controller.rb @@ -1,5 +1,6 @@ # frozen_string_literal: true -require 'myetm/staff_applications' + +require "myetm/staff_applications" module Admin # Updates a staff application with a new URI. @@ -19,7 +20,7 @@ def update ) if result.success? - flash[:notice] = 'The application was updated.' + flash[:notice] = "The application was updated." else flash[:alert] = result.failure.errors.full_messages.to_sentence end diff --git a/app/controllers/admin/users_controller.rb b/app/controllers/admin/users_controller.rb index 47118a6..061fda4 100644 --- a/app/controllers/admin/users_controller.rb +++ b/app/controllers/admin/users_controller.rb @@ -11,26 +11,27 @@ def org # All users def all - @users = User.all.includes(:saved_scenarios)#, :collections) + @users = User.all.includes(:saved_scenarios) # , :collections) end - # Instant confirmation for our users that struggel with their spam + # Instant confirmation for our users that struggle with their spam def confirm @user.confirm! + flash[:notice] = "User confirmed." end def edit; end def update - if @user.update!(user_params.compact_blank) - flash[:notice] = t('admin.users.edit.success') + if @user.update(user_params.compact_blank) + flash[:notice] = t("admin.users.edit.success") respond_to do |format| format.html { redirect_to(admin_users_path) } format.turbo_stream do render turbo_stream: [ - turbo_stream.update(:modal, ''), + turbo_stream.update(:modal, ""), turbo_user, turbo_notice ] @@ -48,19 +49,17 @@ def set_user end def user_params - params.require(:user).permit(:name, :email, :password, :admin) + attributes = [:name, :email, :password] + attributes << :admin if current_user&.admin? + params.require(:user).permit(*attributes) end def turbo_notice(message = nil) - if message.nil? - message = flash[:notice] - flash.delete(:notice) - end - + message ||= flash.delete(:notice) return if message.nil? turbo_stream.update( - 'toast', + "toast", ToastComponent.new(type: :notice, message:).render_in(view_context) ) end diff --git a/app/controllers/api/v1/base_controller.rb b/app/controllers/api/v1/base_controller.rb index a75da3d..010d0e6 100644 --- a/app/controllers/api/v1/base_controller.rb +++ b/app/controllers/api/v1/base_controller.rb @@ -6,12 +6,12 @@ class BaseController < ActionController::API before_action :authenticate_request! rescue_from ActionController::ParameterMissing do |e| - render json: { errors: [e.message] }, status: :bad_request + render json: { errors: [ e.message ] }, status: :bad_request end rescue_from ActiveRecord::RecordNotFound do |e| render json: { - errors: ["No such #{e.model.underscore.humanize.downcase}: #{e.id}"] + errors: [ "No such #{e.model.underscore.humanize.downcase}: #{e.id}" ] }, status: :not_found end @@ -21,14 +21,14 @@ class BaseController < ActionController::API rescue_from CanCan::AccessDenied do |e| if e.subject.is_a?(SavedScenario) && !e.subject.private? - render status: :forbidden, json: { errors: ['Scenario does not belong to you'] } + render status: :forbidden, json: { errors: [ "Scenario does not belong to you" ] } else render_not_found end end rescue_from MyEtm::Auth::DecodeError do - render json: { errors: ['Invalid or expired token'] }, status: :unauthorized + render json: { errors: [ "Invalid or expired token" ] }, status: :unauthorized end private @@ -37,13 +37,13 @@ class BaseController < ActionController::API def decoded_token return @decoded_token if defined?(@decoded_token) - auth_header = request.headers['Authorization'] - token = auth_header&.split(' ')&.last + auth_header = request.headers["Authorization"] + token = auth_header&.split(" ")&.last return nil unless token @decoded_token = MyEtm::Auth.decode(token) rescue MyEtm::Auth::DecodeError, MyEtm::Auth::TokenExchangeError => e - Rails.logger.debug "Token decoding failed: #{e.message}" + Rails.logger.debug("Token decoding failed: #{e.message}") nil end @@ -78,15 +78,15 @@ def authenticate_request! @current_user = User.find(doorkeeper_token.resource_owner_id) elsif decoded_token unless current_user - render json: { errors: ['Unauthorized'] }, status: :unauthorized + render json: { errors: [ "Unauthorized" ] }, status: :unauthorized end else - render json: { errors: ['Authentication required'] }, status: :unauthorized + render json: { errors: [ "Authentication required" ] }, status: :unauthorized end end # Send a 404 response with an optional JSON body. - def render_not_found(body = { errors: ['Not found'] }) + def render_not_found(body = { errors: [ "Not found" ] }) render json: body, status: :not_found end @@ -99,7 +99,7 @@ def render_not_found(body = { errors: ['Not found'] }) def process_action(*args) super rescue ActionDispatch::Http::Parameters::ParseError => e - render status: 400, json: { errors: [e.message] } + render status: 400, json: { errors: [ e.message ] } end def track_token_use @@ -122,7 +122,6 @@ def find_user_from_token user_data = decoded_token[:user] User.find_or_create_by(id: decoded_token[:sub]) do |user| user.assign_attributes(user_data) - end end diff --git a/app/controllers/api/v1/saved_scenarios_controller.rb b/app/controllers/api/v1/saved_scenarios_controller.rb index fbc7f5c..7a3b6ac 100644 --- a/app/controllers/api/v1/saved_scenarios_controller.rb +++ b/app/controllers/api/v1/saved_scenarios_controller.rb @@ -1,7 +1,6 @@ module Api module V1 class SavedScenariosController < BaseController - load_and_authorize_resource(class: SavedScenario, only: %i[index show create update destroy]) # GET /saved_scenarios or /saved_scenarios.json @@ -10,7 +9,7 @@ def index .saved_scenarios .available .includes(:featured_scenario, :users) - .order('updated_at DESC') + .order("updated_at DESC") render json: saved_scenarios end diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index a4d9ce1..6b308b2 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -84,12 +84,12 @@ def engine_client # # Returns true. def render_not_found(thing = nil) - content = Rails.root.join('public/404.html').read + content = Rails.root.join("public/404.html").read unless thing.nil? # Swap out the word "page" for something else, when appropriate. document = Nokogiri::HTML.parse(content) - header = document.at_css('h1') + header = document.at_css("h1") header.content = header.content.sub(/\bpage\b/, thing) content = document.to_s @@ -113,7 +113,7 @@ def turbo_notice(message = nil) return if message.nil? turbo_stream.update( - 'toast', + "toast", ToastComponent.new(type: :notice, message:).render_in(view_context) ) end @@ -127,7 +127,7 @@ def turbo_alert(message = nil) return if message.nil? turbo_stream.update( - 'toast', + "toast", ToastComponent.new(type: :alert, message:).render_in(view_context) ) end diff --git a/app/controllers/discarded_controller.rb b/app/controllers/discarded_controller.rb index fd73f3d..a3cb5b8 100644 --- a/app/controllers/discarded_controller.rb +++ b/app/controllers/discarded_controller.rb @@ -7,6 +7,6 @@ def index .saved_scenarios .discarded .includes(:featured_scenario, :users) - .order('updated_at DESC') + .order("updated_at DESC") end end diff --git a/app/controllers/featured_scenarios_controller.rb b/app/controllers/featured_scenarios_controller.rb index a263bd0..a497a02 100644 --- a/app/controllers/featured_scenarios_controller.rb +++ b/app/controllers/featured_scenarios_controller.rb @@ -33,7 +33,7 @@ def update end def confirm_destroy - render :confirm_destroy, layout: 'application' + render :confirm_destroy, layout: "application" end def destroy diff --git a/app/controllers/identity/access_tokens_controller.rb b/app/controllers/identity/access_tokens_controller.rb index 0be57cf..f2c5627 100644 --- a/app/controllers/identity/access_tokens_controller.rb +++ b/app/controllers/identity/access_tokens_controller.rb @@ -9,9 +9,9 @@ def create # Validate client credentials if valid_client? token = generate_access_token - render json: { access_token: token, token_type: 'Bearer', expires_in: 3600 } + render json: { access_token: token, token_type: "Bearer", expires_in: 3600 } else - render json: { error: 'invalid_client' }, status: :unauthorized + render json: { error: "invalid_client" }, status: :unauthorized end end diff --git a/app/controllers/identity/newsletter_controller.rb b/app/controllers/identity/newsletter_controller.rb index a4c7a56..cefd8e9 100644 --- a/app/controllers/identity/newsletter_controller.rb +++ b/app/controllers/identity/newsletter_controller.rb @@ -7,7 +7,7 @@ class NewsletterController < ApplicationController before_action :require_mailchimp_configured def edit - return redirect_to(identity_profile_path) unless turbo_frame_request? + redirect_to(identity_profile_path) unless turbo_frame_request? end def update diff --git a/app/controllers/identity/settings_controller.rb b/app/controllers/identity/settings_controller.rb index 9af5fed..438b72c 100644 --- a/app/controllers/identity/settings_controller.rb +++ b/app/controllers/identity/settings_controller.rb @@ -17,7 +17,7 @@ def update_name if @user.update(update_params) redirect_to( identity_profile_path, - notice: I18n.t('identity.settings.update_name.success') + notice: I18n.t("identity.settings.update_name.success") ) SyncUserJob.perform_later(@user.id) @@ -41,7 +41,7 @@ def update_email redirect_to( identity_profile_path, - notice: I18n.t('identity.settings.update_email.success') + notice: I18n.t("identity.settings.update_email.success") ) else render(:edit_email, status: :unprocessable_entity) @@ -63,7 +63,7 @@ def update_password redirect_to( identity_profile_path, - notice: I18n.t('identity.settings.update_password.success') + notice: I18n.t("identity.settings.update_password.success") ) else render(:edit_password, status: :unprocessable_entity) diff --git a/app/controllers/identity/tokens_controller.rb b/app/controllers/identity/tokens_controller.rb index 399d95d..2d0d8af 100644 --- a/app/controllers/identity/tokens_controller.rb +++ b/app/controllers/identity/tokens_controller.rb @@ -29,7 +29,7 @@ def create else Identity::TokenMailer.created_token(result.value!).deliver_later - flash[:notice] = t('identity.tokens.created') + flash[:notice] = t("identity.tokens.created") redirect_to identity_tokens_path end end @@ -40,7 +40,7 @@ def create def destroy token.oauth_access_token.update!(revoked_at: Time.now.utc) - flash[:notice] = t('identity.tokens.revoked') + flash[:notice] = t("identity.tokens.revoked") respond_to do |format| format.html { redirect_to identity_tokens_path } @@ -49,10 +49,10 @@ def destroy ui_action = if current_user.personal_access_tokens.not_expired.count.positive? turbo_stream.remove(token) else - turbo_stream.replace(@token, partial: 'identity/tokens/empty_state') + turbo_stream.replace(@token, partial: "identity/tokens/empty_state") end - render turbo_stream: [ui_action, turbo_notice] + render turbo_stream: [ ui_action, turbo_notice ] end end end diff --git a/app/controllers/saved_scenario_users_controller.rb b/app/controllers/saved_scenario_users_controller.rb index 2958f59..0627e92 100644 --- a/app/controllers/saved_scenario_users_controller.rb +++ b/app/controllers/saved_scenario_users_controller.rb @@ -28,7 +28,7 @@ def new saved_scenario_id: @saved_scenario.id ) - render 'new', layout: 'application' + render "new", layout: "application" end # Creates a new SavedScenarioUser for the given SavedScenario. @@ -102,7 +102,7 @@ def update # # GET /saved_scenarios/:saved_scenario_id/users/:id/confirm_destroy def confirm_destroy - render 'confirm_destroy', layout: 'application' + render "confirm_destroy", layout: "application" end # Destroys an existing SavedScenarioUser for this SavedScenario. @@ -127,7 +127,8 @@ def destroy end else puts result.errors - flash[:alert] = "#{t('saved_scenario_users.errors.destroy')} #{t('saved_scenario_users.errors.general')}" + flash[:alert] = +"#{t('saved_scenario_users.errors.destroy')} #{t('saved_scenario_users.errors.general')}" respond_to do |format| format.turbo_stream do @@ -161,7 +162,7 @@ def assign_saved_scenario def assign_saved_scenario_user @saved_scenario_user = @saved_scenario.saved_scenario_users.find(permitted_params[:id]) rescue ActiveRecord::RecordNotFound - redirect_to saved_scenario_users_path, notice: 'Something went wrong' + redirect_to saved_scenario_users_path, notice: "Something went wrong" end def turbo_append_user diff --git a/app/controllers/saved_scenarios_controller.rb b/app/controllers/saved_scenarios_controller.rb index 68a3a5e..0d33f5d 100644 --- a/app/controllers/saved_scenarios_controller.rb +++ b/app/controllers/saved_scenarios_controller.rb @@ -18,7 +18,7 @@ def index .saved_scenarios .available .includes(:featured_scenario, :users) - .order('updated_at DESC') + .order("updated_at DESC") end # GET /saved_scenarios/1 or /saved_scenarios/1.json @@ -77,13 +77,13 @@ def update end def confirm_destroy - render :confirm_destroy, layout: 'application' + render :confirm_destroy, layout: "application" end # DELETE /saved_scenarios/1 or /saved_scenarios/1.json def destroy @saved_scenario.destroy - flash.notice = t('scenario.trash.deleted_flash') + flash.notice = t("scenario.trash.deleted_flash") redirect_to discarded_path end @@ -121,7 +121,7 @@ def discard @saved_scenario.discarded_at = Time.zone.now @saved_scenario.save(touch: false) - flash.notice = t('trash.discarded_flash') + flash.notice = t("trash.discarded_flash") flash[:undo_params] = undiscard_saved_scenario_path(@saved_scenario) end @@ -136,7 +136,7 @@ def undiscard @saved_scenario.discarded_at = nil @saved_scenario.save(touch: false) - flash.notice = t('trash.undiscarded_flash') + flash.notice = t("trash.undiscarded_flash") flash[:undo_params] = discard_saved_scenario_path(@saved_scenario) end diff --git a/app/controllers/static_pages_controller.rb b/app/controllers/static_pages_controller.rb index b0baa20..876c353 100644 --- a/app/controllers/static_pages_controller.rb +++ b/app/controllers/static_pages_controller.rb @@ -1,5 +1,5 @@ class StaticPagesController < ApplicationController - before_action :require_feedback_email, only: [:send_message] + before_action :require_feedback_email, only: [ :send_message ] # invisible_captcha( # only: [:send_message], @@ -8,7 +8,6 @@ class StaticPagesController < ApplicationController # ) def empty - end def contact @@ -32,13 +31,13 @@ def send_message ContactUsMailer.contact_email( @message, locale: I18n.locale, - user_agent: request.env['HTTP_USER_AGENT'] + user_agent: request.env["HTTP_USER_AGENT"] ).deliver - flash[:notice] = t('contact.contact.success_flash') + flash[:notice] = t("contact.contact.success_flash") redirect_to contact_url else - flash[:alert] = @message.errors.join(', ') + flash[:alert] = @message.errors.join(", ") redirect_to contact_url end end diff --git a/app/controllers/users/devise_controller.rb b/app/controllers/users/devise_controller.rb index 0fb241c..07036f8 100644 --- a/app/controllers/users/devise_controller.rb +++ b/app/controllers/users/devise_controller.rb @@ -2,7 +2,7 @@ module Users class DeviseController < ApplicationController - layout 'login' + layout "login" # Used to make Devise compatible with Turbo. class Responder < ActionController::Responder diff --git a/app/controllers/users/registrations_controller.rb b/app/controllers/users/registrations_controller.rb index 40f9c56..f9c5601 100644 --- a/app/controllers/users/registrations_controller.rb +++ b/app/controllers/users/registrations_controller.rb @@ -2,14 +2,14 @@ module Users class RegistrationsController < Devise::RegistrationsController - before_action :configure_sign_up_params, only: [:create] - before_action :configure_account_update_params, only: [:update] - skip_before_action :require_no_authentication, only: [:new] - before_action :check_already_authenticated, only: [:new] + before_action :configure_sign_up_params, only: [ :create ] + before_action :configure_account_update_params, only: [ :update ] + skip_before_action :require_no_authentication, only: [ :new ] + before_action :check_already_authenticated, only: [ :new ] def confirm_destroy @counts = stats_for_destroy - render :confirm_destroy, layout: 'application' + render :confirm_destroy, layout: "application" end def destroy @@ -46,22 +46,21 @@ def update_resource(resource, params) # If you have extra params to permit, append them to the sanitizer. def configure_sign_up_params - devise_parameter_sanitizer.permit(:sign_up, keys: [:name]) + devise_parameter_sanitizer.permit(:sign_up, keys: [ :name ]) end # If you have extra params to permit, append them to the sanitizer. def configure_account_update_params - devise_parameter_sanitizer.permit(:account_update, keys: [:name]) + devise_parameter_sanitizer.permit(:account_update, keys: [ :name ]) end # Check if the user is already signed in and redirect back to client or to root. def check_already_authenticated - if user_signed_in? + return unless user_signed_in? token = MyEtm::Auth.user_jwt(current_user, client_uri: params[:redirect_to]) redirect_url = URI(params[:redirect_to] || root_path) redirect_url.query = URI.encode_www_form(token: token) redirect_to redirect_url.to_s - end end # Fetches information about what entities will be deleted with the account. diff --git a/app/controllers/users/sessions_controller.rb b/app/controllers/users/sessions_controller.rb index bf5a319..77ccce8 100644 --- a/app/controllers/users/sessions_controller.rb +++ b/app/controllers/users/sessions_controller.rb @@ -4,8 +4,7 @@ module Users class SessionsController < Devise::SessionsController def create super do - - if session['user_return_to'].to_s.start_with?('/oauth/authorize') && is_flashing_format? + if session["user_return_to"].to_s.start_with?("/oauth/authorize") && is_flashing_format? # Don't show the flash message when redirecting to an OAuth action. flash.delete(:notice) end diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index dd7eb8e..4301fd7 100644 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -17,7 +17,7 @@ def update if @user.save @user.staff_applications.destroy_all unless @user.admin? - redirect_to users_path, notice: 'User updated' + redirect_to users_path, notice: "User updated" else render :edit end @@ -29,7 +29,7 @@ def create @user.role_id = params[:user][:role_id] if current_user && current_user.admin? if @user.save - redirect_to users_path, notice: 'User added' + redirect_to users_path, notice: "User added" else render :new end @@ -39,9 +39,9 @@ def resend_confirmation_email user = User.find_by(id: params[:id]) if user.nil? - flash[:notice] = 'User does not exist.' + flash[:notice] = "User does not exist." elsif user.confirmed_at? - flash[:notice] = 'User is already confirmed.' + flash[:notice] = "User is already confirmed." else user.send_confirmation_instructions flash[:notice] = "Confirmation email resent to #{user.email}." @@ -56,6 +56,8 @@ def find_user end def user_attributes - params.require(:user).permit(:email, :name, :admin) + attributes = [:email, :name] + attributes << :admin if current_user&.admin? + params.require(:user).permit(*attributes) end end diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 0f2a46f..50c0df9 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -1,7 +1,7 @@ module ApplicationHelper def notice_message if notice.is_a?(Hash) - notice[:message] || notice['message'] + notice[:message] || notice["message"] else notice end @@ -9,14 +9,14 @@ def notice_message def alert_message if alert.is_a?(Hash) - alert[:message] || alert['message'] + alert[:message] || alert["message"] else alert end end def identity_back_to_etm_url - session[:back_to_etm_url] || Settings.etmodel_uri || 'https://energytransitionmodel.com' + session[:back_to_etm_url] || Settings.etmodel_uri || "https://energytransitionmodel.com" end # Like simple_format, except without inserting breaks on newlines. @@ -27,14 +27,14 @@ def format_paragraphs(text) end def format_staff_config(config, app) - etengine_url = Settings.etengine.uri || 'http://YOUR_ETENGINE_URL' + etengine_url = Settings.etengine.uri || "http://YOUR_ETENGINE_URL" format(config, app.attributes.symbolize_keys.merge( - myetm_url: root_url.chomp('/root'), + myetm_url: root_url.chomp("/root"), etengine_url: etengine_url, - etmodel_url: Settings.etmodel.uri || 'http://YOUR_ETMODEL_URL', - collections_url: Settings.collections.uri || 'http://YOUR_COLLECTIONS_URL', - etengine_uid: Doorkeeper::Application.find_by(uri: etengine_url)&.id || 'YOUR_ETEngine_ID_HERE' + etmodel_url: Settings.etmodel.uri || "http://YOUR_ETMODEL_URL", + collections_url: Settings.collections.uri || "http://YOUR_COLLECTIONS_URL", + etengine_uid: Doorkeeper::Application.find_by(uri: etengine_url)&.id || "YOUR_ETEngine_ID_HERE" )) end diff --git a/app/helpers/button_helper.rb b/app/helpers/button_helper.rb index 6fad8a4..3eaf9ae 100644 --- a/app/helpers/button_helper.rb +++ b/app/helpers/button_helper.rb @@ -15,21 +15,21 @@ module ButtonHelper }.freeze SIZES = { - sm: ['px-2 py-1'], - base: ['px-3 py-1.5'], - lg: ['px-4 py-2'] + sm: [ "px-2 py-1" ], + base: [ "px-3 py-1.5" ], + lg: [ "px-4 py-2" ] }.freeze NEGATE_PADDING = { - sm: { x: '-mx-2', y: '-my-1' }, - base: { x: '-mx-3', y: '-my-1.5' }, - lg: { x: '-mx-4', y: '-my-2' } + sm: { x: "-mx-2", y: "-my-1" }, + base: { x: "-mx-3", y: "-my-1.5" }, + lg: { x: "-mx-4", y: "-my-2" } }.freeze def button_classes(additional = nil, color: :default, size: :base, negate_padding: false) negative_margin = button_negated_padding_classes(size, negate_padding) - classes = (BASE_CLASSES + COLORS.fetch(color) + SIZES.fetch(size)).join(' ') + classes = (BASE_CLASSES + COLORS.fetch(color) + SIZES.fetch(size)).join(" ") classes += " #{negative_margin}" if negative_margin classes += " #{additional}" if additional diff --git a/app/helpers/heroicon_helper.rb b/app/helpers/heroicon_helper.rb index c4f9665..d224271 100644 --- a/app/helpers/heroicon_helper.rb +++ b/app/helpers/heroicon_helper.rb @@ -2,4 +2,4 @@ module HeroiconHelper include Heroicon::Engine.helpers -end \ No newline at end of file +end diff --git a/app/helpers/identity/token_mailer_helper.rb b/app/helpers/identity/token_mailer_helper.rb index aa344da..1fd2260 100644 --- a/app/helpers/identity/token_mailer_helper.rb +++ b/app/helpers/identity/token_mailer_helper.rb @@ -4,11 +4,11 @@ module Identity module TokenMailerHelper def token_permissions(token) permissions = [ - ['View your public scenarios', 'public'], - ["View other people's public scenarios", 'public'], - ['View your private scenarios', 'scenarios:read'], - ['Create new scenarios and change your public and private scenarios', 'scenarios:write'], - ['Delete your public and private scenarios', 'scenarios:delete'] + [ "View your public scenarios", "public" ], + [ "View other people's public scenarios", "public" ], + [ "View your private scenarios", "scenarios:read" ], + [ "Create new scenarios and change your public and private scenarios", "scenarios:write" ], + [ "Delete your public and private scenarios", "scenarios:delete" ] ] permissions diff --git a/app/helpers/identity/tokens_helper.rb b/app/helpers/identity/tokens_helper.rb index 935fc72..d60a601 100644 --- a/app/helpers/identity/tokens_helper.rb +++ b/app/helpers/identity/tokens_helper.rb @@ -5,15 +5,15 @@ module TokensHelper def token_expiration_options(value) options_for_select( [ - token_expiration_option('n_days', 7), - token_expiration_option('n_days', 30), - token_expiration_option('n_days', 60), - token_expiration_option('n_days', 90), - token_expiration_option('one_year', 365), + token_expiration_option("n_days", 7), + token_expiration_option("n_days", 30), + token_expiration_option("n_days", 60), + token_expiration_option("n_days", 90), + token_expiration_option("one_year", 365), [ - t('identity.tokens.expiration_options.never'), - 'never', - { 'data-message' => t('identity.tokens.expiration_options.never_message') } + t("identity.tokens.expiration_options.never"), + "never", + { "data-message" => t("identity.tokens.expiration_options.never_message") } ] ], value @@ -22,11 +22,11 @@ def token_expiration_options(value) def token_expiration_option(message_key, days) [ - t(message_key, scope: 'identity.tokens.expiration_options', n: days), + t(message_key, scope: "identity.tokens.expiration_options", n: days), days, { - 'data-message' => t( - 'identity.tokens.expiration_options.expires_at_message', + "data-message" => t( + "identity.tokens.expiration_options.expires_at_message", date: l(days.days.from_now, format: :date) ) } diff --git a/app/jobs/identity/destroy_user_job.rb b/app/jobs/identity/destroy_user_job.rb index 88521af..517ac1b 100644 --- a/app/jobs/identity/destroy_user_job.rb +++ b/app/jobs/identity/destroy_user_job.rb @@ -6,7 +6,7 @@ class Identity::DestroyUserJob < ApplicationJob def perform(user_id) user = User.find(user_id) - MyEtm::Auth.model_client(user).delete('/api/v1/user') if Settings.etmodel.uri + MyEtm::Auth.model_client(user).delete("/api/v1/user") if Settings.etmodel.uri # Personal access tokens must be deleted before the access tokens, otherwise the destory will # fail due to a foreign key constraint. diff --git a/app/jobs/identity/sync_user_job.rb b/app/jobs/identity/sync_user_job.rb index ee20b0b..1c43862 100644 --- a/app/jobs/identity/sync_user_job.rb +++ b/app/jobs/identity/sync_user_job.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true -require 'uri' -require 'net/http' +require "uri" +require "net/http" # Syncs a user's identity with ETModel. class Identity::SyncUserJob < ApplicationJob @@ -13,7 +13,7 @@ def perform(user_id) user = User.find(user_id) MyEtm::Auth.model_client(user).put( - '/api/v1/user', + "/api/v1/user", user.to_json(except: %i[admin created_at updated_at]) ) diff --git a/app/mailers/contact_us_mailer.rb b/app/mailers/contact_us_mailer.rb index 863596c..836f84a 100644 --- a/app/mailers/contact_us_mailer.rb +++ b/app/mailers/contact_us_mailer.rb @@ -11,7 +11,7 @@ def contact_email(message, locale: nil, user_agent: nil) to: Settings.feedback_email, from: Settings.feedback_email, reply_to: message.email, - subject: 'ETM Feedback' + subject: "ETM Feedback" ) end end diff --git a/app/mailers/scenario_invitation_mailer.rb b/app/mailers/scenario_invitation_mailer.rb index 1140f3e..e8a31ee 100644 --- a/app/mailers/scenario_invitation_mailer.rb +++ b/app/mailers/scenario_invitation_mailer.rb @@ -11,7 +11,7 @@ def invite_user(email, inviter_name, new_role, saved_scenario_details) to: email, from: Settings.mailer.from, subject: "#{t('scenario_invitation_mailer.invite_user.subject')} #{@saved_scenario_title}", - template_name: 'scenario_invitation' + template_name: "scenario_invitation" ) end diff --git a/app/models/api/token_ability.rb b/app/models/api/token_ability.rb index 6ea8ecb..3412861 100644 --- a/app/models/api/token_ability.rb +++ b/app/models/api/token_ability.rb @@ -13,34 +13,39 @@ def initialize(token, user) # scenarios:read # -------------- - return unless scopes.include?('scenarios:read') + return unless scopes.include?("scenarios:read") - can :read, SavedScenario, id: SavedScenarioUser.where(user_id: user.id, role_id: User::Roles.index_of(:scenario_viewer)..).pluck(:saved_scenario_id) + can :read, SavedScenario, + id: SavedScenarioUser.where(user_id: user.id, role_id: User::Roles.index_of(:scenario_viewer)..).pluck(:saved_scenario_id) # scenarios:write # --------------- - return unless scopes.include?('scenarios:write') + return unless scopes.include?("scenarios:write") can :create, SavedScenario # Unowned public scenario. can :update, SavedScenario, private: false - cannot :update, SavedScenario, private: false, id: SavedScenarioUser.pluck(:saved_scenario_id) + cannot(:update, SavedScenario, private: false, + id: SavedScenarioUser.pluck(:saved_scenario_id)) # Self-owned scenario. - can :update, SavedScenario, id: SavedScenarioUser.where(user_id: user.id, role_id: User::Roles.index_of(:scenario_collaborator)..).pluck(:saved_scenario_id) + can :update, SavedScenario, + id: SavedScenarioUser.where(user_id: user.id, role_id: User::Roles.index_of(:scenario_collaborator)..).pluck(:saved_scenario_id) # Actions that involve reading one scenario and writing to another. can :clone, SavedScenario, private: false - can :clone, SavedScenario, id: SavedScenarioUser.where(user_id: user.id, role_id: User::Roles.index_of(:scenario_collaborator)..).pluck(:saved_scenario_id) + can :clone, SavedScenario, + id: SavedScenarioUser.where(user_id: user.id, role_id: User::Roles.index_of(:scenario_collaborator)..).pluck(:saved_scenario_id) # scenarios:delete # ---------------- - return unless scopes.include?('scenarios:delete') + return unless scopes.include?("scenarios:delete") - can :destroy, SavedScenario, id: SavedScenarioUser.where(user_id: user.id, role_id: User::Roles.index_of(:scenario_owner)).pluck(:saved_scenario_id) + can :destroy, SavedScenario, + id: SavedScenarioUser.where(user_id: user.id, role_id: User::Roles.index_of(:scenario_owner)).pluck(:saved_scenario_id) end private @@ -49,7 +54,7 @@ def extract_scopes(token) if token.respond_to?(:scopes) # doorkeeper_token token.scopes elsif token.is_a?(Hash) - token[:scopes] || token['scopes'] || [] # decoded_token + token[:scopes] || token["scopes"] || [] # decoded_token else [] end diff --git a/app/models/contact_us_message.rb b/app/models/contact_us_message.rb index 63dcfc9..cb112d3 100644 --- a/app/models/contact_us_message.rb +++ b/app/models/contact_us_message.rb @@ -6,9 +6,9 @@ class ContactUsMessage < Dry::Struct include ActiveModel::AttributeMethods include ActiveModel::Conversion - attribute :name, Dry::Types['strict.string'] - attribute :email, Dry::Types['strict.string'] - attribute :message, Dry::Types['strict.string'] + attribute :name, Dry::Types["strict.string"] + attribute :email, Dry::Types["strict.string"] + attribute :message, Dry::Types["strict.string"] attr_reader :errors diff --git a/app/models/featured_scenario.rb b/app/models/featured_scenario.rb index 0d84974..0e9ed22 100644 --- a/app/models/featured_scenario.rb +++ b/app/models/featured_scenario.rb @@ -10,7 +10,7 @@ class FeaturedScenario < ApplicationRecord SORTABLE_GROUPS = [ *GROUPS, :rest, nil ].freeze belongs_to :saved_scenario - belongs_to :owner, class_name: 'FeaturedScenarioUser', optional: true + belongs_to :owner, class_name: "FeaturedScenarioUser", optional: true has_rich_text :description_en has_rich_text :description_nl diff --git a/app/models/nasty_cache.rb b/app/models/nasty_cache.rb index 18a98b3..192940c 100644 --- a/app/models/nasty_cache.rb +++ b/app/models/nasty_cache.rb @@ -93,7 +93,7 @@ def fetch(key, opts = {}) # alias to fetch(key, cache: true) def fetch_cached(key, &block) - fetch(key, :cache => true, &block) + fetch(key, cache: true, &block) end def get(key, opts = {}) @@ -113,9 +113,9 @@ def delete(key) Rails.cache.delete(rails_cache_key(key)) end -############## -# protected -############## + ############## + # protected + ############## # Expires Rails.cache. Easiest way is to Rails.cache.clear # Otherwise you could track the keys cached by MemoryCache in an @@ -163,7 +163,7 @@ def global_timestamp end def rails_cache_key(key) - ["NastyCache", local_timestamp, key].join('/') + [ "NastyCache", local_timestamp, key ].join("/") end # Internal: Sends a message to the Rails logger if NastyCache verbose mode diff --git a/app/models/personal_access_token.rb b/app/models/personal_access_token.rb index 3fda41a..4857cf0 100644 --- a/app/models/personal_access_token.rb +++ b/app/models/personal_access_token.rb @@ -3,10 +3,10 @@ class PersonalAccessToken < ApplicationRecord include Doorkeeper::Models::ExpirationTimeSqlMath - TOKEN_PREFIX = Rails.env.staging? ? 'etm_beta_' : 'etm_' + TOKEN_PREFIX = Rails.env.staging? ? "etm_beta_" : "etm_" belongs_to :user - belongs_to :oauth_access_token, class_name: 'Doorkeeper::AccessToken', dependent: :destroy + belongs_to :oauth_access_token, class_name: "Doorkeeper::AccessToken", dependent: :destroy validates :name, presence: true diff --git a/app/models/staff_application.rb b/app/models/staff_application.rb index abcb904..f81970e 100644 --- a/app/models/staff_application.rb +++ b/app/models/staff_application.rb @@ -3,7 +3,7 @@ # Relates staff (admin) users to local OAuth applications. class StaffApplication < ApplicationRecord belongs_to :user - belongs_to :application, class_name: 'OAuthApplication', dependent: :destroy + belongs_to :application, class_name: "OAuthApplication", dependent: :destroy validates :name, presence: true validates :user, uniqueness: { scope: :name } diff --git a/app/models/user.rb b/app/models/user.rb index 212038c..ba7873a 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -10,22 +10,22 @@ class User < ApplicationRecord # Include default devise modules. Others available are: # :confirmable, :lockable, :timeoutable and :omniauthable, :registerable devise :database_authenticatable, :registerable, - :recoverable, :rememberable, :validatable, - :confirmable, :trackable + :recoverable, :rememberable, :validatable, + :confirmable, :trackable # rubocop:disable Rails/InverseOf has_many :access_grants, - class_name: 'Doorkeeper::AccessGrant', + class_name: "Doorkeeper::AccessGrant", foreign_key: :resource_owner_id, dependent: :delete_all has_many :access_tokens, - class_name: 'Doorkeeper::AccessToken', + class_name: "Doorkeeper::AccessToken", foreign_key: :resource_owner_id, dependent: :delete_all has_many :oauth_applications, - class_name: 'OAuthApplication', + class_name: "OAuthApplication", dependent: :delete_all, as: :owner @@ -79,8 +79,8 @@ def self.from_identity!(identity_user) # Finds or creates a user from a JWT token. def self.from_jwt!(token) - id = token['sub'] - raise 'Token does not contain user information' unless id.present? + id = token["sub"] + raise "Token does not contain user information" unless id.present? User.find_or_create_by!(id: id) end end diff --git a/app/services/api_scenario/update_privacy.rb b/app/services/api_scenario/update_privacy.rb index c082b96..481ca39 100644 --- a/app/services/api_scenario/update_privacy.rb +++ b/app/services/api_scenario/update_privacy.rb @@ -20,13 +20,13 @@ def call @http_client.put("/api/v3/scenarios/#{@id}", scenario: { private: @private }) ServiceResult.success rescue Faraday::ResourceNotFound - ServiceResult.failure('Scenario not found') + ServiceResult.failure("Scenario not found") rescue Faraday::UnprocessableEntityError # Trying to update an unowned scenario. Ignore. ServiceResult.success rescue Faraday::Error => e Sentry.capture_exception(e) - ServiceResult.failure('Failed to update scenario') + ServiceResult.failure("Failed to update scenario") end end end diff --git a/app/services/api_scenario/users/create.rb b/app/services/api_scenario/users/create.rb index 372ba24..88af5e6 100644 --- a/app/services/api_scenario/users/create.rb +++ b/app/services/api_scenario/users/create.rb @@ -17,11 +17,11 @@ def call ServiceResult.success( @http_client.post( "/api/v3/scenarios/#{@scenario_id}/users", - { scenario_users: [@scenario_user], invitation_args: @invitation_args } + { scenario_users: [ @scenario_user ], invitation_args: @invitation_args } ).body ) rescue Faraday::ResourceNotFound - ServiceResult.failure('Scenario not found') + ServiceResult.failure("Scenario not found") rescue Faraday::UnprocessableEntityError => e ServiceResult.single_failure_from_unprocessable_entity_on_multiple_objects(e) rescue Faraday::Error => e diff --git a/app/services/api_scenario/users/destroy.rb b/app/services/api_scenario/users/destroy.rb index c2e870e..de03c02 100644 --- a/app/services/api_scenario/users/destroy.rb +++ b/app/services/api_scenario/users/destroy.rb @@ -15,11 +15,11 @@ def initialize(http_client, scenario_id, scenario_user) def call ServiceResult.success( @http_client.delete( - "/api/v3/scenarios/#{@scenario_id}/users", scenario_users: [@scenario_user] + "/api/v3/scenarios/#{@scenario_id}/users", scenario_users: [ @scenario_user ] ).body ) rescue Faraday::ResourceNotFound - ServiceResult.failure('Scenario not found') + ServiceResult.failure("Scenario not found") rescue Faraday::UnprocessableEntityError => e ServiceResult.single_failure_from_unprocessable_entity_on_multiple_objects(e) rescue Faraday::Error => e diff --git a/app/services/api_scenario/users/update.rb b/app/services/api_scenario/users/update.rb index d3676a6..db4e0c3 100644 --- a/app/services/api_scenario/users/update.rb +++ b/app/services/api_scenario/users/update.rb @@ -15,13 +15,13 @@ def initialize(http_client, scenario_id, scenario_user) def call ServiceResult.success( @http_client.put( - "/api/v3/scenarios/#{@scenario_id}/users", scenario_users: [@scenario_user] + "/api/v3/scenarios/#{@scenario_id}/users", scenario_users: [ @scenario_user ] ).body ) rescue Faraday::ResourceNotFound - ServiceResult.failure('Scenario not found') + ServiceResult.failure("Scenario not found") rescue Faraday::ForbiddenError - ServiceResult.failure('No access to this scenario') + ServiceResult.failure("No access to this scenario") rescue Faraday::UnprocessableEntityError => e ServiceResult.single_failure_from_unprocessable_entity_on_multiple_objects(e) rescue Faraday::Error => e diff --git a/app/services/create_personal_access_token.rb b/app/services/create_personal_access_token.rb index 7675e92..9f83a79 100644 --- a/app/services/create_personal_access_token.rb +++ b/app/services/create_personal_access_token.rb @@ -7,7 +7,7 @@ class Params < Dry::Struct include ActiveModel::Validations extend ActiveModel::Translation - SCOPES_PUBLIC = 'openid public' + SCOPES_PUBLIC = "openid public" SCOPES_READ = "#{SCOPES_PUBLIC} scenarios:read".freeze SCOPES_WRITE = "#{SCOPES_READ} scenarios:write".freeze SCOPES_DELETE = "#{SCOPES_WRITE} scenarios:delete".freeze @@ -19,12 +19,12 @@ class Params < Dry::Struct delete: SCOPES_DELETE }.freeze - ExpiresType = Dry::Types['coercible.integer'] | Dry::Types['coercible.string'] + ExpiresType = Dry::Types["coercible.integer"] | Dry::Types["coercible.string"] - attribute :name, Dry::Types['coercible.string'].default('') - attribute :permissions, Dry::Types['coercible.symbol'].default(:public) - attribute :email_scope, Dry::Types['params.bool'].default(false) - attribute :profile_scope, Dry::Types['params.bool'].default(false) + attribute :name, Dry::Types["coercible.string"].default("") + attribute :permissions, Dry::Types["coercible.symbol"].default(:public) + attribute :email_scope, Dry::Types["params.bool"].default(false) + attribute :profile_scope, Dry::Types["params.bool"].default(false) attribute :expires_in, ExpiresType.default(30) transform_keys(&:to_sym) @@ -32,8 +32,8 @@ class Params < Dry::Struct validates :name, presence: true validates :permissions, inclusion: { in: SCOPES.keys } validates :expires_in, - numericality: { greater_than: 0, unless: :never_expires? }, - inclusion: { in: %w[never], message: :invalid, if: :never_expires? } + numericality: { greater_than: 0, unless: :never_expires? }, + inclusion: { in: %w[never], message: :invalid, if: :never_expires? } def to_oauth_token_params { @@ -49,13 +49,13 @@ def to_key = nil def scopes [ SCOPES[permissions], - email_scope ? 'email' : nil, - profile_scope ? 'profile' : nil - ].compact.join(' ') + email_scope ? "email" : nil, + profile_scope ? "profile" : nil + ].compact.join(" ") end def never_expires? - expires_in == 'never' + expires_in == "never" end end diff --git a/app/services/create_saved_scenario_user.rb b/app/services/create_saved_scenario_user.rb index 5da001f..748a39c 100644 --- a/app/services/create_saved_scenario_user.rb +++ b/app/services/create_saved_scenario_user.rb @@ -29,7 +29,7 @@ def call ServiceResult.success(saved_scenario_user) rescue ActiveRecord::RecordNotUnique - ServiceResult.failure('duplicate') + ServiceResult.failure("duplicate") end private diff --git a/app/services/create_staff_application.rb b/app/services/create_staff_application.rb index 0843518..c31fe3a 100644 --- a/app/services/create_staff_application.rb +++ b/app/services/create_staff_application.rb @@ -13,7 +13,7 @@ def self.call(user, app_config, uri: nil) uri = URI.parse(uri || app.uri || app_config.uri) - uri.path = '' + uri.path = "" uri.query = nil uri.fragment = nil diff --git a/app/services/service_result.rb b/app/services/service_result.rb index 5d5821d..b9a4784 100644 --- a/app/services/service_result.rb +++ b/app/services/service_result.rb @@ -27,10 +27,10 @@ def self.failure(errors = [], value = nil) # Public: Creates a failure result from a Faraday::UnprocessableEntityError. def self.failure_from_unprocessable_entity(exception, value = nil) - errors = exception.response[:body]['errors'] + errors = exception.response[:body]["errors"] if errors.is_a?(Hash) - errors = exception.response[:body]['errors'].flat_map do |key, messages| + errors = exception.response[:body]["errors"].flat_map do |key, messages| messages.map { |message| "#{key.humanize} #{message}" } end end @@ -39,7 +39,7 @@ def self.failure_from_unprocessable_entity(exception, value = nil) end def self.single_failure_from_unprocessable_entity_on_multiple_objects(exception, value = nil) - errors = exception.response[:body]['errors'] + errors = exception.response[:body]["errors"] errors = errors.values.first if errors.is_a?(Hash) failure(errors, value) @@ -74,7 +74,7 @@ def or(fallback = nil) # Public: Returns the value if the result is successful, otherwise raises an error with the # given message. def unwrap(error_msg = nil) - error_msg ||= 'Cannot unwrap failed ServiceResult' + error_msg ||= "Cannot unwrap failed ServiceResult" failure? ? raise("#{error_msg}: #{Array(@errors).join(', ')}") : @value end end diff --git a/config/importmap.rb b/config/importmap.rb index 30e0f4e..84f3d78 100644 --- a/config/importmap.rb +++ b/config/importmap.rb @@ -1,5 +1,5 @@ # Pin npm packages by running ./bin/importmap -pin 'identity', preload: true +pin "identity", preload: true pin "application" pin "@hotwired/turbo-rails", to: "turbo.min.js" @@ -7,11 +7,11 @@ pin "@hotwired/stimulus-loading", to: "stimulus-loading.js" pin "local-time", to: "https://cdn.skypack.dev/local-time" -pin 'focus-trap', to: 'https://ga.jspm.io/npm:focus-trap@7.0.0/dist/focus-trap.esm.js' -pin 'tabbable', to: 'https://ga.jspm.io/npm:tabbable@6.0.1/dist/index.esm.js' -pin 'stimulus-use', to: 'https://ga.jspm.io/npm:stimulus-use@0.51.1/dist/index.js' -pin 'focus-trap', to: 'https://ga.jspm.io/npm:focus-trap@7.0.0/dist/focus-trap.esm.js' -pin 'hotkeys-js', to: 'https://ga.jspm.io/npm:hotkeys-js@3.10.1/dist/hotkeys.esm.js' +pin "focus-trap", to: "https://ga.jspm.io/npm:focus-trap@7.0.0/dist/focus-trap.esm.js" +pin "tabbable", to: "https://ga.jspm.io/npm:tabbable@6.0.1/dist/index.esm.js" +pin "stimulus-use", to: "https://ga.jspm.io/npm:stimulus-use@0.51.1/dist/index.js" +pin "focus-trap", to: "https://ga.jspm.io/npm:focus-trap@7.0.0/dist/focus-trap.esm.js" +pin "hotkeys-js", to: "https://ga.jspm.io/npm:hotkeys-js@3.10.1/dist/hotkeys.esm.js" pin_all_from "app/javascript/controllers", under: "controllers" pin "trix" diff --git a/lib/myetm/auth.rb b/lib/myetm/auth.rb index 732a632..318a8c2 100644 --- a/lib/myetm/auth.rb +++ b/lib/myetm/auth.rb @@ -8,20 +8,20 @@ module Auth # Generates a new signing key for use in development and saves it to the tmp directory. def signing_key_content - return ENV['OPENID_SIGNING_KEY'] if ENV['OPENID_SIGNING_KEY'].present? + return ENV["OPENID_SIGNING_KEY"] if ENV["OPENID_SIGNING_KEY"].present? - key_path = Rails.root.join('tmp/openid.key') + key_path = Rails.root.join("tmp/openid.key") return key_path.read if key_path.exist? - unless Rails.env.test? || Rails.env.development? || ENV['DOCKER_BUILD'] - raise 'No signing key is present. Please set the OPENID_SIGNING_KEY environment ' \ - 'variable or add the key to tmp/openid.key.' + unless Rails.env.test? || Rails.env.development? || ENV["DOCKER_BUILD"] + raise "No signing key is present. Please set the OPENID_SIGNING_KEY environment " \ + "variable or add the key to tmp/openid.key." end key = OpenSSL::PKey::RSA.new(2048).to_pem - unless ENV['DOCKER_BUILD'] + unless ENV["DOCKER_BUILD"] key_path.write(key) key_path.chmod(0o600) end @@ -47,14 +47,15 @@ def user_jwt(user = nil, scopes: [], client_id: nil) } key = signing_key - JWT.encode(payload, key, 'RS256', typ: 'JWT', kid: key.to_jwk['kid']) + JWT.encode(payload, key, "RS256", typ: "JWT", kid: key.to_jwk["kid"]) end # Returns a Faraday client for a user, which will send requests to the specified client app. def client_app_client(user, client_app) client_app_client ||= begin Faraday.new(client_app.uri) do |conn| - conn.request(:authorization, 'Bearer', -> { user_jwt(user, scopes: client_app.scopes, client_id: client_app.uid) }) + conn.request(:authorization, "Bearer", -> { + user_jwt(user, scopes: client_app.scopes, client_id: client_app.uid) }) conn.request(:json) conn.response(:json) conn.response(:raise_error) @@ -75,7 +76,7 @@ def model_client(user) # Checks if the token is in JWT format def jwt_format?(token) - token.count('.') == 2 + token.count(".") == 2 end # Decodes a JWT token @@ -84,7 +85,7 @@ def decode(jwt_token) jwt_token, signing_key.public_key, true, - algorithm: 'RS256' + algorithm: "RS256" ).first verify_claims(decoded_token) decoded_token.symbolize_keys @@ -96,19 +97,20 @@ def decode(jwt_token) def verify_claims(decoded_token) # Verify the issuer issuer = Doorkeeper::OpenidConnect.configuration.issuer.call(nil, nil) - raise DecodeError, 'Invalid issuer' unless decoded_token['iss'] == issuer + raise DecodeError, "Invalid issuer" unless decoded_token["iss"] == issuer # Dynamically fetch the expected audiences from OAuth applications expected_audiences = Doorkeeper::Application.pluck(:uid) - unless expected_audiences.include?(decoded_token['aud']) - raise DecodeError, 'Invalid audience' + unless expected_audiences.include?(decoded_token["aud"]) + raise DecodeError, "Invalid audience" end # Verify the token has not expired - raise DecodeError, 'Token has expired' unless decoded_token['exp'] && decoded_token['exp'] > Time.now.to_i + raise DecodeError, + "Token has expired" unless decoded_token["exp"] && decoded_token["exp"] > Time.now.to_i end - module_function :decode, :jwt_format?, :verify_claims, :signing_key_content, :user_jwt, :signing_key, :model_client, :engine_client, :client_app_client - + module_function :decode, :jwt_format?, :verify_claims, :signing_key_content, :user_jwt, + :signing_key, :model_client, :engine_client, :client_app_client end end diff --git a/lib/myetm/mailchimp.rb b/lib/myetm/mailchimp.rb index 99a75b7..84b1847 100644 --- a/lib/myetm/mailchimp.rb +++ b/lib/myetm/mailchimp.rb @@ -16,7 +16,7 @@ def client end Faraday.new(Settings.mailchimp.list_url) do |conn| - conn.request(:authorization, :basic, '', Settings.mailchimp.api_key) + conn.request(:authorization, :basic, "", Settings.mailchimp.api_key) conn.request(:json) conn.response(:json) conn.response(:raise_error) @@ -35,7 +35,7 @@ def fetch_subscriber(email) # Returns if the e-mail address is subscribed to the newsletter. def subscribed?(email) - %w[pending subscribed].include?(fetch_subscriber(email)['status']) + %w[pending subscribed].include?(fetch_subscriber(email)["status"]) rescue Faraday::ResourceNotFound false end diff --git a/lib/myetm/staff_applications.rb b/lib/myetm/staff_applications.rb index 1ae7be7..4210ad8 100644 --- a/lib/myetm/staff_applications.rb +++ b/lib/myetm/staff_applications.rb @@ -1,12 +1,13 @@ # frozen_string_literal: true - require_relative 'staff_applications/app_config' + + require_relative "staff_applications/app_config" module MyEtm # Holds config information about OAuth accounts created for staff users. module StaffApplications class << self def all - [etengine, etmodel, collections] + [ etengine, etmodel, collections ] end def find(key) @@ -22,13 +23,13 @@ def find(key) def etengine AppConfig.new( - key: 'etengine', - name: 'Engine (Local)', - scopes: 'openid email profile roles public scenarios:read scenarios:write scenarios:delete', - uri: 'http://localhost:3000', - redirect_path: '/auth/identity/callback', - run_command: 'bundle exec rails server -p %s', - config_path: 'config/settings.local.yml', + key: "etengine", + name: "Engine (Local)", + scopes: "openid email profile roles public scenarios:read scenarios:write scenarios:delete", + uri: "http://localhost:3000", + redirect_path: "/auth/identity/callback", + run_command: "bundle exec rails server -p %s", + config_path: "config/settings.local.yml", config_content: <<~YAML, idp_url: %s @@ -44,13 +45,13 @@ def etengine def etmodel AppConfig.new( - key: 'etmodel', - name: 'Model (Local)', - scopes: 'openid email profile roles public scenarios:read scenarios:write scenarios:delete', - uri: 'http://localhost:3001', - redirect_path: '/auth/identity/callback', - run_command: 'bundle exec rails server -p %s', - config_path: 'config/settings.local.yml', + key: "etmodel", + name: "Model (Local)", + scopes: "openid email profile roles public scenarios:read scenarios:write scenarios:delete", + uri: "http://localhost:3001", + redirect_path: "/auth/identity/callback", + run_command: "bundle exec rails server -p %s", + config_path: "config/settings.local.yml", config_content: <<~YAML, idp_url: %s ete_url: %s @@ -68,13 +69,13 @@ def etmodel def collections AppConfig.new( - key: 'collections', - name: 'Collections (Local)', - scopes: 'openid email profile public scenarios:read scenarios:write', - uri: 'http://localhost:3005', - redirect_path: '/api/auth/callback/identity', - run_command: 'yarn dev -p %s', - config_path: '.env.local', + key: "collections", + name: "Collections (Local)", + scopes: "openid email profile public scenarios:read scenarios:write", + uri: "http://localhost:3005", + redirect_path: "/api/auth/callback/identity", + run_command: "yarn dev -p %s", + config_path: ".env.local", config_content: <<~ENV, # Protocol and host for MyETM. No trailing slash please. NEXT_PUBLIC_MYETM_URL=%s diff --git a/lib/myetm/staff_applications/app_config.rb b/lib/myetm/staff_applications/app_config.rb index 14cae40..0707784 100644 --- a/lib/myetm/staff_applications/app_config.rb +++ b/lib/myetm/staff_applications/app_config.rb @@ -4,18 +4,18 @@ module MyEtm module StaffApplications # Defines an OAuth application which will be created for staff users. class AppConfig < Dry::Struct - attribute :key, Dry::Types['strict.string'] - attribute :name, Dry::Types['strict.string'] - attribute :uri, Dry::Types['strict.string'] - attribute? :redirect_path, Dry::Types['strict.string'] - attribute :confidential, Dry::Types['strict.bool'].default(true) - attribute :scopes, Dry::Types['strict.string'].default('public') - attribute? :run_command, Dry::Types['strict.string'] + attribute :key, Dry::Types["strict.string"] + attribute :name, Dry::Types["strict.string"] + attribute :uri, Dry::Types["strict.string"] + attribute? :redirect_path, Dry::Types["strict.string"] + attribute :confidential, Dry::Types["strict.bool"].default(true) + attribute :scopes, Dry::Types["strict.string"].default("public") + attribute? :run_command, Dry::Types["strict.string"] - attribute :config_path, Dry::Types['strict.string'] - attribute? :config_prologue, Dry::Types['strict.string'] - attribute :config_content, Dry::Types['strict.string'] - attribute? :config_epilogue, Dry::Types['strict.string'] + attribute :config_path, Dry::Types["strict.string"] + attribute? :config_prologue, Dry::Types["strict.string"] + attribute :config_content, Dry::Types["strict.string"] + attribute? :config_epilogue, Dry::Types["strict.string"] # Creates an attribute hash for the OAuth application. def to_model_attributes diff --git a/lib/tasks/identity.rake b/lib/tasks/identity.rake index 2e8cb3a..3476b38 100644 --- a/lib/tasks/identity.rake +++ b/lib/tasks/identity.rake @@ -3,9 +3,9 @@ namespace :identity do task scheduled: %i[trim_tokens notify_expiring_tokens] - desc 'Clear our revoked and expired tokens' + desc "Clear our revoked and expired tokens" task trim_tokens: :environment do - delete_before = (ENV['DOORKEEPER_DAYS_TRIM_THRESHOLD'] || 30).to_i.days.ago + delete_before = (ENV["DOORKEEPER_DAYS_TRIM_THRESHOLD"] || 30).to_i.days.ago expire = [ <<~SQL.squish, { delete_before: } (revoked_at IS NOT NULL AND revoked_at < :delete_before) OR @@ -23,7 +23,7 @@ namespace :identity do end end - desc 'Notify users of soon-to-expire tokens' + desc "Notify users of soon-to-expire tokens" task notify_expiring_tokens: :environment do tokens = PersonalAccessToken .joins(:oauth_access_token) diff --git a/spec/components/identity/token/scope_component_spec.rb b/spec/components/identity/token/scope_component_spec.rb index 27cba72..f83c41e 100644 --- a/spec/components/identity/token/scope_component_spec.rb +++ b/spec/components/identity/token/scope_component_spec.rb @@ -11,7 +11,6 @@ end it 'does not hide the scope from screen readers' do - expect(rendered).not_to have_selector('div[aria-hidden="true"]') end end diff --git a/spec/controllers/saved_scenario_users_controller_spec.rb b/spec/controllers/saved_scenario_users_controller_spec.rb index 48fa0f8..8d429c9 100644 --- a/spec/controllers/saved_scenario_users_controller_spec.rb +++ b/spec/controllers/saved_scenario_users_controller_spec.rb @@ -6,10 +6,10 @@ before do # Disable relaying ScenarioUserUpdates to ETEngine allow(ApiScenario::Users::Create).to receive(:call).and_return( - ServiceResult.success([{ + ServiceResult.success([ { 'user_email' => 'test@test.com', 'role_id' => User::Roles.index_of(:scenario_owner) - }]) + } ]) ) allow(ApiScenario::Users::Update).to receive(:call).and_return(ServiceResult.success) allow(ApiScenario::Users::Destroy).to receive(:call).and_return(ServiceResult.success) @@ -73,10 +73,10 @@ end describe 'a scenario user' do - let(:saved_scenario) { FactoryBot.create :saved_scenario, id: 648692 } - let(:user_viewer) { FactoryBot.create :user } - let(:user_collaborator) { FactoryBot.create :user } - let(:user_owner) { FactoryBot.create :user } + let(:saved_scenario) { FactoryBot.create(:saved_scenario, id: 648692) } + let(:user_viewer) { FactoryBot.create(:user) } + let(:user_collaborator) { FactoryBot.create(:user) } + let(:user_owner) { FactoryBot.create(:user) } let!(:scenario_viewer) do FactoryBot.create( :saved_scenario_user, @@ -194,8 +194,8 @@ end describe 'a scenario owner' do - let(:user) { FactoryBot.create :user } - let(:saved_scenario) { FactoryBot.create :saved_scenario, id: 648694 } + let(:user) { FactoryBot.create(:user) } + let(:saved_scenario) { FactoryBot.create(:saved_scenario, id: 648694) } let!(:scenario_owner) do FactoryBot.create( :saved_scenario_user, @@ -252,7 +252,7 @@ expect( saved_scenario.saved_scenario_users.find_by(user_email: 'test@test.com')&.role_id ).to eq( - User::Roles.index_of(:scenario_owner) + User::Roles.index_of(:scenario_owner) ) end @@ -284,8 +284,8 @@ end describe 'an admin user' do - let(:admin) { FactoryBot.create :admin } - let(:saved_scenario) { FactoryBot.create :saved_scenario, id: 648695 } + let(:admin) { FactoryBot.create(:admin) } + let(:saved_scenario) { FactoryBot.create(:saved_scenario, id: 648695) } let!(:scenario_owner) do FactoryBot.create( :saved_scenario_user, diff --git a/spec/mailers/identity/token_spec.rb b/spec/mailers/identity/token_spec.rb index ed66623..c0c4fc0 100644 --- a/spec/mailers/identity/token_spec.rb +++ b/spec/mailers/identity/token_spec.rb @@ -12,7 +12,7 @@ it 'renders the headers' do expect(mail.subject).to eq('You created a new token') - expect(mail.to).to eq([user.email]) + expect(mail.to).to eq([ user.email ]) expect(mail.from).to eq(Mail::Field.parse("From: #{Settings.mailer.from}").addresses) end @@ -35,7 +35,7 @@ it 'renders the headers' do expect(mail.subject).to eq('Your personal access token will expire soon') - expect(mail.to).to eq([user.email]) + expect(mail.to).to eq([ user.email ]) expect(mail.from).to eq(Mail::Field.parse("From: #{Settings.mailer.from}").addresses) end diff --git a/spec/mailers/previews/identity/token_preview.rb b/spec/mailers/previews/identity/token_preview.rb index 7c8c3ad..088541d 100644 --- a/spec/mailers/previews/identity/token_preview.rb +++ b/spec/mailers/previews/identity/token_preview.rb @@ -1,9 +1,7 @@ # Preview all emails at http://localhost:3000/rails/mailers/identity/token class Identity::TokenPreview < ActionMailer::Preview - # Preview this email at http://localhost:3000/rails/mailers/identity/token/created_token def created_token Identity::TokenMailer.created_token end - end diff --git a/spec/mailers/scenario_invitation_mailer_spec.rb b/spec/mailers/scenario_invitation_mailer_spec.rb index 9406fc7..6bdc835 100644 --- a/spec/mailers/scenario_invitation_mailer_spec.rb +++ b/spec/mailers/scenario_invitation_mailer_spec.rb @@ -10,7 +10,7 @@ it 'renders the headers' do expect(mail.subject).to eq('Invitation: ETM scenario Some saved scenario') - expect(mail.to).to eq([email]) + expect(mail.to).to eq([ email ]) expect(mail.from).to eq(Mail::Field.parse("From: #{Settings.mailer.from}").addresses) end diff --git a/spec/models/saved_scenario_spec.rb b/spec/models/saved_scenario_spec.rb index 21adc46..6e8a7a7 100644 --- a/spec/models/saved_scenario_spec.rb +++ b/spec/models/saved_scenario_spec.rb @@ -119,7 +119,7 @@ it 'adds the old scenario_id to the history' do expect { ss.update_with_api_params(scenario_id: 2) } .to change(ss, :scenario_id_history) - .from([]).to([1]) + .from([]).to([ 1 ]) end end diff --git a/spec/requests/api/saved_scenarios_spec.rb b/spec/requests/api/saved_scenarios_spec.rb index d27a5e8..8570340 100644 --- a/spec/requests/api/saved_scenarios_spec.rb +++ b/spec/requests/api/saved_scenarios_spec.rb @@ -23,7 +23,7 @@ it 'returns the saved scenarios' do expect(response.parsed_body).to match_array( - [user_ss1, user_ss2].as_json + [ user_ss1, user_ss2 ].as_json ) end @@ -285,7 +285,7 @@ expect { request } .to change { scenario.reload.scenario_id_history } .from([]) - .to([previous_id]) + .to([ previous_id ]) end end @@ -325,7 +325,7 @@ context 'when updating with a historic scenario ID' do before do - scenario.update(scenario_id_history: [999_999, 2, 111_111]) + scenario.update(scenario_id_history: [ 999_999, 2, 111_111 ]) scenario.reload end @@ -337,7 +337,7 @@ it 'changes the scenario ID history' do expect { request } .to change { scenario.reload.scenario_id_history } - .from([999_999, 2, 111_111]).to([999_999]) + .from([ 999_999, 2, 111_111 ]).to([ 999_999 ]) end it 'changes the scenario ID' do diff --git a/spec/requests/saved_scenarios_spec.rb b/spec/requests/saved_scenarios_spec.rb index 6425fd6..ef5b009 100644 --- a/spec/requests/saved_scenarios_spec.rb +++ b/spec/requests/saved_scenarios_spec.rb @@ -35,8 +35,8 @@ let(:client) { Faraday.new(url: 'http://et.engine') } let(:user) { FactoryBot.create(:user) } let!(:user_scenario) { FactoryBot.create(:saved_scenario, id: 648695, user: user) } - let(:admin) { FactoryBot.create :admin } - let!(:admin_scenario) { FactoryBot.create :saved_scenario, user: admin, id: 648696 } + let(:admin) { FactoryBot.create(:admin) } + let!(:admin_scenario) { FactoryBot.create(:saved_scenario, user: admin, id: 648696) } before { allow(MyEtm::Auth).to receive(:client_app_client).and_return(client) } @@ -181,7 +181,7 @@ it 'updates the API scenarios' do expect(ApiScenario::UpdatePrivacy).to have_received(:call_with_ids).with( - anything, [user_scenario.id], private: false + anything, [ user_scenario.id ], private: false ) end end @@ -228,7 +228,7 @@ it 'updates the API scenarios' do expect(ApiScenario::UpdatePrivacy).to have_received(:call_with_ids).with( - anything, [user_scenario.id], private: true + anything, [ user_scenario.id ], private: true ) end end diff --git a/spec/services/api_scenario/users/create.rb b/spec/services/api_scenario/users/create.rb index 37f7af5..7b48968 100644 --- a/spec/services/api_scenario/users/create.rb +++ b/spec/services/api_scenario/users/create.rb @@ -57,8 +57,7 @@ end it 'returns the scenario error messages' do - expect(result.errors).to eq(['Id is invalid']) + expect(result.errors).to eq([ 'Id is invalid' ]) end end end - diff --git a/spec/services/api_scenario/users/destroy.rb b/spec/services/api_scenario/users/destroy.rb index 513193b..198cb3d 100644 --- a/spec/services/api_scenario/users/destroy.rb +++ b/spec/services/api_scenario/users/destroy.rb @@ -57,8 +57,7 @@ end it 'returns the scenario error messages' do - expect(result.errors).to eq(['Id is invalid']) + expect(result.errors).to eq([ 'Id is invalid' ]) end end end - diff --git a/spec/services/api_scenario/users/update.rb b/spec/services/api_scenario/users/update.rb index 1321abc..0d5a122 100644 --- a/spec/services/api_scenario/users/update.rb +++ b/spec/services/api_scenario/users/update.rb @@ -57,8 +57,7 @@ end it 'returns the scenario error messages' do - expect(result.errors).to eq(['Id is invalid']) + expect(result.errors).to eq([ 'Id is invalid' ]) end end end - diff --git a/spec/services/create_saved_scenario_user_spec.rb b/spec/services/create_saved_scenario_user_spec.rb index 688988f..2dae909 100644 --- a/spec/services/create_saved_scenario_user_spec.rb +++ b/spec/services/create_saved_scenario_user_spec.rb @@ -7,12 +7,12 @@ let(:user) { FactoryBot.create(:user) } let(:email) { 'hello@me.com' } let(:new_viewer_user_params) { { role_id: 1, user_email: email } } - let(:api_result) { ServiceResult.success([{ 'role_id' => 1, 'user_email' => email }]) } + let(:api_result) { ServiceResult.success([ { 'role_id' => 1, 'user_email' => email } ]) } let(:result) { described_class.call(client, saved_scenario, user.name, new_viewer_user_params) } let!(:saved_scenario) do - FactoryBot.create :saved_scenario, - user: user, - id: 648_695 + FactoryBot.create(:saved_scenario, + user: user, + id: 648_695) end before do @@ -34,7 +34,7 @@ describe '#value' do subject { result.value } - it { is_expected.to be_a SavedScenarioUser } + it { is_expected.to be_a(SavedScenarioUser) } it { is_expected.to be_persisted } end @@ -47,7 +47,7 @@ context 'when the record was invalid' do let(:new_viewer_user_params) { { role_id: 1, user_email: 'ppp' } } - let(:api_result) { ServiceResult.failure(['Invalid email']) } + let(:api_result) { ServiceResult.failure([ 'Invalid email' ]) } it 'returns a ServiceResult' do expect(result).to be_a(ServiceResult) @@ -76,12 +76,12 @@ end it 'returns the scenario error messages' do - expect(result.errors).to eq(['duplicate']) + expect(result.errors).to eq([ 'duplicate' ]) end end context 'when the API response is unsuccessful' do - let(:api_result) { ServiceResult.failure(['Nope']) } + let(:api_result) { ServiceResult.failure([ 'Nope' ]) } it 'returns a ServiceResult' do expect(result).to be_a(ServiceResult) @@ -92,12 +92,12 @@ end it 'returns the scenario error messages' do - expect(result.errors).to eq(['Nope']) + expect(result.errors).to eq([ 'Nope' ]) end end context 'when there is a found linked user' do - let(:existing_user) {create(:user)} + let(:existing_user) { create(:user) } let(:new_viewer_user_params) { { role_id: 1, user_email: existing_user.email } } it 'returns a ServiceResult' do diff --git a/spec/services/destroy_saved_scenario_user_spec.rb b/spec/services/destroy_saved_scenario_user_spec.rb index c0c4afb..e5d2c41 100644 --- a/spec/services/destroy_saved_scenario_user_spec.rb +++ b/spec/services/destroy_saved_scenario_user_spec.rb @@ -52,7 +52,7 @@ end it 'returns the scenario error messages' do - expect(result.errors).to eq([:ownership]) + expect(result.errors).to eq([ :ownership ]) end it 'does not change the owner of the the SavedScenario' do @@ -63,7 +63,7 @@ end context 'when the API response is unsuccessful' do - let(:api_result) { ServiceResult.failure(['Nope']) } + let(:api_result) { ServiceResult.failure([ 'Nope' ]) } it 'returns a ServiceResult' do expect(result).to be_a(ServiceResult) @@ -74,7 +74,7 @@ end it 'returns the scenario error messages' do - expect(result.errors).to eq(['Nope']) + expect(result.errors).to eq([ 'Nope' ]) end end end diff --git a/spec/services/update_saved_scenario_user_spec.rb b/spec/services/update_saved_scenario_user_spec.rb index e94d3e1..be4ce23 100644 --- a/spec/services/update_saved_scenario_user_spec.rb +++ b/spec/services/update_saved_scenario_user_spec.rb @@ -58,7 +58,7 @@ end it 'returns the scenario error messages' do - expect(result.errors).to eq([:ownership]) + expect(result.errors).to eq([ :ownership ]) end it 'does not change the owner of the the SavedScenario' do @@ -69,7 +69,7 @@ end context 'when the API response is unsuccessful' do - let(:api_result) { ServiceResult.failure(['Nope']) } + let(:api_result) { ServiceResult.failure([ 'Nope' ]) } it 'returns a ServiceResult' do expect(result).to be_a(ServiceResult) @@ -80,7 +80,7 @@ end it 'returns the scenario error messages' do - expect(result.errors).to eq(['Nope']) + expect(result.errors).to eq([ 'Nope' ]) end end end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 8c43555..5e292e8 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -24,7 +24,7 @@ # config.mock_with :mocha # config.mock_with :flexmock # config.mock_with :rr - config.mock_with :rspec + config.mock_with(:rspec) # Remove this line if you're not using ActiveRecord or ActiveRecord fixtures config.fixture_path = "#{::Rails.root}/spec/fixtures" @@ -45,7 +45,7 @@ config.include(FactoryBot::Syntax::Methods) - config.include Devise::Test::IntegrationHelpers, type: :request + config.include(Devise::Test::IntegrationHelpers, type: :request) config.include(Devise::Test::ControllerHelpers, type: :controller) config.include(AuthorizationHelper) @@ -73,9 +73,9 @@ Shoulda::Matchers.configure do |config| config.integrate do |with| # Choose a test framework: - with.test_framework :rspec + with.test_framework(:rspec) # Choose one or more libraries: - with.library :rails + with.library(:rails) end end diff --git a/spec/system/delete_account_spec.rb b/spec/system/delete_account_spec.rb index 729b0cc..aed856f 100644 --- a/spec/system/delete_account_spec.rb +++ b/spec/system/delete_account_spec.rb @@ -24,7 +24,7 @@ fill_in 'Password', with: user.password begin - click_button 'Permanently delete account' + click_button('Permanently delete account') rescue ActionController::RoutingError # This is raised because it redirects to ETModel, which isn't available in tests. end diff --git a/spec/system/locale_spec.rb b/spec/system/locale_spec.rb index 5b6774d..349e125 100644 --- a/spec/system/locale_spec.rb +++ b/spec/system/locale_spec.rb @@ -4,16 +4,16 @@ pending 'allows switching the language' do sign_in(create(:user)) - visit '/identity/profile' + visit('/identity/profile') expect(page).to have_css('header button', text: 'Sign out') - visit '/identity/profile?locale=nl' + visit('/identity/profile?locale=nl') expect(page).to have_css('header button', text: 'Uitloggen') - visit '/identity/profile?locale=en' + visit('/identity/profile?locale=en') expect(page).to have_css('header button', text: 'Sign out') - visit '/identity/profile?locale=de' + visit('/identity/profile?locale=de') expect(page).to have_css('header button', text: 'Sign out') ensure I18n.locale = :en # rubocop:disable Rails/I18nLocaleAssignment