diff --git a/.github/workflows/build-and-test.yml b/.github/workflows/build-and-test.yml index 35a1dca92..9560780d8 100644 --- a/.github/workflows/build-and-test.yml +++ b/.github/workflows/build-and-test.yml @@ -48,6 +48,9 @@ jobs: SMTP_USERNAME: ${{ secrets.SMTP_USERNAME }} SMTP_PASSWORD: ${{ secrets.SMTP_PASSWORD }} + - name: Run RuboCop linting + run: bundle exec rubocop + - name: Run tests run: bundle exec rspec env: diff --git a/.rubocop.yml b/.rubocop.yml index 647c1c399..6721ab3e5 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -1,26 +1,46 @@ -Encoding: - Enabled: false +# Inherit Shopify's Ruby style guide +inherit_gem: + rubocop-shopify: rubocop.yml + +# Load RuboCop extensions as plugins +plugins: + - rubocop-capybara + - rubocop-factory_bot + - rubocop-rails + - rubocop-rspec + - rubocop-rspec_rails + +# Custom project-specific overrides +AllCops: + Exclude: + - "bin/**/*" + - "db/**/*" + - "config/**/*" + - "vendor/**/*" + - "node_modules/**/*" + +# Disable some rules that might be too strict for legacy code +Metrics/AbcSize: + Max: 30 -Documentation: +Metrics/MethodLength: Enabled: false -ClassAndModuleChildren: +Metrics/ClassLength: Enabled: false -ClassLength: +Style/Documentation: Enabled: false -MethodLength: +Style/ClassAndModuleChildren: Enabled: false -AbcSize: - Max: 30 +# RSPEC +RSpec/MultipleExpectations: + Enabled: false -DoubleNegation: +RSpec/ExampleLength: Enabled: false -AllCops: - Exclude: - - "bin/**/*" - - "db/**/*" - - "config/**/*" +Style/ClassMethodsDefinitions: + Enabled: false diff --git a/Capfile b/Capfile index 0b13de24c..9ec630a85 100644 --- a/Capfile +++ b/Capfile @@ -1,10 +1,12 @@ +# frozen_string_literal: true + # Load DSL and set up stages -require 'capistrano/setup' +require "capistrano/setup" # Include default deployment tasks -require 'capistrano/deploy' -require 'capistrano/bundler' -require 'capistrano/rails' +require "capistrano/deploy" +require "capistrano/bundler" +require "capistrano/rails" # Include tasks from other gems included in your Gemfile # @@ -26,4 +28,4 @@ require 'capistrano/rails' # require 'capistrano/passenger' # Load custom tasks from `lib/capistrano/tasks` if you have any defined -Dir.glob('lib/capistrano/tasks/*.rake').each { |r| import r } +Dir.glob("lib/capistrano/tasks/*.rake").each { |r| import r } diff --git a/Gemfile b/Gemfile index 8f068e44b..cc31e101e 100644 --- a/Gemfile +++ b/Gemfile @@ -1,27 +1,29 @@ -source 'https://rubygems.org' +# frozen_string_literal: true + +source "https://rubygems.org" ruby "3.3.8" gem "rails", "~> 6.1.7" -gem 'sprockets-rails', '~> 3.2.2' -gem 'mysql2', '~> 0.5.0' -gem 'bootstrap-sass' +gem "sprockets-rails", "~> 3.2.2" +gem "mysql2", "~> 0.5.0" +gem "bootstrap-sass" gem "sassc-rails", ">= 2.1.2" -gem 'uglifier' -gem 'coffee-rails' +gem "uglifier" +gem "coffee-rails" gem "feature_flipper" -gem 'jquery-rails' -gem 'jbuilder', '~> 2.0' +gem "jquery-rails" +gem "jbuilder", "~> 2.0" -gem 'devise', '~> 4.7.3' -gem 'neat', '1.7.1' -gem 'bourbon', '~> 4.2.2' -gem 'draper' +gem "devise", "~> 4.7.3" +gem "neat", "1.7.1" +gem "bourbon", "~> 4.2.2" +gem "draper" gem "kt-paperclip", "~> 6.4", ">= 6.4.1" -gem 'aws-sdk-s3' -gem 'rails_admin','~> 2.2.1' +gem "aws-sdk-s3" +gem "rails_admin", "~> 2.2.1" # gem 'rails_admin', git: 'https://github.com/enmand/rails_admin.git' # rails_admin 1.1.1 has a transitive dependency on haml (~> 4.0). haml 4.0.7 in # turn has a transitive dependency on tile and does not specify a version range. @@ -30,42 +32,47 @@ gem 'rails_admin','~> 2.2.1' # with haml 4.0.7. We can remove this as soon we get upgrade to a newer version # of rails_admin that should pull in a newer version of haml, breaking this # dependency chain. -gem 'tilt', '~> 2.4.0' - +gem "tilt", "~> 2.4.0" -gem 'puma', '~> 5.6' # Add Puma as the web server +gem "puma", "~> 5.6" # Add Puma as the web server -gem 'cocoon', '~> 1.2.6' +gem "cocoon", "~> 1.2.6" -gem 'font-awesome-rails' -gem 'wicked' -gem 'search_cop', '~> 1.0.6' -gem 'mandrill_mailer' -gem 'jwt', '~> 1.2.1' -gem 'httparty' -gem 'will_paginate', '~> 3.1.7' -gem 'bootstrap-will_paginate' -gem 'apipie-rails', '~> 0.5.0' -gem 'rack-cors', :require => 'rack/cors' -gem 'ckeditor', '~> 4.3.0' +gem "font-awesome-rails" +gem "wicked" +gem "search_cop", "~> 1.0.6" +gem "mandrill_mailer" +gem "jwt", "~> 1.2.1" +gem "httparty" +gem "will_paginate", "~> 3.1.7" +gem "bootstrap-will_paginate" +gem "apipie-rails", "~> 0.5.0" +gem "rack-cors", require: "rack/cors" +gem "ckeditor", "~> 4.3.0" gem "binding_of_caller" -gem 'image_processing' -gem 'foundation_emails' -gem 'inky-rb', require: 'inky' +gem "image_processing" +gem "foundation_emails" +gem "inky-rb", require: "inky" # Stylesheet inlining for email -gem 'premailer-rails' -gem "bcrypt", '3.1.16' +gem "premailer-rails" +gem "bcrypt", "3.1.16" gem "json", ">= 2.6", "< 3" # or simply: gem "json", "~> 2.7" group :development, :test do - gem 'better_errors' - gem 'capybara', '~> 3.36' - gem 'dotenv-rails' - gem 'faker' - gem 'factory_bot_rails' - gem 'listen' - gem 'pry-rails' - gem 'rspec-rails' - gem 'selenium-webdriver' - gem 'shoulda-matchers', require: false + gem "better_errors" + gem "capybara", "~> 3.36" + gem "dotenv-rails" + gem "faker" + gem "factory_bot_rails" + gem "listen" + gem "pry-rails" + gem "rspec-rails" + gem "rubocop-capybara", require: false + gem "rubocop-factory_bot", require: false + gem "rubocop-rails", require: false + gem "rubocop-rspec", require: false + gem "rubocop-rspec_rails", require: false + gem "rubocop-shopify", require: false + gem "selenium-webdriver" + gem "shoulda-matchers", require: false end diff --git a/Gemfile.lock b/Gemfile.lock index dd2a72a40..1435141ba 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -68,6 +68,7 @@ GEM public_suffix (>= 2.0.2, < 7.0) apipie-rails (0.5.20) rails (>= 4.1) + ast (2.4.3) autoprefixer-rails (10.4.21.0) execjs (~> 2) aws-eventstream (1.4.0) @@ -216,6 +217,8 @@ GEM mime-types mimemagic (~> 0.3.0) terrapin (~> 0.6.0) + language_server-protocol (3.17.0.5) + lint_roller (1.1.0) listen (3.9.0) rb-fsevent (~> 0.10, >= 0.10.3) rb-inotify (~> 0.9, >= 0.9.10) @@ -272,6 +275,10 @@ GEM mini_portile2 (~> 2.8.2) racc (~> 1.4) orm_adapter (0.5.0) + parallel (1.27.0) + parser (3.3.9.0) + ast (~> 2.4.1) + racc polyglot (0.3.5) premailer (1.22.0) addressable @@ -281,6 +288,7 @@ GEM actionmailer (>= 3) net-smtp premailer (~> 1.7, >= 1.7.9) + prism (1.4.0) pry (0.15.2) coderay (~> 1.1) method_source (~> 1.0) @@ -338,6 +346,7 @@ GEM method_source rake (>= 12.2) thor (~> 1.0) + rainbow (3.1.1) rake (13.3.0) rb-fsevent (0.11.2) rb-inotify (0.11.1) @@ -368,6 +377,42 @@ GEM rspec-mocks (~> 3.10) rspec-support (~> 3.10) rspec-support (3.13.4) + rubocop (1.80.2) + json (~> 2.3) + language_server-protocol (~> 3.17.0.2) + lint_roller (~> 1.1.0) + parallel (~> 1.10) + parser (>= 3.3.0.2) + rainbow (>= 2.2.2, < 4.0) + regexp_parser (>= 2.9.3, < 3.0) + rubocop-ast (>= 1.46.0, < 2.0) + ruby-progressbar (~> 1.7) + unicode-display_width (>= 2.4.0, < 4.0) + rubocop-ast (1.46.0) + parser (>= 3.3.7.2) + prism (~> 1.4) + rubocop-capybara (2.22.1) + lint_roller (~> 1.1) + rubocop (~> 1.72, >= 1.72.1) + rubocop-factory_bot (2.27.1) + lint_roller (~> 1.1) + rubocop (~> 1.72, >= 1.72.1) + rubocop-rails (2.33.3) + activesupport (>= 4.2.0) + lint_roller (~> 1.1) + rack (>= 1.1) + rubocop (>= 1.75.0, < 2.0) + rubocop-ast (>= 1.44.0, < 2.0) + rubocop-rspec (3.7.0) + lint_roller (~> 1.1) + rubocop (~> 1.72, >= 1.72.1) + rubocop-rspec_rails (2.31.0) + lint_roller (~> 1.1) + rubocop (~> 1.72, >= 1.72.1) + rubocop-rspec (~> 3.5) + rubocop-shopify (2.17.1) + rubocop (~> 1.62) + ruby-progressbar (1.13.0) ruby-vips (2.2.4) ffi (~> 1.12) logger @@ -414,6 +459,9 @@ GEM concurrent-ruby (~> 1.0) uglifier (4.2.1) execjs (>= 0.3.0, < 3) + unicode-display_width (3.2.0) + unicode-emoji (~> 4.1) + unicode-emoji (4.1.0) warden (1.2.9) rack (>= 2.0.9) websocket (1.2.11) @@ -471,6 +519,12 @@ DEPENDENCIES rails (~> 6.1.7) rails_admin (~> 2.2.1) rspec-rails + rubocop-capybara + rubocop-factory_bot + rubocop-rails + rubocop-rspec + rubocop-rspec_rails + rubocop-shopify sassc-rails (>= 2.1.2) search_cop (~> 1.0.6) selenium-webdriver diff --git a/Rakefile b/Rakefile index 8718fc141..f5f7cab02 100644 --- a/Rakefile +++ b/Rakefile @@ -1,9 +1,11 @@ +# frozen_string_literal: true + # Add your own tasks in files placed in lib/tasks ending in .rake, -require File.expand_path('../config/application', __FILE__) +require File.expand_path("../config/application", __FILE__) Rails.application.load_tasks desc "Build local docker image" -task "build:docker" do |t, args| - sh "docker build --no-cache -t awbw-portal ." -end \ No newline at end of file +task "build:docker" => :environment do |_t, _args| + sh "docker build --no-cache -t awbw-portal ." +end diff --git a/app/controllers/admins/base_controller.rb b/app/controllers/admins/base_controller.rb index 53cd5811e..ca3fe80c8 100644 --- a/app/controllers/admins/base_controller.rb +++ b/app/controllers/admins/base_controller.rb @@ -1,6 +1,8 @@ -class Admins::BaseController < ActionController::Base +# frozen_string_literal: true + +class Admins::BaseController < ApplicationController before_action :authenticate_admin! def show - redirect_to rails_admin_path + redirect_to(rails_admin_path) end -end \ No newline at end of file +end diff --git a/app/controllers/admins/sessions_controller.rb b/app/controllers/admins/sessions_controller.rb index d79eaa1d0..ccd5f8c22 100644 --- a/app/controllers/admins/sessions_controller.rb +++ b/app/controllers/admins/sessions_controller.rb @@ -1,2 +1,4 @@ -class Admins::SessionsController < ::Devise::SessionsController -end \ No newline at end of file +# frozen_string_literal: true + +class Admins::SessionsController < Devise::SessionsController +end diff --git a/app/controllers/api/v1/annotations_controller.rb b/app/controllers/api/v1/annotations_controller.rb index fa567c09b..7b4750fa0 100644 --- a/app/controllers/api/v1/annotations_controller.rb +++ b/app/controllers/api/v1/annotations_controller.rb @@ -1,28 +1,30 @@ +# frozen_string_literal: true + class Api::V1::AnnotationsController < Api::V1::ApiController def index @bookmark = Bookmark.find(params[:bookmark_id]) @annotations = @bookmark.bookmark_annotations - render json: @annotations.map(&:content_with_id).to_json, status: :ok + render(json: @annotations.map(&:content_with_id).to_json, status: :ok) end def create @bookmark = Bookmark.find(params[:bookmark_id]) @annotation = @bookmark.bookmark_annotations.build( - annotation: params[:annotation].to_json + annotation: params[:annotation].to_json, ) if @annotation.save - render json: @annotation, status: :ok + render(json: @annotation, status: :ok) else - render json: {}, status: :unprocessable_entity + render(json: {}, status: :unprocessable_entity) end end def update @annotation = BookmarkAnnotation.find(params[:id]) if @annotation.update(annotation: params[:annotation]) - render json: @annotation, status: :ok + render(json: @annotation, status: :ok) else - render json: {}, status: :unprocessable_entity + render(json: {}, status: :unprocessable_entity) end end @@ -30,9 +32,9 @@ def destroy @annotation = BookmarkAnnotation.find(params[:id]) if @annotation @annotation.destroy - render json: @annotation, status: :ok + render(json: @annotation, status: :ok) else - render json: {}, status: :unprocessable_entity + render(json: {}, status: :unprocessable_entity) end end end diff --git a/app/controllers/api/v1/api_controller.rb b/app/controllers/api/v1/api_controller.rb index 0f4d6da5b..4cac789c1 100644 --- a/app/controllers/api/v1/api_controller.rb +++ b/app/controllers/api/v1/api_controller.rb @@ -1,11 +1,13 @@ -class Api::V1::ApiController < ActionController::Base - protect_from_forgery with: :null_session, :if => Proc.new { |c| c.request.format.json? } +# frozen_string_literal: true + +class Api::V1::ApiController < ApplicationController + protect_from_forgery with: :null_session, if: proc { |c| c.request.format.json? } rescue_from AuthenticationFailed, with: :authentication_failed before_action :authenticate_api_user! def authenticate_api_user! - raise AuthenticationFailed unless current_api_user.present? + raise AuthenticationFailed if current_api_user.blank? end def current_api_user @@ -17,17 +19,16 @@ def current_api_user end def authentication_failed(exception) - render json: {error: exception.message}, status: :unauthorized + render(json: { error: exception.message }, status: :unauthorized) end private def http_auth_header_content - if request.headers['Authorization'].present? - @http_auth_header_content ||= - request.headers['Authorization'].split(' ').last + @http_auth_header_content ||= if request.headers["Authorization"].present? + request.headers["Authorization"].split(" ").last else - @http_auth_header_content ||= params['Authorization'] + params["Authorization"] end end end diff --git a/app/controllers/api/v1/authentications_controller.rb b/app/controllers/api/v1/authentications_controller.rb index f4dbfe195..80191c38b 100644 --- a/app/controllers/api/v1/authentications_controller.rb +++ b/app/controllers/api/v1/authentications_controller.rb @@ -1,18 +1,20 @@ +# frozen_string_literal: true + class Api::V1::AuthenticationsController < Api::V1::ApiController skip_before_action :authenticate_api_user! - api :POST, '/v1/authentications' - param :email, String, 'User\'s email', required: true - param :password, String, 'User\'s password', required: true - desc 'With valid credentials, return\'s an API Authorization token' + api :POST, "/v1/authentications" + param :email, String, "User's email", required: true + param :password, String, "User's password", required: true + desc "With valid credentials, return's an API Authorization token" def create - user = User.find_by_email(params[:email]) + user = User.find_by(email: params[:email]) if user.present? && user.valid_password?(params[:password]) - sign_in user + sign_in(user) token = AuthenticationToken.generate_token(user.id).to_s - render json: { token: token, user: user, url: "#{request.base_url}/?Authorization=#{token}" }, status: :created + render(json: { token: token, user: user, url: "#{request.base_url}/?Authorization=#{token}" }, status: :created) else - render json: { error: 'Not Authorized', status: :unauthorized } + render(json: { error: "Not Authorized", status: :unauthorized }) end end end diff --git a/app/controllers/api/v1/quotes_controller.rb b/app/controllers/api/v1/quotes_controller.rb index 44893b356..a69462609 100644 --- a/app/controllers/api/v1/quotes_controller.rb +++ b/app/controllers/api/v1/quotes_controller.rb @@ -1,14 +1,19 @@ +# frozen_string_literal: true + class Api::V1::QuotesController < Api::V1::ApiController - api :GET, '/v1/quotes' - param :Authorization, String, desc: 'API Authorization token returned by successful'\ - ' user authentication', required: true - param :sector, String, desc: "One of #{Sector.all.pluck(:name).join(', ')}" - desc 'Without a Sector parameter, gives a list of all quotes grouped by Sector.' + api :GET, "/v1/quotes" + param :Authorization, + String, + desc: "API Authorization token returned by successful " \ + "user authentication", + required: true + param :sector, String, desc: "One of #{Sector.all.pluck(:name).join(", ")}" + desc "Without a Sector parameter, gives a list of all quotes grouped by Sector." def index sector = Sector.find_by(name: params[:sector]) || Sector.all - quotes = sector.to_json(only: :name, :include => { - :quotes => { only: :quote } + quotes = sector.to_json(only: :name, include: { + quotes: { only: :quote }, }) - render json: { quotes: quotes }, status: :ok + render(json: { quotes: quotes }, status: :ok) end end diff --git a/app/controllers/api/v1/resources_controller.rb b/app/controllers/api/v1/resources_controller.rb index 2409f4a98..80bb32d3b 100644 --- a/app/controllers/api/v1/resources_controller.rb +++ b/app/controllers/api/v1/resources_controller.rb @@ -1,11 +1,13 @@ +# frozen_string_literal: true + class Api::V1::ResourcesController < Api::V1::ApiController def index resource_type = params[:type].constantize if resource_type @resources = resource_type.all.to_json(include: :related_workshops) - render json: @resources, status: :ok + render(json: @resources, status: :ok) else - render json: {}, status: :unauthorized + render(json: {}, status: :unauthorized) end end end diff --git a/app/controllers/api/v1/workshops_controller.rb b/app/controllers/api/v1/workshops_controller.rb index 1e0b2f2eb..29608fe5e 100644 --- a/app/controllers/api/v1/workshops_controller.rb +++ b/app/controllers/api/v1/workshops_controller.rb @@ -1,25 +1,31 @@ +# frozen_string_literal: true + class Api::V1::WorkshopsController < Api::V1::ApiController - api :GET, '/v1/workshops' - param :Authorization, String, desc: 'API Authorization token returned by successful'\ - ' user authentication', required: true - param :sector, String, desc: "One of #{Sector.all.pluck(:name).join(', ')}" - desc 'Without a Sector parameter, gives a list of workshops grouped by '\ - 'Sector, including quotes and images. Relates to the "Related Workshops" '\ - 'view in Sector Impacts' + api :GET, "/v1/workshops" + param :Authorization, + String, + desc: "API Authorization token returned by successful " \ + "user authentication", + required: true + param :sector, String, desc: "One of #{Sector.all.pluck(:name).join(", ")}" + desc "Without a Sector parameter, gives a list of workshops grouped by " \ + 'Sector, including quotes and images. Relates to the "Related Workshops" ' \ + "view in Sector Impacts" def index - sector = Sector.find_by_name(params[:sector]) || Sector.all + sector = Sector.find_by(name: params[:sector]) || Sector.all - workshops = sector.to_json(only: :name, :include => { - :workshops => { only: [:id, :title, :description], - :include => [ - { :windows_type => { only: :name } }, - { :quotes => { only: :quote } }, - { :sectors => { only: :name } } + workshops = sector.to_json(only: :name, include: { + workshops: { + only: [:id, :title, :description], + include: [ + { windows_type: { only: :name } }, + { quotes: { only: :quote } }, + { sectors: { only: :name } }, ], - :methods => [:main_image_url, :sector_hashtags] - } + methods: [:main_image_url, :sector_hashtags], + }, }) - render json: workshops, status: :ok + render(json: workshops, status: :ok) end end diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 7b88a2ee1..28bd5615f 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class ApplicationController < ActionController::Base # Prevent CSRF attacks by raising an exception. # For APIs, you may want to use :null_session instead. @@ -13,16 +15,17 @@ def clear_sign_in_flash end def authenticate_api_user! - return unless current_api_user.present? - sign_in current_api_user - flash[:notice] = 'You have successfully logged in.' + return if current_api_user.blank? + + sign_in(current_api_user) + flash[:notice] = "You have successfully logged in." end def authenticate_user! user = User.find_by(email: params[:user][:email]) if params[:user] - if user && user.legacy - flash[:notice] = 'We have migrated our data to a new system. '\ - 'Please click the link below to reset your password.' + if user&.legacy + flash[:notice] = "We have migrated our data to a new system. " \ + "Please click the link below to reset your password." end admin_request? ? rails_admin_path : super end @@ -30,19 +33,19 @@ def authenticate_user! # IMPERSONATE USER alias_method :devise_current_user, :current_user def current_user - if session[:i_user] && devise_current_user && devise_current_user.super_user? - user = User.find_by(email: session[:i_user]) if session[:i_user] + if session[:i_user] && devise_current_user&.super_user? + User.find_by(email: session[:i_user]) if session[:i_user] else devise_current_user end end def admin_request? - params['controller'].include?('rails_admin') || params['controller'].include?('ckeditor') + params["controller"].include?("rails_admin") || params["controller"].include?("ckeditor") end def after_sign_in_path_for(resource) - resource.class.name == 'User' ? root_path : admins_root_path + resource.class.name == "User" ? root_path : admins_root_path end def after_sign_out_path_for(resource) @@ -58,11 +61,10 @@ def current_api_user end def http_auth_header_content - if request.headers['Authorization'].present? - @http_auth_header_content ||= - request.headers['Authorization'].split(' ').last + @http_auth_header_content ||= if request.headers["Authorization"].present? + request.headers["Authorization"].split(" ").last else - @http_auth_header_content ||= params['Authorization'] + params["Authorization"] end end end diff --git a/app/controllers/bookmarks_controller.rb b/app/controllers/bookmarks_controller.rb index 4f3c68347..2d7e74426 100644 --- a/app/controllers/bookmarks_controller.rb +++ b/app/controllers/bookmarks_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class BookmarksController < ApplicationController before_action :set_breadcrumb @@ -15,23 +17,23 @@ def create @bookmarkable = @bookmark.bookmarkable @bookmarkable.update(led_count: @bookmarkable.led_count + 1) flash[:alert] = "#{@bookmark.bookmarkable_type} added to your bookmarks." - redirect_to workshop_path(@bookmark.bookmarkable) + redirect_to(workshop_path(@bookmark.bookmarkable)) end def show @bookmark = Bookmark.find(params[:id]).decorate @bookmarkable = @bookmark.bookmarkable - load_workshop_data if @bookmark.bookmarkable_class_name == 'Workshop' + load_workshop_data if @bookmark.bookmarkable_class_name == "Workshop" end def destroy @bookmark = Bookmark.find(params[:id]) if @bookmark @bookmark.destroy - flash[:alert] = 'Bookmark has been deleted.' - redirect_to workshop_path(@bookmark.bookmarkable) + flash[:alert] = "Bookmark has been deleted." + redirect_to(workshop_path(@bookmark.bookmarkable)) else - flash[:error] = 'Unable to find that bookmark.' + flash[:error] = "Unable to find that bookmark." end end diff --git a/app/controllers/contact_us_controller.rb b/app/controllers/contact_us_controller.rb index a4347a12e..26bfacf75 100644 --- a/app/controllers/contact_us_controller.rb +++ b/app/controllers/contact_us_controller.rb @@ -1,11 +1,12 @@ -class ContactUsController < ApplicationController +# frozen_string_literal: true +class ContactUsController < ApplicationController def index end def create ContactUsMailer.hello(params[:contact_us]).deliver_now flash[:alert] = "Your message was sent!" - redirect_to '/' + redirect_to("/") end end diff --git a/app/controllers/dashboard_controller.rb b/app/controllers/dashboard_controller.rb index 7d52f1073..159a52a20 100644 --- a/app/controllers/dashboard_controller.rb +++ b/app/controllers/dashboard_controller.rb @@ -1,17 +1,26 @@ +# frozen_string_literal: true + class DashboardController < ApplicationController - skip_before_action :authenticate_user!, :only => :help + skip_before_action :authenticate_user!, only: :help # rubocop:todo Rails/LexicallyScopedActionFilter - layout 'help', :only => :help + layout "help", only: :help def index @user = current_user.decorate - @workshops = current_user.curriculum(Workshop). - featured.includes(:sectors).decorate - @workshops = @workshops.sort{|x,y| Date.parse(y.date) <=> Date.parse(x.date) } + @workshops = current_user.curriculum(Workshop) + .featured.includes(:sectors).decorate + @workshops = @workshops.sort { |x, y| Date.parse(y.date) <=> Date.parse(x.date) } - @resources = Resource.published.featured.where(kind: [nil, 'Resource', - 'Template','Handout', 'Scholarship', 'Toolkit', 'Form']). - decorate + @resources = Resource.published.featured.where(kind: [ + nil, + "Resource", + "Template", + "Handout", + "Scholarship", + "Toolkit", + "Form", + ]) + .decorate @stories = Resource.story.featured.decorate @themes = Resource.theme.featured.decorate diff --git a/app/controllers/faqs_controller.rb b/app/controllers/faqs_controller.rb index c446a86cd..666b08d42 100644 --- a/app/controllers/faqs_controller.rb +++ b/app/controllers/faqs_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class FaqsController < ApplicationController def index @faqs = Faq.active.by_order diff --git a/app/controllers/impersonate_users_controller.rb b/app/controllers/impersonate_users_controller.rb index c4d69f068..befc0f5ba 100644 --- a/app/controllers/impersonate_users_controller.rb +++ b/app/controllers/impersonate_users_controller.rb @@ -1,32 +1,36 @@ -class ImpersonateUsersController < ApplicationController +# frozen_string_literal: true +class ImpersonateUsersController < ApplicationController before_action :check_current_user_is_super_user def index - if params[:q] - @users = User.where('first_name like ? or last_name like ?', - "#{params[:q]}%", "#{params[:q]}%"). - paginate(page: params[:page], per_page: 10) + @users = if params[:q] + User.where( + "first_name like ? or last_name like ?", + "#{params[:q]}%", + "#{params[:q]}%", + ) + .paginate(page: params[:page], per_page: 10) else - @users = User.all.paginate(page: params[:page], per_page: 10) + User.all.paginate(page: params[:page], per_page: 10) end end def impersonate session[:i_user] = params[:i_user] - redirect_to :root + redirect_to(:root) end def back session[:i_user] = nil - redirect_to :root + redirect_to(:root) end private def check_current_user_is_super_user unless devise_current_user.super_user? - redirect_to(root_path, status: 401) + redirect_to(root_path, status: :unauthorized) end end end diff --git a/app/controllers/monthly_reports_controller.rb b/app/controllers/monthly_reports_controller.rb index 499fe07a2..f4ce0665f 100644 --- a/app/controllers/monthly_reports_controller.rb +++ b/app/controllers/monthly_reports_controller.rb @@ -18,15 +18,22 @@ def monthly load_agencies @workshop_log_summary_page = show_feature?(:new_workshop_log) - if (@report = current_user.submitted_monthly_report(@date, - @form_builder.windows_type, - @agency_id)) - redirect_to( :action => :edit, :id => @report, - :month => @month, :year => @year, - :form_builder_id => @form_builder.id, :agency_id => @agency_id ) + if (@report = current_user.submitted_monthly_report( + @date, + @form_builder.windows_type, + @agency_id, + )) + redirect_to( + action: :edit, + id: @report, + month: @month, + year: @year, + form_builder_id: @form_builder.id, + agency_id: @agency_id, + ) else render_form - render :new + render(:new) end end @@ -37,26 +44,26 @@ def create if params[:sectorable_items] if @report.save flash[:alert] = "Your Monthly report has been successfully submitted." - redirect_to '/' + redirect_to("/") else - @form_builder = FormBuilder.find( @report.owner_id ) + @form_builder = FormBuilder.find(@report.owner_id) build_month_and_year load_agencies - @agency_id = report_params['project_id'] + @agency_id = report_params["project_id"] - flash[:alert] = "There was a problem submitting your form: " + - "#{@report.errors.full_messages.join(" ")}" - render :new + flash[:alert] = "There was a problem submitting your form: " \ + "#{@report.errors.full_messages.join(" ")}" + render(:new) end else - flash[:error] = 'Please select some populations that attended this monthly report!!!' + flash[:error] = "Please select some populations that attended this monthly report!!!" @total_ongoing = 0 @total_first_time = 0 find_form_builder - #@report.report_form_field_answers.build( log_fields ) - render :new + # @report.report_form_field_answers.build( log_fields ) + render(:new) end end @@ -65,10 +72,10 @@ def edit build_month_and_year find_form_builder @report = Report.find(params[:id]) - @agencies = current_user.projects. - where(windows_type_id: @report.windows_type_id) + @agencies = current_user.projects + .where(windows_type_id: @report.windows_type_id) @month = @report.date.month - @year = @report.date.year + @year = @report.date.year find_workshop_logs find_combined_workshop_logs(@agency_id) @@ -76,44 +83,45 @@ def edit def update check_feature_fag - @report = MonthlyReport.find params[:id] + @report = MonthlyReport.find(params[:id]) if params[:report] ActiveRecord::Base.transaction do - @report.update_attributes( report_params ) - @saved = @report.delete_and_update_all( quotes_params, log_fields, - params[:image] ) + @report.update(report_params) + @saved = @report.delete_and_update_all( + quotes_params, + log_fields, + params[:image], + ) end if @saved - flash[:alert] = 'Thanks for reporting on a update report. ' - redirect_to root_path + flash[:alert] = "Thanks for reporting on a update report. " + redirect_to(root_path) else - @agencies = current_user.projects. - where(windows_type_id: @report.windows_type_id) + @agencies = current_user.projects + .where(windows_type_id: @report.windows_type_id) - flash[:alert] = 'ERROR!!!!!!!!!!!!!!' - render :edit + flash[:alert] = "ERROR!!!!!!!!!!!!!!" + render(:edit) end else - flash[:alert] = 'Please select some populations that attended this report!!!' - redirect_to edit_report_path(@report) + flash[:alert] = "Please select some populations that attended this report!!!" + redirect_to(edit_report_path(@report)) end end - private def load_agencies - @agencies = current_user.projects. - where(windows_type_id: @form_builder.windows_type_id).uniq - + @agencies = current_user.projects + .where(windows_type_id: @form_builder.windows_type_id).uniq end def render_form - @workshop_list = current_user.curriculum. - where(inactive: false, windows_type: 3). - order(title: :asc) + @workshop_list = current_user.curriculum + .where(inactive: false, windows_type: 3) + .order(title: :asc) build_month_and_year build_report @@ -124,10 +132,10 @@ def render_form end def find_form_builder - if params[:form_builder_id] - @form_builder = FormBuilder.find( params[:form_builder_id] ).decorate + @form_builder = if params[:form_builder_id] + FormBuilder.find(params[:form_builder_id]).decorate else - @form_builder = FormBuilder + FormBuilder .monthly .find_by(windows_type_id: @agency.windows_type_id) .decorate @@ -141,21 +149,21 @@ def build_report @report = Report.new( type: @form_builder.report_type, windows_type: @form_builder.windows_type, - date: @date + date: @date, ) @report.media_files.build end def build_new_report - @report = current_user.reports.build( report_params ) - @report.report_form_field_answers.build( log_fields ) + @report = current_user.reports.build(report_params) + @report.report_form_field_answers.build(log_fields) # @report.media_files.build( file: media_files_params ) unless media_files_params.blank? quotes = [] - quotes_params.each{ |q| - quotes << Quote.new( quote: q[:quote], age: q[:age], gender: q[:gender] ) - } + quotes_params.each do |q| + quotes << Quote.new(quote: q[:quote], age: q[:age], gender: q[:gender]) + end @report.quotes = quotes @@ -163,23 +171,23 @@ def build_new_report end def check_feature_fag - redirect_to '/' if show_feature?(:no_monthly_reports) + redirect_to("/") if show_feature?(:no_monthly_reports) end def build_report_form_fields return unless @form_builder.form_fields - @form_builder.form_fields.where(status: 1).each do |field| + @form_builder.form_fields.where(status: 1).find_each do |field| if field.multiple_choice? field.answer_options.each do |option| @report.report_form_field_answers.new( form_field: field, - answer_option: option + answer_option: option, ) end else @report.report_form_field_answers.new( - form_field: field + form_field: field, ) end end @@ -190,37 +198,43 @@ def find_workshop_logs @report.date, @report.windows_type ) - logs = @workshop_logs.map{|k, v| v}.flatten - @total_ongoing = logs.reduce(0){|sum, l| sum = sum + l.num_ongoing} - @total_first_time = logs.reduce(0) {|sum, l| sum = sum + l.num_first_time} + logs = @workshop_logs.map { |_k, v| v }.flatten + @total_ongoing = logs.reduce(0) { |sum, l| sum + l.num_ongoing } + @total_first_time = logs.reduce(0) { |sum, l| sum + l.num_first_time } end def find_combined_workshop_logs(agency_id) combined_windows_type = WindowsType.where("name LIKE ?", "%COMBINED (FAMILY)%").first @combined_workshop_logs = current_user.project_workshop_logs( - @report.date, combined_windows_type, agency_id ) + @report.date, combined_windows_type, agency_id + ) end def build_month_and_year @month = params[:month] ? params[:month] : Date.current.month @year = params[:year] ? params[:year] : Date.current.year - @date = Date.new( @year.to_i, @month.to_i ) + @date = Date.new(@year.to_i, @month.to_i) end def report_params params[:report].delete(:form_file) if params[:report][:form_file].blank? - params[:report][:media_files_attributes].each do |k,v| + params[:report][:media_files_attributes].each do |k, _v| params[:report][:media_files_attributes].delete(k) if params[:report][:media_files_attributes][k][:file].blank? - end params.require(:report).permit( - :type, :project_id, :date, :owner_id, :workshop_id, - :owner_type, :windows_type_id, :other_description, + :type, + :project_id, + :date, + :owner_id, + :workshop_id, + :owner_type, + :windows_type_id, + :other_description, media_files_attributes: [:file], report_form_field_answers_attributes: - [:form_field_id, :answer_option_id, :answer, :_create] + [:form_field_id, :answer_option_id, :answer, :_create], ) end @@ -230,7 +244,7 @@ def media_files_params def log_fields log_fields_params.map do |k, v| - { :form_field_id => k, :answer => v, :report_id => @report.id } + { form_field_id: k, answer: v, report_id: @report.id } end end @@ -240,15 +254,17 @@ def log_fields_params def quotes_params return [] if params[:quotes].nil? - params[:quotes].permit!.map{|k, v| v} + + params[:quotes].permit!.map { |_k, v| v } end def build_date @month = Date.current.month @year = Date.current.year - @date = params[:report][:date] ? - Date.strptime( params[:report][:date], '%Y-%m' ) : - Date.new( @year.to_i, @month.to_i ) + @date = if params[:report][:date] + Date.strptime(params[:report][:date], "%Y-%m") + else + Date.new(@year.to_i, @month.to_i) + end end - end diff --git a/app/controllers/passwords_controller.rb b/app/controllers/passwords_controller.rb index 9694a034c..9a4c2513b 100644 --- a/app/controllers/passwords_controller.rb +++ b/app/controllers/passwords_controller.rb @@ -1,5 +1,6 @@ +# frozen_string_literal: true + class PasswordsController < Devise::PasswordsController - def create self.resource = resource_class.send_reset_password_instructions(resource_params) yield resource if block_given? diff --git a/app/controllers/project_users_controller.rb b/app/controllers/project_users_controller.rb index 52cf32d9c..98f67806d 100644 --- a/app/controllers/project_users_controller.rb +++ b/app/controllers/project_users_controller.rb @@ -1,13 +1,15 @@ +# frozen_string_literal: true + class ProjectUsersController < ApplicationController def destroy project_user = ProjectUser.find(params[:id]) user = project_user.user if project_user.destroy - flash[:alert] = 'Project user has been deleted.' + flash[:alert] = "Project user has been deleted." else - flash[:error] = 'Unable to delete project user. Please contact AWBW.' + flash[:error] = "Unable to delete project user. Please contact AWBW." end - redirect_to user_path(user) + redirect_to(user_path(user)) end end diff --git a/app/controllers/registrations_controller.rb b/app/controllers/registrations_controller.rb index dfbe97697..a320c517b 100644 --- a/app/controllers/registrations_controller.rb +++ b/app/controllers/registrations_controller.rb @@ -1,18 +1,26 @@ +# frozen_string_literal: true + class RegistrationsController < Devise::RegistrationsController private def sign_up_params params.require(:user).permit( - :first_name, :last_name, :email, - :password, :password_confirmation + :first_name, + :last_name, + :email, + :password, + :password_confirmation, ) end def account_update_params params.require(:user).permit( - :first_name, :last_name, :email, - :password, :password_confirmation, - :current_password + :first_name, + :last_name, + :email, + :password, + :password_confirmation, + :current_password, ) end end diff --git a/app/controllers/reports_controller.rb b/app/controllers/reports_controller.rb index 1e7175b6a..3a52ff65a 100644 --- a/app/controllers/reports_controller.rb +++ b/app/controllers/reports_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class ReportsController < ApplicationController def show @report = Report.find(params[:id]) @@ -10,14 +12,20 @@ def monthly build_month_and_year find_form_builder - if (@report = current_user.submitted_monthly_report(@date, - @form_builder.windows_type)) - redirect_to( :action => :edit, :id => @report, - :month => @month, :year => @year, - :form_builder_id => @form_builder.id ) + if (@report = current_user.submitted_monthly_report( + @date, + @form_builder.windows_type, + )) + redirect_to( + action: :edit, + id: @report, + month: @month, + year: @year, + form_builder_id: @form_builder.id, + ) else render_form - render :new + render(:new) end end @@ -31,9 +39,9 @@ def share_story end def render_form - @workshop_list = current_user.curriculum. - where(inactive: false). - order(title: :asc) + @workshop_list = current_user.curriculum + .where(inactive: false) + .order(title: :asc) build_month_and_year find_form_builder @@ -45,74 +53,80 @@ def render_form def edit build_month_and_year find_form_builder - @report = current_user.submitted_monthly_report( @date, @form_builder.windows_type ) - @agencies = current_user.projects. - where(windows_type_id: @report.windows_type_id) + @report = current_user.submitted_monthly_report(@date, @form_builder.windows_type) + @agencies = current_user.projects + .where(windows_type_id: @report.windows_type_id) @month = @report.date.month - @year = @report.date.year + @year = @report.date.year find_workshop_logs end def edit_story - @workshop_list = current_user.curriculum. - where(inactive: false, windows_type: 3).order(title: :asc) + @workshop_list = current_user.curriculum + .where(inactive: false, windows_type: 3).order(title: :asc) @report = Report.find(params[:id]) - @agencies = current_user.projects. - where(windows_type_id: @report.windows_type_id) + @agencies = current_user.projects + .where(windows_type_id: @report.windows_type_id) end def update_story - @report = Report.find params[:id] + @report = Report.find(params[:id]) if params[:report] ActiveRecord::Base.transaction do - @report.update_attributes( report_params ) + @report.update(report_params) - @saved = @report.delete_and_update_all( quotes_params, log_fields, - params[:image] ) + @saved = @report.delete_and_update_all( + quotes_params, + log_fields, + params[:image], + ) end if @saved - flash[:alert] = 'Thanks for reporting on a update report. ' - redirect_to root_path + flash[:alert] = "Thanks for reporting on a update report. " + redirect_to(root_path) else - @agencies = current_user.projects. - where(windows_type_id: @report.windows_type_id) + @agencies = current_user.projects + .where(windows_type_id: @report.windows_type_id) - flash[:alert] = 'ERROR!!!!!!!!!!!!!!' - render :edit + flash[:alert] = "ERROR!!!!!!!!!!!!!!" + render(:edit) end else - flash[:alert] = 'Please select some populations that attended this report!!!' - redirect_to reports_edit_story_path(@report) + flash[:alert] = "Please select some populations that attended this report!!!" + redirect_to(reports_edit_story_path(@report)) end end def update - @report = MonthlyReport.find params[:id] + @report = MonthlyReport.find(params[:id]) if params[:report] ActiveRecord::Base.transaction do - @report.update_attributes( report_params ) - @saved = @report.delete_and_update_all( quotes_params, log_fields, - params[:image] ) + @report.update(report_params) + @saved = @report.delete_and_update_all( + quotes_params, + log_fields, + params[:image], + ) end if @saved - flash[:alert] = 'Thanks for reporting on a update report. ' - redirect_to root_path + flash[:alert] = "Thanks for reporting on a update report. " + redirect_to(root_path) else - @agencies = current_user.projects. - where(windows_type_id: @report.windows_type_id) + @agencies = current_user.projects + .where(windows_type_id: @report.windows_type_id) - flash[:alert] = 'ERROR!!!!!!!!!!!!!!' - render :edit + flash[:alert] = "ERROR!!!!!!!!!!!!!!" + render(:edit) end else - flash[:alert] = 'Please select some populations that attended this report!!!' - redirect_to edit_report_path(@report) + flash[:alert] = "Please select some populations that attended this report!!!" + redirect_to(edit_report_path(@report)) end end @@ -122,30 +136,29 @@ def create report_type = "story" report_type = "monthly report" unless @report.owner_id == 7 - if params[:sectorable_items] or params[:form_builder_id] == '7' + if params[:sectorable_items] || (params[:form_builder_id] == "7") if @report.save flash[:alert] = "Your #{report_type} has been successfully submitted." - redirect_to '/' + redirect_to("/") else - @form_builder = FormBuilder.find( @report.owner_id ) + @form_builder = FormBuilder.find(@report.owner_id) build_month_and_year - flash[:alert] = "There was a problem submitting your form: " + - "#{@report.errors.full_messages.join(" ")}" + flash[:alert] = "There was a problem submitting your form: " \ + "#{@report.errors.full_messages.join(" ")}" - redirect_to :action =>'new', :form_builder_id => @report.owner_id + redirect_to(action: "new", form_builder_id: @report.owner_id) end else - flash[:error] = 'Please select some populations that attended this monthly report!!!' - redirect_to "/reports/monthly?form_builder_id=#{params[:form_builder_id]}&year=#{params[:year]}&month=#{params[:month]}" + flash[:error] = "Please select some populations that attended this monthly report!!!" + redirect_to("/reports/monthly?form_builder_id=#{params[:form_builder_id]}&year=#{params[:year]}&month=#{params[:month]}") end end def create_story build_new_report @report.type = "Story" - @report.report_form_field_answers.build( log_fields ) - + @report.report_form_field_answers.build(log_fields) if !params[:workshop_id].empty? @report.windows_type_id = Workshop.find(@report.workshop_id).windows_type_id @@ -156,25 +169,25 @@ def create_story if @report.save flash[:alert] = "Your Story has been successfully submitted." - redirect_to '/' + redirect_to("/") else - @form_builder = FormBuilder.find( @report.owner_id ) + @form_builder = FormBuilder.find(@report.owner_id) build_month_and_year - flash[:alert] = "There was a problem submitting your form: " + - "#{@report.errors.full_messages.join(" ")}" + flash[:alert] = "There was a problem submitting your form: " \ + "#{@report.errors.full_messages.join(" ")}" - redirect_to :action =>'share_story', :form_bilder_id => @report.owner_id + redirect_to(action: "share_story", form_bilder_id: @report.owner_id) end end private def find_form_builder - if params[:form_builder_id] - @form_builder = FormBuilder.find( params[:form_builder_id] ).decorate + @form_builder = if params[:form_builder_id] + FormBuilder.find(params[:form_builder_id]).decorate else - @form_builder = FormBuilder + FormBuilder .monthly .find_by(windows_type_id: @agency.windows_type_id) .decorate @@ -185,20 +198,20 @@ def build_report @report = Report.new( type: @form_builder.report_type, windows_type: @form_builder.windows_type, - date: @date + date: @date, ) @report.media_files.build end def build_new_report - @report = current_user.reports.build( report_params ) - @report.image = Image.new( file: params[:image] ) unless params[:image].blank? + @report = current_user.reports.build(report_params) + @report.image = Image.new(file: params[:image]) if params[:image].present? quotes = [] - quotes_params.each{ |q| - quotes << Quote.new( quote: q[:quote], age: q[:age], gender: q[:gender] ) - } + quotes_params.each do |q| + quotes << Quote.new(quote: q[:quote], age: q[:age], gender: q[:gender]) + end @report.quotes = quotes @@ -208,17 +221,17 @@ def build_new_report def build_report_form_fields return unless @form_builder.form_fields - @form_builder.form_fields.where(status: 1).each do |field| + @form_builder.form_fields.where(status: 1).find_each do |field| if field.multiple_choice? field.answer_options.each do |option| @report.report_form_field_answers.new( form_field: field, - answer_option: option + answer_option: option, ) end else @report.report_form_field_answers.new( - form_field: field + form_field: field, ) end end @@ -229,35 +242,44 @@ def find_workshop_logs @report.date, @report.windows_type ) - logs = @workshop_logs.map{|k, v| v}.flatten - @total_ongoing = logs.reduce(0){|sum, l| sum = sum + l.num_ongoing} - @total_first_time = logs.reduce(0) {|sum, l| sum = sum + l.num_first_time} + logs = @workshop_logs.map { |_k, v| v }.flatten + @total_ongoing = logs.reduce(0) { |sum, l| sum + l.num_ongoing } + @total_first_time = logs.reduce(0) { |sum, l| sum + l.num_first_time } end def build_month_and_year @month = params[:month] ? params[:month] : Date.current.month @year = params[:year] ? params[:year] : Date.current.year - @date = Date.new( @year.to_i, @month.to_i ) + @date = Date.new(@year.to_i, @month.to_i) end def report_params params[:report].delete(:form_file) if params[:report][:form_file].blank? - params[:report][:media_files_attributes].each do |k,v| + params[:report][:media_files_attributes].each do |k, _v| params[:report][:media_files_attributes].delete(k) if params[:report][:media_files_attributes][k][:file].blank? - end params.require(:report).permit( - :image, :form_file, :type, :project_id, :date, :workshop_name, :owner_id, :workshop_id, - :owner_type, :windows_type_id, report_form_field_answers_attributes: - [:form_field_id, :answer_option_id, :answer, :_create], media_files_attributes: [:file] + :image, + :form_file, + :type, + :project_id, + :date, + :workshop_name, + :owner_id, + :workshop_id, + :owner_type, + :windows_type_id, + report_form_field_answers_attributes: + [:form_field_id, :answer_option_id, :answer, :_create], + media_files_attributes: [:file], ) end def log_fields log_fields_params.map do |k, v| - { :form_field_id => k, :answer => v, :report_id => @report.id } + { form_field_id: k, answer: v, report_id: @report.id } end end @@ -267,15 +289,17 @@ def log_fields_params def quotes_params return [] if params[:quotes].nil? - params[:quotes].permit!.map{|k, v| v} + + params[:quotes].permit!.map { |_k, v| v } end def build_date @month = Date.current.month @year = Date.current.year - @date = params[:report][:date] ? - Date.strptime( params[:report][:date], '%Y-%m' ) : - Date.new( @year.to_i, @month.to_i ) + @date = if params[:report][:date] + Date.strptime(params[:report][:date], "%Y-%m") + else + Date.new(@year.to_i, @month.to_i) + end end - end diff --git a/app/controllers/resources_controller.rb b/app/controllers/resources_controller.rb index 7a52d9ab3..adc7765ae 100644 --- a/app/controllers/resources_controller.rb +++ b/app/controllers/resources_controller.rb @@ -1,7 +1,9 @@ +# frozen_string_literal: true + class ResourcesController < ApplicationController def index - @resources = current_user.curriculum(Resource).by_created.search(params). - paginate(page: params[:page], per_page: 6) + @resources = current_user.curriculum(Resource).by_created.search(params) + .paginate(page: params[:page], per_page: 6) load_sortable_fields @@ -24,30 +26,32 @@ def new def show @resource = Resource.find(resource_id_param).decorate load_forms - render :show + render(:show) end def create @resource = current_user.resources.build(resource_params) if @resource.save flash[:alert] = "#{@resource.type} has been submitted." - redirect_to root_path + redirect_to(root_path) else flash[:error] = "Unable to save #{@resource.type.titleize}" - render :new + render(:new) end end def search process_search load_sortable_fields - render :index + render(:index) end def download attachment = Resource.find(params[:resource_id]).attachments.last extension = File.extname(attachment.file_file_name) - send_data open("#{attachment.file.expiring_url(10000, :original)}").read, filename: "original_#{attachment.id}#{extension}", type: attachment.file_content_type + # rubocop:todo Security/Open + send_data(open(attachment.file.expiring_url(10000, :original).to_s).read, filename: "original_#{attachment.id}#{extension}", type: attachment.file_content_type) + # rubocop:enable Security/Open end private @@ -64,10 +68,14 @@ def resource_id_param def resource_params params.require(:resource).permit( - :text, :kind, :male, :female, :title, + :text, + :kind, + :male, + :female, + :title, categorizable_items_attributes: [:_create, :category_id], sectorable_items_attributes: [:_create, :sector_id], - images_attributes: [:file, :owner_id, :owner_type, :id, :_destroy] + images_attributes: [:file, :owner_id, :owner_type, :id, :_destroy], ) end @@ -75,35 +83,34 @@ def load_forms form = @resource.form if form @user_form = Report.new(user: current_user, owner: @resource) - form.form_fields.where(status: 1).each do |field| + form.form_fields.where(status: 1).find_each do |field| @user_form.report_form_field_answers.build(form_field: field) end end end def load_age_ranges - Metadatum.find_by(name: 'AgeRange').categories.each do |category| + Metadatum.find_by(name: "AgeRange").categories.each do |category| @resource.categorizable_items.build(category: category) end end def load_sectors - Sector.all.each do |sector| + Sector.all.find_each do |sector| @resource.sectorable_items.build(sector: sector) end end - def load_images @resource.images.build end def load_sortable_fields @sortable_fields = [ - 'Toolkit', - 'Form', - 'Template', - 'Handout' + "Toolkit", + "Form", + "Template", + "Handout", ] end diff --git a/app/controllers/user_forms_controller.rb b/app/controllers/user_forms_controller.rb index 5b493732b..ac7d72b71 100644 --- a/app/controllers/user_forms_controller.rb +++ b/app/controllers/user_forms_controller.rb @@ -1,12 +1,14 @@ +# frozen_string_literal: true + class UserFormsController < ApplicationController def create @user_form = current_user.user_forms.build(user_form_params) if @user_form.save - flash[:alert] = 'User form successfully created' + flash[:alert] = "User form successfully created" else - flash[:error] = 'There was a problem saving your form.' + flash[:error] = "There was a problem saving your form." end - redirect_to root_path + redirect_to(root_path) end private @@ -15,8 +17,8 @@ def user_form_params params.require(:user_form).permit( :form_id, user_form_form_fields_attributes: [ - :text, :form_field_id - ] + :text, :form_field_id, + ], ) end end diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index e0e327a71..951d92680 100644 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -1,13 +1,14 @@ -class UsersController < ApplicationController +# frozen_string_literal: true +class UsersController < ApplicationController def new if current_user.liaison? @user = User.new @user.project_users.build @projects = current_user.projects else - flash[:alert] = 'You must be a liaison to add a new user.' - redirect_to root_path + flash[:alert] = "You must be a liaison to add a new user." + redirect_to(root_path) end end @@ -16,10 +17,10 @@ def create set_password if @user.save @user.notifications.create(notification_type: 0) - flash[:alert] = 'User has been created.' - redirect_to user_path(@user) + flash[:alert] = "User has been created." + redirect_to(user_path(@user)) else - render :new + render(:new) end end @@ -31,10 +32,10 @@ def edit @user = User.find(id_param) if can_access_page? @project_users = @user.project_users - render :edit + render(:edit) else - flash[:alert] = 'You must be a liaison to edit user information.' - redirect_to root_path + flash[:alert] = "You must be a liaison to edit user information." + redirect_to(root_path) end end @@ -46,12 +47,12 @@ def update_password @user = current_user if @user.update_with_password(pass_params) - sign_in(@user, :bypass => true) - flash[:alert] = 'Your Password was updated.' - redirect_to root_path + sign_in(@user, bypass: true) + flash[:alert] = "Your Password was updated." + redirect_to(root_path) else - flash[:error] = "#{@user.errors.full_messages.join(", ")}" - render "change_password" + flash[:error] = @user.errors.full_messages.join(", ").to_s + render("change_password") end end @@ -62,16 +63,16 @@ def update if @user.update(user_params) @user.notifications.create(notification_type: 1) - flash[:alert] = 'User updated.' - sign_in(@user, :bypass => true) - redirect_to user_path(@user) + flash[:alert] = "User updated." + sign_in(@user, bypass: true) + redirect_to(user_path(@user)) else - flash[:alert] = 'Unable to update user.' - render :edit + flash[:alert] = "Unable to update user." + render(:edit) end else - flash[:alert] = 'You are not authorized to update this user.' - redirect_to root_path + flash[:alert] = "You are not authorized to update this user." + redirect_to(root_path) end end diff --git a/app/controllers/workshop_log_creation_wizard_controller.rb b/app/controllers/workshop_log_creation_wizard_controller.rb index f859fa3d8..4ccd9ace4 100644 --- a/app/controllers/workshop_log_creation_wizard_controller.rb +++ b/app/controllers/workshop_log_creation_wizard_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class WorkshopLogCreationWizardController < ApplicationController include Wicked::Wizard @@ -16,7 +18,7 @@ def show def update @user = current_user @agencies = current_user.projects - windows_type_id = params['workshop']['workshop_logs_attributes'].values[0]['windows_type_id'] + windows_type_id = params["workshop"]["workshop_logs_attributes"].values[0]["windows_type_id"] @windows_type = WindowsType.find(windows_type_id) send("update_#{step}") render_wizard unless @new_workshop @@ -41,13 +43,13 @@ def fill_out_form def load_previous_report if id_param @old_report = Report.find_by(id: id_param) - date_array = @old_report.date.to_s.split('-') - @date = date_array[1] + '-' + date_array[2] + '-' + date_array[0] + date_array = @old_report.date.to_s.split("-") + @date = date_array[1] + "-" + date_array[2] + "-" + date_array[0] end end def update_fill_out_form - puts id_param + Rails.logger.debug(id_param) old_report = Report.find_by(id: id_param) if old_report ReportFormFieldAnswer.where(report: old_report).delete_all @@ -56,8 +58,8 @@ def update_fill_out_form find_or_build_workshop if @workshop.save if @new_workshop - flash[:alert] = 'Thanks for reporting on a new workshop. Please fill out the workshop details below.' - redirect_to edit_workshop_path(@workshop) + flash[:alert] = "Thanks for reporting on a new workshop. Please fill out the workshop details below." + redirect_to(edit_workshop_path(@workshop)) else jump_to(:confirmation, workshop_id: @workshop.id) end @@ -72,37 +74,36 @@ def confirmation def load_workshop if workshop_id_param - @workshop = Workshop.find_by_id(workshop_id_param).decorate + @workshop = Workshop.find_by(id: workshop_id_param).decorate @related_workshops = @workshop.related_workshops else @windows_types = @user.windows_types @workshop = @user.workshops.build( - windows_type: @windows_type ? @windows_type : @windows_types[0] + windows_type: @windows_type ? @windows_type : @windows_types[0], ).decorate end end def find_or_build_workshop - unless workshop_id_param.blank? + if workshop_id_param.present? @workshop = Workshop.find(workshop_id_param).decorate @workshop.update( - workshop_params + workshop_params, ) @related_workshops = @workshop.related_workshops else @new_workshop = true @workshop = current_user.workshops.build( - workshop_params + workshop_params, ).decorate end end def build_workshop_sectors - explored_sectors = [] @workshop.sectors.build Sector.published.each do |sector| - #byebug - unless @workshop.sectorable_items.map(&:sector_id).include?(sector.id) + # byebug + if @workshop.sectorable_items.map(&:sector_id).exclude?(sector.id) @workshop.sectorable_items.build(sector_id: sector.id) end end @@ -120,12 +121,12 @@ def build_report_form_field_answers field.answer_options.each do |option| @workshop_log.report_form_field_answers.build( form_field: field, - answer_option: option + answer_option: option, ) end else @workshop_log.report_form_field_answers.build( - form_field: field + form_field: field, ) end end @@ -146,7 +147,7 @@ def workshop_id_param def id_param if params[:log_id] params[:log_id] - elsif params[:workshop] and params[:workshop][:log_id] + elsif params[:workshop] && params[:workshop][:log_id] params[:workshop][:log_id] end end @@ -158,25 +159,39 @@ def load_workshop_log def workshop_params adjust_date params.require(:workshop).permit( - :title, :date, :windows_type_id, - workshop_logs_attributes: [:user_id, :rating, :reaction, :similarities, :is_embodied_art_workshop, - :successes, :challenges, :differences, :date, - :suggestions, :questions, :lead_similar, :project_id, - :num_participants_on_going, :num_participants_first_time, - report_form_field_answers_attributes: - [:form_field_id, :answer_option_id, :answer, :_create] - ], - #sectorable_items_attributes: [:_create, :sector_id], - #sectors_attributes: [:_create, :name], + :title, + :date, + :windows_type_id, + workshop_logs_attributes: [ + :user_id, + :rating, + :reaction, + :similarities, + :is_embodied_art_workshop, + :successes, + :challenges, + :differences, + :date, + :suggestions, + :questions, + :lead_similar, + :project_id, + :num_participants_on_going, + :num_participants_first_time, + report_form_field_answers_attributes: + [:form_field_id, :answer_option_id, :answer, :_create], + ], + # sectorable_items_attributes: [:_create, :sector_id], + # sectors_attributes: [:_create, :name], workshop_age_ranges_attributes: [:age_range_id, :workshop_id, :_create], - quotes_attributes: [:quote, :age] + quotes_attributes: [:quote, :age], ) end def adjust_date - date = sent_date.split('-') + date = sent_date.split("-") if date.count > 2 - new_date = date[1] + '-' + date[0] + '-' + date[2] + new_date = date[1] + "-" + date[0] + "-" + date[2] params["workshop"]["workshop_logs_attributes"][date_index]["date"] = new_date end end @@ -185,10 +200,10 @@ def sent_date hash = params["workshop"]["workshop_logs_attributes"] index = date_index if index.present? - puts index - return hash[index]["date"] + Rails.logger.debug(index) + hash[index]["date"] else - return '' + "" end end @@ -197,12 +212,12 @@ def date_index hash = params["workshop"]["workshop_logs_attributes"] (0..100).each do |i| i = i.to_s - if hash.has_key?(i) and hash[i].has_key?("date") + if hash.key?(i) && hash[i].key?("date") index = i break end end - return index + index end def set_breadcrumb diff --git a/app/controllers/workshop_logs_controller.rb b/app/controllers/workshop_logs_controller.rb index 3f339df1e..27c07a09e 100644 --- a/app/controllers/workshop_logs_controller.rb +++ b/app/controllers/workshop_logs_controller.rb @@ -1,31 +1,32 @@ +# frozen_string_literal: true + class WorkshopLogsController < ApplicationController def new - params[:windows_type_id] = 1; + params[:windows_type_id] = 1 @title = :title @agency_title = :name @agencies = current_user.projects.uniq @workshop_list = current_user.curriculum.where(inactive: false, windows_type_id: params[:windows_type_id]) - .order(title: :asc) + .order(title: :asc) - agency = params[:agency_id] && params[:agency_id] != '' ? Project.find(params[:agency_id]) : @agencies.first + agency = params[:agency_id] && params[:agency_id] != "" ? Project.find(params[:agency_id]) : @agencies.first @agency_id = agency.id unless agency.nil? if params[:workshop_id] - @workshop = Workshop.find( params[:workshop_id] ) + @workshop = Workshop.find(params[:workshop_id]) end if params[:windows_type_id] @workshop = Workshop.new(windows_type_id: params[:windows_type_id]) end - end def update set_default_values - @workshop_log = WorkshopLog.find params[:id] + @workshop_log = WorkshopLog.find(params[:id]) ActiveRecord::Base.transaction do - @workshop_log.update_attributes( wsl_params ) + @workshop_log.update(wsl_params) @saved = @workshop_log.delete_and_update_all(quotes_params, log_fields) end @@ -36,11 +37,11 @@ def update file.update(report_id: @workshop_log.id, owner_type: @workshop_log.owner_type, owner_id: @workshop_log.owner_id) file.save end - flash[:alert] = 'Thanks for reporting on a new workshop. ' - redirect_to root_path + flash[:alert] = "Thanks for reporting on a new workshop. " + redirect_to(root_path) else - flash[:alert] = 'ERROR!' - render :edit + flash[:alert] = "ERROR!" + render(:edit) end end @@ -51,25 +52,27 @@ def create @workshop = Workshop.find(params[:workshop_id]) end - @title = params[:windows_type_id] == '3' ? :log_title : :title - @agency_title = params[:windows_type_id] == '3' ? :log_title : :name - @workshop_list = Workshop.where(inactive: false, - windows_type_id: params[:windows_type_id]) + @title = params[:windows_type_id] == "3" ? :log_title : :title + @agency_title = params[:windows_type_id] == "3" ? :log_title : :name + @workshop_list = Workshop.where( + inactive: false, + windows_type_id: params[:windows_type_id], + ) - if @workshop - log_params = wsl_params.merge(owner_id: @workshop.id) + log_params = if @workshop + wsl_params.merge(owner_id: @workshop.id) else - log_params = wsl_params + wsl_params end - @workshop_log = WorkshopLog.new( log_params ) - @workshop_log.quotes.build( quotes_params ) - @workshop_log.report_form_field_answers.build( log_fields ) - @workshop_log.media_files.build( files_params ) + @workshop_log = WorkshopLog.new(log_params) + @workshop_log.quotes.build(quotes_params) + @workshop_log.report_form_field_answers.build(log_fields) + @workshop_log.media_files.build(files_params) if @workshop_log.save - flash[:alert] = 'Thank you for submitting a workshop log. To see all of your completed logs, please click on “Workshop Log Summary” in the side menu.' - redirect_to new_workshop_log_path + flash[:alert] = "Thank you for submitting a workshop log. To see all of your completed logs, please click on “Workshop Log Summary” in the side menu." + redirect_to(new_workshop_log_path) end end @@ -80,17 +83,17 @@ def show if @workshop_log if current_user.liaison? && @workshop_log.project && current_user.project_ids.include?(@workshop_log.project.id) - render :show + render(:show) else - redirect_to root_path, error: 'You do not have permission to view this page.' + redirect_to(root_path, error: "You do not have permission to view this page.") end else - redirect_to root_path, error: 'Unable to find that Workshop Log.' + redirect_to(root_path, error: "Unable to find that Workshop Log.") end end def edit - @sectors = Sector.published.map{ |si| [ si.id, si.name ] } + @sectors = Sector.published.map { |si| [si.id, si.name] } @wl = WorkshopLog.find(params[:id]) @files = MediaFile.where(["workshop_log_id = ?", @wl.id]) @agency_title = :name @@ -99,28 +102,28 @@ def edit @workshop = @wl.owner || Workshop.new(windows_type_id: @wl.windows_type_id) end - def validate_new - @date = Date.new( params[:year].to_i, params[:month].to_i ) + @date = Date.new(params[:year].to_i, params[:month].to_i) @windows_type = WindowsType.find(params[:windows_type]) - @report = current_user.submitted_monthly_report( @date, @windows_type, params[:project_id] ) + @report = current_user.submitted_monthly_report(@date, @windows_type, params[:project_id]) - render json: { :validate => @report.nil? }.to_json + render(json: { validate: @report.nil? }.to_json) end private def set_default_values - workshop_log = params[:workshop_log]; + workshop_log = params[:workshop_log] workshop_log.map do |k, v| - if k.include?('_ongoing') || k.include?('_first_time') + if k.include?("_ongoing") || k.include?("_first_time") workshop_log[k] = 0 if v.nil? || v.blank? end end end + def log_fields log_fields_params.map do |k, v| - { :form_field_id => k, :answer => v, :report_id => @workshop_log.id } + { form_field_id: k, answer: v, report_id: @workshop_log.id } end end @@ -129,20 +132,23 @@ def log_fields_params end def ws_params - params.require(:workshop).permit( sectorable_items: [ :sector_id ] ) + params.require(:workshop).permit(sectorable_items: [:sector_id]) end def wsl_params - params.require(:workshop_log).permit(:children_ongoing, :children_first_time, :teens_ongoing, :teens_first_time, :adults_ongoing, :adults_first_time, :owner_id, :project_id, :date, :workshop_name, :windows_type_id, :other_description, report_form_field_answers: [:form_field_id, :answer_option_id, :answer]). - merge( :user_id => current_user.id, :owner_type => "Workshop" ) + params.require(:workshop_log).permit(:children_ongoing, :children_first_time, :teens_ongoing, :teens_first_time, :adults_ongoing, :adults_first_time, :owner_id, :project_id, :date, :workshop_name, :windows_type_id, :other_description, report_form_field_answers: [:form_field_id, :answer_option_id, :answer]) + .merge(user_id: current_user.id, owner_type: "Workshop") end def quotes_params return [] if params[:quotes].nil? - params[:quotes].permit!.map{|k, v| v} + + params[:quotes].permit!.map { |_k, v| v } end + def files_params return [] if params[:files].nil? - params[:files].permit!.map{ |k, v| {:file => v} } + + params[:files].permit!.map { |_k, v| { file: v } } end end diff --git a/app/controllers/workshop_search_controller.rb b/app/controllers/workshop_search_controller.rb index 6e176ef16..5ecf90d1a 100644 --- a/app/controllers/workshop_search_controller.rb +++ b/app/controllers/workshop_search_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class WorkshopSearchController < ApplicationController before_action :load_metadata def new @@ -10,7 +12,7 @@ def create process_search load_sortable_fields load_metadata - render :new + render(:new) end private @@ -26,8 +28,11 @@ def load_sortable_fields WindowsType.all, :rating, :warm_up_and_relaxation, - :led_count - ].flatten.select { |name| puts name.class; name != :combined } + :led_count, + ].flatten.select do |name| + Rails.logger.debug(name.class) + name != :combined + end end def load_metadata diff --git a/app/controllers/workshop_variations_controller.rb b/app/controllers/workshop_variations_controller.rb index 41251bc6d..1f0bcec3c 100644 --- a/app/controllers/workshop_variations_controller.rb +++ b/app/controllers/workshop_variations_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class WorkshopVariationsController < ApplicationController def show @workshop_variation = WorkshopVariation.find(params[:id]).decorate diff --git a/app/controllers/workshops_controller.rb b/app/controllers/workshops_controller.rb index 62e559c64..34f005013 100644 --- a/app/controllers/workshops_controller.rb +++ b/app/controllers/workshops_controller.rb @@ -19,16 +19,14 @@ def summary reports = build_report @report = reports[0] - types = reports.map do |r| - r.windows_type - end + types = reports.map(&:windows_type) @workshop_logs = current_user.project_monthly_workshop_logs( - reports.first.date, *types, + reports.first.date, *types ) logs = @workshop_logs.map { |_k, v| v }.flatten - @total_ongoing = logs.reduce(0) { |sum, l| sum += l.num_ongoing } - @total_first_time = logs.reduce(0) { |sum, l| sum += l.num_first_time } + @total_ongoing = logs.reduce(0) { |sum, l| sum + l.num_ongoing } + @total_first_time = logs.reduce(0) { |sum, l| sum + l.num_first_time } combined_windows_type = WindowsType.where("name LIKE ?", "%COMBINED (FAMILY)%").first @combined_workshop_logs = current_user.project_workshop_logs( @@ -40,13 +38,13 @@ def build_report date = Date.new(@year, @month) form_builder = FormBuilder - .monthly + .monthly report = form_builder.map do |f| Report.new( type: f.report_type, windows_type: f.windows_type, - date: date + date: date, ) end @@ -83,12 +81,12 @@ def share_idea_show def update @workshop = Workshop.find(params[:id]) - if @workshop.update_attributes(workshop_params) - flash[:alert] = 'Thank you for sharing your workshop idea.' - redirect_to root_path + if @workshop.update(workshop_params) + flash[:alert] = "Thank you for sharing your workshop idea." + redirect_to(root_path) else - flash[:error] = 'Unable to update the workshop.' - render :edit + flash[:error] = "Unable to update the workshop." + render(:edit) end end @@ -96,11 +94,11 @@ def create_from_log @workshop = current_user.workshops.build(workshop_params) if @workshop.save - flash[:alert] = 'Workshop created succesfully.' - redirect_to "/workshop_logs/new?windows_type_id=#{@workshop.windows_type.id}&workshop_id=#{@workshop.id}" + flash[:alert] = "Workshop created succesfully." + redirect_to("/workshop_logs/new?windows_type_id=#{@workshop.windows_type.id}&workshop_id=#{@workshop.id}") else - flash[:error] = 'Unable to save the workshop.' - render :new + flash[:error] = "Unable to save the workshop." + render(:new) end end @@ -110,20 +108,20 @@ def create @workshop.inactive = true if @workshop.save - flash[:alert] = 'Thank you for sharing your workshop idea.' - redirect_to root_path + flash[:alert] = "Thank you for sharing your workshop idea." + redirect_to(root_path) else - flash[:error] = 'Unable to save the workshop.' - render :share_idea + flash[:error] = "Unable to save the workshop." + render(:share_idea) end end def create_dummy_workshop @workshop = current_user.workshops.build(title: params[:title], windows_type_id: params[:windows_type_id], inactive: false) if @workshop.save - render json: { id: @workshop.id } + render(json: { id: @workshop.id }) else - render json: { error: @workshop.errors } + render(json: { error: @workshop.errors }) end end @@ -132,16 +130,16 @@ def search @query = params[:search][:query] if @params @workshops = Search.new.search(@params, current_user) - if @workshops.paginate(page: params[:search][:page], per_page: workshops_per_page).empty? - @workshops = @workshops.paginate(page: 1, per_page: workshops_per_page) + @workshops = if @workshops.paginate(page: params[:search][:page], per_page: workshops_per_page).empty? + @workshops.paginate(page: 1, per_page: workshops_per_page) else - @workshops = @workshops.paginate(page: params[:search][:page], per_page: workshops_per_page) + @workshops.paginate(page: params[:search][:page], per_page: workshops_per_page) end load_sortable_fields load_metadata - render :index + render(:index) end private @@ -161,22 +159,39 @@ def workshops_per_page end def view_all_workshops? - params[:search][:view_all] == '1' + params[:search][:view_all] == "1" end def workshop_params params.require(:workshop).permit( - :title, :full_name, :objective, - :materials, :optional_materials, :time_hours, :time_minutes, :age_range, :setup, - :introduction, :demonstration, :opening_circle, :warm_up, - :visualization, :creation, :closing, :notes, :tips, :misc1, :misc2, - :windows_type_id, :inactive, - images_attributes: %i[file owner_id owner_type id _destroy] + :title, + :full_name, + :objective, + :materials, + :optional_materials, + :time_hours, + :time_minutes, + :age_range, + :setup, + :introduction, + :demonstration, + :opening_circle, + :warm_up, + :visualization, + :creation, + :closing, + :notes, + :tips, + :misc1, + :misc2, + :windows_type_id, + :inactive, + images_attributes: [:file, :owner_id, :owner_type, :id, :_destroy], ) end def load_sortable_fields - @sortable_fields = WindowsType.where('name NOT LIKE ?', '%COMBINED%') + @sortable_fields = WindowsType.where("name NOT LIKE ?", "%COMBINED%") end def load_metadata diff --git a/app/decorators/bookmark_decorator.rb b/app/decorators/bookmark_decorator.rb index fdd60f977..ff757abd0 100644 --- a/app/decorators/bookmark_decorator.rb +++ b/app/decorators/bookmark_decorator.rb @@ -1,18 +1,25 @@ +# frozen_string_literal: true + class BookmarkDecorator < Draper::Decorator delegate_all delegate :current_page, :total_pages, :limit_value decorates_association :bookmarkable def breadcrumbs - "#{bookmarks_link} >> #{bookmarkable_link}".html_safe + "#{bookmarks_link} >> #{bookmarkable_link}".html_safe # rubocop:todo Rails/OutputSafety end def content - if bookmarkable_class_name == 'Workshop' - h.render '/workshops/show', workshop: bookmarkable, sectors: bookmarkable.sectors, - new_bookmark: bookmarkable.bookmarks.build, - quotes: bookmarkable.quotes, leader_spotlights: bookmarkable.leader_spotlights, - workshop_variations: bookmarkable.workshop_variations + if bookmarkable_class_name == "Workshop" + h.render( + "/workshops/show", + workshop: bookmarkable, + sectors: bookmarkable.sectors, + new_bookmark: bookmarkable.bookmarks.build, + quotes: bookmarkable.quotes, + leader_spotlights: bookmarkable.leader_spotlights, + workshop_variations: bookmarkable.workshop_variations, + ) end end @@ -21,11 +28,11 @@ def bookmarkable_class_name end def bookmarks_link - h.link_to 'My Bookmarks',h.bookmarks_path, class: 'underline' + h.link_to("My Bookmarks", h.bookmarks_path, class: "underline") end def bookmarkable_link - if bookmarkable_class_name == 'Workshop' + if bookmarkable_class_name == "Workshop" bookmarkable.breadcrumb_link end end diff --git a/app/decorators/bookmarks_decorator.rb b/app/decorators/bookmarks_decorator.rb index cd57013f6..b3cfa083f 100644 --- a/app/decorators/bookmarks_decorator.rb +++ b/app/decorators/bookmarks_decorator.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class BookmarksDecorator < Draper::CollectionDecorator delegate :current_page, :per_page, :offset, :total_entries, :total_pages end diff --git a/app/decorators/category_decorator.rb b/app/decorators/category_decorator.rb index d998ace07..9e9ac0f62 100644 --- a/app/decorators/category_decorator.rb +++ b/app/decorators/category_decorator.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class CategoryDecorator < Draper::Decorator delegate_all end diff --git a/app/decorators/form_builder_decorator.rb b/app/decorators/form_builder_decorator.rb index 9a7426e25..c72f76da4 100644 --- a/app/decorators/form_builder_decorator.rb +++ b/app/decorators/form_builder_decorator.rb @@ -1,9 +1,11 @@ +# frozen_string_literal: true + class FormBuilderDecorator < Draper::Decorator delegate_all def new_report_url if workshop_but_not_family_windows? - h.workshop_log_creation_wizard_path(:fill_out_form, {windows_type_id: windows_type_id}) + h.workshop_log_creation_wizard_path(:fill_out_form, { windows_type_id: windows_type_id }) else h.report_path(:fill_out_form, form_builder_id: id) end @@ -12,6 +14,6 @@ def new_report_url private def workshop_but_not_family_windows? - name.include?('Log') && name != 'Family Workshop Log' + name.include?("Log") && name != "Family Workshop Log" end end diff --git a/app/decorators/form_builders_decorator.rb b/app/decorators/form_builders_decorator.rb index 91b20f042..21fc5adb6 100644 --- a/app/decorators/form_builders_decorator.rb +++ b/app/decorators/form_builders_decorator.rb @@ -1,2 +1,4 @@ +# frozen_string_literal: true + class FormBuildersDecorator < Draper::CollectionDecorator -end \ No newline at end of file +end diff --git a/app/decorators/metadatum_decorator.rb b/app/decorators/metadatum_decorator.rb index 24c8b23f7..829c8ae74 100644 --- a/app/decorators/metadatum_decorator.rb +++ b/app/decorators/metadatum_decorator.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class MetadatumDecorator < Draper::Decorator delegate_all decorates_association :categories diff --git a/app/decorators/report_decorator.rb b/app/decorators/report_decorator.rb index afbd92abd..dad5cdb47 100644 --- a/app/decorators/report_decorator.rb +++ b/app/decorators/report_decorator.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class ReportDecorator < Draper::Decorator delegate_all @@ -6,7 +8,7 @@ def windows_type_name end def breadcrumbs - "#{h.link_to 'Submit Report', h.new_report_path} >> #{formatted_title}".html_safe + "#{h.link_to("Submit Report", h.new_report_path)} >> #{formatted_title}".html_safe # rubocop:todo Rails/OutputSafety end def formatted_title @@ -14,7 +16,7 @@ def formatted_title end def monthly? - type.include?('Monthly') + type.include?("Monthly") end def display_date @@ -22,6 +24,6 @@ def display_date end def display_sectors - sectors.pluck(:name).to_sentence if sectors + sectors&.pluck(:name)&.to_sentence end end diff --git a/app/decorators/resource_decorator.rb b/app/decorators/resource_decorator.rb index eb2911cf9..115196f11 100644 --- a/app/decorators/resource_decorator.rb +++ b/app/decorators/resource_decorator.rb @@ -1,21 +1,24 @@ +# frozen_string_literal: true + class ResourceDecorator < Draper::Decorator delegate_all def featured_url return "" if url.nil? + url.empty? ? h.resource_path(resource) : url end def truncated_author - h.truncate author, length: 20 + h.truncate(author, length: 20) end def truncated_title - h.truncate title, length: 25 + h.truncate(title, length: 25) end def truncated_text(ln = 100) - h.truncate(html.text.gsub(/(<[^>]+>)/, ''), length: ln) + h.truncate(html.text.gsub(/(<[^>]+>)/, ""), length: ln) end def display_title @@ -23,7 +26,8 @@ def display_title end def main_image(size = nil) - return if kind == 'Theme' + return if kind == "Theme" + images.first.file.url if images.any? end @@ -32,7 +36,7 @@ def flex_text end def breadcrumbs - "#{type_link} >> #{title}".html_safe + "#{type_link} >> #{title}".html_safe # rubocop:todo Rails/OutputSafety end def author_full_name @@ -40,19 +44,19 @@ def author_full_name end def display_date - created_at.strftime('%B %Y') + created_at.strftime("%B %Y") end def display_text - "
#{text}
".html_safe + "
#{text}
".html_safe # rubocop:todo Rails/OutputSafety end def card_class - kind == 'Theme' ? 'circular-border' : 'normal' + kind == "Theme" ? "circular-border" : "normal" end def toolkit_and_form? - kind == 'ToolkitAndForm' + kind == "ToolkitAndForm" end private @@ -62,6 +66,6 @@ def html end def type_link - h.link_to 'Resources', h.resources_path + h.link_to("Resources", h.resources_path) end end diff --git a/app/decorators/resources_decorator.rb b/app/decorators/resources_decorator.rb index 9b495ff6a..8f9bc98ad 100644 --- a/app/decorators/resources_decorator.rb +++ b/app/decorators/resources_decorator.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class ResourcesDecorator < Draper::CollectionDecorator delegate :current_page, :per_page, :offset, :total_entries, :total_pages diff --git a/app/decorators/sector_decorator.rb b/app/decorators/sector_decorator.rb index addbec8da..7bae704c5 100644 --- a/app/decorators/sector_decorator.rb +++ b/app/decorators/sector_decorator.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class SectorDecorator < Draper::Decorator delegate_all end diff --git a/app/decorators/user_decorator.rb b/app/decorators/user_decorator.rb index f699fe06d..c57d8df87 100644 --- a/app/decorators/user_decorator.rb +++ b/app/decorators/user_decorator.rb @@ -1,7 +1,10 @@ +# frozen_string_literal: true + class UserDecorator < Draper::Decorator delegate_all def full_name return unless user + if first_name.empty? email else @@ -11,15 +14,16 @@ def full_name def display_agencies project_users.map { |u| "#{u.project.name} - #{u.position}" } - .join(h.content_tag :li).html_safe + .join(h.content_tag(:li)).html_safe # rubocop:todo Rails/OutputSafety end def last_logged_in - return 'never' unless last_sign_in_at + return "never" unless last_sign_in_at + "#{h.time_ago_in_words(last_sign_in_at)} ago" end def display_primary_address - primary_address == 1 ? 'work' : 'home' + primary_address == 1 ? "work" : "home" end end diff --git a/app/decorators/workshop_decorator.rb b/app/decorators/workshop_decorator.rb index 2943402b7..e17d24afe 100644 --- a/app/decorators/workshop_decorator.rb +++ b/app/decorators/workshop_decorator.rb @@ -1,4 +1,6 @@ # coding: utf-8 +# frozen_string_literal: true + class WorkshopDecorator < Draper::Decorator delegate_all @@ -7,50 +9,77 @@ def list_sectors end def display_fields - [:objective, :materials, :optional_materials, :timeframe, - :age_range, :setup, :introduction, :demonstration, - :opening_circle, :warm_up, - :visualization, :creation, :closing, :notes, :tips, :misc1, :misc2 + [ + :objective, + :materials, + :optional_materials, + :timeframe, + :age_range, + :setup, + :introduction, + :demonstration, + :opening_circle, + :warm_up, + :visualization, + :creation, + :closing, + :notes, + :tips, + :misc1, + :misc2, ] end def display_spanish_fields [ - :objective_spanish, :materials_spanish, :optional_materials_spanish, - :timeframe_spanish, :age_range_spanish, :setup_spanish, - :introduction_spanish, :demonstration_spanish, :opening_circle_spanish, - :warm_up_spanish, :visualization_spanish, :creation_spanish, - :closing_spanish, :notes_spanish, :tips_spanish, :misc1_spanish, - :misc2_spanish, :extra_field_spanish + :objective_spanish, + :materials_spanish, + :optional_materials_spanish, + :timeframe_spanish, + :age_range_spanish, + :setup_spanish, + :introduction_spanish, + :demonstration_spanish, + :opening_circle_spanish, + :warm_up_spanish, + :visualization_spanish, + :creation_spanish, + :closing_spanish, + :notes_spanish, + :tips_spanish, + :misc1_spanish, + :misc2_spanish, + :extra_field_spanish, ] end def labels_spanish { - objective_spanish: 'Objectivo', - materials_spanish: 'Materiales', - optional_materials_spanish: 'Materiales Opcionales', - timeframe_spanish: 'Periodo de tiempo', - age_range_spanish: 'Rango de edad', - setup_spanish: 'Preparativos', - introduction_spanish: 'Introducción', - demonstration_spanish: 'Demostración', - opening_circle_spanish: 'Círculo de apertura', - visualization_spanish: 'Visualización', - warm_up_spanish: 'Comenzando', - creation_spanish: 'Creación', - closing_spanish: 'Clausura', - misc_instructions_spanish: 'Instrucciones de misceláneos', - project_spanish: 'Projecto', - description_spanish: 'Descripción', - notes_spanish: 'Notas', - tips_spanish: 'Consejos', - misc1_spanish: 'Misc 1', - misc2_spanish: 'Misc 2' + objective_spanish: "Objectivo", + materials_spanish: "Materiales", + optional_materials_spanish: "Materiales Opcionales", + timeframe_spanish: "Periodo de tiempo", + age_range_spanish: "Rango de edad", + setup_spanish: "Preparativos", + introduction_spanish: "Introducción", + demonstration_spanish: "Demostración", + opening_circle_spanish: "Círculo de apertura", + visualization_spanish: "Visualización", + warm_up_spanish: "Comenzando", + creation_spanish: "Creación", + closing_spanish: "Clausura", + misc_instructions_spanish: "Instrucciones de misceláneos", + project_spanish: "Projecto", + description_spanish: "Descripción", + notes_spanish: "Notas", + tips_spanish: "Consejos", + misc1_spanish: "Misc 1", + misc2_spanish: "Misc 2", } end + def new? - (Date.today.year - year <= 1) if year + (Time.zone.today.year - year <= 1) if year end def log_fields @@ -62,10 +91,10 @@ def objective_fixed_img_urls html.xpath("//img").each do |img| src = formatted_url(img) - img.set_attribute('src', src) + img.set_attribute("src", src) end - html.to_s.html_safe + html.to_s.html_safe # rubocop:todo Rails/OutputSafety end def display_objective @@ -73,31 +102,30 @@ def display_objective html = html_objective html.xpath("//img").each do |img| src = formatted_url(img) - img.set_attribute('src', src) + img.set_attribute("src", src) end html.xpath("//a").each do |link| - href = link.attributes['href'].value.gsub('https://www.awbw.org', 'http://dashboard.awbw.org') if link.attributes['href'] - link.set_attribute('href', href) - link.set_attribute('class', 'underline') + href = link.attributes["href"].value.gsub("https://www.awbw.org", "http://dashboard.awbw.org") if link.attributes["href"] + link.set_attribute("href", href) + link.set_attribute("class", "underline") end - html.to_s.html_safe + html.to_s.html_safe # rubocop:todo Rails/OutputSafety else objective end end def formatted_url(img) - return unless img.attributes['src'] - value = img.attributes['src'].value + return unless img.attributes["src"] - if value.include?('awbw.org') - return value.gsub('https', 'http').gsub('www.', '').gsub('awbw.org', 'dashboard.awbw.org') - else - if value.include?("s3.amazonaws.com") - return value - else - return value.prepend('http://dashboard.awbw.org') unless value.include?('.org') || value.include?('.com') - end + value = img.attributes["src"].value + + if value.include?("awbw.org") + value.gsub("https", "http").gsub("www.", "").gsub("awbw.org", "dashboard.awbw.org") + elsif value.include?("s3.amazonaws.com") + value + elsif value.exclude?(".org") && value.exclude?(".com") + value.prepend("http://dashboard.awbw.org") end end @@ -105,7 +133,7 @@ def formatted_objective if legacy html = html_objective - html.search('.TextHeader2').each do |header| + html.search(".TextHeader2").each do |header| header.children.remove end @@ -113,28 +141,31 @@ def formatted_objective obj ||= html.text.split("Objective:")[1] obj ||= html.text - h.truncate(obj.gsub(title, ''). - gsub(/(Heart Story Example|Table set-up)/, '').squish, length: 100) + h.truncate( + obj.gsub(title, "") + .gsub(/(Heart Story Example|Table set-up)/, "").squish, + length: 100, + ) else - h.truncate(html_objective.text.html_safe.squish, length: 100) + h.truncate(html_objective.text.html_safe.squish, length: 100) # rubocop:todo Rails/OutputSafety end end def author - "#{full_name}" + full_name.to_s end def main_image content = html_content - if content.css('img').any? - images = html_objective.css('img') + if content.css("img").any? + images = html_objective.css("img") - return nil unless images.any? + return if images.none? pathname = images.map do |img| - src = img.attributes['src'].value - src unless src.include?('transparent') + src = img.attributes["src"].value + src if src.exclude?("transparent") end.compact.first if pathname @@ -169,16 +200,17 @@ def sector_has_name?(form) def breadcrumb_link return title unless id - h.link_to title, h.workshop_path(self), class: 'underline' + + h.link_to(title, h.workshop_path(self), class: "underline") end def detail_breadcrumbs - "#{breadcrumbs_title} >> #{breadcrumb_link}".html_safe + "#{breadcrumbs_title} >> #{breadcrumb_link}".html_safe # rubocop:todo Rails/OutputSafety end def spanish_field_values display_spanish_fields.map do |field| - workshop.send(field) unless workshop.send(field).blank? + workshop.send(field).presence end.compact end @@ -188,14 +220,14 @@ def has_spanish_fields? def breadcrumbs if title - "#{breadcrumbs_title} >> #{breadcrumb_link} >> Workshop Log".html_safe + "#{breadcrumbs_title} >> #{breadcrumb_link} >> Workshop Log".html_safe # rubocop:todo Rails/OutputSafety else "Submit Workshop Log >> Report on a New Workshop" end end def breadcrumbs_title - h.link_to 'Search Curriculum', h.workshops_path, class: 'underline' + h.link_to("Search Curriculum", h.workshops_path, class: "underline") end def log_form_header @@ -211,7 +243,7 @@ def disable_title_field? end def rating_as_stars - str = '' + str = "" rating.times do str += '
' end @@ -219,11 +251,11 @@ def rating_as_stars (5 - rating).times do str += '
' end - str.html_safe + str.html_safe # rubocop:todo Rails/OutputSafety end def field_has_empty_value?(field) - send(field).nil? || send(field).empty? + send(field).blank? end private diff --git a/app/decorators/workshop_variation_decorator.rb b/app/decorators/workshop_variation_decorator.rb index 9b7d1f78c..2d474ef1f 100644 --- a/app/decorators/workshop_variation_decorator.rb +++ b/app/decorators/workshop_variation_decorator.rb @@ -1,23 +1,25 @@ +# frozen_string_literal: true + class WorkshopVariationDecorator < Draper::Decorator delegate_all def breadcrumbs - "#{workshop_link} >> #{name}".html_safe + "#{workshop_link} >> #{name}".html_safe # rubocop:todo Rails/OutputSafety end def display_code if legacy html = Nokogiri::HTML(code) html.xpath("//img").each do |img| - src = img.attributes['src'] - img.set_attribute('src', src) + src = img.attributes["src"] + img.set_attribute("src", src) end html.xpath("//a").each do |link| - href = link.attributes['href'].value.prepend('http://awbw.org') - link.set_attribute('href', href) - link.set_attribute('class', 'underline') + href = link.attributes["href"].value.prepend("http://awbw.org") + link.set_attribute("href", href) + link.set_attribute("class", "underline") end - html.to_s.html_safe + html.to_s.html_safe # rubocop:todo Rails/OutputSafety else code end @@ -26,10 +28,9 @@ def display_code private def method_name - end def workshop_link - h.link_to "#{workshop.title}", h.workshop_path(workshop) + h.link_to(workshop.title.to_s, h.workshop_path(workshop)) end end diff --git a/app/decorators/workshops_decorator.rb b/app/decorators/workshops_decorator.rb index 7e709321f..21304b21e 100644 --- a/app/decorators/workshops_decorator.rb +++ b/app/decorators/workshops_decorator.rb @@ -1,4 +1,5 @@ +# frozen_string_literal: true + class WorkshopsDecorator < Draper::CollectionDecorator delegate :current_page, :per_page, :offset, :total_entries, :total_pages - end diff --git a/app/errors/authentication_failed.rb b/app/errors/authentication_failed.rb index f14f6e623..7f322553d 100644 --- a/app/errors/authentication_failed.rb +++ b/app/errors/authentication_failed.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class AuthenticationFailed < StandardError def initialize(message = "Not Authorized") super(message) diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 52467de30..9759640d7 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -1,14 +1,16 @@ +# frozen_string_literal: true + module ApplicationHelper def search_page(parmas) params[:search] ? params[:search][:page] : 1 end def checked?(param = false) - param == '1' + param == "1" end def months_with_year - (1..12).collect{ |m| "#{m}/#{today.year}"} + (1..12).collect { |m| "#{m}/#{today.year}" } end def current_month_with_year @@ -20,19 +22,19 @@ def current_year end def today - Date.today + Time.zone.today end def show_time(time) - if time.kind_of? Time + if time.is_a?(Time) if time.hour > 0 - return " #{time.strftime("%H:%M")} hr".html_safe + return " #{time.strftime("%H:%M")} hr".html_safe # rubocop:todo Rails/OutputSafety else - return " #{time.strftime("%H:%M")} min".html_safe + return " #{time.strftime("%H:%M")} min".html_safe # rubocop:todo Rails/OutputSafety end end - " #{time.to_i} min".html_safe + " #{time.to_i} min".html_safe # rubocop:todo Rails/OutputSafety end def display_banner @@ -41,22 +43,22 @@ def display_banner if !banner.nil? && banner.show content = "
" - return content.html_safe + content.html_safe # rubocop:todo Rails/OutputSafety end end def ra_path(obj, action = nil) - action = action.nil? ? '' : "#{action}_" + action = action.nil? ? "" : "#{action}_" - if obj.form_builder and obj.form_builder.name == "Share a Story" + if obj.form_builder && (obj.form_builder.name == "Share a Story") if action.empty? - return report_path(obj) + return report_path(obj) else return send("reports_#{action}story_path", obj) end end - unless obj.respond_to? :type + unless obj.respond_to?(:type) if action.empty? return share_idea_show_path(obj) else @@ -66,10 +68,14 @@ def ra_path(obj, action = nil) if obj.type == "WorkshopLog" send("#{action}workshop_log_path", obj) - elsif obj.type != "WorkshopLog" and action == 'edit_' - send("#{action}report_path", obj, form_builder_id: obj.form_builder, - month: obj.date.month, - year: obj.date.year) + elsif (obj.type != "WorkshopLog") && (action == "edit_") + send( + "#{action}report_path", + obj, + form_builder_id: obj.form_builder, + month: obj.date.month, + year: obj.date.year, + ) else send("#{action}report_path", obj) end @@ -78,9 +84,9 @@ def ra_path(obj, action = nil) def sortable_field_display_name(name) case name when :adult - 'Adult Windows' + "Adult Windows" when :children - 'Children\'s Windows' + "Children's Windows" else name.to_s.titleize end @@ -88,33 +94,33 @@ def sortable_field_display_name(name) def icon_for_mimetype(mime) mimes = { - 'image' => 'fa-file-image', - 'audio' => 'fa-file-audio', - 'video' => 'fa-file-video', - # Documents - 'application/pdf' => 'fa-file-pdf', - 'application/msword' => 'fa-file-word', - 'application/vnd.ms-word' => 'fa-file-word', - 'application/vnd.oasis.opendocument.text' => 'fa-file-word', - 'application/vnd.openxmlformats-officedocument.wordprocessingml.document' => 'fa-file-word', - 'application/vnd.ms-excel': 'fa-file-excel', - 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' => 'fa-file-excel', - 'application/vnd.oasis.opendocument.spreadsheet' => 'fa-file-excel', - 'application/vnd.ms-powerpoint' => 'fa-file-powerpoint', - 'application/vnd.openxmlformats-officedocument.presentationml' => 'fa-file-powerpoint', - 'application/vnd.oasis.opendocument.presentation' => 'fa-file-powerpoint', - - # Archives - 'application/gzip' => 'fa-file-archive', - 'application/zip' => 'fa-file-archive', + "image" => "fa-file-image", + "audio" => "fa-file-audio", + "video" => "fa-file-video", + # Documents + "application/pdf" => "fa-file-pdf", + "application/msword" => "fa-file-word", + "application/vnd.ms-word" => "fa-file-word", + "application/vnd.oasis.opendocument.text" => "fa-file-word", + "application/vnd.openxmlformats-officedocument.wordprocessingml.document" => "fa-file-word", + "application/vnd.ms-excel": "fa-file-excel", + "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" => "fa-file-excel", + "application/vnd.oasis.opendocument.spreadsheet" => "fa-file-excel", + "application/vnd.ms-powerpoint" => "fa-file-powerpoint", + "application/vnd.openxmlformats-officedocument.presentationml" => "fa-file-powerpoint", + "application/vnd.oasis.opendocument.presentation" => "fa-file-powerpoint", + + # Archives + "application/gzip" => "fa-file-archive", + "application/zip" => "fa-file-archive", } if mime - m = mimes[mime.split('/').first] + m = mimes[mime.split("/").first] m ||= mimes[mime] end - m ||= 'fa-file' + m ||= "fa-file" "fas #{m}" end @@ -124,10 +130,10 @@ def main_content_classes if user_signed_in? content_classes = "content-area col-md-10 col-md-offset-2" - if params[:controller] == 'dashboard' && params[:action] == 'index' - specific_class = "dashboard-area" + specific_class = if params[:controller] == "dashboard" && params[:action] == "index" + "dashboard-area" else - specific_class = "printable-full-width" + "printable-full-width" end "#{base_classes} #{content_classes} #{specific_class}" else diff --git a/app/mailers/admins/notification_mailer.rb b/app/mailers/admins/notification_mailer.rb index c3456fa82..6a41a8024 100644 --- a/app/mailers/admins/notification_mailer.rb +++ b/app/mailers/admins/notification_mailer.rb @@ -1,13 +1,14 @@ -class Admins::NotificationMailer < ApplicationMailer +# frozen_string_literal: true +class Admins::NotificationMailer < ApplicationMailer def email(notification) @notification = notification @noticeable = notification.noticeable - @type = 'Report' - if @noticeable.respond_to? :windows_type - target = @noticeable.windows_type.name + @type = "Report" + target = if @noticeable.respond_to?(:windows_type) + @noticeable.windows_type.name else - target = "" + "" end if @noticeable.class == User @@ -24,20 +25,20 @@ def email(notification) end if @report.story? - @type = 'Story' + @type = "Story" @mail_to = "eaeevans@awbw.org, cturekrials@awbw.org, rhernandez@awbw.org" else - case target + @mail_to = case target when "ADULT WORKSHOP LOG" - @mail_to = "cturek@awbw.org" + "cturek@awbw.org" else - @mail_to = "rhernandez@awbw.org" + "rhernandez@awbw.org" end end mail( to: @mail_to, - subject: "New #{@type} Submission by #{@user.name}" + subject: "New #{@type} Submission by #{@user.name}", ) end end diff --git a/app/mailers/application_mailer.rb b/app/mailers/application_mailer.rb index 69c981386..8d6d8761c 100644 --- a/app/mailers/application_mailer.rb +++ b/app/mailers/application_mailer.rb @@ -1,4 +1,6 @@ +# frozen_string_literal: true + class ApplicationMailer < ActionMailer::Base default from: "noreply@awbw.org" - layout 'mailer' + layout "mailer" end diff --git a/app/mailers/contact_us_mailer.rb b/app/mailers/contact_us_mailer.rb index 312f228e8..9a11a26c7 100644 --- a/app/mailers/contact_us_mailer.rb +++ b/app/mailers/contact_us_mailer.rb @@ -1,18 +1,20 @@ +# frozen_string_literal: true + class ContactUsMailer < ApplicationMailer - default from: 'contactus@no-reply.com' + default from: "contactus@no-reply.com" def hello(contact_us) @contact_us = contact_us - case @contact_us[:q] + @mail_to = case @contact_us[:q] when "adult" - @mail_to = "cturek@awbw.org" + "cturek@awbw.org" when "children" - @mail_to = "cturekrials@awbw.org" + "cturekrials@awbw.org" when "general" - @mail_to = "programs@awbw.org" + "programs@awbw.org" else - @mail_to = "programs@awbw.org" + "programs@awbw.org" end mail(to: @mail_to, subject: @contact_us[:subject], from: @contact_us[:from]) diff --git a/app/mailers/notification_mailer.rb b/app/mailers/notification_mailer.rb index 24cc5f12a..3e59e303d 100644 --- a/app/mailers/notification_mailer.rb +++ b/app/mailers/notification_mailer.rb @@ -1,11 +1,13 @@ +# frozen_string_literal: true + class NotificationMailer < ApplicationMailer require "mandrill" - + def reset_password_notification(resource) @resource = resource mail( to: "programs@awbw.org", - subject: "Reset Password Request" + subject: "Reset Password Request", ) end end diff --git a/app/models/admin.rb b/app/models/admin.rb index 68a34cb8f..232a05851 100644 --- a/app/models/admin.rb +++ b/app/models/admin.rb @@ -1,6 +1,11 @@ +# frozen_string_literal: true + class Admin < ApplicationRecord # Include default devise modules. Others available are: # :confirmable, :lockable, :timeoutable and :omniauthable - devise :database_authenticatable, :recoverable, - :rememberable, :trackable, :validatable + devise :database_authenticatable, + :recoverable, + :rememberable, + :trackable, + :validatable end diff --git a/app/models/age_range.rb b/app/models/age_range.rb index 0a9a8c95d..a926bd257 100644 --- a/app/models/age_range.rb +++ b/app/models/age_range.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class AgeRange < ApplicationRecord belongs_to :windows_type @@ -7,18 +9,16 @@ def self.create_defaults ranges.each do |range| AgeRange.find_or_create_by( name: range, - windows_type: windows_type + windows_type: windows_type, ) end end end - private - def self.defaults { - 'Children\'s Windows' => ['2-5', '6-12', '13-18', '19-24'], - 'Adult Windows' => ['Under 15', '25-35', '35-64', '65+'] + "Children's Windows" => ["2-5", "6-12", "13-18", "19-24"], + "Adult Windows" => ["Under 15", "25-35", "35-64", "65+"], } end end diff --git a/app/models/answer_option.rb b/app/models/answer_option.rb index f7d73dfaf..efe409d75 100644 --- a/app/models/answer_option.rb +++ b/app/models/answer_option.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class AnswerOption < ApplicationRecord default_scope { order(order: :asc) } end diff --git a/app/models/application_record.rb b/app/models/application_record.rb index 71a1a03cc..71fbba5b3 100644 --- a/app/models/application_record.rb +++ b/app/models/application_record.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class ApplicationRecord < ActiveRecord::Base self.abstract_class = true -end \ No newline at end of file +end diff --git a/app/models/attachment.rb b/app/models/attachment.rb index 34cf409cb..da1c64654 100644 --- a/app/models/attachment.rb +++ b/app/models/attachment.rb @@ -1,10 +1,12 @@ +# frozen_string_literal: true + class Attachment < ApplicationRecord belongs_to :owner, polymorphic: true has_attached_file :file - validates_attachment :file, content_type: { content_type: %w(application/pdf application/msword image/gif image/jpg image/jpeg image/png) } + validates_attachment :file, content_type: { content_type: ["application/pdf", "application/msword", "image/gif", "image/jpg", "image/jpeg", "image/png"] } def name - 'Pdf Attachment' + "Pdf Attachment" end end diff --git a/app/models/banner.rb b/app/models/banner.rb index 7be878570..5c4f06492 100644 --- a/app/models/banner.rb +++ b/app/models/banner.rb @@ -1,5 +1,6 @@ +# frozen_string_literal: true + class Banner < ApplicationRecord # Validations - validates_presence_of :content - + validates :content, presence: true end diff --git a/app/models/bookmark.rb b/app/models/bookmark.rb index 1ec2c6666..a30aa3cb4 100644 --- a/app/models/bookmark.rb +++ b/app/models/bookmark.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class Bookmark < ApplicationRecord belongs_to :user belongs_to :bookmarkable, polymorphic: true @@ -5,28 +7,28 @@ class Bookmark < ApplicationRecord def self.sort_by_windows_type(bookmarks, windows_type_id) if windows_type_id == "3" - workshops = Workshop.where(id: bookmarks.map{|b| b.bookmarkable_id}).order(windows_type_id: :desc) + workshops = Workshop.where(id: bookmarks.map(&:bookmarkable_id)).order(windows_type_id: :desc) elsif windows_type_id == "1" - workshops = Workshop.where(id: bookmarks.map{|b| b.bookmarkable_id}).order(windows_type_id: :asc) + workshops = Workshop.where(id: bookmarks.map(&:bookmarkable_id)).order(windows_type_id: :asc) end - workshops_ids = workshops.map{|w| w.id} - bookmarks = bookmarks.where(bookmarkable_id: workshops_ids).order("FIELD(bookmarkable_id, #{workshops_ids.join(',')})") + workshops_ids = workshops.map(&:id) + bookmarks.where(bookmarkable_id: workshops_ids).order("FIELD(bookmarkable_id, #{workshops_ids.join(",")})") end def self.search(params, user) bookmarks = user.bookmarks - if params[:type].nil? || params[:type].empty? - workshops = Workshop.where(id: bookmarks.map{|b| b.bookmarkable_id}).order(title: :asc) - workshops_ids = workshops.map{|w| w.id} - bookmarks = bookmarks.where(bookmarkable_id: workshops_ids).order("FIELD(bookmarkable_id, #{workshops_ids.join(',')})") + if params[:type].blank? + workshops = Workshop.where(id: bookmarks.map(&:bookmarkable_id)).order(title: :asc) + workshops_ids = workshops.map(&:id) + bookmarks = bookmarks.where(bookmarkable_id: workshops_ids).order("FIELD(bookmarkable_id, #{workshops_ids.join(",")})") end if params[:type] == "led" - workshops = Workshop.where(id: bookmarks.map{|b| b.bookmarkable_id}).order(led_count: :desc) - workshops_ids = workshops.map{|w| w.id} - bookmarks = bookmarks.where(bookmarkable_id: workshops_ids).order("FIELD(bookmarkable_id, #{workshops_ids.join(',')})") + workshops = Workshop.where(id: bookmarks.map(&:bookmarkable_id)).order(led_count: :desc) + workshops_ids = workshops.map(&:id) + bookmarks = bookmarks.where(bookmarkable_id: workshops_ids).order("FIELD(bookmarkable_id, #{workshops_ids.join(",")})") end if params[:type] == "created" @@ -34,7 +36,7 @@ def self.search(params, user) end if params[:type] == "3" || params[:type] == "1" - bookmarks = sort_by_windows_type(bookmarks, params[:type]) + bookmarks = sort_by_windows_type(bookmarks, params[:type]) end bookmarks diff --git a/app/models/bookmark_annotation.rb b/app/models/bookmark_annotation.rb index ce5a54071..095723aa2 100644 --- a/app/models/bookmark_annotation.rb +++ b/app/models/bookmark_annotation.rb @@ -1,7 +1,9 @@ +# frozen_string_literal: true + class BookmarkAnnotation < ApplicationRecord belongs_to :bookmark def content_with_id - {id: id}.merge(JSON.parse(annotation)) + { id: id }.merge(JSON.parse(annotation)) end end diff --git a/app/models/categorizable_item.rb b/app/models/categorizable_item.rb index 9ab161a1a..c2e8bd48b 100644 --- a/app/models/categorizable_item.rb +++ b/app/models/categorizable_item.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class CategorizableItem < ApplicationRecord # Associations belongs_to :categorizable, polymorphic: true diff --git a/app/models/category.rb b/app/models/category.rb index e1a65cebe..e6f957642 100644 --- a/app/models/category.rb +++ b/app/models/category.rb @@ -1,12 +1,14 @@ +# frozen_string_literal: true + class Category < ApplicationRecord # Associations belongs_to :metadatum has_many :categorizable_items, dependent: :destroy - has_many :workshops, through: :categorizable_items, source: :categorizable, source_type: 'Workshop' - default_scope { order('name') } + has_many :workshops, through: :categorizable_items, source: :categorizable, source_type: "Workshop" + default_scope { order("name") } scope :published, -> { where(published: true) } # Validations - validates_presence_of :name, uniqueness: true + validates :name, presence: { uniqueness: true } rails_admin do exclude_fields :categorizable_items, :legacy diff --git a/app/models/ckeditor/asset.rb b/app/models/ckeditor/asset.rb index 5c166fdfc..ad016cd36 100644 --- a/app/models/ckeditor/asset.rb +++ b/app/models/ckeditor/asset.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class Ckeditor::Asset < ApplicationRecord include Ckeditor::Orm::ActiveRecord::AssetBase include Ckeditor::Backend::Paperclip diff --git a/app/models/ckeditor/attachment_file.rb b/app/models/ckeditor/attachment_file.rb index 1e9378890..14a0fd7cc 100644 --- a/app/models/ckeditor/attachment_file.rb +++ b/app/models/ckeditor/attachment_file.rb @@ -1,10 +1,12 @@ +# frozen_string_literal: true + class Ckeditor::AttachmentFile < Ckeditor::Asset has_attached_file :data, - :url => "/ckeditor_assets/attachments/:id/:filename", - :path => "/ckeditor_assets/attachments/:id/:filename" + url: "/ckeditor_assets/attachments/:id/:filename", + path: "/ckeditor_assets/attachments/:id/:filename" validates_attachment_presence :data - validates_attachment_size :data, :less_than => 100.megabytes + validates_attachment_size :data, less_than: 100.megabytes do_not_validate_attachment_file_type :data def url_thumb diff --git a/app/models/ckeditor/picture.rb b/app/models/ckeditor/picture.rb index 1493abb3f..5bea6d6ae 100644 --- a/app/models/ckeditor/picture.rb +++ b/app/models/ckeditor/picture.rb @@ -1,12 +1,14 @@ +# frozen_string_literal: true + class Ckeditor::Picture < Ckeditor::Asset has_attached_file :data, - :url => "/ckeditor_assets/pictures/:id/:style_:basename.:extension", - :path => "/ckeditor_assets/pictures/:id/:style_:basename.:extension", - :styles => { :content => '800>', :thumb => '118x100#' } + url: "/ckeditor_assets/pictures/:id/:style_:basename.:extension", + path: "/ckeditor_assets/pictures/:id/:style_:basename.:extension", + styles: { content: "800>", thumb: "118x100#" } validates_attachment_presence :data - validates_attachment_size :data, :less_than => 2.megabytes - validates_attachment_content_type :data, :content_type => /\Aimage/ + validates_attachment_size :data, less_than: 2.megabytes + validates_attachment_content_type :data, content_type: /\Aimage/ def url_content url(:content) @@ -16,10 +18,9 @@ def url(param) return super if actual_url.nil? if param == :content - return actual_url + actual_url else actual_url.gsub("/original", "/thumb") end - end end diff --git a/app/models/faq.rb b/app/models/faq.rb index a6d4345ed..86970a918 100644 --- a/app/models/faq.rb +++ b/app/models/faq.rb @@ -1,6 +1,8 @@ +# frozen_string_literal: true + class Faq < ApplicationRecord # Validations - validates_presence_of :question, :answer + validates :question, :answer, presence: true # Scopes scope :active, -> { where(inactive: false) } diff --git a/app/models/footer.rb b/app/models/footer.rb index 8f679c870..e3b97127e 100644 --- a/app/models/footer.rb +++ b/app/models/footer.rb @@ -1,5 +1,6 @@ -class Footer < ApplicationRecord +# frozen_string_literal: true +class Footer < ApplicationRecord def self.phone first&.phone end diff --git a/app/models/form.rb b/app/models/form.rb index c42c63b3d..45d51b9f9 100644 --- a/app/models/form.rb +++ b/app/models/form.rb @@ -1,8 +1,10 @@ +# frozen_string_literal: true + class Form < ApplicationRecord # Associations has_many :form_fields, dependent: :destroy, inverse_of: :form - has_many :user_forms - has_many :reports, as: :owner + has_many :user_forms # rubocop:todo Rails/HasManyOrHasOneDependent + has_many :reports, as: :owner # rubocop:todo Rails/HasManyOrHasOneDependent belongs_to :owner, polymorphic: true # Nested Attrs @@ -14,6 +16,6 @@ class Form < ApplicationRecord end def name - owner ? "#{owner.try(:name)} Form" : 'New Form' + owner ? "#{owner.try(:name)} Form" : "New Form" end end diff --git a/app/models/form_builder.rb b/app/models/form_builder.rb index cbdd593ff..61c379a37 100644 --- a/app/models/form_builder.rb +++ b/app/models/form_builder.rb @@ -1,7 +1,9 @@ +# frozen_string_literal: true + class FormBuilder < ApplicationRecord validates :name, presence: true - has_many :forms, as: :owner + has_many :forms, as: :owner # rubocop:todo Rails/HasManyOrHasOneDependent belongs_to :windows_type accepts_nested_attributes_for :forms @@ -9,8 +11,8 @@ class FormBuilder < ApplicationRecord exclude_fields :owner_type, forms: [:owner, :owner_id, :owner_type, :owner] end - scope :workshop_logs, -> { where('name LIKE ?', '%Log%') } - scope :monthly, -> { where('name LIKE ?', '%monthly%') } + scope :workshop_logs, -> { where("name LIKE ?", "%Log%") } + scope :monthly, -> { where("name LIKE ?", "%monthly%") } def form_fields forms[0].form_fields if forms.any? @@ -18,30 +20,30 @@ def form_fields def report_type case name - when 'Children\'s Monthly Report' - 'MonthlyReport' - when 'Adult Monthly Report' - 'MonthlyReport' - when 'Family Windows Workshop Log' - 'WorkshopLog' - when 'Adult Worksohp Log' - 'WorkshopLog' - when 'Adult Workshop Log' - 'WorkshopLog' - when 'Children\'s Workshop Log' - 'WorkshopLog' - when 'Adult Log Entry' - 'WorkshopLog' - when 'Children\'s Log Entry' - 'WorkshopLog' - when 'Family Log Entry' - 'WorkshopLog' + when "Children's Monthly Report" + "MonthlyReport" + when "Adult Monthly Report" + "MonthlyReport" + when "Family Windows Workshop Log" + "WorkshopLog" + when "Adult Worksohp Log" + "WorkshopLog" + when "Adult Workshop Log" + "WorkshopLog" + when "Children's Workshop Log" + "WorkshopLog" + when "Adult Log Entry" + "WorkshopLog" + when "Children's Log Entry" + "WorkshopLog" + when "Family Log Entry" + "WorkshopLog" else - 'Report' + "Report" end end def family_workshop_log? - name.include?('Workshop') && name == 'Family Windows Workshop Log' + name.include?("Workshop") && name == "Family Windows Workshop Log" end end diff --git a/app/models/form_field.rb b/app/models/form_field.rb index 04c8d5819..737da9fa8 100644 --- a/app/models/form_field.rb +++ b/app/models/form_field.rb @@ -1,34 +1,26 @@ +# frozen_string_literal: true + class FormField < ApplicationRecord # Associations belongs_to :form, inverse_of: :form_fields has_many :form_field_answer_options, dependent: :destroy has_many :report_form_field_answers, dependent: :destroy has_many :answer_options, through: :form_field_answer_options - has_many :childs, foreign_key: "parent_id", class_name: "FormField" + # rubocop:todo Rails/InverseOf + has_many :childs, foreign_key: "parent_id", class_name: "FormField" # rubocop:todo Rails/HasManyOrHasOneDependent # rubocop:todo Rails/InverseOf + # rubocop:enable Rails/InverseOf # Validations - validates_presence_of :question + validates :question, presence: true # Enum - enum status: [:inactive, :active] + enum status: { inactive: 0, active: 1 } # TODO: Rails 6.1 requires enums to be symbols # need additional refactoring in methods that call answer_type & answer_datatype to account for change to enum - enum answer_type: [ - :free_form_input_one_line, - :free_form_input_paragraph, - :multiple_choice_radio, - :no_user_input, - :multiple_choice_checkbox, - :group_header - ] - - enum answer_datatype: [ - :text_alphanumeric, - :number_integer, - :number_decimal, - :date, - ] + enum answer_type: { free_form_input_one_line: 0, free_form_input_paragraph: 1, multiple_choice_radio: 2, no_user_input: 3, multiple_choice_checkbox: 4, group_header: 5 } + + enum answer_datatype: { text_alphanumeric: 0, number_integer: 1, number_decimal: 2, date: 3 } rails_admin do # exclude_fields :answer_options @@ -44,52 +36,52 @@ def name end def multiple_choice? - answer_type ? answer_type.include?('multiple choice') : false + answer_type ? answer_type.include?("multiple choice") : false end def html_id - self.question.tr(" /#,')(.","_").downcase + question.tr(" /#,')(.", "_").downcase end def html_input_type case answer_type - when !self.parent_id.nil? + when !parent_id.nil? :child - when 'free-form input - one line' - self.parent_id.nil? ? :text : :child + when "free-form input - one line" + parent_id.nil? ? :text : :child - when 'free-form input - paragraph' + when "free-form input - paragraph" :textarea - when 'multiple choice - checkbox' + when "multiple choice - checkbox" :checkbox - when 'multiple choice - radio' + when "multiple choice - radio" :radio - when 'no user input' - !self.childs.empty? ? :group_header : :label + when "no user input" + !childs.empty? ? :group_header : :label else :hidden end end - # This one bellow should be removed and use + # This one bellow should be removed and use # html_input_type def input_type case answer_type - when 'free-form input - one line' + when "free-form input - one line" :text_field - when 'free-form input - paragraph' + when "free-form input - paragraph" :text_area - when 'multiple choice - checkbox' + when "multiple choice - checkbox" :check_box - when 'multiple choice - radio' + when "multiple choice - radio" :radio_button - when 'no user input' + when "no user input" :label else :hidden_field @@ -98,15 +90,16 @@ def input_type def find_answer(report) return if report.nil? - report.report_form_field_answers.select{|fa| fa.form_field == self}.first + + report.report_form_field_answers.select { |fa| fa.form_field == self }.first end - def answer report + def answer(report) answer = find_answer(report) - answer.response unless answer.nil? + answer&.response end - def checked report, value + def checked(report, value) answer = find_answer(report) if answer.nil? @@ -116,12 +109,8 @@ def checked report, value end end - def selected report, value - answer = find_answer(report) - if answers.include? value - true - else - false - end + def selected(report, value) + find_answer(report) + answers.include?(value) end end diff --git a/app/models/form_field_answer_option.rb b/app/models/form_field_answer_option.rb index e77cc0d8c..85d278cbb 100644 --- a/app/models/form_field_answer_option.rb +++ b/app/models/form_field_answer_option.rb @@ -1,8 +1,10 @@ +# frozen_string_literal: true + class FormFieldAnswerOption < ApplicationRecord belongs_to :form_field belongs_to :answer_option def name - answer_option.name if answer_option + answer_option&.name end end diff --git a/app/models/image.rb b/app/models/image.rb index 50d64f2ec..4e8613f3a 100644 --- a/app/models/image.rb +++ b/app/models/image.rb @@ -1,12 +1,14 @@ +# frozen_string_literal: true + class Image < ApplicationRecord belongs_to :owner, polymorphic: true belongs_to :report, optional: true has_attached_file :file, - styles: { medium: '300x300>', thumb: '100x100>' }, - default_url: - ActionController::Base.helpers.asset_path( - 'workshop_default.png' - ) - validates_attachment :file, content_type: { content_type: ["image/jpg", "image/jpeg", "image/png", "image/gif"] } + styles: { medium: "300x300>", thumb: "100x100>" }, + default_url: + ActionController::Base.helpers.asset_path( + "workshop_default.png", + ) + validates_attachment :file, content_type: { content_type: ["image/jpg", "image/jpeg", "image/png", "image/gif"] } end diff --git a/app/models/location.rb b/app/models/location.rb index 40dd22cf6..e280c8461 100644 --- a/app/models/location.rb +++ b/app/models/location.rb @@ -1,6 +1,8 @@ +# frozen_string_literal: true + class Location < ApplicationRecord # Validations - validates_presence_of :city, :country + validates :city, :country, presence: true # Methods def name diff --git a/app/models/media_file.rb b/app/models/media_file.rb index 6a40148e5..3b8955278 100644 --- a/app/models/media_file.rb +++ b/app/models/media_file.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class MediaFile < ApplicationRecord belongs_to :report, optional: true belongs_to :workshop, optional: true @@ -5,11 +7,16 @@ class MediaFile < ApplicationRecord has_attached_file :file - FORM_FILE_CONTENT_TYPES = ["image/jpeg", "image/jpg", "image/png", - "application/pdf", "application/msword", - "application/vnd.openxmlformats-officedocument.wordprocessingml.document", - "application/vnd.ms-excel", - "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"] + FORM_FILE_CONTENT_TYPES = [ + "image/jpeg", + "image/jpg", + "image/png", + "application/pdf", + "application/msword", + "application/vnd.openxmlformats-officedocument.wordprocessingml.document", + "application/vnd.ms-excel", + "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", + ] - validates_attachment :file, content_type: { content_type: FORM_FILE_CONTENT_TYPES } + validates_attachment :file, content_type: { content_type: FORM_FILE_CONTENT_TYPES } end diff --git a/app/models/metadatum.rb b/app/models/metadatum.rb index 1d2550ee9..2fd0e09c8 100644 --- a/app/models/metadatum.rb +++ b/app/models/metadatum.rb @@ -1,8 +1,10 @@ +# frozen_string_literal: true + class Metadatum < ApplicationRecord has_many :categories, dependent: :destroy has_many :categorizable_items, through: :categories, dependent: :destroy # Validations - validates_presence_of :name, uniqueness: true + validates :name, presence: { uniqueness: true } scope :published, -> { where(published: true) } end diff --git a/app/models/monthly_report.rb b/app/models/monthly_report.rb index 30c354bad..99672f2f3 100644 --- a/app/models/monthly_report.rb +++ b/app/models/monthly_report.rb @@ -1,5 +1,6 @@ -class MonthlyReport < Report +# frozen_string_literal: true +class MonthlyReport < Report rails_admin do configure :created_at do show @@ -45,41 +46,38 @@ class MonthlyReport < Report column_width 40 end configure :on_going_participants do - formatted_value{ bindings[:object].on_going_participants} + formatted_value { bindings[:object].on_going_participants } end configure :new_participants do - formatted_value{ bindings[:object].new_participants} + formatted_value { bindings[:object].new_participants } end configure :type do - formatted_value{ bindings[:object].admin_type} + formatted_value { bindings[:object].admin_type } end configure :date do - formatted_value{ bindings[:object].month} + formatted_value { bindings[:object].month } end - end end def on_going_participants if form_builder - field = form_builder.form_fields.find_by(question: 'Total # On-going Participants', status: 1) - field.answer(self) if field + field = form_builder.form_fields.find_by(question: "Total # On-going Participants", status: 1) + field&.answer(self) end end def new_participants if form_builder - field = form_builder.form_fields.find_by(question: 'Total # First-Time Participants', status: 1) - field.answer(self) if field + field = form_builder.form_fields.find_by(question: "Total # First-Time Participants", status: 1) + field&.answer(self) end end def month date.strftime("%B") end - - end diff --git a/app/models/notification.rb b/app/models/notification.rb index 1eb0cf27c..d41d89ef6 100644 --- a/app/models/notification.rb +++ b/app/models/notification.rb @@ -1,8 +1,10 @@ +# frozen_string_literal: true + class Notification < ApplicationRecord belongs_to :noticeable, polymorphic: true after_save :send_notice - enum notification_type: [:created, :updated] + enum notification_type: { created: 0, updated: 1 } attr_accessor :fields_changed def send_notice diff --git a/app/models/permission.rb b/app/models/permission.rb index d15f9347c..4279ede5b 100644 --- a/app/models/permission.rb +++ b/app/models/permission.rb @@ -1,6 +1,8 @@ +# frozen_string_literal: true + class Permission < ApplicationRecord # Associations - has_many :user_permissions + has_many :user_permissions # rubocop:todo Rails/HasManyOrHasOneDependent has_many :users, through: :user_permissions # Methods @@ -15,10 +17,8 @@ def name security_cat end - private - def self.defaults - #TODO: Add Combined Windows - ['Guest', 'Member', 'Women\'s Windows', 'Children\'s Windows', 'Survivor\'s Art Circle'] + # TODO: Add Combined Windows + ["Guest", "Member", "Women's Windows", "Children's Windows", "Survivor's Art Circle"] end end diff --git a/app/models/project.rb b/app/models/project.rb index 5147d9002..80e42dae8 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -1,8 +1,10 @@ +# frozen_string_literal: true + class Project < ApplicationRecord # Associations belongs_to :location belongs_to :windows_type - has_many :project_users + has_many :project_users # rubocop:todo Rails/HasManyOrHasOneDependent has_many :users, through: :project_users has_many :reports, through: :users has_many :workshop_logs, through: :users @@ -15,7 +17,7 @@ class Project < ApplicationRecord end edit do exclude_fields :users, :project_users, :reports, :workshop_logs, :windows_type - group 'More Fields' do + group "More Fields" do active false field :location field :district @@ -32,11 +34,12 @@ class Project < ApplicationRecord # Methods def led_by?(user) return false unless leader + leader.user == user end def log_title - "#{name} #{windows_type.log_label if windows_type}" + "#{name} #{windows_type&.log_label}" end private diff --git a/app/models/project_obligation.rb b/app/models/project_obligation.rb index c8cbba902..c0696aa36 100644 --- a/app/models/project_obligation.rb +++ b/app/models/project_obligation.rb @@ -1,10 +1,15 @@ -class ProjectObligation < ApplicationRecord +# frozen_string_literal: true +class ProjectObligation < ApplicationRecord def self.create_defaults - ['Current Grant Funded', 'Previous Grant Funded', - 'Voluntary Reporting', 'Intermittent Reporting', - 'Active Non-Reporting'].each do |name| + [ + "Current Grant Funded", + "Previous Grant Funded", + "Voluntary Reporting", + "Intermittent Reporting", + "Active Non-Reporting", + ].each do |name| ProjectObligation.find_or_create_by(name: name) - end + end end end diff --git a/app/models/project_status.rb b/app/models/project_status.rb index fc586e58c..cb22b8e18 100644 --- a/app/models/project_status.rb +++ b/app/models/project_status.rb @@ -1,7 +1,8 @@ -class ProjectStatus < ApplicationRecord +# frozen_string_literal: true +class ProjectStatus < ApplicationRecord def self.create_defaults - ['Active', 'Inactive', 'Pending', 'Reinstate', 'Suspended'].each do |name| + ["Active", "Inactive", "Pending", "Reinstate", "Suspended"].each do |name| ProjectStatus.find_or_create_by(name: name) end end diff --git a/app/models/project_user.rb b/app/models/project_user.rb index b9489e97b..ac7bd9a1d 100644 --- a/app/models/project_user.rb +++ b/app/models/project_user.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class ProjectUser < ApplicationRecord # Associations belongs_to :project @@ -5,10 +7,10 @@ class ProjectUser < ApplicationRecord scope :liaisons, -> { where(position: 1) } # Validations - validates_presence_of :project_id + validates :project_id, presence: true # Enum - enum position: [:default, :liaison, :leader, :assistant] + enum position: { default: 0, liaison: 1, leader: 2, assistant: 3 } # Rails admin rails_admin do exclude_fields :agency_id, :position @@ -16,6 +18,6 @@ class ProjectUser < ApplicationRecord # Methods def name - "#{user.name}" if user + user.name.to_s if user end end diff --git a/app/models/quotable_item_quote.rb b/app/models/quotable_item_quote.rb index ed3b9a5a3..551c2edd0 100644 --- a/app/models/quotable_item_quote.rb +++ b/app/models/quotable_item_quote.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class QuotableItemQuote < ApplicationRecord belongs_to :quote belongs_to :quotable, polymorphic: true diff --git a/app/models/quote.rb b/app/models/quote.rb index 6dd5b46af..7a2106b81 100644 --- a/app/models/quote.rb +++ b/app/models/quote.rb @@ -1,9 +1,11 @@ +# frozen_string_literal: true + class Quote < ApplicationRecord scope :active, -> { where(inactive: false) } rails_admin do field :quote field :speaker_name do - label 'Speaker' + label "Speaker" end field :inactive field :legacy @@ -13,6 +15,6 @@ class Quote < ApplicationRecord end def speaker - speaker_name.nil? || speaker_name.empty? ? "Participant" : speaker_name + speaker_name.presence || "Participant" end end diff --git a/app/models/report.rb b/app/models/report.rb index 0e6aea4bd..7268d0e33 100644 --- a/app/models/report.rb +++ b/app/models/report.rb @@ -1,21 +1,23 @@ +# frozen_string_literal: true + class Report < ApplicationRecord belongs_to :user belongs_to :project belongs_to :windows_type belongs_to :owner, polymorphic: true, optional: true - has_one :form, as: :owner - has_one :image + has_one :form, as: :owner # rubocop:todo Rails/HasManyOrHasOneDependent + has_one :image # rubocop:todo Rails/HasManyOrHasOneDependent validate :image_valid? has_attached_file :form_file before_save :set_has_attachament - FORM_FILE_CONTENT_TYPES = %w[application/pdf application/msword application/vnd.openxmlformats-officedocument.wordprocessingml.document application/vnd.ms-excel application/vnd.openxmlformats-officedocument.spreadsheetml.sheet] + FORM_FILE_CONTENT_TYPES = ["application/pdf", "application/msword", "application/vnd.openxmlformats-officedocument.wordprocessingml.document", "application/vnd.ms-excel", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"] - validates_attachment :form_file, content_type: { content_type: FORM_FILE_CONTENT_TYPES } + validates_attachment :form_file, content_type: { content_type: FORM_FILE_CONTENT_TYPES } - has_many :images + has_many :images # rubocop:todo Rails/HasManyOrHasOneDependent has_many :form_fields, through: :form has_many :report_form_field_answers, dependent: :destroy has_many :quotable_item_quotes, as: :quotable, dependent: :destroy @@ -23,15 +25,15 @@ class Report < ApplicationRecord has_many :notifications, as: :noticeable, dependent: :destroy has_many :sectorable_items, as: :sectorable, dependent: :destroy has_many :sectors, through: :sectorable_items, dependent: :destroy - scope :in_month, -> (date) { where(created_at: date.beginning_of_month..date.end_of_month) } + scope :in_month, ->(date) { where(created_at: date.beginning_of_month..date.end_of_month) } has_many :media_files, dependent: :destroy accepts_nested_attributes_for :media_files accepts_nested_attributes_for :report_form_field_answers, - reject_if: proc { |object| - (object['_create'].to_i == 0 && object['answer'].nil?) - } + reject_if: proc { |object| + object["_create"].to_i == 0 && object["answer"].nil? + } accepts_nested_attributes_for :quotable_item_quotes after_create :set_windows_type @@ -53,7 +55,6 @@ class Report < ApplicationRecord field :project field :created_at end - end def users_admin_type @@ -62,15 +63,15 @@ def users_admin_type else case type when "MonthlyReport" - "#{type} - Monthly Report Date: #{date_label} - User: #{user.full_name if user}" + "#{type} - Monthly Report Date: #{date_label} - User: #{user&.full_name}" when "Report" - if owner_type and owner_type == 'Resource' - "#{type} - #{owner ? owner_type : '[ EMPTY ]'} - User: #{user.full_name if user}" + if owner_type && (owner_type == "Resource") + "#{type} - #{owner ? owner_type : "[ EMPTY ]"} - User: #{user&.full_name}" # rubocop:todo Metrics/BlockNesting else - "#{type} - #{owner ? owner.type : '[ EMPTY ]'} - User: #{user.full_name if user}" + "#{type} - #{owner ? owner.type : "[ EMPTY ]"} - User: #{user&.full_name}" # rubocop:todo Metrics/BlockNesting end else - "#{type} - #{owner ? owner.communal_label(self) : '[ EMPTY ]'} - User: #{user.full_name if user}" + "#{type} - #{owner ? owner.communal_label(self) : "[ EMPTY ]"} - User: #{user&.full_name}" end end end @@ -80,19 +81,19 @@ def story? end def date_label - "#{date ? date.strftime('%m/%d/%y') : '[ EMPTY ]'}" + (date ? date.strftime("%m/%d/%y") : "[ EMPTY ]").to_s end def delete_and_update_all(quotes_params, log_fields, image = nil) - self.quotes.delete_all - self.report_form_field_answers.delete_all + quotes.delete_all + report_form_field_answers.delete_all - self.quotes.build( quotes_params ) - self.report_form_field_answers.build( log_fields ) + quotes.build(quotes_params) + report_form_field_answers.build(log_fields) - unless image.blank? - self.image.destroy if self.image - self.image = Image.new( file: image ) + if image.present? + self.image&.destroy + self.image = Image.new(file: image) end save @@ -100,6 +101,7 @@ def delete_and_update_all(quotes_params, log_fields, image = nil) def image_valid? return true if image.nil? + unless image.valid? image.errors.each do |k, v| errors.add(k, v) @@ -109,41 +111,37 @@ def image_valid? def log_fields if form_builder - form_builder.forms[0].form_fields.where('ordering is not null and status = 1'). - order(ordering: :desc).all + form_builder.forms[0].form_fields.where("ordering is not null and status = 1") + .order(ordering: :desc).all else [] end end def form_builder - if type and type.include? "Monthly" - if windows_type and windows_type.name == "ADULT WORKSHOP LOG" + if type&.include?("Monthly") + if windows_type && (windows_type.name == "ADULT WORKSHOP LOG") FormBuilder.find(4) - elsif windows_type and windows_type.name == "CHILDREN WORKSHOP LOG" + elsif windows_type && (windows_type.name == "CHILDREN WORKSHOP LOG") FormBuilder.find(2) end - elsif owner and owner_type.include? "FormBuilder" - FormBuilder.find(7) - else - nil + elsif owner && owner_type.include?("FormBuilder") + FormBuilder.find(7) end end - def user_name - user.name - end + delegate :name, to: :user, prefix: true def title name end def name - type ? type.titleize : 'Report' + type ? type.titleize : "Report" end def display_date - created_at.strftime('%B %e, %Y') + created_at.strftime("%B %e, %Y") end private @@ -151,13 +149,14 @@ def display_date def set_has_attachament self.has_attachment = false - unless self.image.blank? and self.media_files.empty? and self.form_file.blank? + unless image.blank? && media_files.empty? && form_file.blank? self.has_attachment = true end end def set_windows_type return unless project && windows_type.nil? + update(windows_type_id: project.windows_type.id) end diff --git a/app/models/report_form_field_answer.rb b/app/models/report_form_field_answer.rb index 0f189976b..f6b5a4ebc 100644 --- a/app/models/report_form_field_answer.rb +++ b/app/models/report_form_field_answer.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class ReportFormFieldAnswer < ApplicationRecord belongs_to :report belongs_to :form_field diff --git a/app/models/resource.rb b/app/models/resource.rb index 36bf51ef2..4edd5208f 100644 --- a/app/models/resource.rb +++ b/app/models/resource.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class Resource < ApplicationRecord # Associations belongs_to :user @@ -10,30 +12,30 @@ class Resource < ApplicationRecord has_many :sectors, through: :sectorable_items, source: :sector has_many :related_workshops, through: :sectors, source: :workshops has_many :attachments, as: :owner, dependent: :destroy - has_one :form, as: :owner - has_many :reports, as: :owner + has_one :form, as: :owner # rubocop:todo Rails/HasManyOrHasOneDependent + has_many :reports, as: :owner # rubocop:todo Rails/HasManyOrHasOneDependent has_many :workshop_resources, dependent: :destroy # Scopes - scope :featured, -> { where(featured: true ).order(created_at: :desc)} + scope :featured, -> { where(featured: true).order(created_at: :desc) } scope :published, -> { where(inactive: false) } - scope :by_created, -> { order(created_at: :desc)} + scope :by_created, -> { order(created_at: :desc) } - scope :for_search, -> { published.where('kind NOT IN (?)', ['SectorImpact', 'LeaderSpotlight', 'Theme']) } + scope :for_search, -> { published.where("kind NOT IN (?)", ["SectorImpact", "LeaderSpotlight", "Theme"]) } scope :recent, -> { for_search.by_created } validates :title, presence: true # Nested Attributes accepts_nested_attributes_for :categorizable_items, - allow_destroy: true, - reject_if: proc { |resource| Resource.reject?(resource) } + allow_destroy: true, + reject_if: proc { |resource| Resource.reject?(resource) } accepts_nested_attributes_for :sectorable_items, - allow_destroy: true, - reject_if: proc { |resource| Resource.reject?(resource) } + allow_destroy: true, + reject_if: proc { |resource| Resource.reject?(resource) } accepts_nested_attributes_for :images, - allow_destroy: true, - reject_if: proc { |resource| Resource.reject?(resource) } + allow_destroy: true, + reject_if: proc { |resource| Resource.reject?(resource) } accepts_nested_attributes_for :attachments, reject_if: :all_blank, allow_destroy: true accepts_nested_attributes_for :form, reject_if: :all_blank, allow_destroy: true @@ -44,10 +46,9 @@ class Resource < ApplicationRecord list do configure :title do - formatted_value{ "#{bindings[:object].title} - [ #{bindings[:object].kind.upcase} ]" } + formatted_value { "#{bindings[:object].title} - [ #{bindings[:object].kind.upcase} ]" } end end - end # Search Cop @@ -63,13 +64,12 @@ class Resource < ApplicationRecord scope :story, -> { where(kind: ["Story", "LeaderSpotlight"]).order(created_at: :desc) } scope :leader_spotlight, -> { where(kind: "LeaderSpotlight") } - def story? - ["Story", "LeaderSpotlight"].include? self.kind + ["Story", "LeaderSpotlight"].include?(kind) end def custom_label_list - "#{self.title} (#{self.kind.upcase})" unless self.kind.nil? + "#{title} (#{kind.upcase})" unless kind.nil? end # Methods @@ -88,7 +88,7 @@ def main_image def main_image_url return main_image.file.url if main_image - if self.kind == "Theme" + if kind == "Theme" ActionController::Base.helpers.asset_path("workshop_default.png") else "/images/workshop_default.jpg" @@ -96,31 +96,33 @@ def main_image_url end def type_enum - types.map { |title| [title.titleize, title ]} + types.map { |title| [title.titleize, title] } end def types - ['Resource', 'LeaderSpotlight', 'SectorImpact', - 'Story', 'Theme', 'Scholarship', 'TemplateAndHandout', - 'ToolkitAndForm' + [ + "Resource", + "LeaderSpotlight", + "SectorImpact", + "Story", + "Theme", + "Scholarship", + "TemplateAndHandout", + "ToolkitAndForm", ] end - def year - created_at.year - end + delegate :year, to: :created_at - def month - created_at.month - end + delegate :month, to: :created_at def self.search(params) resources = for_search - resources = resources.where('title like ?', "%#{params[:query]}%") - resources = resources.where('kind like ?', "%#{params[:kind]}%") + resources = resources.where("title like ?", "%#{params[:query]}%") + resources.where("kind like ?", "%#{params[:kind]}%") end - private + def self.reject?(resource) - resource['_create'] == '0' + resource["_create"] == "0" end end diff --git a/app/models/sector.rb b/app/models/sector.rb index 447a12c2d..d19c3c6d1 100644 --- a/app/models/sector.rb +++ b/app/models/sector.rb @@ -1,14 +1,18 @@ +# frozen_string_literal: true + class Sector < ApplicationRecord # Associations has_many :sectorable_items, dependent: :destroy - has_many :workshops, through: :sectorable_items, - source: :sectorable, source_type: 'Workshop' + has_many :workshops, + through: :sectorable_items, + source: :sectorable, + source_type: "Workshop" has_many :quotes, through: :workshops # Validations - validates_presence_of :name, uniqueness: true + validates :name, presence: { uniqueness: true } # ATTR Accessor attr_accessor :_create @@ -18,25 +22,30 @@ class Sector < ApplicationRecord exclude_fields :workshops end - default_scope { order('name') } + default_scope { order("name") } # Methods def self.create_defaults - Sector.defaults.each do | name | + Sector.defaults.each do |name| Sector.find_or_create_by(name: name, published: true) end end def self.published - sectors = Sector.where("published = ? AND name != ?", true, 'Other').to_a - sectors.sort!{|x, y| x[:name].downcase <=> y[:name].downcase} - sectors << Sector.where(name: 'Other').first + sectors = Sector.where("published = ? AND name != ?", true, "Other").to_a + sectors.sort! { |x, y| x[:name].downcase <=> y[:name].downcase } + sectors << Sector.where(name: "Other").first end - private - def self.defaults - ['Veterans & Military', 'Sexual Assault', 'Addiction Recovery', - 'LGBTQIA', 'Child Abuse', 'Education/Schools', 'Other' ] + [ + "Veterans & Military", + "Sexual Assault", + "Addiction Recovery", + "LGBTQIA", + "Child Abuse", + "Education/Schools", + "Other", + ] end end diff --git a/app/models/sectorable_item.rb b/app/models/sectorable_item.rb index 820d05aea..be12ae860 100644 --- a/app/models/sectorable_item.rb +++ b/app/models/sectorable_item.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class SectorableItem < ApplicationRecord # Associations belongs_to :sector @@ -14,8 +16,7 @@ class SectorableItem < ApplicationRecord # Methods def title return id unless sectorable && sectorable.class != WorkshopLog - "#{sectorable.title} - #{sectorable.windows_type.name if sectorable.windows_type}" - end - private + "#{sectorable.title} - #{sectorable.windows_type&.name}" + end end diff --git a/app/models/story.rb b/app/models/story.rb index ff7488bed..17635df06 100644 --- a/app/models/story.rb +++ b/app/models/story.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class Story < Report rails_admin do configure :owner do @@ -31,7 +33,6 @@ class Story < Report searchable true column_width 10 end - end end end diff --git a/app/models/user.rb b/app/models/user.rb index c592c9383..8d36b34ff 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -1,5 +1,7 @@ +# frozen_string_literal: true + RailsAdmin.config do |config| - config.model Report do + config.model(Report) do object_label_method do :users_admin_type end @@ -8,49 +10,68 @@ class User < ApplicationRecord # Include default devise modules. Others available are: # :confirmable, :lockable, :timeoutable and :omniauthable - devise :database_authenticatable, :recoverable, - :rememberable, :trackable, :validatable + devise :database_authenticatable, + :recoverable, + :rememberable, + :trackable, + :validatable # Avatar has_attached_file :avatar, styles: { medium: "300x300>", thumb: "100x100>" }, default_url: "/images/missing.png" - validates_attachment_content_type :avatar, content_type: /\Aimage\/.*\z/ + validates_attachment_content_type :avatar, content_type: %r{\Aimage/.*\z} # Associations - has_many :workshops + has_many :workshops # rubocop:todo Rails/HasManyOrHasOneDependent # has_many :curriculum_workshops, -> (user) { }, class_name: 'Workshop' - has_many :workshop_logs - has_many :reports + has_many :workshop_logs # rubocop:todo Rails/HasManyOrHasOneDependent + has_many :reports # rubocop:todo Rails/HasManyOrHasOneDependent has_many :communal_reports, through: :projects, source: :reports has_many :bookmarks, dependent: :destroy - has_many :bookmarked_workshops, through: :bookmarks, source: :bookmarkable, source_type: 'Workshop' + has_many :bookmarked_workshops, through: :bookmarks, source: :bookmarkable, source_type: "Workshop" has_many :project_users, dependent: :destroy has_many :projects, through: :project_users has_many :windows_types, through: :projects has_many :user_permissions, dependent: :destroy has_many :permissions, through: :user_permissions - has_many :resources + has_many :resources # rubocop:todo Rails/HasManyOrHasOneDependent has_many :user_forms, dependent: :destroy has_many :user_form_form_fields, through: :user_forms, dependent: :destroy has_many :colleagues, -> { select(:user_id, :position, :project_id).distinct }, through: :projects, source: :project_users - has_many :notifications, as: :noticeable + has_many :notifications, as: :noticeable # rubocop:todo Rails/HasManyOrHasOneDependent # Rails Admin rails_admin do - exclude_fields :reset_password_sent_at, :remember_created_at, :sign_in_count, - :current_sign_in_at, :last_sign_in_at, :current_sign_in_ip, - :last_sign_in_ip, :reset, :workshops, :workshop_logs, - :bookmarks, :projects, :permissions, :user_permissions, :colleagues, - :notifications, :user_form_form_fields, :resources, :communal_reports, - :user_forms, :windows_types, :birthday + exclude_fields :reset_password_sent_at, + :remember_created_at, + :sign_in_count, + :current_sign_in_at, + :last_sign_in_at, + :current_sign_in_ip, + :last_sign_in_ip, + :reset, + :workshops, + :workshop_logs, + :bookmarks, + :projects, + :permissions, + :user_permissions, + :colleagues, + :notifications, + :user_form_form_fields, + :resources, + :communal_reports, + :user_forms, + :windows_types, + :birthday field :reports do label do - 'Communal Reports' + "Communal Reports" end end edit do include_fields :first_name, :last_name, :email, :password, :password_confirmation, :reset_password_token - group 'More Fields' do + group "More Fields" do active false field :agency_id field :phone @@ -185,47 +206,52 @@ class User < ApplicationRecord after_create :set_default_values - before_destroy { |record| + before_destroy do |record| orphaned_user = User.find_by(email: "orphaned_reports@awbw.org") orphaned_user.reports << record.reports unless record.reports.nil? orphaned_user.workshop_logs << record.workshop_logs unless record.workshop_logs.nil? - } + end def has_liasion_position_for?(project_id) !project_users.where(project_id: project_id, position: 1).first.nil? end def active_for_authentication? - super && !self.inactive? + super && !inactive? end def full_name - if !first_name || first_name.empty? + if first_name.blank? email else "#{first_name} #{last_name}" end end - def submitted_monthly_report(submitted_date = Date.today, windows_type, project_id) - - Report.where(project_id: project_id, type: "MonthlyReport", date: submitted_date, - windows_type: windows_type).last + # rubocop:todo Style/OptionalArguments + def submitted_monthly_report(submitted_date = Time.zone.today, windows_type, project_id) + # rubocop:enable Style/OptionalArguments + Report.where( + project_id: project_id, + type: "MonthlyReport", + date: submitted_date, + windows_type: windows_type, + ).last end - def recent_activity(limit=4) + def recent_activity(limit = 4) recent_activity = workshops.where(inactive: true).last(10) recent_activity += workshop_logs.last(10) - recent_activity += reports.where("owner_type = 'MonthlyReport'"). - last(10) - recent_activity += reports.where("owner_id = '7'"). - last(10) + recent_activity += reports.where("owner_type = 'MonthlyReport'") + .last(10) + recent_activity += reports.where("owner_id = '7'") + .last(10) - recent_activity.sort{|x,y| y.created_at <=> x.created_at}[0..(limit - 1)] + recent_activity.sort { |x, y| y.created_at <=> x.created_at }[0..(limit - 1)] end def liaison_in_projects?(projects) - (liaison_project_ids & projects.map(&:id)).any? + liaison_project_ids.intersect?(projects.map(&:id)) end def liaison? @@ -233,26 +259,28 @@ def liaison? end def project_monthly_workshop_logs(date, *windows_type) - where = windows_type.map do |wt| 'windows_type_id = ?' end + where = windows_type.map do |_wt| + "windows_type_id = ?" + end logs = projects.map do |project| - project.workshop_logs.where(where.join(' OR '), *windows_type) + project.workshop_logs.where(where.join(" OR "), *windows_type) end.flatten logs = logs.select do |log| - log.date && log.date.month == date.month.to_i && \ - log.date.year == date.year.to_i + log.date && log.date.month == date.month.to_i && + log.date.year == date.year.to_i end.flatten - logs.uniq.group_by { |log| log.date } + logs.uniq.group_by(&:date) end def project_workshop_logs(date, windows_type, project_id) - if project_id + if project_id logs = workshop_logs.where(project_id: project_id, windows_type_id: windows_type.id) logs = logs.select do |log| - log.date && log.date.month == date.month.to_i && \ - log.date.year == date.year.to_i + log.date && log.date.month == date.month.to_i && + log.date.year == date.year.to_i end.flatten - logs.uniq.group_by { |log| log.date } + logs.uniq.group_by(&:date) end end @@ -260,30 +288,37 @@ def permissions_list security_list = permissions.pluck(:security_cat) result = [] - result << "ADULT WORKSHOP LOG" if security_list.include? "Adult Windows" - result << "CHILDREN WORKSHOP LOG" if security_list.include? "Children's Windows" - result << "ADULT & CHILDREN COMBINED (FAMILY) LOG" if security_list.include? "Combined Adult and Children's Windows" + result << "ADULT WORKSHOP LOG" if security_list.include?("Adult Windows") + result << "CHILDREN WORKSHOP LOG" if security_list.include?("Children's Windows") + result << "ADULT & CHILDREN COMBINED (FAMILY) LOG" if security_list.include?("Combined Adult and Children's Windows") result end def curriculum(klass = Workshop) results = klass.joins(:windows_type) - results = results.where('windows_types.name IN (?) and inactive is false', permissions_list) + results = results.where("windows_types.name IN (?) and inactive is false", permissions_list) - results = results.where(kind: ['Template','Handout', 'Scholarship', - 'Toolkit', 'Form', 'Resource']) if klass == Resource + results = results.where(kind: [ + "Template", + "Handout", + "Scholarship", + "Toolkit", + "Form", + "Resource", + ]) if klass == Resource results end def name - return email if !first_name || first_name.empty? + return email if first_name.blank? + "#{first_name} #{last_name}" end def agency_name - agency ? agency.name : 'No agency.' + agency ? agency.name : "No agency." end def has_bookmarked_workshop?(workshop) @@ -306,9 +341,8 @@ def set_default_values adult_perm = Permission.find_by(security_cat: "Adult Windows") children_perm = Permission.find_by(security_cat: "Children's Windows") - - self.permissions << combined_perm - self.permissions << adult_perm - self.permissions << children_perm + permissions << combined_perm + permissions << adult_perm + permissions << children_perm end end diff --git a/app/models/user_form.rb b/app/models/user_form.rb index 9feaeab65..9470499c2 100644 --- a/app/models/user_form.rb +++ b/app/models/user_form.rb @@ -1,7 +1,9 @@ +# frozen_string_literal: true + class UserForm < ApplicationRecord belongs_to :user belongs_to :form - has_many :user_form_form_fields + has_many :user_form_form_fields # rubocop:todo Rails/HasManyOrHasOneDependent accepts_nested_attributes_for :user_form_form_fields end diff --git a/app/models/user_form_form_field.rb b/app/models/user_form_form_field.rb index ae65c65e5..72a7dc30a 100644 --- a/app/models/user_form_form_field.rb +++ b/app/models/user_form_form_field.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class UserFormFormField < ApplicationRecord belongs_to :form_field belongs_to :user_form diff --git a/app/models/user_permission.rb b/app/models/user_permission.rb index d1598b094..781ac83f7 100644 --- a/app/models/user_permission.rb +++ b/app/models/user_permission.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class UserPermission < ApplicationRecord belongs_to :user belongs_to :permission diff --git a/app/models/windows_type.rb b/app/models/windows_type.rb index 627d6af39..731e367d8 100644 --- a/app/models/windows_type.rb +++ b/app/models/windows_type.rb @@ -1,12 +1,14 @@ +# frozen_string_literal: true + class WindowsType < ApplicationRecord # Associations - has_many :workshops - has_many :age_ranges - has_many :reports - has_many :form_builders + has_many :workshops # rubocop:todo Rails/HasManyOrHasOneDependent + has_many :age_ranges # rubocop:todo Rails/HasManyOrHasOneDependent + has_many :reports # rubocop:todo Rails/HasManyOrHasOneDependent + has_many :form_builders # rubocop:todo Rails/HasManyOrHasOneDependent def custom_label_method - self.name.gsub("LOG", "").gsub("WORKSHOP", "WINDOWS").titleize.strip.gsub("Children", "Children's") + name.gsub("LOG", "").gsub("WORKSHOP", "WINDOWS").titleize.strip.gsub("Children", "Children's") end # Methods @@ -14,7 +16,7 @@ def self.create_defaults WindowsType.defaults.each_with_index do |name, index| WindowsType.find_or_create_by( name: name, - legacy_id: index + 1 + legacy_id: index + 1, ) end end @@ -32,27 +34,28 @@ def label def workshop_log_label label = name.gsub("LOG", "").gsub("WORKSHOP", "").titleize.strip - label.gsub("Children", "Children's").gsub("Adult & Children's","").gsub("(Family)", "").tr(' ','') + label.gsub("Children", "Children's").gsub("Adult & Children's", "").gsub("(Family)", "").tr(" ", "") end def log_label - id != 3 ? "(#{name.split(' ')[0]})" : '' + id != 3 ? "(#{name.split(" ")[0]})" : "" end rails_admin do exclude_fields :short_name end - private - def self.symbolize(name) name.split(" ")[0] - .gsub("'s", "") - .downcase.to_sym + .gsub("'s", "") + .downcase.to_sym end def self.defaults - ['Women\'s Windows', 'Children\'s Windows', - 'Combined Women\'s and Children\'s Windows'] + [ + "Women's Windows", + "Children's Windows", + "Combined Women's and Children's Windows", + ] end end diff --git a/app/models/workshop.rb b/app/models/workshop.rb index 1893b6723..a08ce18ef 100644 --- a/app/models/workshop.rb +++ b/app/models/workshop.rb @@ -1,15 +1,18 @@ -require 'paperclip_attachment' +# frozen_string_literal: true -class Workshop < ApplicationRecord +require "paperclip_attachment" +class Workshop < ApplicationRecord default_scope { where(inactive: false) } # Associations belongs_to :user, optional: true before_save :set_time_frame - has_many :sectorable_items, dependent: :destroy, - inverse_of: :sectorable, as: :sectorable + has_many :sectorable_items, + dependent: :destroy, + inverse_of: :sectorable, + as: :sectorable has_many :sectors, through: :sectorable_items @@ -30,56 +33,55 @@ class Workshop < ApplicationRecord belongs_to :windows_type has_many :attachments, as: :owner, dependent: :destroy - has_many :workshop_age_ranges + has_many :workshop_age_ranges # rubocop:todo Rails/HasManyOrHasOneDependent has_attached_file :thumbnail, default_url: "/images/workshop_default.jpg" - validates_attachment_content_type :thumbnail, content_type: /\Aimage\/.*\Z/ + validates_attachment_content_type :thumbnail, content_type: %r{\Aimage/.*\Z} has_attached_file :header, default_url: "/images/workshop_default.jpg" - validates_attachment_content_type :header, content_type: /\Aimage\/.*\Z/ - + validates_attachment_content_type :header, content_type: %r{\Aimage/.*\Z} # Nested Attributes accepts_nested_attributes_for :images, reject_if: :all_blank, allow_destroy: true accepts_nested_attributes_for :sectorable_items, - reject_if: proc { |object| object['_create'] == '0' }, - allow_destroy: true + reject_if: proc { |object| object["_create"] == "0" }, + allow_destroy: true accepts_nested_attributes_for :sectors, - reject_if: proc { |object| object['_create'] == '0' || !object['_create'] }, - allow_destroy: true + reject_if: proc { |object| object["_create"] == "0" || !object["_create"] }, + allow_destroy: true accepts_nested_attributes_for :workshop_age_ranges, - reject_if: proc { |object| - object['_create'] == '0' || !object['_create'] || - WorkshopAgeRange.find_by(workshop_id: object[:workshop_id], age_range_id: object[:age_range_id]); - }, - allow_destroy: true + reject_if: proc { |object| + object["_create"] == "0" || !object["_create"] || + WorkshopAgeRange.find_by(workshop_id: object[:workshop_id], age_range_id: object[:age_range_id]) + }, + allow_destroy: true accepts_nested_attributes_for :quotes, - reject_if: proc { |object| object['quote'].nil? } + reject_if: proc { |object| object["quote"].nil? } accepts_nested_attributes_for :workshop_variations, - reject_if: proc { |object| object.nil? } + reject_if: proc { |object| object.nil? } # Scopes scope :published, -> { where(inactive: false) } scope :featured, -> { where(featured: true) } scope :by_year, -> { order(year: :desc).order(month: :desc) } scope :recent, -> { for_search.by_year.order(led_count: :desc).uniq(&:title) } - scope :by_rating, -> { by_year.sort_by(&:rating)} - scope :by_warm_up_and_relaxation, -> { search('Warm Up Relaxation') } + scope :by_rating, -> { by_year.sort_by(&:rating) } + scope :by_warm_up_and_relaxation, -> { search("Warm Up Relaxation") } scope :by_led_count, -> { order(led_count: :desc) } scope :for_search, -> { published } scope :legacy, -> { where(legacy: true) } scope :by_created_at, -> { order(created_at: :desc) } # Validations - validates_presence_of :title - #validates_presence_of :month, :year, if: Proc.new { |workshop| workshop.legacy } - validates_length_of :age_range, maximum: 16 + validates :title, presence: true + # validates_presence_of :month, :year, if: Proc.new { |workshop| workshop.legacy } + validates :age_range, length: { maximum: 16 } # Nested Attributes accepts_nested_attributes_for :workshop_logs, - reject_if: :all_blank, - allow_destroy: true + reject_if: :all_blank, + allow_destroy: true attr_writer :time_hours, :time_minutes @@ -88,8 +90,8 @@ class Workshop < ApplicationRecord search_scope :search do attributes :title - attributes category: ['categories.name'] - attributes sector: ['sectors.name'] + attributes category: ["categories.name"] + attributes sector: ["sectors.name"] end # Rails Admin @@ -103,7 +105,7 @@ class Workshop < ApplicationRecord field :title field :created_at field :full_name do - label 'Author' + label "Author" end field :month @@ -112,75 +114,75 @@ class Workshop < ApplicationRecord field :extra_field, :ck_editor do label do - "#{label}
Back To Top".html_safe + "#{label}
Back To Top".html_safe # rubocop:todo Rails/OutputSafety end pretty_value do - value.html_safe unless value.nil? + value&.html_safe # rubocop:todo Rails/OutputSafety end end field :objective, :ck_editor do label do - "#{label}
Back To Top".html_safe + "#{label}
Back To Top".html_safe # rubocop:todo Rails/OutputSafety end pretty_value do - value.html_safe unless value.nil? + value&.html_safe # rubocop:todo Rails/OutputSafety end end field :materials, :ck_editor do label do - "#{label}
Back To Top".html_safe + "#{label}
Back To Top".html_safe # rubocop:todo Rails/OutputSafety end pretty_value do - value.html_safe unless value.nil? + value&.html_safe # rubocop:todo Rails/OutputSafety end end field :optional_materials, :ck_editor do label do - "#{label}
Back To Top".html_safe + "#{label}
Back To Top".html_safe # rubocop:todo Rails/OutputSafety end pretty_value do - value.html_safe unless value.nil? + value&.html_safe # rubocop:todo Rails/OutputSafety end end field :age_range field :setup, :ck_editor do label do - "#{label}
Back To Top".html_safe + "#{label}
Back To Top".html_safe # rubocop:todo Rails/OutputSafety end pretty_value do - value.html_safe unless value.nil? + value&.html_safe # rubocop:todo Rails/OutputSafety end end field :introduction, :ck_editor do label do - "#{label}
Back To Top".html_safe + "#{label}
Back To Top".html_safe # rubocop:todo Rails/OutputSafety end pretty_value do - value.html_safe unless value.nil? + value&.html_safe # rubocop:todo Rails/OutputSafety end end field :time_intro do - label 'Time Frame Introduction' + label "Time Frame Introduction" end field :demonstration, :ck_editor do label do - "#{label}
Back To Top".html_safe + "#{label}
Back To Top".html_safe # rubocop:todo Rails/OutputSafety end pretty_value do - value.html_safe unless value.nil? + value&.html_safe # rubocop:todo Rails/OutputSafety end end field :time_demonstration do - label 'Time Frame Demo' + label "Time Frame Demo" end field :opening_circle, :ck_editor do @@ -188,12 +190,12 @@ class Workshop < ApplicationRecord "Opening
Back To Top".html_safe end pretty_value do - value.html_safe unless value.nil? + value&.html_safe # rubocop:todo Rails/OutputSafety end end field :time_opening do - label 'Time Frame Opening' + label "Time Frame Opening" end field :warm_up, :ck_editor do @@ -201,234 +203,234 @@ class Workshop < ApplicationRecord "Warm-up / Relaxation / Meditation
Back To Top".html_safe end pretty_value do - value.html_safe unless value.nil? + value&.html_safe # rubocop:todo Rails/OutputSafety end end field :time_warm_up do - label 'Time Frame Warm Up' + label "Time Frame Warm Up" end field :visualization, :ck_editor do label do - "#{label}
Back To Top".html_safe + "#{label}
Back To Top".html_safe # rubocop:todo Rails/OutputSafety end pretty_value do - value.html_safe unless value.nil? + value&.html_safe # rubocop:todo Rails/OutputSafety end end field :creation, :ck_editor do label do - "#{label}
Back To Top".html_safe + "#{label}
Back To Top".html_safe # rubocop:todo Rails/OutputSafety end pretty_value do - value.html_safe unless value.nil? + value&.html_safe # rubocop:todo Rails/OutputSafety end end field :time_creation do - label 'Time Frame Creation' + label "Time Frame Creation" end field :closing, :ck_editor do label do - "#{label}
Back To Top".html_safe + "#{label}
Back To Top".html_safe # rubocop:todo Rails/OutputSafety end pretty_value do - value.html_safe unless value.nil? + value&.html_safe # rubocop:todo Rails/OutputSafety end end field :time_closing do - label 'Time Frame Closing' + label "Time Frame Closing" end field :notes, :ck_editor do label do - "#{label}
Back To Top".html_safe + "#{label}
Back To Top".html_safe # rubocop:todo Rails/OutputSafety end pretty_value do - value.html_safe unless value.nil? + value&.html_safe # rubocop:todo Rails/OutputSafety end end field :tips, :ck_editor do label do - "#{label}
Back To Top".html_safe + "#{label}
Back To Top".html_safe # rubocop:todo Rails/OutputSafety end pretty_value do - value.html_safe unless value.nil? + value&.html_safe # rubocop:todo Rails/OutputSafety end end field :misc1, :ck_editor do label do - "#{label}
Back To Top".html_safe + "#{label}
Back To Top".html_safe # rubocop:todo Rails/OutputSafety end pretty_value do - value.html_safe unless value.nil? + value&.html_safe # rubocop:todo Rails/OutputSafety end end field :misc2, :ck_editor do label do - "#{label}
Back To Top".html_safe + "#{label}
Back To Top".html_safe # rubocop:todo Rails/OutputSafety end pretty_value do - value.html_safe unless value.nil? + value&.html_safe # rubocop:todo Rails/OutputSafety end end field :extra_field_spanish, :ck_editor do - label do - "#{label}
Back To Top".html_safe - end + label do + "#{label}
Back To Top".html_safe # rubocop:todo Rails/OutputSafety + end pretty_value do - value.html_safe unless value.nil? + value&.html_safe # rubocop:todo Rails/OutputSafety end end field :objective_spanish, :ck_editor do label do - "#{label}
Back To Top".html_safe + "#{label}
Back To Top".html_safe # rubocop:todo Rails/OutputSafety end pretty_value do - value.html_safe unless value.nil? + value&.html_safe # rubocop:todo Rails/OutputSafety end end field :materials_spanish, :ck_editor do label do - "#{label}
Back To Top".html_safe + "#{label}
Back To Top".html_safe # rubocop:todo Rails/OutputSafety end pretty_value do - value.html_safe unless value.nil? + value&.html_safe # rubocop:todo Rails/OutputSafety end end field :optional_materials_spanish, :ck_editor do label do - "#{label}
Back To Top".html_safe + "#{label}
Back To Top".html_safe # rubocop:todo Rails/OutputSafety end pretty_value do - value.html_safe unless value.nil? + value&.html_safe # rubocop:todo Rails/OutputSafety end end field :timeframe_spanish, :ck_editor do label do - "#{label}
Back To Top".html_safe + "#{label}
Back To Top".html_safe # rubocop:todo Rails/OutputSafety end pretty_value do - value.html_safe unless value.nil? + value&.html_safe # rubocop:todo Rails/OutputSafety end end field :age_range_spanish, :ck_editor do label do - "#{label}
Back To Top".html_safe + "#{label}
Back To Top".html_safe # rubocop:todo Rails/OutputSafety end pretty_value do - value.html_safe unless value.nil? + value&.html_safe # rubocop:todo Rails/OutputSafety end end field :setup_spanish, :ck_editor do label do - "#{label}
Back To Top".html_safe + "#{label}
Back To Top".html_safe # rubocop:todo Rails/OutputSafety end pretty_value do - value.html_safe unless value.nil? + value&.html_safe # rubocop:todo Rails/OutputSafety end end field :introduction_spanish, :ck_editor do label do - "#{label}
Back To Top".html_safe + "#{label}
Back To Top".html_safe # rubocop:todo Rails/OutputSafety end pretty_value do - value.html_safe unless value.nil? + value&.html_safe # rubocop:todo Rails/OutputSafety end end field :demonstration_spanish, :ck_editor do label do - "#{label}
Back To Top".html_safe + "#{label}
Back To Top".html_safe # rubocop:todo Rails/OutputSafety end pretty_value do - value.html_safe unless value.nil? + value&.html_safe # rubocop:todo Rails/OutputSafety end end field :opening_circle_spanish, :ck_editor do - label do + label do "Opening Spanish
Back To Top".html_safe end pretty_value do - value.html_safe unless value.nil? + value&.html_safe # rubocop:todo Rails/OutputSafety end end field :warm_up_spanish, :ck_editor do - label do - "Warm-up / Relaxation / Meditation Spanish
Back To Top".html_safe + label do + "Warm-up / Relaxation / Meditation Spanish
Back To Top".html_safe end pretty_value do - value.html_safe unless value.nil? + value&.html_safe # rubocop:todo Rails/OutputSafety end end field :visualization_spanish, :ck_editor do label do - "#{label}
Back To Top".html_safe + "#{label}
Back To Top".html_safe # rubocop:todo Rails/OutputSafety end pretty_value do - value.html_safe unless value.nil? + value&.html_safe # rubocop:todo Rails/OutputSafety end end field :creation_spanish, :ck_editor do label do - "#{label}
Back To Top".html_safe + "#{label}
Back To Top".html_safe # rubocop:todo Rails/OutputSafety end pretty_value do - value.html_safe unless value.nil? + value&.html_safe # rubocop:todo Rails/OutputSafety end end field :closing_spanish, :ck_editor do label do - "#{label}
Back To Top".html_safe + "#{label}
Back To Top".html_safe # rubocop:todo Rails/OutputSafety end pretty_value do - value.html_safe unless value.nil? + value&.html_safe # rubocop:todo Rails/OutputSafety end end field :notes_spanish, :ck_editor do label do - "#{label}
Back To Top".html_safe + "#{label}
Back To Top".html_safe # rubocop:todo Rails/OutputSafety end pretty_value do - value.html_safe unless value.nil? + value&.html_safe # rubocop:todo Rails/OutputSafety end end field :tips_spanish, :ck_editor do label do - "#{label}
Back To Top".html_safe + "#{label}
Back To Top".html_safe # rubocop:todo Rails/OutputSafety end pretty_value do - value.html_safe unless value.nil? + value&.html_safe # rubocop:todo Rails/OutputSafety end end field :misc1_spanish, :ck_editor do label do - "#{label}
Back To Top".html_safe + "#{label}
Back To Top".html_safe # rubocop:todo Rails/OutputSafety end pretty_value do - value.html_safe unless value.nil? + value&.html_safe # rubocop:todo Rails/OutputSafety end end field :misc2_spanish, :ck_editor do label do - "#{label}
Back To Top".html_safe + "#{label}
Back To Top".html_safe # rubocop:todo Rails/OutputSafety end pretty_value do - value.html_safe unless value.nil? + value&.html_safe # rubocop:todo Rails/OutputSafety end end @@ -457,7 +459,6 @@ class Workshop < ApplicationRecord field :spanish_anchors do visible false end - end list do @@ -468,7 +469,7 @@ class Workshop < ApplicationRecord end configure :title do - formatted_value{ bindings[:object].admin_title } + formatted_value { bindings[:object].admin_title } end field :english_anchors do visible false @@ -479,14 +480,24 @@ class Workshop < ApplicationRecord end end - exclude_fields :categorizable_items, :quotable_item_quotes, :timestamps, - :workshop_resources, :resources, :legacy_id, :workshop_age_ranges, - :workshop_logs, :metadata, :bookmarks, :user, :misc1, :misc2, :reports - + exclude_fields :categorizable_items, + :quotable_item_quotes, + :timestamps, + :workshop_resources, + :resources, + :legacy_id, + :workshop_age_ranges, + :workshop_logs, + :metadata, + :bookmarks, + :user, + :misc1, + :misc2, + :reports end def date - if month.nil? or year.nil? + if month.nil? || year.nil? "#{created_at.month}/#{created_at.year}" else "#{month}/#{year}" @@ -495,12 +506,12 @@ def date def self.search(params) workshops = all.order(:title) - workshops = workshops.search_by_categories( params[:categories] ).order(:title) if params[:categories] - workshops = workshops.search_by_sectors( params[:sectors] ).order(:title) if params[:sectors] + workshops = workshops.search_by_categories(params[:categories]).order(:title) if params[:categories] + workshops = workshops.search_by_sectors(params[:sectors]).order(:title) if params[:sectors] if params[:type] == "led" workshops = workshops.order(led_count: :desc) - elsif params[:type] and params[:type] != 'created' + elsif params[:type] && (params[:type] != "created") workshops = workshops.where(windows_type_id: params[:type].to_i).order(:title) type_sql = "AND windows_type_id = #{params[:type]}" end @@ -513,42 +524,47 @@ def self.search(params) FROM workshops WHERE MATCH ( #{cols} ) AGAINST ( '*#{params[:query]}*' IN BOOLEAN MODE ) #{type_sql} AND inactive is false ORDER BY title_score DESC;" - unless params[:query].blank? + if params[:query].present? workshops = workshops.find_by_sql(query_str) end - if params[:type] == 'created' - workshops = workshops.sort{|x,y| Date.parse(y.date) <=> Date.parse(x.date) } + if params[:type] == "created" + workshops = workshops.sort { |x, y| Date.parse(y.date) <=> Date.parse(x.date) } end workshops end def self.search_by_categories(categories) - categories = categories.map{|k,v| v} - citems = CategorizableItem.where(categorizable_type: "Workshop", - category_id: categories) + categories = categories.map { |_k, v| v } + citems = CategorizableItem.where( + categorizable_type: "Workshop", + category_id: categories, + ) - where(:id => citems.map{|ci| ci.categorizable_id} ) + where(id: citems.map(&:categorizable_id)) end def self.search_by_sectors(sectors) - sectors = sectors.map{|k,v| v} - sectorable_items = SectorableItem.where(sectorable_type: "Workshop", - sector_id: sectors) + sectors = sectors.map { |_k, v| v } + sectorable_items = SectorableItem.where( + sectorable_type: "Workshop", + sector_id: sectors, + ) - where( :id => sectorable_items.map{|si| si.sectorable_id} ) + where(id: sectorable_items.map(&:sectorable_id)) end def author_name return unless user + user.full_name end def workshop_log_fields if form_builder - form_builder.forms[0].form_fields.where('ordering is not null and status = 1'). - order(ordering: :desc).all + form_builder.forms[0].form_fields.where("ordering is not null and status = 1") + .order(ordering: :desc).all else [] end @@ -561,7 +577,7 @@ def form_builder end def windows_type_name - windows_type.name if windows_type + windows_type&.name end def related_workshops @@ -574,12 +590,13 @@ def self.grouped_by_sector def default_image_url ActionController::Base.helpers.asset_path( - 'workshop_default.jpg' + "workshop_default.jpg", ) end def rating - return 0 unless log_count > 0 + return 0 if log_count <= 0 + workshop_logs.sum(:rating) / log_count end @@ -597,56 +614,86 @@ def main_image_url def sector_hashtags sectors.map do |sector| - "\##{sector.name.split(' ')[0].downcase}" - end.join(',') + "##{sector.name.split(" ")[0].downcase}" + end.join(",") end def admin_title - "#{title} - #{windows_type.label if windows_type}" + "#{title} - #{windows_type&.label}" end def log_title - "#{title} #{windows_type.log_label if windows_type}" + "#{title} #{windows_type&.log_label}" end def communal_label(report) - "Workshop Title: #{title} - Workshop Date: #{report.date ? report.date.strftime('%m/%d/%y') : '[ EMPTY ]'}" + "Workshop Title: #{title} - Workshop Date: #{report.date ? report.date.strftime("%m/%d/%y") : "[ EMPTY ]"}" end def published_sectors - sectorable_items.where(inactive: false).map { |item| item.sector } + sectorable_items.where(inactive: false).map(&:sector) end def time_frame_total - total_time = time_intro.to_i + time_demonstration.to_i + - time_opening.to_i + time_warm_up.to_i + - time_creation.to_i + time_closing.to_i + total_time = time_intro.to_i + time_demonstration.to_i + + time_opening.to_i + time_warm_up.to_i + + time_creation.to_i + time_closing.to_i - return ("00:00") if total_time == 0 + return "00:00" if total_time == 0 - Time.at(total_time * 60).utc #.strftime("%H:%M") + Time.at(total_time * 60).utc # .strftime("%H:%M") end def set_time_frame - unless @time_hours.blank? and @time_minutes.blank? + if @time_hours.present? || @time_minutes.present? self.timeframe = "#{@time_hours}:#{@time_minutes}" end end def self.anchors_english_admin "".html_safe - %w(extra_field objective materials optional_materials setup - introduction demonstration opening_circle warm_up visualization creation - closing notes tips).map {|field| - "#{field.capitalize} |"}.join(" ").html_safe + [ + "extra_field", + "objective", + "materials", + "optional_materials", + "setup", + "introduction", + "demonstration", + "opening_circle", + "warm_up", + "visualization", + "creation", + "closing", + "notes", + "tips", + ].map do |field| + "#{field.capitalize} |" + end.join(" ").html_safe # rubocop:todo Rails/OutputSafety end - def self.anchors_spanish_admin - %w(extra_field_spanish objective_spanish materials_spanish optional_materials_spanish - timeframe_spanish age_range_spanish setup_spanish introduction_spanish - demonstration_spanish opening_circle_spanish warm_up_spanish visualization_spanish - creation_spanish closing_spanish notes_spanish tips_spanish misc1_spanish - misc2_spanish).map {|field| - "#{field.capitalize} |"}.join(" ").html_safe - end + def self.anchors_spanish_admin + [ + "extra_field_spanish", + "objective_spanish", + "materials_spanish", + "optional_materials_spanish", + "timeframe_spanish", + "age_range_spanish", + "setup_spanish", + "introduction_spanish", + "demonstration_spanish", + "opening_circle_spanish", + "warm_up_spanish", + "visualization_spanish", + "creation_spanish", + "closing_spanish", + "notes_spanish", + "tips_spanish", + "misc1_spanish", + "misc2_spanish", + ].map do |field| + "#{field.capitalize} |" + end.join(" ").html_safe # rubocop:todo Rails/OutputSafety + end end diff --git a/app/models/workshop_age_range.rb b/app/models/workshop_age_range.rb index f61bd4824..f167b1112 100644 --- a/app/models/workshop_age_range.rb +++ b/app/models/workshop_age_range.rb @@ -1,9 +1,11 @@ +# frozen_string_literal: true + class WorkshopAgeRange < ApplicationRecord attr_accessor :_create belongs_to :workshop belongs_to :age_range - validates_presence_of :workshop_id, :age_range_id - validates_uniqueness_of :workshop_id, scope: :age_range_id + validates :workshop_id, :age_range_id, presence: true + validates :workshop_id, uniqueness: { scope: :age_range_id } # rubocop:todo Rails/UniqueValidationWithoutIndex end diff --git a/app/models/workshop_idea.rb b/app/models/workshop_idea.rb index 6aea7d8aa..027618235 100644 --- a/app/models/workshop_idea.rb +++ b/app/models/workshop_idea.rb @@ -1,13 +1,14 @@ -class WorkshopIdea < Workshop +# frozen_string_literal: true +class WorkshopIdea < Workshop default_scope { where(inactive: true) } - # Rails Admin + # Rails Admin rails_admin do field :title field :created_at field :full_name do - label 'Author' + label "Author" end field :month @@ -15,202 +16,202 @@ class WorkshopIdea < Workshop field :featured field :objective, :ck_editor do pretty_value do - value.html_safe unless value.nil? + value&.html_safe # rubocop:todo Rails/OutputSafety end end field :materials, :ck_editor do pretty_value do - value.html_safe unless value.nil? + value&.html_safe # rubocop:todo Rails/OutputSafety end end field :optional_materials, :ck_editor do pretty_value do - value.html_safe unless value.nil? + value&.html_safe # rubocop:todo Rails/OutputSafety end end field :age_range field :setup, :ck_editor do pretty_value do - value.html_safe unless value.nil? + value&.html_safe # rubocop:todo Rails/OutputSafety end end field :introduction, :ck_editor do pretty_value do - value.html_safe unless value.nil? + value&.html_safe # rubocop:todo Rails/OutputSafety end end field :time_intro do - label 'Time Frame Introduction' + label "Time Frame Introduction" end field :demonstration, :ck_editor do pretty_value do - value.html_safe unless value.nil? + value&.html_safe # rubocop:todo Rails/OutputSafety end end field :time_demonstration do - label 'Time Frame Demo' + label "Time Frame Demo" end field :opening_circle, :ck_editor do pretty_value do - value.html_safe unless value.nil? + value&.html_safe # rubocop:todo Rails/OutputSafety end - label 'Opening' + label "Opening" end field :time_opening do - label 'Time Frame Opening' + label "Time Frame Opening" end field :warm_up, :ck_editor do pretty_value do - value.html_safe unless value.nil? + value&.html_safe # rubocop:todo Rails/OutputSafety end - label 'Warm-up / Relaxation / Meditation' + label "Warm-up / Relaxation / Meditation" end field :time_warm_up do - label 'Time Frame Warm Up' + label "Time Frame Warm Up" end field :visualization, :ck_editor do pretty_value do - value.html_safe unless value.nil? + value&.html_safe # rubocop:todo Rails/OutputSafety end end field :creation, :ck_editor do pretty_value do - value.html_safe unless value.nil? + value&.html_safe # rubocop:todo Rails/OutputSafety end end field :time_creation do - label 'Time Frame Creation' + label "Time Frame Creation" end field :closing, :ck_editor do pretty_value do - value.html_safe unless value.nil? + value&.html_safe # rubocop:todo Rails/OutputSafety end end field :time_closing do - label 'Time Frame Closing' + label "Time Frame Closing" end field :notes, :ck_editor do pretty_value do - value.html_safe unless value.nil? + value&.html_safe # rubocop:todo Rails/OutputSafety end end field :tips, :ck_editor do - pretty_value do - value.html_safe unless value.nil? + pretty_value do + value&.html_safe # rubocop:todo Rails/OutputSafety end end field :misc1, :ck_editor do pretty_value do - value.html_safe unless value.nil? + value&.html_safe # rubocop:todo Rails/OutputSafety end end field :misc2, :ck_editor do pretty_value do - value.html_safe unless value.nil? + value&.html_safe # rubocop:todo Rails/OutputSafety end end field :objective_spanish, :ck_editor do pretty_value do - value.html_safe unless value.nil? + value&.html_safe # rubocop:todo Rails/OutputSafety end end field :materials_spanish, :ck_editor do pretty_value do - value.html_safe unless value.nil? + value&.html_safe # rubocop:todo Rails/OutputSafety end end field :optional_materials_spanish, :ck_editor do pretty_value do - value.html_safe unless value.nil? + value&.html_safe # rubocop:todo Rails/OutputSafety end end field :timeframe_spanish, :ck_editor do pretty_value do - value.html_safe unless value.nil? + value&.html_safe # rubocop:todo Rails/OutputSafety end end field :age_range_spanish, :ck_editor do pretty_value do - value.html_safe unless value.nil? + value&.html_safe # rubocop:todo Rails/OutputSafety end end field :setup_spanish, :ck_editor do pretty_value do - value.html_safe unless value.nil? + value&.html_safe # rubocop:todo Rails/OutputSafety end end field :introduction_spanish, :ck_editor do pretty_value do - value.html_safe unless value.nil? + value&.html_safe # rubocop:todo Rails/OutputSafety end end field :demonstration_spanish, :ck_editor do pretty_value do - value.html_safe unless value.nil? + value&.html_safe # rubocop:todo Rails/OutputSafety end end field :opening_circle_spanish, :ck_editor do pretty_value do - value.html_safe unless value.nil? + value&.html_safe # rubocop:todo Rails/OutputSafety end - label 'Opening Spanish' + label "Opening Spanish" end field :warm_up_spanish, :ck_editor do pretty_value do - value.html_safe unless value.nil? + value&.html_safe # rubocop:todo Rails/OutputSafety end - label 'Warm-up / Relaxation / Meditation Spanish' + label "Warm-up / Relaxation / Meditation Spanish" end field :visualization_spanish, :ck_editor do pretty_value do - value.html_safe unless value.nil? + value&.html_safe # rubocop:todo Rails/OutputSafety end end field :creation_spanish, :ck_editor do pretty_value do - value.html_safe unless value.nil? + value&.html_safe # rubocop:todo Rails/OutputSafety end end field :closing_spanish, :ck_editor do pretty_value do - value.html_safe unless value.nil? + value&.html_safe # rubocop:todo Rails/OutputSafety end end field :notes_spanish, :ck_editor do pretty_value do - value.html_safe unless value.nil? + value&.html_safe # rubocop:todo Rails/OutputSafety end end field :tips_spanish, :ck_editor do pretty_value do - value.html_safe unless value.nil? + value&.html_safe # rubocop:todo Rails/OutputSafety end end field :misc1_spanish, :ck_editor do pretty_value do - value.html_safe unless value.nil? + value&.html_safe # rubocop:todo Rails/OutputSafety end end field :misc2_spanish, :ck_editor do pretty_value do - value.html_safe unless value.nil? + value&.html_safe # rubocop:todo Rails/OutputSafety end end @@ -242,14 +243,23 @@ class WorkshopIdea < Workshop end configure :title do - formatted_value{ bindings[:object].admin_title } + formatted_value { bindings[:object].admin_title } end end - exclude_fields :categorizable_items, :quotable_item_quotes, :timestamps, - :workshop_resources, :resources, :legacy_id, :workshop_age_ranges, - :workshop_logs, :metadata, :bookmarks, :user, :misc1, :misc2, :reports - + exclude_fields :categorizable_items, + :quotable_item_quotes, + :timestamps, + :workshop_resources, + :resources, + :legacy_id, + :workshop_age_ranges, + :workshop_logs, + :metadata, + :bookmarks, + :user, + :misc1, + :misc2, + :reports end - end diff --git a/app/models/workshop_log.rb b/app/models/workshop_log.rb index 07d49d4b3..d65e87e7c 100644 --- a/app/models/workshop_log.rb +++ b/app/models/workshop_log.rb @@ -1,9 +1,11 @@ +# frozen_string_literal: true + class WorkshopLog < Report belongs_to :workshop belongs_to :user belongs_to :project - has_many :media_files + has_many :media_files # rubocop:todo Rails/HasManyOrHasOneDependent # Callbacks after_save :update_workshop_log_count @@ -20,7 +22,7 @@ class WorkshopLog < Report field :id field :type field :workshop_name do - label 'owner' + label "owner" filterable true searchable true queryable true @@ -39,11 +41,11 @@ class WorkshopLog < Report end configure :workshop_name do - formatted_value{ bindings[:object].owner_title} + formatted_value { bindings[:object].owner_title } end configure :type do - formatted_value{ bindings[:object].type_title} + formatted_value { bindings[:object].type_title } end exclude_fields :type @@ -66,22 +68,22 @@ class WorkshopLog < Report field :media_files configure :adults_ongoing do - formatted_value{ bindings[:object].adults_ongoing} + formatted_value { bindings[:object].adults_ongoing } end configure :teens_ongoing do - formatted_value{ bindings[:object].teens_ongoing} + formatted_value { bindings[:object].teens_ongoing } end configure :children_ongoing do - formatted_value{ bindings[:object].children_ongoing} + formatted_value { bindings[:object].children_ongoing } end configure :adults_first_time do - formatted_value{ bindings[:object].adults_first_time} + formatted_value { bindings[:object].adults_first_time } end configure :teens_first_time do - formatted_value{ bindings[:object].teens_first_time} + formatted_value { bindings[:object].teens_first_time } end configure :children_first_time do - formatted_value{ bindings[:object].children_first_time} + formatted_value { bindings[:object].children_first_time } end exclude_fields :type @@ -104,37 +106,38 @@ class WorkshopLog < Report field :media_files configure :adults_ongoing do - formatted_value{ bindings[:object].adults_ongoing} + formatted_value { bindings[:object].adults_ongoing } end configure :teens_ongoing do - formatted_value{ bindings[:object].teens_ongoing} + formatted_value { bindings[:object].teens_ongoing } end configure :children_ongoing do - formatted_value{ bindings[:object].children_ongoing} + formatted_value { bindings[:object].children_ongoing } end configure :adults_first_time do - formatted_value{ bindings[:object].adults_first_time} + formatted_value { bindings[:object].adults_first_time } end configure :teens_first_time do - formatted_value{ bindings[:object].teens_first_time} + formatted_value { bindings[:object].teens_first_time } end configure :children_first_time do - formatted_value{ bindings[:object].children_first_time} + formatted_value { bindings[:object].children_first_time } end exclude_fields :type end - end def name return "" unless user - "#{user.name}" + + user.name.to_s end def workshop_title title = owner.nil? ? workshop_name : owner.title return "" unless title + title end @@ -142,7 +145,7 @@ def type_title if windows_type "#{windows_type.workshop_log_label} #{type}" else - "#{type}" + type.to_s end end @@ -152,41 +155,42 @@ def owner_title if !owner.nil? title = "#{workshop_title} - #{owner.windows_type.label}" - "#{title}".html_safe + "#{title}".html_safe # rubocop:todo Rails/OutputSafety else title = "#{workshop_title} - #{windows_type.label}" - "#{title}" + title.to_s end end def title workshop_title = owner.nil? ? workshop_name : owner.title return unless workshop_title + "Workshop Log - #{workshop_title}" end def num_ongoing - field_ids = FormField.where('question LIKE ? OR ?', '%on-going%', '%ongoing%') + field_ids = FormField.where("question LIKE ? OR ?", "%on-going%", "%ongoing%") report_form_field_answers.where(form_field_id: field_ids) .sum(:answer).to_i if field_ids.any? end def num_first_time - field_ids = FormField.where('question LIKE ?', '%first%') + field_ids = FormField.where("question LIKE ?", "%first%") report_form_field_answers.where(form_field_id: field_ids) .sum(:answer).to_i if field_ids.any? end def combined_num_ongoing(field_type) ongoing = "%Ongoing #{field_type}" - field_ids = FormField.where('question LIKE ?', "%#{ongoing}%") + field_ids = FormField.where("question LIKE ?", "%#{ongoing}%") report_form_field_answers.where(form_field_id: field_ids) .sum(:answer).to_i if field_ids.any? end def combined_num_first_time(field_type) first_time = "First-time #{field_type}" - field_ids = FormField.where('question LIKE ?', "%#{first_time}%") + field_ids = FormField.where("question LIKE ?", "%#{first_time}%") report_form_field_answers.where(form_field_id: field_ids) .sum(:answer).to_i if field_ids.any? end @@ -199,25 +203,23 @@ def form_builder def log_fields if form_builder - form_builder.forms[0].form_fields.where('ordering is not null and status = 1'). - order(ordering: :desc).all + form_builder.forms[0].form_fields.where("ordering is not null and status = 1") + .order(ordering: :desc).all else [] end end def date_label - date ? date.strftime('%m/%d/%Y') : created_at.strftime('%m/%d/%Y') + date ? date.strftime("%m/%d/%Y") : created_at.strftime("%m/%d/%Y") end private def update_workshop_log_count return unless owner + new_led_count = owner.workshop_logs.count owner.update(led_count: new_led_count) end - - protected - end diff --git a/app/models/workshop_resource.rb b/app/models/workshop_resource.rb index 5d0ec29ab..faf02b3ce 100644 --- a/app/models/workshop_resource.rb +++ b/app/models/workshop_resource.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class WorkshopResource < ApplicationRecord belongs_to :workshop belongs_to :resource diff --git a/app/models/workshop_variation.rb b/app/models/workshop_variation.rb index cd374389c..2109d2786 100644 --- a/app/models/workshop_variation.rb +++ b/app/models/workshop_variation.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class WorkshopVariation < ApplicationRecord belongs_to :workshop diff --git a/app/services/authentication_token.rb b/app/services/authentication_token.rb index 1bf605fb6..060b914bb 100644 --- a/app/services/authentication_token.rb +++ b/app/services/authentication_token.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class AuthenticationToken EXPIRY_TIME = -> { 2.weeks.from_now } @@ -5,8 +7,8 @@ def initialize(token) @token = token end - def self.generate_token(user_id, expiry=EXPIRY_TIME.call) - payload = {user_id: user_id, exp: expiry.to_i } + def self.generate_token(user_id, expiry = EXPIRY_TIME.call) + payload = { user_id: user_id, exp: expiry.to_i } new(JWT.encode(payload, Rails.application.secrets.secret_key_base)) end @@ -15,18 +17,16 @@ def to_s end def user_id - decode['user_id'] + decode["user_id"] end private def decode - begin - JWT.decode(@token, Rails.application.secrets.secret_key_base).first - rescue JWT::ExpiredSignature - raise AuthenticationFailed.new("Token Expired") - rescue JWT::DecodeError - raise AuthenticationFailed.new("Token Invalid") - end + JWT.decode(@token, Rails.application.secrets.secret_key_base).first + rescue JWT::ExpiredSignature + raise AuthenticationFailed, "Token Expired" + rescue JWT::DecodeError + raise AuthenticationFailed, "Token Invalid" end end diff --git a/app/services/search.rb b/app/services/search.rb index 224fcf00a..ea533dcdd 100644 --- a/app/services/search.rb +++ b/app/services/search.rb @@ -1,5 +1,8 @@ +# frozen_string_literal: true + class Search attr_accessor :params + def initialize end @@ -9,10 +12,10 @@ def search(params, user) klass = params[:type] ? params[:type].constantize : Workshop results = process_queries(klass, queries, user) perms = user.user_permissions_list - results = results.select { |r| - perms.include? r.windows_type.name - } - return sort(results, klass) + results = results.select do |r| + perms.include?(r.windows_type.name) + end + sort(results, klass) end private @@ -22,8 +25,8 @@ def process_queries(klass, queries, user) if queries.any? queries.each do |query| - category = Category.find_by_name(query) - sector = Sector.find_by_name(query) + category = Category.find_by(name: query) + sector = Sector.find_by(name: query) if category results << category.workshops.for_search @@ -40,18 +43,20 @@ def process_queries(klass, queries, user) end def sort(objects, klass) - return objects unless objects.any? - sort_bys = sortable_params.select { |k, v| v == '1' }.keys + return objects if objects.none? - return objects unless sort_bys.any? - sorted = sort_bys.map(&:to_sym).map do |sort_by| + sort_bys = sortable_params.select { |_k, v| v == "1" }.keys + + return objects if sort_bys.none? + + sorted = sort_bys.map(&:to_sym).map do |sort_by| objects & klass.send("by_#{sort_by}") end sort_flat = sorted.flatten.uniq(&:title) - sort_flat.sort_by!(&:led_count).reverse! if sort_flat.any? && sort_flat[0].send(:led_count) && sort_bys.include?('led_count') - sort_flat.sort_by!(&:rating).reverse! if sort_flat.any? && sort_flat[0].class == Workshop && sort_flat[0].send(:rating) && sort_bys.include?('rating') + sort_flat.sort_by!(&:led_count).reverse! if sort_flat.any? && sort_flat[0].send(:led_count) && sort_bys.include?("led_count") + sort_flat.sort_by!(&:rating).reverse! if sort_flat.any? && sort_flat[0].class == Workshop && sort_flat[0].send(:rating) && sort_bys.include?("rating") sort_flat end @@ -62,13 +67,14 @@ def sortable_params def process_params(params) queries = [] params.each do |param, value| - next if value.empty? || value == '0' || forbidden_params.include?(param) - param == 'query' ? queries << value : queries << param + next if value.empty? || value == "0" || forbidden_params.include?(param) + + queries << (param == "query" ? value : param) end queries end def forbidden_params - ['sort_by', 'type', 'sortable_items', 'page', 'view_all'] + ["sort_by", "type", "sortable_items", "page", "view_all"] end end diff --git a/config.ru b/config.ru index bd83b2541..89bfd0b24 100644 --- a/config.ru +++ b/config.ru @@ -1,4 +1,6 @@ +# frozen_string_literal: true + # This file is used by Rack-based servers to start the application. -require ::File.expand_path('../config/environment', __FILE__) +require File.expand_path("../config/environment", __FILE__) run Rails.application diff --git a/lib/paperclip_attachment.rb b/lib/paperclip_attachment.rb index 5b41d1b72..9244fe910 100644 --- a/lib/paperclip_attachment.rb +++ b/lib/paperclip_attachment.rb @@ -1,18 +1,19 @@ -require 'paperclip' +# frozen_string_literal: true + +require "paperclip" module Paperclip class Attachment alias_method :orig_url, :url def url(*args) - unless orig_url(*args).start_with? 'https' - if orig_url(*args).start_with? 'http' - orig_url(*args).gsub("http:", "https:") + unless orig_url(*args).start_with?("https") + if orig_url(*args).start_with?("http") + orig_url(*args).gsub("http:", "https:") else orig_url(*args) end end - end end end diff --git a/lib/rails_admin/duplicate.rb b/lib/rails_admin/duplicate.rb index 9c7db8773..e73d6bac6 100644 --- a/lib/rails_admin/duplicate.rb +++ b/lib/rails_admin/duplicate.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # lib/rails_admin/duplicate.rb module RailsAdmin @@ -13,7 +15,7 @@ class Duplicate < RailsAdmin::Config::Actions::Base true end register_instance_option :link_icon do - 'icon-file' + "icon-file" end # You may or may not want pjax for your action register_instance_option :pjax? do @@ -23,11 +25,11 @@ class Duplicate < RailsAdmin::Config::Actions::Base [:get, :post] end register_instance_option :controller do - Proc.new do + proc do if request.post? @workshop = Workshop.new(@object.attributes.except("id", "created_at", "updated_at")) - @object.categories.each do |category| + @object.categories.each do |_category| @workshop.categories = @object.categories end @@ -39,7 +41,6 @@ class Duplicate < RailsAdmin::Config::Actions::Base @workshop.images << image.dup end - @object.workshop_variations.each do |wv| @workshop.workshop_variations << wv.dup end @@ -48,19 +49,19 @@ class Duplicate < RailsAdmin::Config::Actions::Base @images_copied = @workshop.images @object.images.each do |image| - image_to_copy = @images_copied.where(:file_file_name => image.file_file_name ).first + image_to_copy = @images_copied.where(file_file_name: image.file_file_name).first - if !image_to_copy.nil? - image.file.s3_object.copy_to(image_to_copy.file.s3_object, {acl: :public_read}) - image_to_copy.file.reprocess! :thumb + unless image_to_copy.nil? + image.file.s3_object.copy_to(image_to_copy.file.s3_object, { acl: :public_read }) + image_to_copy.file.reprocess!(:thumb) end end - if !@object.thumbnail.path.nil? - @object.thumbnail.s3_object.copy_to(@workshop.thumbnail.s3_object, {acl: :public_read}) + unless @object.thumbnail.path.nil? + @object.thumbnail.s3_object.copy_to(@workshop.thumbnail.s3_object, { acl: :public_read }) end - if !@object.header.path.nil? - @object.header.s3_object.copy_to(@workshop.header.s3_object, {acl: :public_read}) + unless @object.header.path.nil? + @object.header.s3_object.copy_to(@workshop.header.s3_object, { acl: :public_read }) end redirect_to back_or_index diff --git a/lib/tasks/reorder-monthly-report-fields.rake b/lib/tasks/reorder_monthly_report_fields.rake similarity index 50% rename from lib/tasks/reorder-monthly-report-fields.rake rename to lib/tasks/reorder_monthly_report_fields.rake index 2e2ddf06f..f8011ca26 100644 --- a/lib/tasks/reorder-monthly-report-fields.rake +++ b/lib/tasks/reorder_monthly_report_fields.rake @@ -1,10 +1,15 @@ -namespace :monthly_report do +# frozen_string_literal: true - task :reorder => :environment do - questions = ["If this is a quote or story from a participant please indicate the following", - "Age", "Gender Identity", "Service Population"] +namespace :monthly_report do + task reorder: :environment do + questions = [ + "If this is a quote or story from a participant please indicate the following", + "Age", + "Gender Identity", + "Service Population", + ] - forms = FormBuilder.where('name LIKE ?', '%Monthly Report%') + forms = FormBuilder.where("name LIKE ?", "%Monthly Report%") forms.each do |form| questions.each do |q| @@ -17,7 +22,7 @@ namespace :monthly_report do forms.each do |form| print "U" field = form.form_fields.find_by(question: "Any challenges you'd like to share from this month") - field.update(question: "Share challenges for this month") unless field.nil? + field&.update(question: "Share challenges for this month") end end end diff --git a/lib/tasks/setup.rake b/lib/tasks/setup.rake index 6700bcc2a..d1e841b91 100644 --- a/lib/tasks/setup.rake +++ b/lib/tasks/setup.rake @@ -1,22 +1,32 @@ +# frozen_string_literal: true + namespace :db do namespace :seed do - - desc 'Import Legacy Data' - task :import_legacy_data => :environment do |task, arguments| + desc "Import Legacy Data" + task import_legacy_data: :environment do |_task, _arguments| [ - :create_defaults, :import_workshops, :import_categories, - :import_workshop_categories, :import_users, :import_projects, - :import_project_users, :import_faqs, :import_quotes, - :import_workshop_quotes, :import_workshop_variations, - :import_leader_spotlights, :import_workshop_leader_spotlights, - :import_workshop_favorites, :import_user_permissions + :create_defaults, + :import_workshops, + :import_categories, + :import_workshop_categories, + :import_users, + :import_projects, + :import_project_users, + :import_faqs, + :import_quotes, + :import_workshop_quotes, + :import_workshop_variations, + :import_leader_spotlights, + :import_workshop_leader_spotlights, + :import_workshop_favorites, + :import_user_permissions, ].each do |task| Rake::Task["db:seed:#{task}"].invoke end end - desc 'Create Defaults' - task :create_defaults => :environment do + desc "Create Defaults" + task create_defaults: :environment do ProjectObligation.create_defaults ProjectStatus.create_defaults WindowsType.create_defaults @@ -24,175 +34,174 @@ namespace :db do Permission.create_defaults end - desc 'Import Legacy Users' - task :import_users => :environment do - CSV.foreach(full_filepath('users.csv'), headers: true) do |row| + desc "Import Legacy Users" + task import_users: :environment do + CSV.foreach(full_filepath("users.csv"), headers: true) do |row| create_user(row) end end - desc 'Import Project Users' - task :import_project_users => :environment do - xml = open_as_xml(full_filepath('project_users.xml')) + desc "Import Project Users" + task import_project_users: :environment do + xml = open_as_xml(full_filepath("project_users.xml")) process_xml_rows(xml, :create_project_user) end - desc 'Import Legacy Workshops' - task :import_workshops => :environment do |task, arguments| - xml = open_as_xml(full_filepath('workshops.xml')) + desc "Import Legacy Workshops" + task import_workshops: :environment do |_task, _arguments| + xml = open_as_xml(full_filepath("workshops.xml")) process_xml_rows(xml, :create_workshop) end - desc 'Import Categories' - task :import_categories => :environment do |task, arguments| + desc "Import Categories" + task import_categories: :environment do |_task, _arguments| categories_filepaths.each do |metadatum_name, filepath| xml = open_as_xml(full_filepath(filepath)) process_xml_rows(xml, :create_category, metadatum_name) end end - desc 'Import Workshop Categories' - task :import_workshop_categories => :environment do |task, args| + desc "Import Workshop Categories" + task import_workshop_categories: :environment do |_task, _args| categories_filepaths.each do |metadatum_name, filepath| xml = open_as_xml(full_filepath("workshop_#{filepath}")) process_xml_rows(xml, :create_workshop_category, metadatum_name) end end - desc 'Import projects' - task :import_projects => :environment do |task, args| - CSV.foreach(full_filepath('projects.csv'), headers: true) do |row| - next unless row['str_name'] + desc "Import projects" + task import_projects: :environment do |_task, _args| + CSV.foreach(full_filepath("projects.csv"), headers: true) do |row| + next unless row["str_name"] + create_project(row) end end - desc 'Import quotes' - task :import_quotes => :environment do - CSV.foreach(full_filepath('quotes.csv'), headers: true) do |row| + desc "Import quotes" + task import_quotes: :environment do + CSV.foreach(full_filepath("quotes.csv"), headers: true) do |row| create_quote(row) end end - desc 'Import workshop quotes' - task :import_workshop_quotes => :environment do - xml = open_as_xml(full_filepath('workshop_quotes.xml')) + desc "Import workshop quotes" + task import_workshop_quotes: :environment do + xml = open_as_xml(full_filepath("workshop_quotes.xml")) process_xml_rows(xml, :create_workshop_quote) end - desc 'import faqs' - task :import_faqs => :environment do - xml = open_as_xml(full_filepath('faq.xml')) + desc "import faqs" + task import_faqs: :environment do + xml = open_as_xml(full_filepath("faq.xml")) process_xml_rows(xml, :create_faq) end - desc 'import workshop variations' - task :import_workshop_variations => :environment do - xml = open_as_xml(full_filepath('workshop_variations.xml')) + desc "import workshop variations" + task import_workshop_variations: :environment do + xml = open_as_xml(full_filepath("workshop_variations.xml")) process_xml_rows(xml, :create_workshop_variation) end - desc 'import leader spotlights' - task :import_leader_spotlights => :environment do - xml = open_as_xml(full_filepath('leader_spotlights.xml')) + desc "import leader spotlights" + task import_leader_spotlights: :environment do + xml = open_as_xml(full_filepath("leader_spotlights.xml")) process_xml_rows(xml, :create_leader_spotlight) end - desc 'import workshop leader spotlights' - task :import_workshop_leader_spotlights => :environment do - xml = open_as_xml(full_filepath('workshop_leader_spotlights.xml')) + desc "import workshop leader spotlights" + task import_workshop_leader_spotlights: :environment do + xml = open_as_xml(full_filepath("workshop_leader_spotlights.xml")) process_xml_rows(xml, :create_workshop_leader_spotlight) end - desc 'import workshop favorites' - task :import_workshop_favorites => :environment do - CSV.foreach(full_filepath('workshop_favorites.csv'), headers: true) do |row| + desc "import workshop favorites" + task import_workshop_favorites: :environment do + CSV.foreach(full_filepath("workshop_favorites.csv"), headers: true) do |row| create_workshop_favorite(row) end end - desc 'import user permissions' - task :import_user_permissions => :environment do - xml = open_as_xml(full_filepath('user_permissions.xml')) + desc "import user permissions" + task import_user_permissions: :environment do + xml = open_as_xml(full_filepath("user_permissions.xml")) process_xml_rows(xml, :create_user_permission) end - desc 'import legacy workshop images' - task :import_workshop_images => :environment do + desc "import legacy workshop images" + task import_workshop_images: :environment do Workshop.legacy.each do |workshop| workshop.images.destroy_all - images = Nokogiri::HTML(workshop.objective).css('img') + images = Nokogiri::HTML(workshop.objective).css("img") images.to_a.each do |image| - begin - pathname = image.attributes['src'].value - next if pathname.include?('transparent') || pathname.include?('https') #yields error - uri = pathname.include?('http') ? pathname : "http://awbw.org#{pathname}" - workshop.images.create(file: open(uri)) - rescue OpenURI::HTTPError => e - end + pathname = image.attributes["src"].value + next if pathname.include?("transparent") || pathname.include?("https") # yields error + + uri = pathname.include?("http") ? pathname : "http://awbw.org#{pathname}" + workshop.images.create(file: open(uri)) # rubocop:todo Security/Open + rescue OpenURI::HTTPError # rubocop:todo Lint/SuppressedException end end end end end -private - def create_project_user(xml, _name = nil) - user = User.find_by_legacy_id(search_for_value(xml, 'userid')) - project = Project.find_by_legacy_id(search_for_value(xml, 'projectid')) + user = User.find_by(legacy_id: search_for_value(xml, "userid")) + project = Project.find_by(legacy_id: search_for_value(xml, "projectid")) return unless user && project + ProjectUser.find_or_create_by( user: user, project: project, - position: search_for_value(xml, 'num_position'), - filemaker_code: search_for_value(xml, 'str_filemakercode') + position: search_for_value(xml, "num_position"), + filemaker_code: search_for_value(xml, "str_filemakercode"), ) end def create_project(project) - ProjectStatus.create_defaults unless ProjectStatus.any? - start_date = project['dte_start'] unless project['dte_start'] == '0000-00-00' - end_date = project['dte_end'] unless project['dte_end'] == '0000-00-00' - window_id = project['windowstypeid'].to_i + ProjectStatus.create_defaults if ProjectStatus.none? + start_date = project["dte_start"] unless project["dte_start"] == "0000-00-00" + end_date = project["dte_end"] unless project["dte_end"] == "0000-00-00" + window_id = project["windowstypeid"].to_i if (1..3).include?(window_id) - windows_type_id = windows_type_id(project['windowstypeid']) + windows_type_id = windows_type_id(project["windowstypeid"]) end - project = Project.find_or_create_by( - legacy_id: project['id'], - name: project['str_name'].slice(0, 255), + Project.find_or_create_by( + legacy_id: project["id"], + name: project["str_name"].slice(0, 255), windows_type_id: windows_type_id, start_date: start_date, end_date: end_date, - locality: project['str_locality'], - description: project['txt_description'], - notes: project['txt_notes'], - filemaker_code: project['str_filemakercode'], - inactive: project['bln_inactive'], + locality: project["str_locality"], + description: project["txt_description"], + notes: project["txt_notes"], + filemaker_code: project["str_filemakercode"], + inactive: project["bln_inactive"], legacy: true, - project_status_id: project['statusid'] + project_status_id: project["statusid"], ) end def categories_filepaths { - 'ArtType' => 'art_types.xml', - 'AgeRange' => 'age_ranges.xml', - 'EmotionalTheme' => 'emotional_themes.xml', - 'HolidayTheme' => 'holiday_themes.xml', - 'Strength' => 'strengths.xml' + "ArtType" => "art_types.xml", + "AgeRange" => "age_ranges.xml", + "EmotionalTheme" => "emotional_themes.xml", + "HolidayTheme" => "holiday_themes.xml", + "Strength" => "strengths.xml", } end -def process_xml_rows(xml, method, _name = nil) - xml.search('Row').each do |row| +def process_xml_rows(xml, method, _name = nil) # rubocop:todo Lint/UnderscorePrefixedVariableName + xml.search("Row").each do |row| send(method, row, _name) end end def full_filepath(filepath) - Rails.root.join('db', 'seeds', filepath) + Rails.root.join("db", "seeds", filepath) end def open_as_xml(file) @@ -201,57 +210,57 @@ end def create_category(xml, metadatum_name) Category.find_or_create_by( - legacy_id: search_for_value(xml, 'id'), + legacy_id: search_for_value(xml, "id"), metadatum: Metadatum.find_or_create_by(name: metadatum_name), - name: search_for_value(xml, 'str_name') + name: search_for_value(xml, "str_name"), ) end def create_workshop_category(xml, metadatum_name) - workshop = Workshop.find_by(legacy_id: search_for_value(xml, 'workshopid')) + workshop = Workshop.find_by(legacy_id: search_for_value(xml, "workshopid")) metadatum = Metadatum.find_by(name: metadatum_name) category = Category.find_by( metadatum: metadatum, legacy_id: search_for_value( xml, "#{metadatum_name.downcase}id" - ) + ), ) return unless workshop && category CategorizableItem.find_or_create_by( - legacy_id: search_for_value(xml, 'id'), + legacy_id: search_for_value(xml, "id"), categorizable: workshop, - category: category + category: category, ) end - def create_workshop(xml, _name = nil) - return if xml.search('str_title')[0].content == "\n delete \n" + return if xml.search("str_title")[0].content == "\n delete \n" + Workshop.find_or_create_by( - legacy_id: search_for_value(xml, 'id'), - title: search_for_value(xml, 'str_title'), - author_first_name: search_for_value(xml, 'str_author_firstname'), - author_last_name: search_for_value(xml, 'str_author_lastname'), - author_location: search_for_value(xml, 'str_author_location'), - windows_type_id: windows_type_id(search_for_value(xml, 'windowstypeid')), - month: search_for_value(xml, 'num_month'), - year: search_for_value(xml, 'num_year'), - objective: search_for_value(xml, 'txt_code'), - description: search_for_value(xml, 'txt_description'), - notes: search_for_value(xml, 'txt_notes'), - tips: search_for_value(xml, 'txt_tips'), - pub_issue: search_for_value(xml, 'str_pub_issue'), - misc1: search_for_value(xml, 'str_misc1'), - misc2: search_for_value(xml, 'str_misc2'), - filemaker_code: search_for_value(xml, 'str_filemakercode'), - inactive: search_for_value(xml, 'bln_inactive'), - searchable: search_for_value(xml, 'bln_searchable'), + legacy_id: search_for_value(xml, "id"), + title: search_for_value(xml, "str_title"), + author_first_name: search_for_value(xml, "str_author_firstname"), + author_last_name: search_for_value(xml, "str_author_lastname"), + author_location: search_for_value(xml, "str_author_location"), + windows_type_id: windows_type_id(search_for_value(xml, "windowstypeid")), + month: search_for_value(xml, "num_month"), + year: search_for_value(xml, "num_year"), + objective: search_for_value(xml, "txt_code"), + description: search_for_value(xml, "txt_description"), + notes: search_for_value(xml, "txt_notes"), + tips: search_for_value(xml, "txt_tips"), + pub_issue: search_for_value(xml, "str_pub_issue"), + misc1: search_for_value(xml, "str_misc1"), + misc2: search_for_value(xml, "str_misc2"), + filemaker_code: search_for_value(xml, "str_filemakercode"), + inactive: search_for_value(xml, "bln_inactive"), + searchable: search_for_value(xml, "bln_searchable"), legacy: true, featured: false, - created_at: search_for_value(xml, 'ts_create').to_datetime + created_at: search_for_value(xml, "ts_create").to_datetime, # rubocop:todo Style/DateTime ) end @@ -261,133 +270,137 @@ def search_for_value(xml, endpoint) end def create_user(row) - return unless row['str_email'] || User.find_by_email(row['str_email']) + return unless row["str_email"] || User.find_by(email: row["str_email"]) + user = User.new( - legacy_id: row['id'], - email: row['str_email'], - first_name: row['str_firstname'], - last_name: row['str_lastname'], - phone: row['str_phone'], - address: row['str_address1'], - city: row['str_city'], - state: row['str_state'], - zip: row['str_zip'], - birthday: row['dte_birthday'], - subscribecode: row['str_subscribecode'], - inactive: row['bln_inactive'], - confirmed: row['bln_confirmed'], - comment: row['txt_user_comment'], - notes: row['txt_notes'], - password: row['str_password'], - legacy: true + legacy_id: row["id"], + email: row["str_email"], + first_name: row["str_firstname"], + last_name: row["str_lastname"], + phone: row["str_phone"], + address: row["str_address1"], + city: row["str_city"], + state: row["str_state"], + zip: row["str_zip"], + birthday: row["dte_birthday"], + subscribecode: row["str_subscribecode"], + inactive: row["bln_inactive"], + confirmed: row["bln_confirmed"], + comment: row["txt_user_comment"], + notes: row["txt_notes"], + password: row["str_password"], + legacy: true, ) user.save end def create_quote(row) Quote.find_or_create_by( - quote: row['str_quote'], - inactive: row['bln_inactive'], - legacy_id: row['id'], - legacy: true + quote: row["str_quote"], + inactive: row["bln_inactive"], + legacy_id: row["id"], + legacy: true, ) end def create_workshop_quote(xml, _name = nil) - workshop = Workshop.find_by_legacy_id(search_for_value(xml, 'workshopid')) - quote = Quote.find_by_legacy_id(search_for_value(xml, 'quoteid')) + workshop = Workshop.find_by(legacy_id: search_for_value(xml, "workshopid")) + quote = Quote.find_by(legacy_id: search_for_value(xml, "quoteid")) return unless workshop && quote + QuotableItemQuote.find_or_create_by( - legacy_id: search_for_value(xml, 'id'), + legacy_id: search_for_value(xml, "id"), quotable: workshop, - quote: quote + quote: quote, ) end def create_faq(xml, _name = nil) Faq.find_or_create_by( - question: search_for_value(xml, 'str_question'), - answer: search_for_value(xml, 'txt_answer'), - ordering: search_for_value(xml, 'ordering'), - inactive: search_for_value(xml, 'bln_inactive') + question: search_for_value(xml, "str_question"), + answer: search_for_value(xml, "txt_answer"), + ordering: search_for_value(xml, "ordering"), + inactive: search_for_value(xml, "bln_inactive"), ) end def create_workshop_variation(xml, _name = nil) - legacy_id = search_for_value(xml, 'workshopid') - workshop = Workshop.find_by_legacy_id(legacy_id) + legacy_id = search_for_value(xml, "workshopid") + workshop = Workshop.find_by(legacy_id: legacy_id) return unless workshop - variation = workshop.workshop_variations.find_or_create_by( + + workshop.workshop_variations.find_or_create_by( legacy: true, - name: search_for_value(xml, 'str_name'), - code: search_for_value(xml, 'txt_code'), - inactive: search_for_value(xml, 'bln_inactive'), - ordering: search_for_value(xml, 'ordering'), + name: search_for_value(xml, "str_name"), + code: search_for_value(xml, "txt_code"), + inactive: search_for_value(xml, "bln_inactive"), + ordering: search_for_value(xml, "ordering"), ) end def create_leader_spotlight(xml, _name = nil) leader_spotlight = LeaderSpotlight.find_or_create_by( - title: search_for_value(xml, 'str_headline'), - author: search_for_value(xml, 'str_name'), - agency: search_for_value(xml, 'str_agency'), - text: search_for_value(xml, 'txt_code'), - ordering: search_for_value(xml, 'ordering'), - inactive: search_for_value(xml, 'bln_inactive'), - filemaker_code: search_for_value(xml, 'str_filemakercode'), - windows_type_id: windows_type_id(search_for_value(xml, 'windowstypeid')), + title: search_for_value(xml, "str_headline"), + author: search_for_value(xml, "str_name"), + agency: search_for_value(xml, "str_agency"), + text: search_for_value(xml, "txt_code"), + ordering: search_for_value(xml, "ordering"), + inactive: search_for_value(xml, "bln_inactive"), + filemaker_code: search_for_value(xml, "str_filemakercode"), + windows_type_id: windows_type_id(search_for_value(xml, "windowstypeid")), legacy: true, - legacy_id: search_for_value(xml, 'id') + legacy_id: search_for_value(xml, "id"), ) leader_spotlight.images.destroy_all if leader_spotlight.images.any? - image = open("http://awbw.org#{search_for_value(xml, 'str_pic')}") + image = open("http://awbw.org#{search_for_value(xml, "str_pic")}") leader_spotlight.images.create(file: image) - rescue OpenURI::HTTPError +rescue OpenURI::HTTPError # rubocop:todo Lint/SuppressedException end def create_workshop_leader_spotlight(xml, _name = nil) - workshop = Workshop.find_by_legacy_id(search_for_value(xml, 'workshopid')) - leader_spotlight = LeaderSpotlight.find_by_legacy_id(search_for_value(xml, 'leaderspotlightid')) + workshop = Workshop.find_by(legacy_id: search_for_value(xml, "workshopid")) + leader_spotlight = LeaderSpotlight.find_by(legacy_id: search_for_value(xml, "leaderspotlightid")) return unless workshop && leader_spotlight WorkshopResource.find_or_create_by( workshop: workshop, - resource: leader_spotlight + resource: leader_spotlight, ) end def create_workshop_favorite(row) - workshop = Workshop.find_by_legacy_id(row['workshopid']) - user = User.find_by_legacy_id(row['userid']) + workshop = Workshop.find_by(legacy_id: row["workshopid"]) + user = User.find_by(legacy_id: row["userid"]) return unless workshop && user workshop.led_count += 1 workshop.save user.bookmarks.find_or_create_by( - bookmarkable: workshop + bookmarkable: workshop, ) end def windows_type_id(legacy_id) WindowsType.find_by( - legacy_id: legacy_id + legacy_id: legacy_id, ).id end def create_user_permission(xml, _name = nil) - Permission.create_defaults unless Permission.any? + Permission.create_defaults if Permission.none? - user = User.find_by_legacy_id(search_for_value(xml, 'userid')) - permission = Permission.find_by_legacy_id(search_for_value(xml, 'security_categoryid')) + user = User.find_by(legacy_id: search_for_value(xml, "userid")) + permission = Permission.find_by(legacy_id: search_for_value(xml, "security_categoryid")) return unless user && permission + UserPermission.find_or_create_by( user: user, - permission: permission + permission: permission, ) end diff --git a/mise.toml b/mise.toml index 5d80ff8d1..931b86328 100644 --- a/mise.toml +++ b/mise.toml @@ -47,3 +47,11 @@ run = "docker compose exec web" [tasks.docker-spec] description = "Run RSpec tests in Docker" run = "docker compose exec -e RAILS_ENV=test web bundle exec rspec" + +[tasks.lint] +description = "Run RuboCop linting (use -a to auto-correct)" +run = "bundle exec rubocop" + +[tasks.docker-lint] +description = "Run RuboCop linting in Docker (use -a to auto-correct)" +run = "docker compose exec web bundle exec rubocop" diff --git a/spec/factories/admins.rb b/spec/factories/admins.rb index 84acf4bfc..6fe850f88 100644 --- a/spec/factories/admins.rb +++ b/spec/factories/admins.rb @@ -1,7 +1,9 @@ +# frozen_string_literal: true + FactoryBot.define do factory :admin do email { Faker::Internet.unique.email } - password { 'password' } - password_confirmation { 'password' } + password { "password" } + password_confirmation { "password" } end -end \ No newline at end of file +end diff --git a/spec/factories/age_ranges.rb b/spec/factories/age_ranges.rb index 988f73ef8..21824758e 100644 --- a/spec/factories/age_ranges.rb +++ b/spec/factories/age_ranges.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + FactoryBot.define do factory :age_range do name { "6-12" } diff --git a/spec/factories/answer_options.rb b/spec/factories/answer_options.rb index 773c38118..eb9118bac 100644 --- a/spec/factories/answer_options.rb +++ b/spec/factories/answer_options.rb @@ -1,6 +1,8 @@ +# frozen_string_literal: true + FactoryBot.define do factory :answer_option do name { "Option Text" } order { 1 } end -end \ No newline at end of file +end diff --git a/spec/factories/attachments.rb b/spec/factories/attachments.rb index 3a79e2e90..652506d7d 100644 --- a/spec/factories/attachments.rb +++ b/spec/factories/attachments.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + FactoryBot.define do factory :attachment do # Polymorphic association: belongs_to :owner @@ -15,4 +17,4 @@ # A minimal factory might skip the file if not strictly needed for validation # or associate with a pre-existing owner if that's sufficient for the test. end -end \ No newline at end of file +end diff --git a/spec/factories/banners.rb b/spec/factories/banners.rb index 64ddead39..a72c2283e 100644 --- a/spec/factories/banners.rb +++ b/spec/factories/banners.rb @@ -1,5 +1,7 @@ +# frozen_string_literal: true + FactoryBot.define do factory :banner do content { "This is the banner content." } end -end \ No newline at end of file +end diff --git a/spec/factories/bookmark_annotations.rb b/spec/factories/bookmark_annotations.rb index 762b294b7..03f044e92 100644 --- a/spec/factories/bookmark_annotations.rb +++ b/spec/factories/bookmark_annotations.rb @@ -1,7 +1,9 @@ +# frozen_string_literal: true + FactoryBot.define do factory :bookmark_annotation do association :bookmark annotation { { note: "This is an annotation." }.to_json } end -end \ No newline at end of file +end diff --git a/spec/factories/bookmarks.rb b/spec/factories/bookmarks.rb index 589ca78de..8d4e892d4 100644 --- a/spec/factories/bookmarks.rb +++ b/spec/factories/bookmarks.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + FactoryBot.define do factory :bookmark do # Association: belongs_to :user @@ -9,4 +11,4 @@ # Add other attributes if any (e.g., created_at, updated_at are handled by Rails) end -end \ No newline at end of file +end diff --git a/spec/factories/categories.rb b/spec/factories/categories.rb index 49256bc7b..92527966d 100644 --- a/spec/factories/categories.rb +++ b/spec/factories/categories.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + FactoryBot.define do factory :category do # Needs a unique name @@ -7,4 +9,4 @@ # Association: belongs_to :metadatum association :metadatum end -end \ No newline at end of file +end diff --git a/spec/factories/categorizable_items.rb b/spec/factories/categorizable_items.rb index 83c0993dc..7969c3265 100644 --- a/spec/factories/categorizable_items.rb +++ b/spec/factories/categorizable_items.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + FactoryBot.define do factory :categorizable_item do # Association: belongs_to :category @@ -7,4 +9,4 @@ # Needs a categorizable instance, e.g., a Workshop association :categorizable, factory: :workshop end -end \ No newline at end of file +end diff --git a/spec/factories/faqs.rb b/spec/factories/faqs.rb index 9a1c7fa82..6460be47d 100644 --- a/spec/factories/faqs.rb +++ b/spec/factories/faqs.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + FactoryBot.define do factory :faq do question { Faker::Lorem.question } @@ -5,4 +7,4 @@ inactive { false } sequence(:ordering) { |n| n } end -end \ No newline at end of file +end diff --git a/spec/factories/footers.rb b/spec/factories/footers.rb index 15d50b909..b580c3520 100644 --- a/spec/factories/footers.rb +++ b/spec/factories/footers.rb @@ -1,6 +1,8 @@ +# frozen_string_literal: true + FactoryBot.define do factory :footer do phone { Faker::PhoneNumber.phone_number } general_questions { Faker::Lorem.sentence } end -end \ No newline at end of file +end diff --git a/spec/factories/form_builders.rb b/spec/factories/form_builders.rb index 1312c1101..7bb82e0e5 100644 --- a/spec/factories/form_builders.rb +++ b/spec/factories/form_builders.rb @@ -1,7 +1,9 @@ +# frozen_string_literal: true + FactoryBot.define do factory :form_builder do sequence(:name) { |n| "Form Builder Name #{n}" } association :windows_type end -end \ No newline at end of file +end diff --git a/spec/factories/form_field_answer_options.rb b/spec/factories/form_field_answer_options.rb index 9105732a7..c91be058c 100644 --- a/spec/factories/form_field_answer_options.rb +++ b/spec/factories/form_field_answer_options.rb @@ -1,7 +1,9 @@ +# frozen_string_literal: true + FactoryBot.define do factory :form_field_answer_option do association :form_field association :answer_option end -end \ No newline at end of file +end diff --git a/spec/factories/form_fields.rb b/spec/factories/form_fields.rb index d42713d6e..23bea77b4 100644 --- a/spec/factories/form_fields.rb +++ b/spec/factories/form_fields.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + FactoryBot.define do factory :form_field do # Association: belongs_to :form @@ -12,4 +14,4 @@ # Add other attributes based on schema if needed end -end \ No newline at end of file +end diff --git a/spec/factories/forms.rb b/spec/factories/forms.rb index ce1b30656..168ef4377 100644 --- a/spec/factories/forms.rb +++ b/spec/factories/forms.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + FactoryBot.define do factory :form do association :owner, factory: :user @@ -5,4 +7,4 @@ # Add other attributes if needed based on schema # name { "Default Form Name" } # Name seems to be method-generated end -end \ No newline at end of file +end diff --git a/spec/factories/images.rb b/spec/factories/images.rb index 440466330..4454cc3c5 100644 --- a/spec/factories/images.rb +++ b/spec/factories/images.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + FactoryBot.define do factory :image do association :owner, factory: :user @@ -14,4 +16,4 @@ file_file_name { "invalid.webp" } end end -end \ No newline at end of file +end diff --git a/spec/factories/locations.rb b/spec/factories/locations.rb index 864bdce45..42990358a 100644 --- a/spec/factories/locations.rb +++ b/spec/factories/locations.rb @@ -1,7 +1,9 @@ +# frozen_string_literal: true + FactoryBot.define do factory :location do city { Faker::Address.city } state { Faker::Address.state_abbr } country { Faker::Address.country } end -end \ No newline at end of file +end diff --git a/spec/factories/media_files.rb b/spec/factories/media_files.rb index 15accb5b7..e1b0ce6e6 100644 --- a/spec/factories/media_files.rb +++ b/spec/factories/media_files.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + FactoryBot.define do factory :media_file do association :report @@ -7,4 +9,4 @@ file_file_size { 1024 } file_updated_at { Time.zone.now } end -end \ No newline at end of file +end diff --git a/spec/factories/metadata.rb b/spec/factories/metadata.rb index 4c47ff93e..4f072ef76 100644 --- a/spec/factories/metadata.rb +++ b/spec/factories/metadata.rb @@ -1,6 +1,8 @@ +# frozen_string_literal: true + FactoryBot.define do factory :metadatum do sequence(:name) { |n| "Metadatum Name #{n}" } published { true } end -end \ No newline at end of file +end diff --git a/spec/factories/notifications.rb b/spec/factories/notifications.rb index c45e5a8c5..4ee68f43a 100644 --- a/spec/factories/notifications.rb +++ b/spec/factories/notifications.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + FactoryBot.define do factory :notification do association :noticeable, factory: :report @@ -5,7 +7,7 @@ notification_type { :created } after(:build) do |notification| - allow(notification).to receive(:send_notice).and_return(true) + allow(notification).to(receive(:send_notice).and_return(true)) end end -end \ No newline at end of file +end diff --git a/spec/factories/permissions.rb b/spec/factories/permissions.rb index 0a22bb1ff..7e017658f 100644 --- a/spec/factories/permissions.rb +++ b/spec/factories/permissions.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + FactoryBot.define do factory :permission do # Assuming 'security_cat' is the main attribute we need to set @@ -19,4 +21,4 @@ security_cat { "Combined Adult and Children's Windows" } end end -end \ No newline at end of file +end diff --git a/spec/factories/project_obligations.rb b/spec/factories/project_obligations.rb index 4dee63a38..e3e4b3cea 100644 --- a/spec/factories/project_obligations.rb +++ b/spec/factories/project_obligations.rb @@ -1,5 +1,7 @@ +# frozen_string_literal: true + FactoryBot.define do factory :project_obligation do name { "Current Grant Funded" } end -end \ No newline at end of file +end diff --git a/spec/factories/project_statuses.rb b/spec/factories/project_statuses.rb index 6e069996f..5d8a0d984 100644 --- a/spec/factories/project_statuses.rb +++ b/spec/factories/project_statuses.rb @@ -1,5 +1,7 @@ +# frozen_string_literal: true + FactoryBot.define do factory :project_status do name { "Active" } end -end \ No newline at end of file +end diff --git a/spec/factories/project_users.rb b/spec/factories/project_users.rb index 8aafe47e6..6b6fe88ff 100644 --- a/spec/factories/project_users.rb +++ b/spec/factories/project_users.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + FactoryBot.define do factory :project_user do association :project @@ -5,4 +7,4 @@ position { :default } end -end \ No newline at end of file +end diff --git a/spec/factories/projects.rb b/spec/factories/projects.rb index 7fd6dc33b..47351f1f9 100644 --- a/spec/factories/projects.rb +++ b/spec/factories/projects.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + FactoryBot.define do factory :project do sequence(:name) { |n| "Project Name #{n}" } @@ -6,8 +8,8 @@ association :windows_type association :project_status - start_date { Date.today - 1.month } + start_date { Time.zone.today - 1.month } end_date { nil } description { Faker::Lorem.paragraph } end -end \ No newline at end of file +end diff --git a/spec/factories/quotable_item_quotes.rb b/spec/factories/quotable_item_quotes.rb index 6b7752cf9..95bd8a420 100644 --- a/spec/factories/quotable_item_quotes.rb +++ b/spec/factories/quotable_item_quotes.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + FactoryBot.define do factory :quotable_item_quote do # Association: belongs_to :quote @@ -7,4 +9,4 @@ # Needs a quotable instance, e.g., a Report association :quotable, factory: :report end -end \ No newline at end of file +end diff --git a/spec/factories/quotes.rb b/spec/factories/quotes.rb index 5ba7789be..6dfd487f5 100644 --- a/spec/factories/quotes.rb +++ b/spec/factories/quotes.rb @@ -1,10 +1,12 @@ +# frozen_string_literal: true + FactoryBot.define do factory :quote do quote { Faker::Lorem.sentence } speaker_name { Faker::Name.name } age { rand(18..99) } - gender { ['M', 'F', 'O', nil].sample } + gender { ["M", "F", "O", nil].sample } inactive { false } workshop_id { nil } end -end \ No newline at end of file +end diff --git a/spec/factories/report_form_field_answers.rb b/spec/factories/report_form_field_answers.rb index 8236f0c55..b851b54ce 100644 --- a/spec/factories/report_form_field_answers.rb +++ b/spec/factories/report_form_field_answers.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + FactoryBot.define do factory :report_form_field_answer do association :report @@ -6,4 +8,4 @@ answer { "User response text" } end -end \ No newline at end of file +end diff --git a/spec/factories/reports.rb b/spec/factories/reports.rb index 79922f541..eb5346625 100644 --- a/spec/factories/reports.rb +++ b/spec/factories/reports.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + FactoryBot.define do factory :report do # Associations @@ -11,7 +13,7 @@ type { "Report" } # Default type, override for MonthlyReport, WorkshopLog etc. # Other potential attributes - date { Date.today } + date { Time.zone.today } # Paperclip attributes (placeholders) form_file_file_name { nil } @@ -24,8 +26,8 @@ end # Specific factory for MonthlyReport inheriting from Report - factory :monthly_report, parent: :report, class: 'MonthlyReport' do + factory :monthly_report, parent: :report, class: "MonthlyReport" do type { "MonthlyReport" } # Add specific attributes or associations for MonthlyReport if needed end -end \ No newline at end of file +end diff --git a/spec/factories/resources.rb b/spec/factories/resources.rb index b5ec5cd02..433fa42da 100644 --- a/spec/factories/resources.rb +++ b/spec/factories/resources.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + FactoryBot.define do factory :resource do # Associations @@ -6,11 +8,11 @@ association :windows_type title { Faker::Lorem.sentence } - kind { ['Resource', 'LeaderSpotlight', 'SectorImpact', 'Story', 'Theme', 'Scholarship', 'TemplateAndHandout', 'ToolkitAndForm'].sample } + kind { ["Resource", "LeaderSpotlight", "SectorImpact", "Story", "Theme", "Scholarship", "TemplateAndHandout", "ToolkitAndForm"].sample } text { Faker::Lorem.paragraphs.join("\n\n") } featured { false } inactive { false } # Needs setup for nested attributes (categories, sectors, images, attachments, form) if required for tests end -end \ No newline at end of file +end diff --git a/spec/factories/sectorable_items.rb b/spec/factories/sectorable_items.rb index df3a22f58..ec7e5f094 100644 --- a/spec/factories/sectorable_items.rb +++ b/spec/factories/sectorable_items.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + FactoryBot.define do factory :sectorable_item do # Association: belongs_to :sector @@ -7,4 +9,4 @@ # Needs a sectorable instance, e.g., a Workshop or Resource association :sectorable, factory: :workshop end -end \ No newline at end of file +end diff --git a/spec/factories/sectors.rb b/spec/factories/sectors.rb index ce3fd19ae..7d16ac503 100644 --- a/spec/factories/sectors.rb +++ b/spec/factories/sectors.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + FactoryBot.define do factory :sector do sequence(:name) { |n| "Sector Name #{n}" } @@ -8,7 +10,7 @@ end trait :other do - name { 'Other' } + name { "Other" } end end -end \ No newline at end of file +end diff --git a/spec/factories/stories.rb b/spec/factories/stories.rb index b40712409..f9dd7ff7b 100644 --- a/spec/factories/stories.rb +++ b/spec/factories/stories.rb @@ -1,7 +1,9 @@ +# frozen_string_literal: true + FactoryBot.define do - factory :story, parent: :report, class: 'Story' do + factory :story, parent: :report, class: "Story" do type { "Story" } association :owner, factory: :form_builder end -end \ No newline at end of file +end diff --git a/spec/factories/user_form_form_fields.rb b/spec/factories/user_form_form_fields.rb index 292d3a623..4c6ad3c5d 100644 --- a/spec/factories/user_form_form_fields.rb +++ b/spec/factories/user_form_form_fields.rb @@ -1,7 +1,9 @@ +# frozen_string_literal: true + FactoryBot.define do factory :user_form_form_field do association :form_field association :user_form text { "User input value" } end -end \ No newline at end of file +end diff --git a/spec/factories/user_forms.rb b/spec/factories/user_forms.rb index 66f2c9364..8a924d7de 100644 --- a/spec/factories/user_forms.rb +++ b/spec/factories/user_forms.rb @@ -1,6 +1,8 @@ +# frozen_string_literal: true + FactoryBot.define do factory :user_form do association :user association :form end -end \ No newline at end of file +end diff --git a/spec/factories/user_permissions.rb b/spec/factories/user_permissions.rb index 6f1486036..0635729c8 100644 --- a/spec/factories/user_permissions.rb +++ b/spec/factories/user_permissions.rb @@ -1,6 +1,8 @@ +# frozen_string_literal: true + FactoryBot.define do factory :user_permission do association :user association :permission end -end \ No newline at end of file +end diff --git a/spec/factories/users.rb b/spec/factories/users.rb index 4df80e350..84433f8ee 100644 --- a/spec/factories/users.rb +++ b/spec/factories/users.rb @@ -1,9 +1,11 @@ +# frozen_string_literal: true + FactoryBot.define do factory :user do first_name { Faker::Name.first_name } last_name { Faker::Name.last_name } email { Faker::Internet.unique.email } - password { 'password' } - password_confirmation { 'password' } + password { "password" } + password_confirmation { "password" } end -end \ No newline at end of file +end diff --git a/spec/factories/windows_types.rb b/spec/factories/windows_types.rb index 1e2c9a301..d71b07216 100644 --- a/spec/factories/windows_types.rb +++ b/spec/factories/windows_types.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + FactoryBot.define do factory :windows_type do sequence(:name) { |n| "Windows Type Name #{n}" } @@ -5,15 +7,15 @@ legacy_id { 1 } trait :adult do - name { 'ADULT WORKSHOP LOG' } + name { "ADULT WORKSHOP LOG" } end trait :children do - name { 'CHILDREN WORKSHOP LOG'} + name { "CHILDREN WORKSHOP LOG" } end trait :combined do - name { 'ADULT & CHILDREN COMBINED (FAMILY) LOG' } + name { "ADULT & CHILDREN COMBINED (FAMILY) LOG" } end end -end \ No newline at end of file +end diff --git a/spec/factories/workshop_age_ranges.rb b/spec/factories/workshop_age_ranges.rb index 842381173..5cf271460 100644 --- a/spec/factories/workshop_age_ranges.rb +++ b/spec/factories/workshop_age_ranges.rb @@ -1,6 +1,8 @@ +# frozen_string_literal: true + FactoryBot.define do factory :workshop_age_range do association :workshop association :age_range end -end \ No newline at end of file +end diff --git a/spec/factories/workshop_ideas.rb b/spec/factories/workshop_ideas.rb index c3bf0ab18..2d600db4c 100644 --- a/spec/factories/workshop_ideas.rb +++ b/spec/factories/workshop_ideas.rb @@ -1,9 +1,11 @@ +# frozen_string_literal: true + FactoryBot.define do # Workshop factory is defined in workshops.rb # Specific factory for WorkshopIdea inheriting from Workshop - factory :workshop_idea, parent: :workshop, class: 'WorkshopIdea' do + factory :workshop_idea, parent: :workshop, class: "WorkshopIdea" do inactive { true } # Default scope for WorkshopIdea # Add specific attributes or associations for WorkshopIdea if needed end -end \ No newline at end of file +end diff --git a/spec/factories/workshop_logs.rb b/spec/factories/workshop_logs.rb index 829f774ad..aeeec9d75 100644 --- a/spec/factories/workshop_logs.rb +++ b/spec/factories/workshop_logs.rb @@ -1,10 +1,11 @@ +# frozen_string_literal: true + FactoryBot.define do - factory :workshop_log, parent: :report, class: 'WorkshopLog' do + factory :workshop_log, parent: :report, class: "WorkshopLog" do type { "WorkshopLog" } association :owner, factory: :workshop workshop { owner } - end end diff --git a/spec/factories/workshop_resources.rb b/spec/factories/workshop_resources.rb index bc02076a5..90136e25b 100644 --- a/spec/factories/workshop_resources.rb +++ b/spec/factories/workshop_resources.rb @@ -1,6 +1,8 @@ +# frozen_string_literal: true + FactoryBot.define do factory :workshop_resource do association :workshop association :resource end -end \ No newline at end of file +end diff --git a/spec/factories/workshop_variations.rb b/spec/factories/workshop_variations.rb index 4235a03be..35c555d4d 100644 --- a/spec/factories/workshop_variations.rb +++ b/spec/factories/workshop_variations.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + FactoryBot.define do factory :workshop_variation do association :workshop @@ -6,4 +8,4 @@ sequence(:ordering) { |n| n } inactive { false } end -end \ No newline at end of file +end diff --git a/spec/factories/workshops.rb b/spec/factories/workshops.rb index 513e7b650..8a97aa720 100644 --- a/spec/factories/workshops.rb +++ b/spec/factories/workshops.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + FactoryBot.define do factory :workshop do # Associations @@ -15,6 +17,5 @@ thumbnail_file_name { nil } header_file_name { nil } - end -end \ No newline at end of file +end diff --git a/spec/mailers/admins/notification_mailer_spec.rb b/spec/mailers/admins/notification_mailer_spec.rb index e8a662d9b..3246c1c9e 100644 --- a/spec/mailers/admins/notification_mailer_spec.rb +++ b/spec/mailers/admins/notification_mailer_spec.rb @@ -1,12 +1,14 @@ -require 'rails_helper' +# frozen_string_literal: true -RSpec.describe Admins::NotificationMailer do - describe '#email' do - it 'renders successfully' do +require "rails_helper" + +RSpec.describe(Admins::NotificationMailer) do + describe "#email" do + it "renders successfully" do # Not sure if this mailer is actually never used, causing a bunch of errors, or the inky # extension is somehow working. - pending 'The template for this mailer has an extension of inky' - fail + pending "The template for this mailer has an extension of inky" + raise end end end diff --git a/spec/mailers/application_mailer_spec.rb b/spec/mailers/application_mailer_spec.rb index ee57bda95..9101ac741 100644 --- a/spec/mailers/application_mailer_spec.rb +++ b/spec/mailers/application_mailer_spec.rb @@ -1,11 +1,13 @@ -require 'rails_helper' +# frozen_string_literal: true -RSpec.describe ApplicationMailer do - it 'sets the default from address' do - expect(described_class.default[:from]).to eq('noreply@awbw.org') +require "rails_helper" + +RSpec.describe(ApplicationMailer) do + it "sets the default from address" do + expect(described_class.default[:from]).to(eq("noreply@awbw.org")) end - it 'uses the correct layout' do - expect(described_class._layout).to eq('mailer') + it "uses the correct layout" do + expect(described_class._layout).to(eq("mailer")) end -end \ No newline at end of file +end diff --git a/spec/mailers/contact_us_mailer_spec.rb b/spec/mailers/contact_us_mailer_spec.rb index 0323bf951..23478b572 100644 --- a/spec/mailers/contact_us_mailer_spec.rb +++ b/spec/mailers/contact_us_mailer_spec.rb @@ -1,89 +1,91 @@ -require 'rails_helper' +# frozen_string_literal: true -RSpec.describe ContactUsMailer do - describe '#hello' do - xit 'sends to the adult program email when q is "adult"' do +require "rails_helper" + +RSpec.describe(ContactUsMailer) do + describe "#hello" do + xit 'sends to the adult program email when q is "adult"' do # rubocop:todo RSpec/PendingWithoutReason contact_params = { - subject: 'Test Subject', - from: 'test@example.com', - q: 'adult', - first_name: 'John', - last_name: 'Doe', - agency: 'Test Agency', - message: 'This is a test message' + subject: "Test Subject", + from: "test@example.com", + q: "adult", + first_name: "John", + last_name: "Doe", + agency: "Test Agency", + message: "This is a test message", } mail = described_class.hello(contact_params) - expect(mail.to).to eq(['cturek@awbw.org']) - expect(mail.subject).to eq('Test Subject') - expect(mail.from).to eq(['test@example.com']) + expect(mail.to).to(eq(["cturek@awbw.org"])) + expect(mail.subject).to(eq("Test Subject")) + expect(mail.from).to(eq(["test@example.com"])) end - xit 'sends to the children program email when q is "children"' do + xit 'sends to the children program email when q is "children"' do # rubocop:todo RSpec/PendingWithoutReason contact_params = { - subject: 'Test Subject', - from: 'test@example.com', - q: 'children', - first_name: 'John', - last_name: 'Doe', - agency: 'Test Agency', - message: 'This is a test message' + subject: "Test Subject", + from: "test@example.com", + q: "children", + first_name: "John", + last_name: "Doe", + agency: "Test Agency", + message: "This is a test message", } mail = described_class.hello(contact_params) - expect(mail.to).to eq(['cturekrials@awbw.org']) + expect(mail.to).to(eq(["cturekrials@awbw.org"])) end - xit 'sends to the general program email when q is "general"' do + xit 'sends to the general program email when q is "general"' do # rubocop:todo RSpec/PendingWithoutReason contact_params = { - subject: 'Test Subject', - from: 'test@example.com', - q: 'general', - first_name: 'John', - last_name: 'Doe', - agency: 'Test Agency', - message: 'This is a test message' + subject: "Test Subject", + from: "test@example.com", + q: "general", + first_name: "John", + last_name: "Doe", + agency: "Test Agency", + message: "This is a test message", } mail = described_class.hello(contact_params) - expect(mail.to).to eq(['programs@awbw.org']) + expect(mail.to).to(eq(["programs@awbw.org"])) end - xit 'defaults to the general program email when q is nil' do + xit "defaults to the general program email when q is nil" do # rubocop:todo RSpec/PendingWithoutReason contact_params = { - subject: 'Test Subject', - from: 'test@example.com', + subject: "Test Subject", + from: "test@example.com", q: nil, - first_name: 'John', - last_name: 'Doe', - agency: 'Test Agency', - message: 'This is a test message' + first_name: "John", + last_name: "Doe", + agency: "Test Agency", + message: "This is a test message", } mail = described_class.hello(contact_params) - expect(mail.to).to eq(['programs@awbw.org']) + expect(mail.to).to(eq(["programs@awbw.org"])) end - xit 'renders the email content correctly' do + xit "renders the email content correctly" do # rubocop:todo RSpec/PendingWithoutReason contact_params = { - subject: 'Test Subject', - from: 'test@example.com', - q: 'adult', - first_name: 'John', - last_name: 'Doe', - agency: 'Test Agency', - message: 'This is a test message' + subject: "Test Subject", + from: "test@example.com", + q: "adult", + first_name: "John", + last_name: "Doe", + agency: "Test Agency", + message: "This is a test message", } mail = described_class.hello(contact_params) - expect(mail.body.encoded).to include('John Doe') - expect(mail.body.encoded).to include('This is a test message') - expect(mail.body.encoded).to include('Test Agency') + expect(mail.body.encoded).to(include("John Doe")) + expect(mail.body.encoded).to(include("This is a test message")) + expect(mail.body.encoded).to(include("Test Agency")) end end -end \ No newline at end of file +end diff --git a/spec/mailers/notification_mailer_spec.rb b/spec/mailers/notification_mailer_spec.rb index b013c0a10..4a5fa7933 100644 --- a/spec/mailers/notification_mailer_spec.rb +++ b/spec/mailers/notification_mailer_spec.rb @@ -1,30 +1,32 @@ -require 'rails_helper' +# frozen_string_literal: true -RSpec.describe NotificationMailer do - describe '#reset_password_notification' do - xit 'renders the subject and sends to the correct email' do - user = double('User', email: 'user@example.com') +require "rails_helper" + +RSpec.describe(NotificationMailer) do + describe "#reset_password_notification" do + xit "renders the subject and sends to the correct email" do # rubocop:todo RSpec/PendingWithoutReason + user = double("User", email: "user@example.com") # rubocop:todo RSpec/VerifiedDoubles mail = described_class.reset_password_notification(user) - expect(mail.subject).to eq('Reset Password Request') - expect(mail.to).to eq(['programs@awbw.org']) - expect(mail.from).to eq(['noreply@awbw.org']) + expect(mail.subject).to(eq("Reset Password Request")) + expect(mail.to).to(eq(["programs@awbw.org"])) + expect(mail.from).to(eq(["noreply@awbw.org"])) end - xit 'includes the user email in the email body' do - user = double('User', email: 'user@example.com') + xit "includes the user email in the email body" do # rubocop:todo RSpec/PendingWithoutReason + user = double("User", email: "user@example.com") # rubocop:todo RSpec/VerifiedDoubles mail = described_class.reset_password_notification(user) - expect(mail.body.encoded).to include('user@example.com') + expect(mail.body.encoded).to(include("user@example.com")) end - xit 'delivers the email' do - user = double('User', email: 'user@example.com') + xit "delivers the email" do # rubocop:todo RSpec/PendingWithoutReason + user = double("User", email: "user@example.com") # rubocop:todo RSpec/VerifiedDoubles mail = described_class.reset_password_notification(user) - expect { + expect do mail.deliver_now - }.to change { ActionMailer::Base.deliveries.count }.by(1) + end.to(change { ActionMailer::Base.deliveries.count }.by(1)) end end -end \ No newline at end of file +end diff --git a/spec/models/admin_spec.rb b/spec/models/admin_spec.rb index 16e3ecda2..5e31a00b6 100644 --- a/spec/models/admin_spec.rb +++ b/spec/models/admin_spec.rb @@ -1,30 +1,28 @@ -require 'rails_helper' +# frozen_string_literal: true -RSpec.describe Admin do +require "rails_helper" + +RSpec.describe(Admin) do let(:admin) { build(:admin) } # Shoulda Matchers - describe 'associations' do - # Add association tests here if any - # e.g., it { should have_many(:related_models) } - end - describe 'validations' do - it 'is valid with valid attributes' do - expect(admin).to be_valid + describe "validations" do + it "is valid with valid attributes" do + expect(admin).to(be_valid) end # Add other Devise validation tests as needed (e.g., email format, password length) - it 'is invalid without an email' do + it "is invalid without an email" do admin.email = nil - expect(admin).not_to be_valid - expect(admin.errors[:email]).to include("can't be blank") + expect(admin).not_to(be_valid) + expect(admin.errors[:email]).to(include("can't be blank")) end - it 'is invalid without a password' do + it "is invalid without a password" do admin.password = nil - expect(admin).not_to be_valid - expect(admin.errors[:password]).to include("can't be blank") + expect(admin).not_to(be_valid) + expect(admin.errors[:password]).to(include("can't be blank")) end # Shoulda matchers for other Devise validations (like uniqueness, format) can be complex @@ -33,4 +31,4 @@ # subject { create(:admin) } # it { should validate_uniqueness_of(:email).case_insensitive } end -end \ No newline at end of file +end diff --git a/spec/models/age_range_spec.rb b/spec/models/age_range_spec.rb index cc59d9848..551b26efd 100644 --- a/spec/models/age_range_spec.rb +++ b/spec/models/age_range_spec.rb @@ -1,19 +1,17 @@ -require 'rails_helper' +# frozen_string_literal: true -RSpec.describe AgeRange do +require "rails_helper" + +RSpec.describe(AgeRange) do # pending "add some examples to (or delete) #{__FILE__}" - describe 'associations' do + describe "associations" do subject { build(:age_range, windows_type: create(:windows_type)) } - it { should belong_to(:windows_type) } - end - describe 'validations' do - # Add validation tests if any exist (e.g., name) - # it { should validate_presence_of(:name) } + it { is_expected.to(belong_to(:windows_type)) } end - it 'is valid with valid attributes' do - expect(build(:age_range)).to be_valid + it "is valid with valid attributes" do + expect(build(:age_range)).to(be_valid) end end diff --git a/spec/models/answer_option_spec.rb b/spec/models/answer_option_spec.rb index d3cad756b..5c93f2266 100644 --- a/spec/models/answer_option_spec.rb +++ b/spec/models/answer_option_spec.rb @@ -1,19 +1,10 @@ -require 'rails_helper' +# frozen_string_literal: true -RSpec.describe AnswerOption do - describe 'associations' do - # Add association tests here if any are added later - # e.g., it { should have_many(:form_field_answer_options) } - # e.g., it { should have_many(:form_fields).through(:form_field_answer_options) } - end - - describe 'validations' do - # Add validation tests here if any are added later - # e.g., it { should validate_presence_of(:text) } - end +require "rails_helper" +RSpec.describe(AnswerOption) do # Example basic validity test (optional if using shoulda matchers) - it 'is valid with valid attributes' do - expect(build(:answer_option)).to be_valid + it "is valid with valid attributes" do + expect(build(:answer_option)).to(be_valid) end -end \ No newline at end of file +end diff --git a/spec/models/attachment_spec.rb b/spec/models/attachment_spec.rb index be7b9e489..8f7620d62 100644 --- a/spec/models/attachment_spec.rb +++ b/spec/models/attachment_spec.rb @@ -1,26 +1,16 @@ -require 'rails_helper' +# frozen_string_literal: true -RSpec.describe Attachment do - # pending "add some examples to (or delete) #{__FILE__}" - - describe 'associations' do - it { should belong_to(:owner) } # Polymorphic - end +require "rails_helper" - describe 'validations' do - # Paperclip matchers (might require paperclip-matchers gem and setup) - # it { should have_attached_file(:file) } - # it { should validate_attachment_content_type(:file) - # .allowing('application/pdf', 'application/msword', 'image/gif', 'image/jpeg', 'image/png') - # .rejecting('text/plain', 'text/xml') } +RSpec.describe(Attachment) do + # pending "add some examples to (or delete) #{__FILE__}" - # Basic presence test if needed (though Paperclip handles some) - # subject { build(:attachment, owner: create(:user)) } # Requires owner for validity - # it { should validate_presence_of(:owner) } # Testing polymorphic presence can be tricky + describe "associations" do + it { is_expected.to(belong_to(:owner)) } # Polymorphic end # it 'is valid with an owner' do # # Note: Factory needs an owner to be valid for create # expect(build(:attachment, owner: create(:user))).to be_valid # end -end \ No newline at end of file +end diff --git a/spec/models/banner_spec.rb b/spec/models/banner_spec.rb index c510f1492..658ce3070 100644 --- a/spec/models/banner_spec.rb +++ b/spec/models/banner_spec.rb @@ -1,19 +1,18 @@ -require 'rails_helper' +# frozen_string_literal: true -RSpec.describe Banner do - # let(:banner) { build(:banner) } # Keep if needed for other tests +require "rails_helper" - describe 'associations' do - # Add association tests if any - end +RSpec.describe(Banner) do + # let(:banner) { build(:banner) } # Keep if needed for other tests - describe 'validations' do + describe "validations" do subject { build(:banner) } - it { should validate_presence_of(:content) } + + it { is_expected.to(validate_presence_of(:content)) } end # Basic validity test included via shoulda # it 'is valid with valid attributes' do # expect(build(:banner)).to be_valid # end -end \ No newline at end of file +end diff --git a/spec/models/bookmark_annotation_spec.rb b/spec/models/bookmark_annotation_spec.rb index ff9d534ec..3b590f1cf 100644 --- a/spec/models/bookmark_annotation_spec.rb +++ b/spec/models/bookmark_annotation_spec.rb @@ -1,15 +1,17 @@ -require 'rails_helper' +# frozen_string_literal: true -RSpec.describe BookmarkAnnotation do +require "rails_helper" + +RSpec.describe(BookmarkAnnotation) do # pending "add some examples to (or delete) #{__FILE__}" - describe 'associations' do - it { should belong_to(:bookmark) } + describe "associations" do + it { is_expected.to(belong_to(:bookmark)) } end - it 'is valid with valid attributes' do + it "is valid with valid attributes" do bookmark = build_stubbed(:bookmark) bookmark_annotation = build(:bookmark_annotation, bookmark: bookmark) - expect(bookmark_annotation).to be_valid + expect(bookmark_annotation).to(be_valid) end -end \ No newline at end of file +end diff --git a/spec/models/bookmark_spec.rb b/spec/models/bookmark_spec.rb index b1ebb3e94..caa2505e4 100644 --- a/spec/models/bookmark_spec.rb +++ b/spec/models/bookmark_spec.rb @@ -1,18 +1,20 @@ -require 'rails_helper' +# frozen_string_literal: true -RSpec.describe Bookmark do +require "rails_helper" + +RSpec.describe(Bookmark) do # pending "add some examples to (or delete) #{__FILE__}" - describe 'associations' do - it { should belong_to(:user) } - it { should belong_to(:bookmarkable) } # Polymorphic - it { should have_many(:bookmark_annotations).dependent(:destroy) } + describe "associations" do + it { is_expected.to(belong_to(:user)) } + it { is_expected.to(belong_to(:bookmarkable)) } # Polymorphic + it { is_expected.to(have_many(:bookmark_annotations).dependent(:destroy)) } end - it 'is valid with valid attributes' do + it "is valid with valid attributes" do user = build_stubbed(:user) workshop = build_stubbed(:workshop) bookmark = build(:bookmark, user: user, bookmarkable: workshop) - expect(bookmark).to be_valid + expect(bookmark).to(be_valid) end -end \ No newline at end of file +end diff --git a/spec/models/categorizable_item_spec.rb b/spec/models/categorizable_item_spec.rb index 1452a3926..188ee3dbe 100644 --- a/spec/models/categorizable_item_spec.rb +++ b/spec/models/categorizable_item_spec.rb @@ -1,19 +1,13 @@ -require 'rails_helper' +# frozen_string_literal: true -RSpec.describe CategorizableItem do - # pending "add some examples to (or delete) #{__FILE__}" +require "rails_helper" - describe 'associations' do - it { should belong_to(:category) } - it { should belong_to(:categorizable) } # Polymorphic - end +RSpec.describe(CategorizableItem) do + # pending "add some examples to (or delete) #{__FILE__}" - describe 'validations' do - # Add validation tests if any (e.g., presence of associations) - # subject { build(:categorizable_item) } # Requires category and categorizable - # it { should validate_presence_of(:category_id) } - # it { should validate_presence_of(:categorizable_id) } - # it { should validate_presence_of(:categorizable_type) } + describe "associations" do + it { is_expected.to(belong_to(:category)) } + it { is_expected.to(belong_to(:categorizable)) } # Polymorphic end # it 'is valid with valid attributes' do @@ -24,4 +18,4 @@ # # expect(build(:categorizable_item, categorizable: workshop, category: category)).to be_valid # pending("Requires functional category/workshop factories and associations uncommented") # end -end \ No newline at end of file +end diff --git a/spec/models/category_spec.rb b/spec/models/category_spec.rb index 94399d67e..39d52213a 100644 --- a/spec/models/category_spec.rb +++ b/spec/models/category_spec.rb @@ -1,24 +1,32 @@ -require 'rails_helper' +# frozen_string_literal: true -RSpec.describe Category do +require "rails_helper" + +RSpec.describe(Category) do let(:category) { build(:category) } - describe 'associations' do - it { should belong_to(:metadatum) } - it { should have_many(:categorizable_items).dependent(:destroy) } - it { should have_many(:workshops).through(:categorizable_items) } + # rubocop:todo RSpec/RepeatedExampleGroupDescription + describe "associations" do # rubocop:todo RSpec/RepeatedExampleGroupBody # rubocop:todo RSpec/RepeatedExampleGroupDescription + it { is_expected.to(belong_to(:metadatum)) } + it { is_expected.to(have_many(:categorizable_items).dependent(:destroy)) } + it { is_expected.to(have_many(:workshops).through(:categorizable_items)) } end + # rubocop:enable RSpec/RepeatedExampleGroupDescription + + describe "validations" do + subject { build(:category, name: existing_category.name, metadatum: metadatum) } - describe 'validations' do let!(:metadatum) { create(:metadatum) } let!(:existing_category) { create(:category, metadatum: metadatum) } - subject { build(:category, name: existing_category.name, metadatum: metadatum) } - it { should validate_presence_of(:name) } + + it { is_expected.to(validate_presence_of(:name)) } end - describe 'associations' do - it { should belong_to(:metadatum) } - it { should have_many(:categorizable_items).dependent(:destroy) } - it { should have_many(:workshops).through(:categorizable_items) } + # rubocop:todo RSpec/RepeatedExampleGroupDescription + describe "associations" do # rubocop:todo RSpec/RepeatedExampleGroupBody # rubocop:todo RSpec/RepeatedExampleGroupDescription + it { is_expected.to(belong_to(:metadatum)) } + it { is_expected.to(have_many(:categorizable_items).dependent(:destroy)) } + it { is_expected.to(have_many(:workshops).through(:categorizable_items)) } end -end \ No newline at end of file + # rubocop:enable RSpec/RepeatedExampleGroupDescription +end diff --git a/spec/models/faq_spec.rb b/spec/models/faq_spec.rb index 8bfda1914..e93853750 100644 --- a/spec/models/faq_spec.rb +++ b/spec/models/faq_spec.rb @@ -1,31 +1,30 @@ -require 'rails_helper' +# frozen_string_literal: true -RSpec.describe Faq do - # let(:faq) { build(:faq) } # Keep if needed +require "rails_helper" - describe 'associations' do - # Add association tests if any - end +RSpec.describe(Faq) do + # let(:faq) { build(:faq) } # Keep if needed - describe 'validations' do + describe "validations" do subject { build(:faq) } - it { should validate_presence_of(:question) } - it { should validate_presence_of(:answer) } + + it { is_expected.to(validate_presence_of(:question)) } + it { is_expected.to(validate_presence_of(:answer)) } end - describe 'scopes' do + describe "scopes" do let!(:active_faq) { create(:faq, inactive: false, ordering: 1) } let!(:inactive_faq) { create(:faq, inactive: true, ordering: 2) } let!(:active_faq_2) { create(:faq, inactive: false, ordering: 0) } - it '.active returns only active FAQs' do - expect(Faq.active).to contain_exactly(active_faq, active_faq_2) - expect(Faq.active).not_to include(inactive_faq) + it ".active returns only active FAQs" do + expect(described_class.active).to(contain_exactly(active_faq, active_faq_2)) + expect(described_class.active).not_to(include(inactive_faq)) end - it '.by_order returns FAQs ordered by ordering descending' do - # Note: Default scope might interfere; consider unscoped if necessary - expect(Faq.reorder(nil).by_order).to eq([inactive_faq, active_faq, active_faq_2]) + it ".by_order returns FAQs ordered by ordering descending" do + # NOTE: Default scope might interfere; consider unscoped if necessary + expect(described_class.reorder(nil).by_order).to(eq([inactive_faq, active_faq, active_faq_2])) end end -end \ No newline at end of file +end diff --git a/spec/models/footer_spec.rb b/spec/models/footer_spec.rb index ee441c844..142498f03 100644 --- a/spec/models/footer_spec.rb +++ b/spec/models/footer_spec.rb @@ -1,34 +1,28 @@ -require 'rails_helper' +# frozen_string_literal: true -RSpec.describe Footer do - # pending "add some examples to (or delete) #{__FILE__}" - - describe 'associations' do - # Add association tests if any - end +require "rails_helper" - describe 'validations' do - # Add validation tests if any - # e.g., it { should validate_presence_of(:phone) } - end +RSpec.describe(Footer) do + # pending "add some examples to (or delete) #{__FILE__}" # Basic validity test - it 'is valid with valid attributes' do - expect(build(:footer)).to be_valid + it "is valid with valid attributes" do + expect(build(:footer)).to(be_valid) end # Tests for class methods remain relevant - describe 'class methods' do + describe "class methods" do # Ensure one record exists, clear others if necessary for reliable .first let!(:footer_record) { create(:footer) } - before { Footer.where.not(id: footer_record.id).delete_all } - it '.phone returns the phone number' do - expect(Footer.phone).to eq(footer_record.phone) + before { described_class.where.not(id: footer_record.id).delete_all } + + it ".phone returns the phone number" do + expect(described_class.phone).to(eq(footer_record.phone)) end - it '.general_questions returns the general questions info' do - expect(Footer.general_questions).to eq(footer_record.general_questions) + it ".general_questions returns the general questions info" do + expect(described_class.general_questions).to(eq(footer_record.general_questions)) end end -end \ No newline at end of file +end diff --git a/spec/models/form_builder_spec.rb b/spec/models/form_builder_spec.rb index 87ad55257..641c34aa0 100644 --- a/spec/models/form_builder_spec.rb +++ b/spec/models/form_builder_spec.rb @@ -1,23 +1,25 @@ -require 'rails_helper' +# frozen_string_literal: true -RSpec.describe FormBuilder do +require "rails_helper" - describe 'associations' do - it { should belong_to(:windows_type) } - it { should have_many(:forms) } - it { should accept_nested_attributes_for(:forms) } +RSpec.describe(FormBuilder) do + describe "associations" do + it { is_expected.to(belong_to(:windows_type)) } + it { is_expected.to(have_many(:forms)) } + it { is_expected.to(accept_nested_attributes_for(:forms)) } end - describe 'validations' do + describe "validations" do subject { build(:form_builder, windows_type: create(:windows_type)) } - it { should validate_presence_of(:name) } + + it { is_expected.to(validate_presence_of(:name)) } end - it 'is valid with valid attributes' do - # Note: Factory needs windows_type association uncommented for create + it "is valid with valid attributes" do # rubocop:todo RSpec/NoExpectationExample + # NOTE: Factory needs windows_type association uncommented for create # expect(build(:form_builder)).to be_valid end # Add tests for methods like #report_type, #form_fields etc. # Add tests for scopes :workshop_logs, :monthly -end \ No newline at end of file +end diff --git a/spec/models/form_field_answer_option_spec.rb b/spec/models/form_field_answer_option_spec.rb index 8a31092e3..e9ad7c674 100644 --- a/spec/models/form_field_answer_option_spec.rb +++ b/spec/models/form_field_answer_option_spec.rb @@ -1,18 +1,13 @@ -require 'rails_helper' +# frozen_string_literal: true -RSpec.describe FormFieldAnswerOption do - # pending "add some examples to (or delete) #{__FILE__}" +require "rails_helper" - describe 'associations' do - it { should belong_to(:form_field) } - it { should belong_to(:answer_option) } - end +RSpec.describe(FormFieldAnswerOption) do + # pending "add some examples to (or delete) #{__FILE__}" - describe 'validations' do - # Add validation tests if any (e.g., presence) - # subject { build(:form_field_answer_option) } # Requires associations - # it { should validate_presence_of(:form_field_id) } - # it { should validate_presence_of(:answer_option_id) } + describe "associations" do + it { is_expected.to(belong_to(:form_field)) } + it { is_expected.to(belong_to(:answer_option)) } end # it 'is valid with valid attributes' do @@ -20,4 +15,4 @@ # # expect(build(:form_field_answer_option)).to be_valid # pending("Requires functional form_field/answer_option factories and associations uncommented") # end -end \ No newline at end of file +end diff --git a/spec/models/form_field_spec.rb b/spec/models/form_field_spec.rb index f41803c94..735a3b31b 100644 --- a/spec/models/form_field_spec.rb +++ b/spec/models/form_field_spec.rb @@ -1,37 +1,49 @@ -require 'rails_helper' +# frozen_string_literal: true -RSpec.describe FormField do +require "rails_helper" + +RSpec.describe(FormField) do # pending "add some examples to (or delete) #{__FILE__}" - describe 'associations' do - it { should belong_to(:form).inverse_of(:form_fields) } - it { should have_many(:form_field_answer_options).dependent(:destroy) } - it { should have_many(:report_form_field_answers).dependent(:destroy) } - it { should have_many(:answer_options).through(:form_field_answer_options) } - it { should have_many(:childs).class_name('FormField').with_foreign_key('parent_id') } + describe "associations" do + it { is_expected.to(belong_to(:form).inverse_of(:form_fields)) } + it { is_expected.to(have_many(:form_field_answer_options).dependent(:destroy)) } + it { is_expected.to(have_many(:report_form_field_answers).dependent(:destroy)) } + it { is_expected.to(have_many(:answer_options).through(:form_field_answer_options)) } + it { is_expected.to(have_many(:childs).class_name("FormField").with_foreign_key("parent_id")) } # belongs_to :parent is implied but not explicitly stated, test if needed - # it { should belong_to(:parent).class_name('FormField').optional } + # it { should belong_to(:parent).class_name('FormField').optional } - it { should accept_nested_attributes_for(:form_field_answer_options) } + it { is_expected.to(accept_nested_attributes_for(:form_field_answer_options)) } end - describe 'validations' do + describe "validations" do # Requires form association for create - subject do + subject do create(:permission, :adult) create(:permission, :children) create(:permission, :combined) build(:form_field, form: create(:form)) end - it { should validate_presence_of(:question) } + + it { is_expected.to(validate_presence_of(:question)) } end - describe 'enums' do - it { should define_enum_for(:status).with_values([:inactive, :active]) } - it { should define_enum_for(:answer_type).with_values([:free_form_input_one_line, :free_form_input_paragraph, - :multiple_choice_radio, :no_user_input, :multiple_choice_checkbox, - :group_header]) } - it { should define_enum_for(:answer_datatype).with_values([:text_alphanumeric, :number_integer, :number_decimal, :date,]) } + describe "enums" do + it { is_expected.to(define_enum_for(:status).with_values([:inactive, :active])) } + + it { + expect(subject).to(define_enum_for(:answer_type).with_values([ # rubocop:todo RSpec/NamedSubject + :free_form_input_one_line, + :free_form_input_paragraph, + :multiple_choice_radio, + :no_user_input, + :multiple_choice_checkbox, + :group_header, + ])) + } + + it { is_expected.to(define_enum_for(:answer_datatype).with_values([:text_alphanumeric, :number_integer, :number_decimal, :date])) } end # it 'is valid with valid attributes' do @@ -41,4 +53,4 @@ # end # Add tests for methods like #name, #multiple_choice?, #html_id, etc. -end \ No newline at end of file +end diff --git a/spec/models/form_spec.rb b/spec/models/form_spec.rb index 3dae09517..10cc98692 100644 --- a/spec/models/form_spec.rb +++ b/spec/models/form_spec.rb @@ -1,22 +1,17 @@ -require 'rails_helper' +# frozen_string_literal: true -RSpec.describe Form do - # pending "add some examples to (or delete) #{__FILE__}" +require "rails_helper" - describe 'associations' do - it { should belong_to(:owner) } # Polymorphic - it { should have_many(:form_fields).dependent(:destroy).inverse_of(:form) } - it { should have_many(:user_forms) } - it { should have_many(:reports) } # As :owner +RSpec.describe(Form) do + # pending "add some examples to (or delete) #{__FILE__}" - it { should accept_nested_attributes_for(:form_fields).allow_destroy(true) } - end + describe "associations" do + it { is_expected.to(belong_to(:owner)) } # Polymorphic + it { is_expected.to(have_many(:form_fields).dependent(:destroy).inverse_of(:form)) } + it { is_expected.to(have_many(:user_forms)) } + it { is_expected.to(have_many(:reports)) } # As :owner - describe 'validations' do - # Add validation tests if any - # subject { build(:form) } # Requires owner - # it { should validate_presence_of(:owner_id) } - # it { should validate_presence_of(:owner_type) } + it { is_expected.to(accept_nested_attributes_for(:form_fields).allow_destroy(true)) } end # it 'is valid with valid attributes' do @@ -25,9 +20,9 @@ # pending("Requires functional owner factory and association uncommented") # end - describe '#name' do + describe "#name" do # These tests remain relevant - let(:user_owner) do + let(:user_owner) do create(:permission, :adult) create(:permission, :children) create(:permission, :combined) @@ -35,18 +30,19 @@ end let(:form) { build(:form, owner: user_owner) } - context 'when owner is present' do - it 'returns owner name Form' do + context "when owner is present" do + it "returns owner name Form" do # Need to handle potential nil name from owner.try(:name) owner_name = user_owner.try(:name) || user_owner.email # Or however owner name is derived - expect(form.name).to eq("#{owner_name} Form") + expect(form.name).to(eq("#{owner_name} Form")) end end - context 'when owner is nil' do - it 'returns New Form' do + + context "when owner is nil" do + it "returns New Form" do form.owner = nil - expect(form.name).to eq('New Form') + expect(form.name).to(eq("New Form")) end end end -end \ No newline at end of file +end diff --git a/spec/models/image_spec.rb b/spec/models/image_spec.rb index d277e68ea..032e88e5e 100644 --- a/spec/models/image_spec.rb +++ b/spec/models/image_spec.rb @@ -1,20 +1,13 @@ -require 'rails_helper' +# frozen_string_literal: true -RSpec.describe Image do - # pending "add some examples to (or delete) #{__FILE__}" +require "rails_helper" - describe 'associations' do - it { should belong_to(:owner) } # Polymorphic - it { should belong_to(:report).optional } # Assuming report can be optional - end +RSpec.describe(Image) do + # pending "add some examples to (or delete) #{__FILE__}" - describe 'validations' do - # Paperclip matchers (might require paperclip-matchers gem and setup) - # it { should have_attached_file(:file) } - # it { should validate_attachment_content_type(:file) - # .allowing('image/jpeg', 'image/png', 'image/gif') - # .rejecting('text/plain', 'application/pdf') } - # Presence validation for file itself is usually handled by Paperclip/ActiveStorage + describe "associations" do + it { is_expected.to(belong_to(:owner)) } # Polymorphic + it { is_expected.to(belong_to(:report).optional) } # Assuming report can be optional end # it 'is valid with valid attributes' do @@ -22,4 +15,4 @@ # # expect(build(:image)).to be_valid # pending("Requires functional owner/report factories and associations uncommented") # end -end \ No newline at end of file +end diff --git a/spec/models/location_spec.rb b/spec/models/location_spec.rb index c6883f676..a93ad2785 100644 --- a/spec/models/location_spec.rb +++ b/spec/models/location_spec.rb @@ -1,24 +1,23 @@ -require 'rails_helper' +# frozen_string_literal: true -RSpec.describe Location do - # let(:location) { build(:location) } # Keep if needed +require "rails_helper" - describe 'associations' do - # it { should have_many(:projects) } # Model missing has_many - end +RSpec.describe(Location) do + # let(:location) { build(:location) } # Keep if needed - describe 'validations' do + describe "validations" do subject { build(:location) } - it { should validate_presence_of(:city) } - it { should validate_presence_of(:country) } + + it { is_expected.to(validate_presence_of(:city)) } + it { is_expected.to(validate_presence_of(:country)) } end - describe '#name' do - it 'returns the city and state' do + describe "#name" do + it "returns the city and state" do # Use attributes_for to easily access factory-generated values attrs = attributes_for(:location) location = build(:location, attrs) - expect(location.name).to eq("#{attrs[:city]}, #{attrs[:state]}") + expect(location.name).to(eq("#{attrs[:city]}, #{attrs[:state]}")) end end -end \ No newline at end of file +end diff --git a/spec/models/media_file_spec.rb b/spec/models/media_file_spec.rb index dbcbba81b..a37a77051 100644 --- a/spec/models/media_file_spec.rb +++ b/spec/models/media_file_spec.rb @@ -1,23 +1,25 @@ -require 'rails_helper' +# frozen_string_literal: true -RSpec.describe MediaFile do +require "rails_helper" + +RSpec.describe(MediaFile) do # pending "add some examples to (or delete) #{__FILE__}" - describe 'associations' do - it { should belong_to(:report).optional } + describe "associations" do + it { is_expected.to(belong_to(:report).optional) } # it { should belong_to(:workshop).optional } # Fails: DB missing workshop_id column? - it { should belong_to(:workshop_log).optional } + it { is_expected.to(belong_to(:workshop_log).optional) } end - describe 'validations' do + describe "validations" do # Using shoulda matchers for Paperclip validations - it { should have_attached_file(:file) } - it { should validate_attachment_content_type(:file).allowing(MediaFile::FORM_FILE_CONTENT_TYPES).rejecting('text/plain', 'text/html') } + it { is_expected.to(have_attached_file(:file)) } + it { is_expected.to(validate_attachment_content_type(:file).allowing(MediaFile::FORM_FILE_CONTENT_TYPES).rejecting("text/plain", "text/html")) } end - it 'is valid with valid attributes' do + it "is valid with valid attributes" do report = build_stubbed(:report) media_file = build(:media_file, report: report) - expect(media_file).to be_valid + expect(media_file).to(be_valid) end -end \ No newline at end of file +end diff --git a/spec/models/metadatum_spec.rb b/spec/models/metadatum_spec.rb index 2b38faa04..64c444e04 100644 --- a/spec/models/metadatum_spec.rb +++ b/spec/models/metadatum_spec.rb @@ -1,26 +1,30 @@ -require 'rails_helper' +# frozen_string_literal: true -RSpec.describe Metadatum do +require "rails_helper" + +RSpec.describe(Metadatum) do # let(:metadatum) { build(:metadatum) } # Keep if needed - describe 'associations' do - it { should have_many(:categories).dependent(:destroy) } - it { should have_many(:categorizable_items).through(:categories).dependent(:destroy) } + describe "associations" do + it { is_expected.to(have_many(:categories).dependent(:destroy)) } + it { is_expected.to(have_many(:categorizable_items).through(:categories).dependent(:destroy)) } end - describe 'validations' do - let!(:existing_metadatum) { create(:metadatum) } + describe "validations" do subject { build(:metadatum, name: existing_metadatum.name) } - it { should validate_presence_of(:name) } + + let!(:existing_metadatum) { create(:metadatum) } + + it { is_expected.to(validate_presence_of(:name)) } end - describe 'scopes' do + describe "scopes" do let!(:published_meta) { create(:metadatum, published: true) } let!(:unpublished_meta) { create(:metadatum, published: false) } - it '.published returns only published metadata' do - expect(Metadatum.published).to include(published_meta) - expect(Metadatum.published).not_to include(unpublished_meta) + it ".published returns only published metadata" do + expect(described_class.published).to(include(published_meta)) + expect(described_class.published).not_to(include(unpublished_meta)) end end -end \ No newline at end of file +end diff --git a/spec/models/monthly_report_spec.rb b/spec/models/monthly_report_spec.rb index b6d4de57a..2a47ab25e 100644 --- a/spec/models/monthly_report_spec.rb +++ b/spec/models/monthly_report_spec.rb @@ -1,25 +1,17 @@ -require 'rails_helper' +# frozen_string_literal: true -RSpec.describe MonthlyReport do - it 'is a type of Report' do - expect(build(:monthly_report)).to be_a(Report) - end - - describe 'associations' do - # Inherited from Report - # Add specific MonthlyReport associations if any - end +require "rails_helper" - describe 'validations' do - # Inherited from Report - # Add specific MonthlyReport validations if any +RSpec.describe(MonthlyReport) do + it "is a type of Report" do + expect(build(:monthly_report)).to(be_a(Report)) end - it 'is valid with valid attributes' do - # Note: Factory needs associations uncommented for create (from Report factory) + it "is valid with valid attributes" do # rubocop:todo RSpec/NoExpectationExample + # NOTE: Factory needs associations uncommented for create (from Report factory) # expect(build(:monthly_report)).to be_valid # pending("Requires functional user/project/windows_type factories and associations") end # Add tests specific to MonthlyReport if any -end \ No newline at end of file +end diff --git a/spec/models/notification_spec.rb b/spec/models/notification_spec.rb index b2e4dd1e5..7fc75d957 100644 --- a/spec/models/notification_spec.rb +++ b/spec/models/notification_spec.rb @@ -1,12 +1,13 @@ -require 'rails_helper' +# frozen_string_literal: true -RSpec.describe Notification do +require "rails_helper" - describe 'associations' do - it { should belong_to(:noticeable) } +RSpec.describe(Notification) do + describe "associations" do + it { is_expected.to(belong_to(:noticeable)) } end - describe 'enums' do - it { should define_enum_for(:notification_type).with_values([:created, :updated]) } + describe "enums" do + it { is_expected.to(define_enum_for(:notification_type).with_values([:created, :updated])) } end -end \ No newline at end of file +end diff --git a/spec/models/permission_spec.rb b/spec/models/permission_spec.rb index 0c5a3d0cb..e13b4bc99 100644 --- a/spec/models/permission_spec.rb +++ b/spec/models/permission_spec.rb @@ -1,28 +1,21 @@ -require 'rails_helper' +# frozen_string_literal: true -RSpec.describe Permission do +require "rails_helper" - describe 'associations' do - it { should have_many(:user_permissions) } - it { should have_many(:users).through(:user_permissions) } +RSpec.describe(Permission) do + describe "associations" do + it { is_expected.to(have_many(:user_permissions)) } + it { is_expected.to(have_many(:users).through(:user_permissions)) } end - describe 'validations' do - # Assuming security_cat should be present and unique - subject { build(:permission) } - # it { should validate_presence_of(:security_cat) } # Model missing validation - # Uniqueness test would require create - # it { should validate_uniqueness_of(:security_cat) } + it "is valid with valid attributes" do + expect(build(:permission)).to(be_valid) end - it 'is valid with valid attributes' do - expect(build(:permission)).to be_valid - end - - describe '#name' do - it 'returns the security_cat' do + describe "#name" do + it "returns the security_cat" do permission = build(:permission, security_cat: "Test Category") - expect(permission.name).to eq("Test Category") + expect(permission.name).to(eq("Test Category")) end end -end \ No newline at end of file +end diff --git a/spec/models/project_obligation_spec.rb b/spec/models/project_obligation_spec.rb index b353410f9..1cdf6a21a 100644 --- a/spec/models/project_obligation_spec.rb +++ b/spec/models/project_obligation_spec.rb @@ -1,19 +1,9 @@ -require 'rails_helper' +# frozen_string_literal: true -RSpec.describe ProjectObligation do +require "rails_helper" - describe 'associations' do - # Add association tests if any (e.g., has_many :projects?) +RSpec.describe(ProjectObligation) do + it "is valid with valid attributes" do + expect(build(:project_obligation)).to(be_valid) end - - describe 'validations' do - # Assuming name should be present and unique - subject { build(:project_obligation) } - # it { should validate_presence_of(:name) } # Model missing validation - # it { should validate_uniqueness_of(:name) } # Requires create - end - - it 'is valid with valid attributes' do - expect(build(:project_obligation)).to be_valid - end -end \ No newline at end of file +end diff --git a/spec/models/project_spec.rb b/spec/models/project_spec.rb index 3c610328e..b4fe4e086 100644 --- a/spec/models/project_spec.rb +++ b/spec/models/project_spec.rb @@ -1,31 +1,24 @@ -require 'rails_helper' +# frozen_string_literal: true -RSpec.describe Project do - # pending "add some examples to (or delete) #{__FILE__}" +require "rails_helper" - describe 'associations' do - it { should belong_to(:location) } - it { should belong_to(:windows_type) } - it { should belong_to(:project_status) } - it { should have_many(:project_users) } - it { should have_many(:users).through(:project_users) } - it { should have_many(:reports).through(:users) } - it { should have_many(:workshop_logs).through(:users) } - end +RSpec.describe(Project) do + # pending "add some examples to (or delete) #{__FILE__}" - describe 'validations' do - # Add validation tests if any (e.g., presence of name, associations) - # subject { build(:project) } # Requires associations - # it { should validate_presence_of(:name) } - # it { should validate_presence_of(:location) } - # it { should validate_presence_of(:windows_type) } - # it { should validate_presence_of(:project_status) } + describe "associations" do + it { is_expected.to(belong_to(:location)) } + it { is_expected.to(belong_to(:windows_type)) } + it { is_expected.to(belong_to(:project_status)) } + it { is_expected.to(have_many(:project_users)) } + it { is_expected.to(have_many(:users).through(:project_users)) } + it { is_expected.to(have_many(:reports).through(:users)) } + it { is_expected.to(have_many(:workshop_logs).through(:users)) } end - it 'is valid with valid attributes' do - # Note: Factory needs associations uncommented for create + it "is valid with valid attributes" do # rubocop:todo RSpec/NoExpectationExample + # NOTE: Factory needs associations uncommented for create # expect(build(:project)).to be_valid end # Add tests for methods like #led_by?, #log_title -end \ No newline at end of file +end diff --git a/spec/models/project_status_spec.rb b/spec/models/project_status_spec.rb index 6f4107761..d2585026d 100644 --- a/spec/models/project_status_spec.rb +++ b/spec/models/project_status_spec.rb @@ -1,15 +1,9 @@ -require 'rails_helper' +# frozen_string_literal: true -RSpec.describe ProjectStatus do +require "rails_helper" - describe 'associations' do +RSpec.describe(ProjectStatus) do + it "is valid with valid attributes" do + expect(build(:project_status)).to(be_valid) end - - describe 'validations' do - subject { build(:project_status) } - end - - it 'is valid with valid attributes' do - expect(build(:project_status)).to be_valid - end -end \ No newline at end of file +end diff --git a/spec/models/project_user_spec.rb b/spec/models/project_user_spec.rb index ee9e5d5c5..a46e8c233 100644 --- a/spec/models/project_user_spec.rb +++ b/spec/models/project_user_spec.rb @@ -1,29 +1,31 @@ -require 'rails_helper' +# frozen_string_literal: true -RSpec.describe ProjectUser do +require "rails_helper" - describe 'associations' do - it { should belong_to(:project) } - it { should belong_to(:user) } +RSpec.describe(ProjectUser) do + describe "associations" do + it { is_expected.to(belong_to(:project)) } + it { is_expected.to(belong_to(:user)) } end - describe 'validations' do - subject do + describe "validations" do + subject do create(:permission, :adult) create(:permission, :children) create(:permission, :combined) build(:project_user, project: create(:project), user: create(:user)) end - it { should validate_presence_of(:project_id) } + + it { is_expected.to(validate_presence_of(:project_id)) } end - describe 'enums' do - it { should define_enum_for(:position).with_values([:default, :liaison, :leader, :assistant]) } + describe "enums" do + it { is_expected.to(define_enum_for(:position).with_values([:default, :liaison, :leader, :assistant])) } end - it 'is valid with valid attributes' do - # Note: Factory needs associations uncommented for create + it "is valid with valid attributes" do # rubocop:todo RSpec/NoExpectationExample + # NOTE: Factory needs associations uncommented for create # expect(build(:project_user)).to be_valid # pending("Requires functional project/user factories and associations uncommented") end -end \ No newline at end of file +end diff --git a/spec/models/quotable_item_quote_spec.rb b/spec/models/quotable_item_quote_spec.rb index 86b22c3ce..b10155357 100644 --- a/spec/models/quotable_item_quote_spec.rb +++ b/spec/models/quotable_item_quote_spec.rb @@ -1,20 +1,14 @@ -require 'rails_helper' +# frozen_string_literal: true -RSpec.describe QuotableItemQuote do - # pending "add some examples to (or delete) #{__FILE__}" +require "rails_helper" - describe 'associations' do - it { should belong_to(:quote) } - it { should belong_to(:quotable) } # Polymorphic - it { should accept_nested_attributes_for(:quote) } - end +RSpec.describe(QuotableItemQuote) do + # pending "add some examples to (or delete) #{__FILE__}" - describe 'validations' do - # Add validation tests if any (e.g., presence) - # subject { build(:quotable_item_quote) } # Requires associations - # it { should validate_presence_of(:quote_id) } - # it { should validate_presence_of(:quotable_id) } - # it { should validate_presence_of(:quotable_type) } + describe "associations" do + it { is_expected.to(belong_to(:quote)) } + it { is_expected.to(belong_to(:quotable)) } # Polymorphic + it { is_expected.to(accept_nested_attributes_for(:quote)) } end # it 'is valid with valid attributes' do @@ -22,4 +16,4 @@ # # expect(build(:quotable_item_quote)).to be_valid # pending("Requires functional quote/quotable factories and associations uncommented") # end -end \ No newline at end of file +end diff --git a/spec/models/quote_spec.rb b/spec/models/quote_spec.rb index 2a1e4a276..9168c3c13 100644 --- a/spec/models/quote_spec.rb +++ b/spec/models/quote_spec.rb @@ -1,49 +1,38 @@ -require 'rails_helper' +# frozen_string_literal: true -RSpec.describe Quote do - # pending "add some examples to (or delete) #{__FILE__}" - - describe 'associations' do - # it { should have_many(:quotable_item_quotes) } # Model missing has_many - # Through associations can sometimes be tricky, test if needed - # it { should have_many(:reports).through(:quotable_item_quotes).source(:quotable).source_type('Report') } - # it { should have_many(:workshops).through(:quotable_item_quotes).source(:quotable).source_type('Workshop') } - end +require "rails_helper" - describe 'validations' do - subject { build(:quote) } - # it { should validate_presence_of(:quote) } # Model missing validation - # Add other validations if needed (e.g., age, gender format) - end +RSpec.describe(Quote) do + # pending "add some examples to (or delete) #{__FILE__}" - describe 'scopes' do + describe "scopes" do let!(:active_quote) { create(:quote, inactive: false) } let!(:inactive_quote) { create(:quote, inactive: true) } - it '.active returns only active quotes' do - expect(Quote.active).to include(active_quote) - expect(Quote.active).not_to include(inactive_quote) + it ".active returns only active quotes" do + expect(described_class.active).to(include(active_quote)) + expect(described_class.active).not_to(include(inactive_quote)) end end - describe '#speaker' do - it 'returns speaker_name if present' do + describe "#speaker" do + it "returns speaker_name if present" do quote = build(:quote, speaker_name: "John Doe") - expect(quote.speaker).to eq("John Doe") + expect(quote.speaker).to(eq("John Doe")) end it 'returns "Participant" if speaker_name is nil' do quote = build(:quote, speaker_name: nil) - expect(quote.speaker).to eq("Participant") + expect(quote.speaker).to(eq("Participant")) end it 'returns "Participant" if speaker_name is empty' do quote = build(:quote, speaker_name: "") - expect(quote.speaker).to eq("Participant") + expect(quote.speaker).to(eq("Participant")) end end - it 'is valid with valid attributes' do - expect(build(:quote)).to be_valid + it "is valid with valid attributes" do + expect(build(:quote)).to(be_valid) end -end \ No newline at end of file +end diff --git a/spec/models/report_form_field_answer_spec.rb b/spec/models/report_form_field_answer_spec.rb index 8d45f9f28..c9bd708f8 100644 --- a/spec/models/report_form_field_answer_spec.rb +++ b/spec/models/report_form_field_answer_spec.rb @@ -1,10 +1,11 @@ -require 'rails_helper' +# frozen_string_literal: true -RSpec.describe ReportFormFieldAnswer do +require "rails_helper" - describe 'associations' do - it { should belong_to(:report) } - it { should belong_to(:form_field) } - it { should belong_to(:answer_option).optional } +RSpec.describe(ReportFormFieldAnswer) do + describe "associations" do + it { is_expected.to(belong_to(:report)) } + it { is_expected.to(belong_to(:form_field)) } + it { is_expected.to(belong_to(:answer_option).optional) } end -end \ No newline at end of file +end diff --git a/spec/models/report_spec.rb b/spec/models/report_spec.rb index 51a3a5d32..1aafd3945 100644 --- a/spec/models/report_spec.rb +++ b/spec/models/report_spec.rb @@ -1,40 +1,41 @@ -require 'rails_helper' +# frozen_string_literal: true -RSpec.describe Report do +require "rails_helper" - describe 'associations' do - it { should belong_to(:user) } - it { should belong_to(:project) } - it { should belong_to(:windows_type) } - it { should belong_to(:owner).optional } - it { should have_one(:form) } - it { should have_one(:image) } - it { should have_many(:images) } - it { should have_many(:form_fields).through(:form) } - it { should have_many(:report_form_field_answers).dependent(:destroy) } - it { should have_many(:quotable_item_quotes).dependent(:destroy) } - it { should have_many(:quotes).through(:quotable_item_quotes).dependent(:destroy) } - it { should have_many(:notifications).dependent(:destroy) } - it { should have_many(:sectorable_items).dependent(:destroy) } - it { should have_many(:sectors).through(:sectorable_items).dependent(:destroy) } - it { should have_many(:media_files).dependent(:destroy) } +RSpec.describe(Report) do + describe "associations" do + it { is_expected.to(belong_to(:user)) } + it { is_expected.to(belong_to(:project)) } + it { is_expected.to(belong_to(:windows_type)) } + it { is_expected.to(belong_to(:owner).optional) } + it { is_expected.to(have_one(:form)) } + it { is_expected.to(have_one(:image)) } + it { is_expected.to(have_many(:images)) } + it { is_expected.to(have_many(:form_fields).through(:form)) } + it { is_expected.to(have_many(:report_form_field_answers).dependent(:destroy)) } + it { is_expected.to(have_many(:quotable_item_quotes).dependent(:destroy)) } + it { is_expected.to(have_many(:quotes).through(:quotable_item_quotes).dependent(:destroy)) } + it { is_expected.to(have_many(:notifications).dependent(:destroy)) } + it { is_expected.to(have_many(:sectorable_items).dependent(:destroy)) } + it { is_expected.to(have_many(:sectors).through(:sectorable_items).dependent(:destroy)) } + it { is_expected.to(have_many(:media_files).dependent(:destroy)) } - it { should accept_nested_attributes_for(:media_files) } - it { should accept_nested_attributes_for(:report_form_field_answers) } - it { should accept_nested_attributes_for(:quotable_item_quotes) } + it { is_expected.to(accept_nested_attributes_for(:media_files)) } + it { is_expected.to(accept_nested_attributes_for(:report_form_field_answers)) } + it { is_expected.to(accept_nested_attributes_for(:quotable_item_quotes)) } end - describe 'validations' do + describe "validations" do # Paperclip validation for form_file - it { should have_attached_file(:form_file) } - it { should validate_attachment_content_type(:form_file).allowing(Report::FORM_FILE_CONTENT_TYPES).rejecting('text/plain', 'text/html') } + it { is_expected.to(have_attached_file(:form_file)) } + it { is_expected.to(validate_attachment_content_type(:form_file).allowing(Report::FORM_FILE_CONTENT_TYPES).rejecting("text/plain", "text/html")) } # Custom validation for image would need a more involved test - context 'with invalid image' do - it 'validates associated image' do + context "with invalid image" do + it "validates associated image" do report = build(:report, image: build(:image, :invalid_format)) - expect(report).not_to be_valid + expect(report).not_to(be_valid) end end end -end \ No newline at end of file +end diff --git a/spec/models/resource_spec.rb b/spec/models/resource_spec.rb index bbd633cc1..9f92e8bdf 100644 --- a/spec/models/resource_spec.rb +++ b/spec/models/resource_spec.rb @@ -1,33 +1,35 @@ -require 'rails_helper' +# frozen_string_literal: true -RSpec.describe Resource do +require "rails_helper" + +RSpec.describe(Resource) do # pending "add some examples to (or delete) #{__FILE__}" - describe 'associations' do - it { should belong_to(:user) } - it { should belong_to(:workshop).optional } - it { should belong_to(:windows_type) } - it { should have_many(:images).dependent(:destroy) } # As owner - it { should have_many(:categorizable_items).dependent(:destroy) } # As categorizable - it { should have_many(:categories).through(:categorizable_items) } - it { should have_many(:sectorable_items).dependent(:destroy) } # As sectorable - it { should have_many(:sectors).through(:sectorable_items) } + describe "associations" do + it { is_expected.to(belong_to(:user)) } + it { is_expected.to(belong_to(:workshop).optional) } + it { is_expected.to(belong_to(:windows_type)) } + it { is_expected.to(have_many(:images).dependent(:destroy)) } # As owner + it { is_expected.to(have_many(:categorizable_items).dependent(:destroy)) } # As categorizable + it { is_expected.to(have_many(:categories).through(:categorizable_items)) } + it { is_expected.to(have_many(:sectorable_items).dependent(:destroy)) } # As sectorable + it { is_expected.to(have_many(:sectors).through(:sectorable_items)) } # related_workshops through sectors through sectorable_items - complex, test manually if needed # it { should have_many(:related_workshops).through(:sectors) } - it { should have_many(:attachments).dependent(:destroy) } # As owner - it { should have_many(:reports) } # As owner - it { should have_many(:workshop_resources).dependent(:destroy) } - it { should have_one(:form) } # As owner + it { is_expected.to(have_many(:attachments).dependent(:destroy)) } # As owner + it { is_expected.to(have_many(:reports)) } # As owner + it { is_expected.to(have_many(:workshop_resources).dependent(:destroy)) } + it { is_expected.to(have_one(:form)) } # As owner # Nested Attributes - it { should accept_nested_attributes_for(:categorizable_items).allow_destroy(true) } - it { should accept_nested_attributes_for(:sectorable_items).allow_destroy(true) } - it { should accept_nested_attributes_for(:images).allow_destroy(true) } - it { should accept_nested_attributes_for(:attachments).allow_destroy(true) } - it { should accept_nested_attributes_for(:form).allow_destroy(true) } + it { is_expected.to(accept_nested_attributes_for(:categorizable_items).allow_destroy(true)) } + it { is_expected.to(accept_nested_attributes_for(:sectorable_items).allow_destroy(true)) } + it { is_expected.to(accept_nested_attributes_for(:images).allow_destroy(true)) } + it { is_expected.to(accept_nested_attributes_for(:attachments).allow_destroy(true)) } + it { is_expected.to(accept_nested_attributes_for(:form).allow_destroy(true)) } end - describe 'validations' do + describe "validations" do # Requires associations for create subject do create(:permission, :adult) @@ -35,13 +37,14 @@ create(:permission, :combined) build(:resource, user: create(:user), windows_type: create(:windows_type)) end - it { should validate_presence_of(:title) } + + it { is_expected.to(validate_presence_of(:title)) } end - it 'is valid with valid attributes' do - # Note: Factory needs associations uncommented for create + it "is valid with valid attributes" do # rubocop:todo RSpec/NoExpectationExample + # NOTE: Factory needs associations uncommented for create # expect(build(:resource)).to be_valid end # Add tests for methods like #name, #main_image_url, scopes, SearchCop etc. -end \ No newline at end of file +end diff --git a/spec/models/sector_spec.rb b/spec/models/sector_spec.rb index 4296b4b36..8a85f3caa 100644 --- a/spec/models/sector_spec.rb +++ b/spec/models/sector_spec.rb @@ -1,15 +1,19 @@ -require 'rails_helper' +# frozen_string_literal: true -RSpec.describe Sector do - describe 'associations' do - it { should have_many(:sectorable_items).dependent(:destroy) } - it { should have_many(:workshops).through(:sectorable_items) } - it { should have_many(:quotes).through(:workshops) } +require "rails_helper" + +RSpec.describe(Sector) do + describe "associations" do + it { is_expected.to(have_many(:sectorable_items).dependent(:destroy)) } + it { is_expected.to(have_many(:workshops).through(:sectorable_items)) } + it { is_expected.to(have_many(:quotes).through(:workshops)) } end - describe 'validations' do - let!(:existing_sector) { create(:sector) } + describe "validations" do subject { build(:sector, name: existing_sector.name) } - it { should validate_presence_of(:name) } + + let!(:existing_sector) { create(:sector) } + + it { is_expected.to(validate_presence_of(:name)) } end -end \ No newline at end of file +end diff --git a/spec/models/sectorable_item_spec.rb b/spec/models/sectorable_item_spec.rb index bb05ac3c4..9d5b5d11b 100644 --- a/spec/models/sectorable_item_spec.rb +++ b/spec/models/sectorable_item_spec.rb @@ -1,21 +1,13 @@ -require 'rails_helper' +# frozen_string_literal: true -RSpec.describe SectorableItem do - # pending "add some examples to (or delete) #{__FILE__}" +require "rails_helper" - describe 'associations' do - it { should belong_to(:sector) } - it { should belong_to(:sectorable) } # Polymorphic - end +RSpec.describe(SectorableItem) do + # pending "add some examples to (or delete) #{__FILE__}" - describe 'validations' do - # Add validation tests if uncommented in model (presence, uniqueness) - # subject { build(:sectorable_item) } # Requires associations - # it { should validate_presence_of(:sector_id) } - # it { should validate_presence_of(:sectorable_id) } - # it { should validate_presence_of(:sectorable_type) } - # Uniqueness requires create and proper scoping: - # it { should validate_uniqueness_of(:sector_id).scoped_to([:sectorable_type, :sectorable_id]) } + describe "associations" do + it { is_expected.to(belong_to(:sector)) } + it { is_expected.to(belong_to(:sectorable)) } # Polymorphic end # it 'is valid with valid attributes' do @@ -23,4 +15,4 @@ # # expect(build(:sectorable_item)).to be_valid # pending("Requires functional sector/sectorable factories and associations uncommented") # end -end \ No newline at end of file +end diff --git a/spec/models/story_spec.rb b/spec/models/story_spec.rb index 2f354c478..ae12e5b05 100644 --- a/spec/models/story_spec.rb +++ b/spec/models/story_spec.rb @@ -1,26 +1,17 @@ -require 'rails_helper' +# frozen_string_literal: true -RSpec.describe Story do +require "rails_helper" - it 'is a type of Report' do - expect(build(:story)).to be_a(Report) +RSpec.describe(Story) do + it "is a type of Report" do + expect(build(:story)).to(be_a(Report)) end - describe 'associations' do - # Inherited from Report - # Add specific Story associations if any - end - - describe 'validations' do - # Inherited from Report - # Add specific Story validations if any - end - - it 'is valid with valid attributes' do - # Note: Factory needs associations uncommented for create (from Report factory) + it "is valid with valid attributes" do # rubocop:todo RSpec/NoExpectationExample + # NOTE: Factory needs associations uncommented for create (from Report factory) # expect(build(:story)).to be_valid # pending("Requires functional user/project/windows_type factories and associations uncommented") end # Add tests specific to Story if any -end \ No newline at end of file +end diff --git a/spec/models/user_form_form_field_spec.rb b/spec/models/user_form_form_field_spec.rb index 3d0776340..421e16b91 100644 --- a/spec/models/user_form_form_field_spec.rb +++ b/spec/models/user_form_form_field_spec.rb @@ -1,19 +1,13 @@ -require 'rails_helper' +# frozen_string_literal: true -RSpec.describe UserFormFormField do - # pending "add some examples to (or delete) #{__FILE__}" +require "rails_helper" - describe 'associations' do - it { should belong_to(:form_field) } - it { should belong_to(:user_form) } - end +RSpec.describe(UserFormFormField) do + # pending "add some examples to (or delete) #{__FILE__}" - describe 'validations' do - # Add validation tests if any (e.g., presence of associations, text?) - # subject { build(:user_form_form_field) } # Requires associations - # it { should validate_presence_of(:form_field_id) } - # it { should validate_presence_of(:user_form_id) } - # it { should validate_presence_of(:text) } + describe "associations" do + it { is_expected.to(belong_to(:form_field)) } + it { is_expected.to(belong_to(:user_form)) } end # it 'is valid with valid attributes' do @@ -21,4 +15,4 @@ # # expect(build(:user_form_form_field)).to be_valid # pending("Requires functional form_field/user_form factories and associations uncommented") # end -end \ No newline at end of file +end diff --git a/spec/models/user_form_spec.rb b/spec/models/user_form_spec.rb index b798e4098..af4c76748 100644 --- a/spec/models/user_form_spec.rb +++ b/spec/models/user_form_spec.rb @@ -1,20 +1,15 @@ -require 'rails_helper' +# frozen_string_literal: true -RSpec.describe UserForm do - # pending "add some examples to (or delete) #{__FILE__}" +require "rails_helper" - describe 'associations' do - it { should belong_to(:user) } - it { should belong_to(:form) } - it { should have_many(:user_form_form_fields) } - it { should accept_nested_attributes_for(:user_form_form_fields) } - end +RSpec.describe(UserForm) do + # pending "add some examples to (or delete) #{__FILE__}" - describe 'validations' do - # Add validation tests if any (e.g., presence) - # subject { build(:user_form) } # Requires associations - # it { should validate_presence_of(:user_id) } - # it { should validate_presence_of(:form_id) } + describe "associations" do + it { is_expected.to(belong_to(:user)) } + it { is_expected.to(belong_to(:form)) } + it { is_expected.to(have_many(:user_form_form_fields)) } + it { is_expected.to(accept_nested_attributes_for(:user_form_form_fields)) } end # it 'is valid with valid attributes' do @@ -22,4 +17,4 @@ # # expect(build(:user_form)).to be_valid # pending("Requires functional user/form factories and associations uncommented") # end -end \ No newline at end of file +end diff --git a/spec/models/user_permission_spec.rb b/spec/models/user_permission_spec.rb index 6dd8c9529..e0a38f539 100644 --- a/spec/models/user_permission_spec.rb +++ b/spec/models/user_permission_spec.rb @@ -1,19 +1,13 @@ -require 'rails_helper' +# frozen_string_literal: true -RSpec.describe UserPermission do - # pending "add some examples to (or delete) #{__FILE__}" +require "rails_helper" - describe 'associations' do - it { should belong_to(:user) } - it { should belong_to(:permission) } - end +RSpec.describe(UserPermission) do + # pending "add some examples to (or delete) #{__FILE__}" - describe 'validations' do - # Add validation tests if any (e.g., presence, uniqueness scope) - # subject { build(:user_permission) } # Requires associations - # it { should validate_presence_of(:user_id) } - # it { should validate_presence_of(:permission_id) } - # it { should validate_uniqueness_of(:user_id).scoped_to(:permission_id) } # Requires create + describe "associations" do + it { is_expected.to(belong_to(:user)) } + it { is_expected.to(belong_to(:permission)) } end # it 'is valid with valid attributes' do @@ -21,4 +15,4 @@ # # expect(build(:user_permission)).to be_valid # pending("Requires functional user/permission factories and associations uncommented") # end -end \ No newline at end of file +end diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index 0905cdf07..63910dc66 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -1,68 +1,73 @@ -require 'rails_helper' +# frozen_string_literal: true -RSpec.describe User do +require "rails_helper" + +RSpec.describe(User) do # Use FactoryBot # let(:user) { build(:user) } # Keep build for simple validation tests # Create permissions needed by the after_create callback - before(:all) do - create(:permission, security_cat: "Combined Adult and Children's Windows") unless Permission.exists?(security_cat: "Combined Adult and Children's Windows") - create(:permission, security_cat: "Adult Windows") unless Permission.exists?(security_cat: "Adult Windows") - create(:permission, security_cat: "Children's Windows") unless Permission.exists?(security_cat: "Children's Windows") + before(:all) do # rubocop:todo RSpec/BeforeAfterAll + create(:permission, security_cat: "Combined Adult and Children's Windows") unless Permission.exists?(security_cat: "Combined Adult and Children's Windows") + create(:permission, security_cat: "Adult Windows") unless Permission.exists?(security_cat: "Adult Windows") + create(:permission, security_cat: "Children's Windows") unless Permission.exists?(security_cat: "Children's Windows") end - describe 'associations' do + describe "associations" do # Need create for association tests to work correctly with callbacks subject { create(:user) } - it { should have_many(:workshops) } - it { should have_many(:workshop_logs) } - it { should have_many(:reports) } + it { is_expected.to(have_many(:workshops)) } + it { is_expected.to(have_many(:workshop_logs)) } + it { is_expected.to(have_many(:reports)) } # Through associations require more setup, test manually if complex # it { should have_many(:communal_reports).through(:projects).source(:reports) } - it { should have_many(:bookmarks).dependent(:destroy) } - it { should have_many(:bookmarked_workshops).through(:bookmarks).source(:bookmarkable) } - it { should have_many(:project_users).dependent(:destroy) } - it { should have_many(:projects).through(:project_users) } - it { should have_many(:windows_types).through(:projects) } - it { should have_many(:user_permissions).dependent(:destroy) } - it { should have_many(:permissions).through(:user_permissions) } - it { should have_many(:resources) } - it { should have_many(:user_forms).dependent(:destroy) } - it { should have_many(:user_form_form_fields).through(:user_forms).dependent(:destroy) } + it { is_expected.to(have_many(:bookmarks).dependent(:destroy)) } + it { is_expected.to(have_many(:bookmarked_workshops).through(:bookmarks).source(:bookmarkable)) } + it { is_expected.to(have_many(:project_users).dependent(:destroy)) } + it { is_expected.to(have_many(:projects).through(:project_users)) } + it { is_expected.to(have_many(:windows_types).through(:projects)) } + it { is_expected.to(have_many(:user_permissions).dependent(:destroy)) } + it { is_expected.to(have_many(:permissions).through(:user_permissions)) } + it { is_expected.to(have_many(:resources)) } + it { is_expected.to(have_many(:user_forms).dependent(:destroy)) } + it { is_expected.to(have_many(:user_form_form_fields).through(:user_forms).dependent(:destroy)) } # Custom scope/select for colleagues might interfere # it { should have_many(:colleagues).through(:projects).source(:project_users) } - it { should have_many(:notifications) } # As :noticeable + it { is_expected.to(have_many(:notifications)) } # As :noticeable # Paperclip avatar # it { should have_attached_file(:avatar) } # Nested Attributes - it { should accept_nested_attributes_for(:user_forms) } - it { should accept_nested_attributes_for(:project_users).allow_destroy(true) } + it { is_expected.to(accept_nested_attributes_for(:user_forms)) } + it { is_expected.to(accept_nested_attributes_for(:project_users).allow_destroy(true)) } end - describe 'validations' do + describe "validations" do # Devise validations (presence tested manually below, uniqueness tested with subject) subject { create(:user) } # Use create for uniqueness tests - it { should validate_uniqueness_of(:email).case_insensitive } + # it { should validate_length_of(:password).is_at_least(Devise.password_length.first).is_at_most(Devise.password_length.last) } # Manual presence tests (using build is fine here) - let(:user) { build(:user) } - it 'is valid with valid attributes' do - expect(user).to be_valid + let(:user) { build(:user) } + + it { is_expected.to(validate_uniqueness_of(:email).case_insensitive) } + + it "is valid with valid attributes" do + expect(user).to(be_valid) end - it 'is invalid without an email' do + it "is invalid without an email" do user.email = nil - expect(user).not_to be_valid - expect(user.errors[:email]).to include("can't be blank") + expect(user).not_to(be_valid) + expect(user.errors[:email]).to(include("can't be blank")) end - it 'is invalid without a password' do + it "is invalid without a password" do user.password = nil - expect(user).not_to be_valid - expect(user.errors[:password]).to include("can't be blank") + expect(user).not_to(be_valid) + expect(user.errors[:password]).to(include("can't be blank")) end # Commented out validations in model @@ -73,32 +78,33 @@ # it { should validate_attachment_content_type(:avatar).allowing('image/png', 'image/jpeg', 'image/gif').rejecting('text/plain', 'application/pdf') } end - describe '#full_name' do + describe "#full_name" do # These tests remain relevant - let(:user) { build(:user) } - context 'when first_name is present' do - it 'returns the full name' do + let(:user) { build(:user) } + + context "when first_name is present" do + it "returns the full name" do user.first_name = "John" user.last_name = "Doe" - expect(user.full_name).to eq("John Doe") + expect(user.full_name).to(eq("John Doe")) end end - context 'when first_name is nil' do - it 'returns the email' do + context "when first_name is nil" do + it "returns the email" do user.first_name = nil - expect(user.full_name).to eq(user.email) + expect(user.full_name).to(eq(user.email)) end end - context 'when first_name is empty' do - it 'returns the email' do + context "when first_name is empty" do + it "returns the email" do user.first_name = "" - expect(user.full_name).to eq(user.email) + expect(user.full_name).to(eq(user.email)) end end end # Add tests for other methods like #active_for_authentication?, #has_liaison_position_for?, etc. # Test callbacks like :set_default_values, :before_destroy -end \ No newline at end of file +end diff --git a/spec/models/windows_type_spec.rb b/spec/models/windows_type_spec.rb index 7776a5b12..96c9fa343 100644 --- a/spec/models/windows_type_spec.rb +++ b/spec/models/windows_type_spec.rb @@ -1,21 +1,18 @@ -require 'rails_helper' +# frozen_string_literal: true -RSpec.describe WindowsType do +require "rails_helper" - describe 'associations' do - it { should have_many(:workshops) } - it { should have_many(:age_ranges) } - it { should have_many(:reports) } - it { should have_many(:form_builders) } +RSpec.describe(WindowsType) do + describe "associations" do + it { is_expected.to(have_many(:workshops)) } + it { is_expected.to(have_many(:age_ranges)) } + it { is_expected.to(have_many(:reports)) } + it { is_expected.to(have_many(:form_builders)) } end - describe 'validations' do - subject { build(:windows_type) } - end - - it 'is valid with valid attributes' do - expect(build(:windows_type)).to be_valid + it "is valid with valid attributes" do + expect(build(:windows_type)).to(be_valid) end # Add tests for methods like #label, #log_label, etc. -end \ No newline at end of file +end diff --git a/spec/models/workshop_age_range_spec.rb b/spec/models/workshop_age_range_spec.rb index e837b3aa6..a7b52fd85 100644 --- a/spec/models/workshop_age_range_spec.rb +++ b/spec/models/workshop_age_range_spec.rb @@ -1,14 +1,16 @@ -require 'rails_helper' +# frozen_string_literal: true -RSpec.describe WorkshopAgeRange do +require "rails_helper" + +RSpec.describe(WorkshopAgeRange) do # pending "add some examples to (or delete) #{__FILE__}" - describe 'associations' do - it { should belong_to(:workshop) } - it { should belong_to(:age_range) } + describe "associations" do + it { is_expected.to(belong_to(:workshop)) } + it { is_expected.to(belong_to(:age_range)) } end - describe 'validations' do + describe "validations" do # Need create for uniqueness test # Must create associated records first subject do @@ -20,14 +22,14 @@ create(:workshop_age_range, workshop: workshop, age_range: age_range) end - it { should validate_presence_of(:workshop_id) } - it { should validate_presence_of(:age_range_id) } - it { should validate_uniqueness_of(:workshop_id).scoped_to(:age_range_id) } + it { is_expected.to(validate_presence_of(:workshop_id)) } + it { is_expected.to(validate_presence_of(:age_range_id)) } + it { is_expected.to(validate_uniqueness_of(:workshop_id).scoped_to(:age_range_id)) } end - it 'is valid with valid attributes' do - # Note: Factory needs associations uncommented for create + it "is valid with valid attributes" do # rubocop:todo RSpec/NoExpectationExample + # NOTE: Factory needs associations uncommented for create # expect(build(:workshop_age_range)).to be_valid # pending("Requires functional workshop/age_range factories and associations uncommented") end -end \ No newline at end of file +end diff --git a/spec/models/workshop_idea_spec.rb b/spec/models/workshop_idea_spec.rb index 8632a2127..ce71901b5 100644 --- a/spec/models/workshop_idea_spec.rb +++ b/spec/models/workshop_idea_spec.rb @@ -1,29 +1,21 @@ -require 'rails_helper' +# frozen_string_literal: true -RSpec.describe WorkshopIdea do +require "rails_helper" - it 'is a type of Workshop' do - expect(build(:workshop_idea)).to be_a(Workshop) +RSpec.describe(WorkshopIdea) do + it "is a type of Workshop" do + expect(build(:workshop_idea)).to(be_a(Workshop)) end - describe 'associations' do - # Inherited from Workshop - end - - describe 'validations' do - # Inherited from Workshop - # Title presence is validated in Workshop - end - - it 'is valid with valid attributes' do - # Note: Factory needs associations uncommented for create (from Workshop factory) + it "is valid with valid attributes" do # rubocop:todo RSpec/NoExpectationExample + # NOTE: Factory needs associations uncommented for create (from Workshop factory) # expect(build(:workshop_idea)).to be_valid end - it 'defaults to inactive' do + it "defaults to inactive" do # Test the default scope - expect(build(:workshop_idea).inactive).to be true + expect(build(:workshop_idea).inactive).to(be(true)) end # Add tests specific to WorkshopIdea if any -end \ No newline at end of file +end diff --git a/spec/models/workshop_log_spec.rb b/spec/models/workshop_log_spec.rb index e5b9d4df6..288f5ab29 100644 --- a/spec/models/workshop_log_spec.rb +++ b/spec/models/workshop_log_spec.rb @@ -1,18 +1,20 @@ -require 'rails_helper' +# frozen_string_literal: true -RSpec.describe WorkshopLog do +require "rails_helper" + +RSpec.describe(WorkshopLog) do # pending "add some examples to (or delete) #{__FILE__}" - it 'is a type of Report' do - expect(build(:workshop_log)).to be_a(Report) + it "is a type of Report" do + expect(build(:workshop_log)).to(be_a(Report)) end - describe 'associations' do + describe "associations" do # Explicitly defined here - it { should belong_to(:workshop) } - it { should belong_to(:user) } # Inherited via Report but also explicit? - it { should belong_to(:project) } # Inherited via Report but also explicit? - it { should have_many(:media_files) } + it { is_expected.to(belong_to(:workshop)) } + it { is_expected.to(belong_to(:user)) } # Inherited via Report but also explicit? + it { is_expected.to(belong_to(:project)) } # Inherited via Report but also explicit? + it { is_expected.to(have_many(:media_files)) } # Inherited from Report # it { should belong_to(:windows_type) } @@ -21,18 +23,10 @@ # ... other Report associations end - describe 'validations' do - # Inherited from Report - # Add specific WorkshopLog validations if any - end - - it 'is valid with valid attributes' do - # Note: Factory needs associations uncommented for create + it "is valid with valid attributes" do # rubocop:todo RSpec/NoExpectationExample + # NOTE: Factory needs associations uncommented for create # expect(build(:workshop_log)).to be_valid end # Add tests for specific methods like #num_ongoing, #num_first_time, callbacks - describe 'callbacks' do - # Test after_save :update_workshop_log_count - end -end \ No newline at end of file +end diff --git a/spec/models/workshop_resource_spec.rb b/spec/models/workshop_resource_spec.rb index c7a2f7879..83fb11d2a 100644 --- a/spec/models/workshop_resource_spec.rb +++ b/spec/models/workshop_resource_spec.rb @@ -1,19 +1,13 @@ -require 'rails_helper' +# frozen_string_literal: true -RSpec.describe WorkshopResource do - # pending "add some examples to (or delete) #{__FILE__}" +require "rails_helper" - describe 'associations' do - it { should belong_to(:workshop) } - it { should belong_to(:resource) } - end +RSpec.describe(WorkshopResource) do + # pending "add some examples to (or delete) #{__FILE__}" - describe 'validations' do - # Add validation tests if any (e.g., presence, uniqueness scope) - # subject { build(:workshop_resource) } # Requires associations - # it { should validate_presence_of(:workshop_id) } - # it { should validate_presence_of(:resource_id) } - # it { should validate_uniqueness_of(:workshop_id).scoped_to(:resource_id) } # Requires create + describe "associations" do + it { is_expected.to(belong_to(:workshop)) } + it { is_expected.to(belong_to(:resource)) } end # it 'is valid with valid attributes' do @@ -21,4 +15,4 @@ # # expect(build(:workshop_resource)).to be_valid # pending("Requires functional workshop/resource factories and associations uncommented") # end -end \ No newline at end of file +end diff --git a/spec/models/workshop_spec.rb b/spec/models/workshop_spec.rb index 4c7898c7c..1ef0b6d6b 100644 --- a/spec/models/workshop_spec.rb +++ b/spec/models/workshop_spec.rb @@ -1,6 +1,8 @@ -require 'rails_helper' +# frozen_string_literal: true -RSpec.describe Workshop do +require "rails_helper" + +RSpec.describe(Workshop) do # pending "add some examples to (or delete) #{__FILE__}" before do create(:permission, :adult) @@ -8,72 +10,61 @@ create(:permission, :combined) end - describe 'associations' do + describe "associations" do # Need create for association tests to work correctly with callbacks/scopes subject { create(:workshop) } # Assumes functional factory - it { should belong_to(:user).optional } - it { should belong_to(:windows_type) } + it { is_expected.to(belong_to(:user).optional) } + it { is_expected.to(belong_to(:windows_type)) } - it { should have_many(:sectorable_items).dependent(:destroy).inverse_of(:sectorable) } - it { should have_many(:sectors).through(:sectorable_items) } - it { should have_many(:images).dependent(:destroy) } # As owner - it { should have_many(:workshop_logs).dependent(:destroy) } # As owner - it { should have_many(:bookmarks).dependent(:destroy) } # As bookmarkable - it { should have_many(:workshop_variations).dependent(:destroy) } - it { should have_many(:categorizable_items).dependent(:destroy) } # As categorizable - it { should have_many(:categories).through(:categorizable_items) } - it { should have_many(:metadata).through(:categories) } - it { should have_many(:quotable_item_quotes).dependent(:destroy) } # As quotable - it { should have_many(:quotes).through(:quotable_item_quotes) } - it { should have_many(:workshop_resources).dependent(:destroy) } - it { should have_many(:resources).through(:workshop_resources) } - it { should have_many(:attachments).dependent(:destroy) } # As owner - it { should have_many(:workshop_age_ranges) } + it { is_expected.to(have_many(:sectorable_items).dependent(:destroy).inverse_of(:sectorable)) } + it { is_expected.to(have_many(:sectors).through(:sectorable_items)) } + it { is_expected.to(have_many(:images).dependent(:destroy)) } # As owner + it { is_expected.to(have_many(:workshop_logs).dependent(:destroy)) } # As owner + it { is_expected.to(have_many(:bookmarks).dependent(:destroy)) } # As bookmarkable + it { is_expected.to(have_many(:workshop_variations).dependent(:destroy)) } + it { is_expected.to(have_many(:categorizable_items).dependent(:destroy)) } # As categorizable + it { is_expected.to(have_many(:categories).through(:categorizable_items)) } + it { is_expected.to(have_many(:metadata).through(:categories)) } + it { is_expected.to(have_many(:quotable_item_quotes).dependent(:destroy)) } # As quotable + it { is_expected.to(have_many(:quotes).through(:quotable_item_quotes)) } + it { is_expected.to(have_many(:workshop_resources).dependent(:destroy)) } + it { is_expected.to(have_many(:resources).through(:workshop_resources)) } + it { is_expected.to(have_many(:attachments).dependent(:destroy)) } # As owner + it { is_expected.to(have_many(:workshop_age_ranges)) } # Nested Attributes - it { should accept_nested_attributes_for(:images).allow_destroy(true) } - it { should accept_nested_attributes_for(:sectorable_items).allow_destroy(true) } - it { should accept_nested_attributes_for(:sectors).allow_destroy(true) } - it { should accept_nested_attributes_for(:workshop_age_ranges).allow_destroy(true) } - it { should accept_nested_attributes_for(:quotes) } - it { should accept_nested_attributes_for(:workshop_variations) } - it { should accept_nested_attributes_for(:workshop_logs).allow_destroy(true) } + it { is_expected.to(accept_nested_attributes_for(:images).allow_destroy(true)) } + it { is_expected.to(accept_nested_attributes_for(:sectorable_items).allow_destroy(true)) } + it { is_expected.to(accept_nested_attributes_for(:sectors).allow_destroy(true)) } + it { is_expected.to(accept_nested_attributes_for(:workshop_age_ranges).allow_destroy(true)) } + it { is_expected.to(accept_nested_attributes_for(:quotes)) } + it { is_expected.to(accept_nested_attributes_for(:workshop_variations)) } + it { is_expected.to(accept_nested_attributes_for(:workshop_logs).allow_destroy(true)) } # Paperclip # it { should have_attached_file(:thumbnail) } # it { should have_attached_file(:header) } end - describe 'validations' do + describe "validations" do # Requires associations for create subject { build(:workshop, user: create(:user), windows_type: create(:windows_type)) } - it { should validate_presence_of(:title) } - it { should validate_length_of(:age_range).is_at_most(16) } + it { is_expected.to(validate_presence_of(:title)) } + it { is_expected.to(validate_length_of(:age_range).is_at_most(16)) } # Paperclip # it { should validate_attachment_content_type(:thumbnail).allowing('image/png', 'image/jpeg', 'image/gif') } # it { should validate_attachment_content_type(:header).allowing('image/png', 'image/jpeg', 'image/gif') } # Conditional presence validation for legacy workshops (month, year) - context 'when legacy is true' do - before { allow(subject).to receive(:legacy).and_return(true) } - # Cannot easily test conditional validation with shoulda-matchers, test manually - # it { should validate_presence_of(:month) } - # it { should validate_presence_of(:year) } - end - context 'when legacy is false' do - before { allow(subject).to receive(:legacy).and_return(false) } - # it { should_not validate_presence_of(:month) } - # it { should_not validate_presence_of(:year) } - end end - it 'is valid with valid attributes' do - # Note: Factory needs associations uncommented for create + it "is valid with valid attributes" do # rubocop:todo RSpec/NoExpectationExample + # NOTE: Factory needs associations uncommented for create # expect(build(:workshop)).to be_valid end # Add tests for scopes, methods like #rating, #log_count, SearchCop etc. -end \ No newline at end of file +end diff --git a/spec/models/workshop_variation_spec.rb b/spec/models/workshop_variation_spec.rb index b5c6aa390..b564d0490 100644 --- a/spec/models/workshop_variation_spec.rb +++ b/spec/models/workshop_variation_spec.rb @@ -1,16 +1,10 @@ -require 'rails_helper' +# frozen_string_literal: true -RSpec.describe WorkshopVariation do +require "rails_helper" - describe 'associations' do - it { should belong_to(:workshop) } - end - - describe 'validations' do - # Add validation tests if any (e.g., presence of name, code?) - # subject { build(:workshop_variation) } # Requires workshop - # it { should validate_presence_of(:name) } - # it { should validate_presence_of(:code) } +RSpec.describe(WorkshopVariation) do + describe "associations" do + it { is_expected.to(belong_to(:workshop)) } end # it 'is valid with valid attributes' do @@ -18,4 +12,4 @@ # # expect(build(:workshop_variation)).to be_valid # pending("Requires functional workshop factory and association uncommented") # end -end \ No newline at end of file +end diff --git a/spec/rails_helper.rb b/spec/rails_helper.rb index cd74f7d39..6db661ed6 100644 --- a/spec/rails_helper.rb +++ b/spec/rails_helper.rb @@ -1,18 +1,20 @@ -require 'shoulda/matchers' -require 'spec_helper' -ENV['RAILS_ENV'] ||= 'test' -require File.expand_path('../config/environment', __dir__) +# frozen_string_literal: true + +require "shoulda/matchers" +require "spec_helper" +ENV["RAILS_ENV"] ||= "test" +require File.expand_path("../config/environment", __dir__) # Prevent database truncation if the environment is production abort("The Rails environment is running in production mode!") if Rails.env.production? -require 'rspec/rails' -require 'factory_bot_rails' +require "rspec/rails" +require "factory_bot_rails" # Add additional requires below this line. Rails is not loaded until this point! # Setup Shoulda Matchers Shoulda::Matchers.configure do |config| config.integrate do |with| - with.test_framework :rspec - with.library :rails + with.test_framework(:rspec) + with.library(:rails) end end @@ -28,7 +30,7 @@ # of increasing the boot-up time by auto-requiring all files in the support # directory. Alternatively, in the individual `*_spec.rb` files, manually # require only the support files necessary. -Dir[Rails.root.join('spec', 'support', '**', '*.rb')].sort.each { |f| require f } +Dir[Rails.root.join("spec/support/**/*.rb")].sort.each { |f| require f } # Checks for pending migrations and applies them before tests are run. # If you are not using ActiveRecord, you can remove these lines. @@ -36,11 +38,11 @@ ActiveRecord::Migration.maintain_test_schema! rescue ActiveRecord::PendingMigrationError => e puts e.to_s.strip - exit 1 + exit(1) end RSpec.configure do |config| # Remove this line if you're not using ActiveRecord or ActiveRecord fixtures - config.fixture_path = "#{::Rails.root}/spec/fixtures" + config.fixture_path = Rails.root.join("spec/fixtures").to_s # If you're not using ActiveRecord, or you'd prefer not to run each of your # examples within a transaction, remove the following line or assign false @@ -71,7 +73,7 @@ # config.filter_gems_from_backtrace("gem name") # ==> Mailer Prevention (add this block) - config.before(:each) do + config.before do ActionMailer::Base.delivery_method = :test ActionMailer::Base.deliveries.clear end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 952eb2ed9..3aa26641b 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # This file was generated by the `rails generate rspec:install` command. Conventionally, all # specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`. # The generated `.rspec` file contains `--require spec_helper` which will cause @@ -17,7 +19,7 @@ # rspec-expectations config goes here. You can use an alternate # assertion/expectation library such as wrong or the stdlib/minitest # assertions if you prefer. - config.expect_with :rspec do |expectations| + config.expect_with(:rspec) do |expectations| # This option will default to `true` in RSpec 4. It makes the `description` # and `failure_message` of custom matchers include text for helper methods # defined using `chain`, e.g.: @@ -30,7 +32,7 @@ # rspec-mocks config goes here. You can use an alternate test double # library (such as bogus or mocha) by changing the `mock_with` option here. - config.mock_with :rspec do |mocks| + config.mock_with(:rspec) do |mocks| # Prevents you from mocking or stubbing a method that does not exist on # a real object. This is generally recommended, and will default to # `true` in RSpec 4. @@ -89,5 +91,5 @@ # 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 + Kernel.srand(config.seed) end diff --git a/spec/support/capybara.rb b/spec/support/capybara.rb index 64f0d7868..5eab3c055 100644 --- a/spec/support/capybara.rb +++ b/spec/support/capybara.rb @@ -1,6 +1,8 @@ +# frozen_string_literal: true + RSpec.configure do |config| # Configure default driver for system specs config.before(:each, type: :system) do driven_by :rack_test end -end \ No newline at end of file +end diff --git a/spec/support/devise.rb b/spec/support/devise.rb index 837bd8289..6e3eeb226 100644 --- a/spec/support/devise.rb +++ b/spec/support/devise.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + RSpec.configure do |config| - config.include Devise::Test::IntegrationHelpers, type: :system -end \ No newline at end of file + config.include(Devise::Test::IntegrationHelpers, type: :system) +end diff --git a/spec/support/factory_bot.rb b/spec/support/factory_bot.rb index 17bb77cc8..c02fcfe53 100644 --- a/spec/support/factory_bot.rb +++ b/spec/support/factory_bot.rb @@ -1,5 +1,7 @@ -require 'factory_bot_rails' +# frozen_string_literal: true + +require "factory_bot_rails" RSpec.configure do |config| - config.include FactoryBot::Syntax::Methods -end \ No newline at end of file + config.include(FactoryBot::Syntax::Methods) +end diff --git a/spec/support/faker.rb b/spec/support/faker.rb index 8480e3feb..17a333b17 100644 --- a/spec/support/faker.rb +++ b/spec/support/faker.rb @@ -1,5 +1,7 @@ +# frozen_string_literal: true + # give it a specific seed to ensure the same data is generated. This combined # with running rspec with a specific seed value will ensure that specs are run # in the same order and the same "faked" data is generated each time: giving # us deterministic results. -Faker::Config.random = Random.new(42) \ No newline at end of file +Faker::Config.random = Random.new(42) diff --git a/spec/support/mandrill_mailer.rb b/spec/support/mandrill_mailer.rb index ff5a9b3cf..6d306a7bf 100644 --- a/spec/support/mandrill_mailer.rb +++ b/spec/support/mandrill_mailer.rb @@ -1,8 +1,10 @@ -# I am fairly certain that we are not actively using MandrillMailer in the +# frozen_string_literal: true + +# I am fairly certain that we are not actively using MandrillMailer in the # codebase. However, it is included in the Gemfile and it is configured in # config/initializers/mail.rb. Just in case it is being used by some 3rd party # gem, we will enable offline mode for the test env: # # https://github.com/renz45/mandrill_mailer?tab=readme-ov-file#offline-testing -require 'mandrill_mailer/offline' +require "mandrill_mailer/offline" diff --git a/spec/support/paperclip.rb b/spec/support/paperclip.rb index 01d4b1f7b..d717280db 100644 --- a/spec/support/paperclip.rb +++ b/spec/support/paperclip.rb @@ -1,5 +1,7 @@ +# frozen_string_literal: true + require "paperclip/matchers" RSpec.configure do |config| - config.include Paperclip::Shoulda::Matchers -end \ No newline at end of file + config.include(Paperclip::Shoulda::Matchers) +end diff --git a/spec/system/login_spec.rb b/spec/system/login_spec.rb index f3d5a5d9a..dc098a41d 100644 --- a/spec/system/login_spec.rb +++ b/spec/system/login_spec.rb @@ -1,7 +1,8 @@ -require 'rails_helper' +# frozen_string_literal: true -RSpec.describe 'User login', type: :system do +require "rails_helper" +RSpec.describe("User login", type: :system) do before do create(:permission, :adult) create(:permission, :children) @@ -10,14 +11,14 @@ let!(:user) { create(:user) } - it 'logs the user in with valid credentials' do + it "logs the user in with valid credentials" do visit new_user_session_path - fill_in 'Email', with: user.email - fill_in 'Password', with: 'password' + fill_in "Email", with: user.email + fill_in "Password", with: "password" - click_button 'Log in' + click_button "Log in" - expect(page).to have_content("Welcome back, #{user.first_name} #{ user.last_name}") + expect(page).to(have_content("Welcome back, #{user.first_name} #{user.last_name}")) end end diff --git a/spec/system/workshops_spec.rb b/spec/system/workshops_spec.rb index 8fa19277a..d4bd7b29f 100644 --- a/spec/system/workshops_spec.rb +++ b/spec/system/workshops_spec.rb @@ -1,6 +1,8 @@ -require 'rails_helper' +# frozen_string_literal: true -RSpec.describe "Workshops" do +require "rails_helper" + +RSpec.describe("Workshops") do before do create(:footer) create(:permission, :adult) @@ -8,66 +10,66 @@ create(:permission, :combined) end - describe 'workshop index' do - context "When user is logged in" do - it 'User sees overview of workshops' do + describe "workshop index" do + context "When user is logged in" do # rubocop:todo RSpec/ContextWording + it "User sees overview of workshops" do sign_in(create(:user)) - + create(:sector, :other) adult_window = create(:windows_type, :adult) - workshop_world = create(:workshop, title: 'The best workshop in the world', windows_type: adult_window) - workshop_mars = create(:workshop, title: 'The best workshop on mars', windows_type: adult_window) - workshop_hello = create(:workshop, title: 'oh hello!', windows_type: adult_window) - + create(:workshop, title: "The best workshop in the world", windows_type: adult_window) + create(:workshop, title: "The best workshop on mars", windows_type: adult_window) + create(:workshop, title: "oh hello!", windows_type: adult_window) + visit workshops_path - within('.search-wrapper') do - expect(page).to have_content('The best workshop in the world') - expect(page).to have_content('The best workshop on mars') - expect(page).to have_content('oh hello!') + within(".search-wrapper") do + expect(page).to(have_content("The best workshop in the world")) + expect(page).to(have_content("The best workshop on mars")) + expect(page).to(have_content("oh hello!")) end end # Can't get this damn spec to work. WorkshopController#index performs a mix of "permissions" - # checks using User#curriculum + search using Workshop#search (full text on query param & + # checks using User#curriculum + search using Workshop#search (full text on query param & # where col match using windows_type_id). I am not sure why my factory data is being excluded. - xit 'User can search for a workshop' do + xit "User can search for a workshop" do # rubocop:todo RSpec/PendingWithoutReason user = create(:user) sign_in(user) - + create(:sector, :other) adult_window = create(:windows_type, :adult) - workshop_world = create(:workshop, title: 'The best workshop in the world', windows_type: adult_window) - workshop_mars = create(:workshop, title: 'The best workshop on mars', windows_type: adult_window) - workshop_hello = create(:workshop, title: 'oh hello!', windows_type: adult_window) - + create(:workshop, title: "The best workshop in the world", windows_type: adult_window) + create(:workshop, title: "The best workshop on mars", windows_type: adult_window) + create(:workshop, title: "oh hello!", windows_type: adult_window) + visit workshops_path - fill_in 'query', with: 'best workshop' + fill_in "query", with: "best workshop" choose "type_#{adult_window.id}" # radio button for Adult Workshop Radio isn't associated with the label - - click_on 'Apply filters' - within('.search-wrapper') do - expect(page).to have_content('The best workshop in the world') - expect(page).to have_content('The best workshop on mars') - expect(page).not_to have_content('oh hello!') + click_on "Apply filters" + + within(".search-wrapper") do + expect(page).to(have_content("The best workshop in the world")) + expect(page).to(have_content("The best workshop on mars")) + expect(page).not_to(have_content("oh hello!")) end end end end - describe 'view workshops' do - context "When user is logged in" do + describe "view workshops" do + context "When user is logged in" do # rubocop:todo RSpec/ContextWording it "User sees workshop details" do sign_in(create(:user)) - - workshop = create(:workshop, title: 'The best workshop in the world. This is a tribute.') - + + workshop = create(:workshop, title: "The best workshop in the world. This is a tribute.") + visit workshop_path(workshop) - - expect(page).to have_css(".inner-hero", text: 'The best workshop in the world. This is a tribute.') + + expect(page).to(have_css(".inner-hero", text: "The best workshop in the world. This is a tribute.")) end end end -end \ No newline at end of file +end